From 88555bbea28342b8a7625bef39de725852cc0033 Mon Sep 17 00:00:00 2001 From: James Cole Date: Sat, 20 Feb 2016 14:18:55 +0100 Subject: [PATCH 01/15] Some translations. --- resources/lang/en_US/firefly.php | 25 +++++++++++++------------ resources/lang/nl_NL/firefly.php | 1 + 2 files changed, 14 insertions(+), 12 deletions(-) diff --git a/resources/lang/en_US/firefly.php b/resources/lang/en_US/firefly.php index e9ed71aa0c..08f1bf31b7 100644 --- a/resources/lang/en_US/firefly.php +++ b/resources/lang/en_US/firefly.php @@ -44,6 +44,7 @@ return [ 'flash_error' => 'Error!', 'flash_info_multiple' => 'There is one message|There are :count messages', 'flash_error_multiple' => 'There is one error|There are :count errors', + 'net_worth' => 'Net worth', // export data: @@ -114,23 +115,23 @@ return [ 'default_rule_action_prepend' => 'Bought the world from ', 'default_rule_action_set_category' => 'Large expenses', - 'trigger' => 'Trigger', - 'trigger_value' => 'Trigger on value', - 'stop_processing_other_triggers' => 'Stop processing other triggers', - 'add_rule_trigger' => 'Add new trigger', - 'action' => 'Action', - 'action_value' => 'Action value', - 'stop_executing_other_actions' => 'Stop executing other actions', - 'add_rule_action' => 'Add new action', - 'edit_rule' => 'Edit rule ":title"', - 'delete_rule' => 'Delete rule ":title"', - 'update_rule' => 'Update rule', + 'trigger' => 'Trigger', + 'trigger_value' => 'Trigger on value', + 'stop_processing_other_triggers' => 'Stop processing other triggers', + 'add_rule_trigger' => 'Add new trigger', + 'action' => 'Action', + 'action_value' => 'Action value', + 'stop_executing_other_actions' => 'Stop executing other actions', + 'add_rule_action' => 'Add new action', + 'edit_rule' => 'Edit rule ":title"', + 'delete_rule' => 'Delete rule ":title"', + 'update_rule' => 'Update rule', 'test_rule_triggers' => 'See matching transactions', 'warning_transaction_subset' => 'For performance reasons this list is limited to :max_num_transactions and may only show a subset of matching transactions', 'warning_no_matching_transactions' => 'No matching transactions found. Please note that for performance reasons, only the last :num_transactions transactions have been checked.', 'warning_no_valid_triggers' => 'No valid triggers provided.', - + // actions and triggers 'rule_trigger_user_action' => 'User action is ":trigger_value"', 'rule_trigger_from_account_starts' => 'Source account starts with ":trigger_value"', diff --git a/resources/lang/nl_NL/firefly.php b/resources/lang/nl_NL/firefly.php index e903fdb754..85be6e27a2 100755 --- a/resources/lang/nl_NL/firefly.php +++ b/resources/lang/nl_NL/firefly.php @@ -44,6 +44,7 @@ return [ 'flash_error' => 'Fout!', 'flash_info_multiple' => 'Er is één melding|Er zijn :count meldingen', 'flash_error_multiple' => 'Er is één fout|Er zijn :count fouten', + 'net_worth' => 'Kapitaal', // export data: From eaf2efc5102707c27db8c11aa666b2c6502c1864 Mon Sep 17 00:00:00 2001 From: James Cole Date: Sat, 20 Feb 2016 18:47:06 +0100 Subject: [PATCH 02/15] Updated favicons. --- public/android-chrome-144x144.png | Bin 3504 -> 3603 bytes public/android-chrome-192x192.png | Bin 4708 -> 4807 bytes public/android-chrome-36x36.png | Bin 933 -> 1032 bytes public/android-chrome-48x48.png | Bin 1208 -> 1307 bytes public/android-chrome-72x72.png | Bin 1768 -> 1867 bytes public/android-chrome-96x96.png | Bin 2350 -> 2449 bytes public/apple-touch-icon-114x114.png | Bin 2299 -> 2088 bytes public/apple-touch-icon-120x120.png | Bin 2388 -> 2205 bytes public/apple-touch-icon-144x144.png | Bin 2906 -> 2666 bytes public/apple-touch-icon-152x152.png | Bin 3068 -> 2782 bytes public/apple-touch-icon-180x180.png | Bin 3629 -> 3298 bytes public/apple-touch-icon-57x57.png | Bin 1173 -> 1155 bytes public/apple-touch-icon-60x60.png | Bin 1244 -> 1195 bytes public/apple-touch-icon-72x72.png | Bin 1477 -> 1393 bytes public/apple-touch-icon-76x76.png | Bin 1543 -> 1460 bytes public/apple-touch-icon-precomposed.png | Bin 5015 -> 4747 bytes public/apple-touch-icon.png | Bin 3629 -> 3298 bytes public/browserconfig.xml | 10 ++-- public/favicon-16x16.png | Bin 509 -> 608 bytes public/favicon-194x194.png | Bin 0 -> 4837 bytes public/favicon-32x32.png | Bin 842 -> 941 bytes public/favicon-96x96.png | Bin 2350 -> 2449 bytes public/manifest.json | 25 +++++----- public/mstile-144x144.png | Bin 3683 -> 3582 bytes public/mstile-150x150.png | Bin 3599 -> 3554 bytes public/mstile-310x150.png | Bin 3866 -> 3828 bytes public/mstile-310x310.png | Bin 7946 -> 7630 bytes public/mstile-70x70.png | Bin 2490 -> 2468 bytes public/safari-pinned-tab.svg | 48 +++++++++++++++++++ resources/views/errors/FireflyException.twig | 19 +------- resources/views/layout/default.twig | 19 +------- resources/views/layout/empty.twig | 19 +------- resources/views/layout/guest.twig | 19 +------- resources/views/partials/favicons.twig | 18 +++++++ 34 files changed, 87 insertions(+), 90 deletions(-) create mode 100644 public/favicon-194x194.png create mode 100644 public/safari-pinned-tab.svg create mode 100644 resources/views/partials/favicons.twig diff --git a/public/android-chrome-144x144.png b/public/android-chrome-144x144.png index 5bbc2e7a610cc3570dc27b470ab83f552b99c52a..0fbc935ef5611eb1be5c2768df52ad1fb822e658 100644 GIT binary patch delta 209 zcmdlWJy~W#C)Wce5g{Fo9NuXMHcmdqQ*WkgV5Dng5MpRyWnyAwVxVncXk}pV>Vz~a z0|SFRc?MtW?ChKk%1w04YQ{%-U-wYUKJ8i5|mi3P*9YgmYI{PP*Pct zs*qVwlFYzRG3W6o9*)8=4UJR&r_Xpk4Pszc=C;;L<`z~K_MR-lEUe(tU~)KxS$T7a r!s#1VP8>ONMCJ(l=?0GlUV03##05(}Ihjrc+QH!I>gTe~DWM4fe#JxS delta 109 zcmbO%vq5@7C)a&uX)!ag8WRNi0dV%FR#7OsixtGBCuh;epdDYoG=OPgg&ebxsLQ0CdnDo&W#< diff --git a/public/android-chrome-192x192.png b/public/android-chrome-192x192.png index 325f76a32cd2bac1a33d640821596ba9a8bb1720..fb8549caefb1450087e75870675b06d844da29ec 100644 GIT binary patch delta 209 zcmaE&a$I#nC)Wce5g{Fo9NuXMHcqY*tT)p&Fw!+L2r;ybP0l+XkKtsF!g delta 109 zcmX@E`b1?yC)a&uXsekrd2W+85m;M@WAPnHBbYCr>mdKI;Vst0FOHz(EtDd diff --git a/public/android-chrome-36x36.png b/public/android-chrome-36x36.png index 8bbc22da5c78bb8e8c3c85b2ad16a3a9d855ef36..c101427bd709a6d0970a2500873497ac4b0d4091 100644 GIT binary patch delta 209 zcmZ3=-oY`Ulj{MKh>(s(4)3%B8z=8(syEX$Fw!+L2r;ybP0l+XkKJpn_O delta 109 zcmeC+Sjs-3lj}aSG%vHThrfQ*#>u;x!cBDzjCGC7Lkx|r42-P|Ewv2{tqcq%$_KSG sFfgc=xJHzuB$lLF<>sekrd2W+85m;M@WAPnHBbYCr>mdKI;Vst08@A!O8@`> diff --git a/public/android-chrome-48x48.png b/public/android-chrome-48x48.png index 948730fdca3fcb62e9924aeb3468f760d7bf174e..3817a33ab751abf353d68aa38077d8eb24788ffe 100644 GIT binary patch delta 209 zcmdnNIh$)jC)Wce5g{Fo9NuXMHcmdrTyLgpV5Dng5MpRyWnyAwVxVncXk}pV>Vz~a z0|SFRc?MtW?ChKk%1w04YQ{%-U-wYUKJ8i5|mi3P*9YgmYI{PP*Pct zs*qVwlFYzRG3W6o9*)8=4UJR&r_Xpk4Pszc=C;;L<`z~K_MR-lEUe(tU~)KxS$T7a r!s#1VP8>ONMCJ(l=?0GlUV03##05(}Ihjrc+QH!I>gTe~DWM4fZS+Ib delta 109 zcmbQuwS#j)C)a&uX)!ag8WRNi0dV%FR#7OsixtGBCuh;epdDYoG=OPgg&ebxsLQ0BkcIi2wiq diff --git a/public/android-chrome-72x72.png b/public/android-chrome-72x72.png index 55a7375e8cf6a6dbf4fecf433dc366c36e545798..92ae9f437bd363ebd99f28bead3fdd57a5a704ce 100644 GIT binary patch delta 209 zcmaFCdzx=TC)Wce5g{Fo9NuXMHctM>T5qOnV5Dng5MpRyWnyAwVxVncXk}pV>Vz~a z0|SFRc?MtW?ChKk%1w04YQ{%-U-wYUKJ8i5|mi3P*9YgmYI{PP*Pct zs*qVwlFYzRG3W6o9*)8=4UJR&r_Xpk4Pszc=C;;L<`z~K_MR-lEUe(tU~)KxS$T7a r!s#1VP8>ONMCJ(l=?0GlUV03##05(}Ihjrc+QH!I>gTe~DWM4f=Y~XX delta 109 zcmX@j_kwpqC)a&uX)!ag8WRNi0dV%FR#7OsixtGBCuh;epdDYoG=OPgg&ebxsLQ0I8iGBLDyZ diff --git a/public/android-chrome-96x96.png b/public/android-chrome-96x96.png index 7ecebf0a2e314545d2b20de535b605f7b8edb90e..3602979589725e4b940849be7135cffc7dfd6a31 100644 GIT binary patch delta 191 zcmZ1{G*Ng$C)Wce5g{Fo9NuXMHcocokTTOXFw!+L2r;y0ev zjZ^-o&v-r!VqjM0)=TCVRu=Z2EW#|T;L>1nIE7hxbBMy}8&^&oIdeqj2>a;bP0l+XkKA%8wR delta 91 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 diff --git a/public/apple-touch-icon-120x120.png b/public/apple-touch-icon-120x120.png index 69f186adff530b66d55cb09478ccd036e9252619..542d5330e4a8e307e123576b10728fb4b5b91688 100644 GIT binary patch delta 2112 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 diff --git a/public/apple-touch-icon-152x152.png b/public/apple-touch-icon-152x152.png index 927af49f12bdaca6b9701c25aead2121dfa5ff67..9e51ddfb643c6c100a9fca74db0ef9925326eda5 100644 GIT binary patch delta 2657 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 P015yANkvXXu0mjfD4rYZ delta 2945 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 P015yANkvXXu0mjfNx3B` delta 3528 zcmV;(4L9=Q8Lb?UbbsFi8w~^n^V$r|000d&Nkl zj3}-c&*-WcyyJ}$^^0LW(0C*pHQuh#7~=V9bk`%sHJZ2vjZs{0;}MJ(ix*%7Q4m4! zKn1zv7#J2*x~jTrpt`#X`u+QwS3i1cs$RYK>WxsUB`LVRc7JF~M@zk}b2DGRArlTf zGZ7yXYMK+0!m~l{dI1uLZu5>mDbX^tDQ>!xfJrUi#ZgAhLg#F0sS`+|bDN){QRvjk zHi9{^=<F%tEK<+Je6LPSwmp z{b)@=-|9fYEPvEKTLaKVNhdZe`1JEHx1LEux44IWXqW|?qty*z z69ZvqPo!cNYz|j5bYh6FB@EDH`HKpb@f#~mLciG5TDox<0utXU_dC%sS2OgjVU`4j z0m-kGH(F9MS1p|?`5!EYw{s6Q+It|Vbid+1MVeQ>M@HOvt@zA7gf7MuB*(4U$f@9J;= zMp19%!GCP2Wq#1c&tx#$F3XerdG^T(9##$CUlNgzo8||7p`MJd;G9>ufucLdqH~CW z4{p%LDKcL4m<(CAxk2A_r)Tz!muH(B^n7||hhJsd<^`SXO%FY#P$SU04b;q@F>;M_ zf-d}!npqbj+d3!cThgzgl~d!tbm`U0yA}rBGJip~bxzP55f{$he|cC$VtPh)cG}@# z))MHi=EWBf66z{2RgP9pfUubE?Ut%1bUKDzIi^-J0RaO z@P$Mf;|ej`9amtU3$*bgK-Kn+RQm|_{yINbV4n+g3OHmNwqV*=_)RZTVxJ5239ztr zdVhpz4?*jP!#T}Be+j5o;o4=;i+(p8oafeH=)e4rNss7^02?Fxuln5f9}-~e4P7(n&JKK>#k&iHzE+?wIRL0W*oGK|BvfW<1$r|S@n~^hsy&WGJ+$&g%=!R=vRI8O zOOj!4Nf25;P&No-XyZDh=&Mnf7!WmO-wm753Qb$-2W{R7zqXM{K+RDyHByv1*1 znqOmSKg(K^BD0nbizk5<9oCI^;4} zg*NER2>Sj~Pn}w3;)#+Ubk=qs^~hy1lhPMq0ew5bT0L;N^vUp^GOoVs7;t?T`$nN3<^)!p5Urd*4<~-G5x19qsg0 z5nDEy7EL`Oi`657SoPIy-~IGw>5o$qZr`|kdQZpzyll{-ZpV+O2M3J_7(IE(zBn0f zDwB0OdF$svqXT-@hlzaS&}Z^aODgmn2K_VgdD+5jGL^_ZDl*y;O(n&~+{=T(7Nc8- zJ+m5NcHF5je!vd;jihuJnSUC^VcG{sq4W^t%#8i%ZQ`pYL=Q?s;RC|oRSd%xI$TU4 z4<^)0B|v_l?mNvuUvjK~nnd_=r9y=(4e1v+-q0t-2|!9}KJsBRrCHBu5o#krn+D=I zy3J~aVGBLG0?M$LpnV9EagAc|kvEQ-1+fkCY(1BgVum zwy7G2DKvgZip5KI)b2ii=q%tbkxC-+#eiyE*)@;+pc6sninJl#_Y|RTY6topD2iA| zP#+cdc!x{cf!-sY1b_9r2x?FyWOrIS&=wKV1&^_@@Qe{dDpd3wEAAeCD(9p}o!x|Be0D86(>ztrd z!5PpSJGUN#&RXAU2s*N^h&2{Fw?G#%3_oiKdN)|6|Ai?bXv@P2jPrt?DPlQAR0eIW zGLFX*I@?dg>ih!JLeO>>wF4dNCSuLNwMPK7Lxgdc^XK_f?e4~N%|GN~P|5oqYr_1Cx-?YU!pN+Zzw z#CK`AA5#_#L7?kg)(G@$fE0--K^4erai_i+!haV!3#5o#@k)+ct_ZaEV+A8{fR1S> zB6(uhwMx&S&2_qIQ-lvZ5omXHC3&o%jZo&QHQvwzTExqx)guK%u!m0X2#^R>Viz0` z=x&tvvp7SCf|!@hL0o+ly$w2Cb@GA*bP|+p>q^K0{fOTBo2oYR$pSii0<;FNCp@qY z-CLHaXI2eeuo(LEz3vg7ScovQ*jv;>7k_VrHWuLv(npWpN3#m6dFaD%Z(ENj!V^WK z5a`6w(~2sB~$sb1)unQ+HdJ^8XJ zlp%P%x2Qk2sDjR3h;;JydqRBbAiB2pV1D!k`VRkapfieVLrj@p-p@cSOWq;0eCNQI{u4Ej7_oO&}NDk3aTcXY+uVYef0bNS)p9E8ecgtB)nfiBtG zlxV$v;FdE{@$pfcyAXb5!G+Lat~Bqru~q-TOx;K-$SR=syO^_YVdvbSfqyfpCymu= zd_uoE9#GX=E*HZA2GD0bC`OXXXsqtMFnkORvSLRSflj3Q2`q`=6FT;jx|Dz0J&m5! z40Op{1PmgzUESrzn7K?Z#8$~H zv(GvY*>#`AnFWVlD~q`kwgsn{dC`__=3iFR`k+$i9dej^;P+%t)qf&AXy5OLR0dPR z9Q1j*z4x{BBh(V?!u##$T*secasDv75W_;sbGS+hZriT2-^eev z{gKKbbWRIhYI?B7{AJs=_GsU8=%n>m%{MYAc$%K^%E;&SnujjKzB{Ke=~n>tUem(v zX66;DIYo1WE-f|2hV5KC>%$JN;AEwD9sGTw7I4i%zmdZ9>;E3=Qhtc7)iQA1)!do} zh2{SsN&)nyMO2oP5eyesH7zhREiyM$F*7ppnF*PkPGc7VVR53F;Ff=+aH7hVNIxsK^l$)pk00000jCLc<=R z*vzob65CL*78A*2Y73STBrIV;ghb6F8McslES?em@QNXxn=y$PA`M|#OeBQFHhYGd zy{cVnI_tg8xwQ?kx<~vW&OhH@();PX_ndRjIS~J};Xjq-X@3KG^;q*Wfl;~(Mnh^5 zC32;!-AV6qDG1+MYL_h8dNL($#$lUi8Quet;FKd@Cn?Ca$~DCkN$|WRXMdIC4an)2gcO0$oJ6*DJR*P2xJH>(h`7VIs!Fe;LnOI@*t2yv&0XYCoED} z1}>i#dx5Yz7HQQ(SxmBf5iqWqMLr%3?m(y0RvHO}KB%sIC&-h|>yya%2O1Of!5o>g zLE0gP23fLfz8XI@zdLfI)gWEWDY!nVEt4a^98HYk;eWHf@WP3e{(w(n*7iM*+_Iil za8*Phl71Hs6ELOa7nk(gw;%PG=Agw|V3Wuq-wa1;H!U&{aF0peS7Q}TmkGK?CYjG+ zE6w@{#I!NVTtNDoZ~8)SW09X`0n&Wm1kCMXk=BV&-XQ6m31o^avUNQCEhL+xfm2Mf zNe2yGN`LA{BH$sDtP6v-l4RLHgw`<0r-NXmU0S5Xgmxx*j)$4%RRyLxnB+RB3Tf^J z;@ViG&4>|iNIJ-%Nbf6KJ`aY$PO^FgFtmb2p64;!MY41Nplf208-aAX))lJ&LkEL& zCV@Lfi_>HQn)gM%6ppJgs)|;5M6MR)%ezB>ZGTc_CUVE`q|jb%m5T0LWL1xqb`n<# zkw<26t| zqJK{rm;1b<+iMRAM?*cEk5V%#N9tlr{PY$3i#~|`ww@kxKiilR&iU&1J*e_b8MoE$ z7QMB9`!xRdm zIx{#cFflqXFrvTY#{d8TS9(-fbW&k=AaHVTW@&6?Aar?fWguyAbYlPjc%0+%3h($07*qoM6N<$g0z#`TL1t6 delta 1072 zcmV-01kd|}36%+ubbsFi8w~^n^V$r|000A>Nkl+jF}MU9Ut}+GrWrDr)#N2tBgJ*1HXvNrkOx&D~q<1JfeupJFalM&4Qj)fX5>Z@)$6; zg#`^WfZ5IB(i{tHN=EkZ7U{)iGACIRElhY~xwhV1E?A+!9 zF+D8kq>SQI^M8Y3J+j>W)P9)0qKSGfjR?*|xp zbk`MQDt|P{*Lq0SC36VSzttdfb#Uit;0H}@z-J9|FEIKQ3*P8~@JPU7{DhfnE1L#iSuzfoVYm1j()h+Vp}>`A$y>`k{dtX@ay-LLOM9A^nW z*ME+zKj7~%esd*_r!6Od+PdXg-@XfBa?b99=gMu%S4*t-!aW6sP=4s`;{RWp9`N_h z_sy1U4*loQielNols!{7P@`MlVN2d{8VZ-aX9I}uzb-nB@>yF?t5X875n86*VzWBNeQa50000bbVXQnWMOn=I%9HWVRU5x zGB7bUEif}JGB;E)GdeIdIxsaWFflqXFnGx$6aWAKC3HntbYx+4WjbwdWNBu304Xvs qF*PkPGc7VVR53F;Ff=+aH7hVNIxsK^l$)pk0000xY(>u4ByX!R6ZKwLD=AZfP?tE@%cV~Vx2mTKV{(tYK0iCcj}3 zk-FWS97rFF!ZSyg+|RaPoFA@?@k?veio(xq7p+O&96dFy&=@ZZ;`tL4Sy-D=96q${ zx*+ay1N@6?Uw>Y<1Gu|98?NHu_LkIB5x|x{MtlZ1N9#dfAZ39KkA=YMISpQsZr|qF zaI+&^KhmI#e5VFR{D4F77^xRd0}?qS&I4rAq@D-^+uACmJaU!GpX{WqP zB^GO%63O&6*({T7wWCADUMku6L?r%{BgL|kBMz$$V}FHmNgUP`c{!62y(u?8FLN91 zwMSh1k?UVXc6)BHjiinO8aBBAK5g?F?XpG!Z#x%UHLaCA{36TG#CwnM-LYm8R^t!W28Fc>T0EpklMyyRV+_26HmbHv{{vdFH29G#M<&1cCpP{#fK+q^7R`|oF zjs{skjEWJzv4_t94bp*l4I{n-BvGS`0iqf2OozrT8nmnj{1j|>B-k*gsz^@o8eqfZ zk@a&bpX8Ap6Kwdt30%8rkU?;)nhl=^cGGF0iGL?Jg=fN@0YD)QlzR!j$b?4@0iGQ+ zB54G;$%3cOn!-evIr(l^81kSXRyUTGwd+=Jc@o($$@E*0S}TIf$0z3mac?@Ax9-J# z%Fj2vNl!QEKC=2XePlQUh9)!%;Qnacf@0C2JYs*Jwr#*+@lrKVH>=l`@Qndi>( z{A}b^XX75sIlX^%O!LNKvCJiFx;mTF9oWe-i>g`$pE-4jwYj1sXWmOl$hl^`SUK%3 z#SIY_dTA{QsnCtaq2p00B{dxyp8qB0hs#dwS_7wq>K27z$2F_e^1|ic_;>Sn@pp>) z)g*=)gMO241Q!}MEif`IGB8vzI65>mIx{#cFflqXFw^2(dy}687k@S_FfuJNFjO%( zIy5voGdL?SF*-0XqQB(F00012dQ@0+Qek%>aB^>EX>4U6ba`-PAZc)PV*mhnoa6Eg z2ys>@D9TUE%t_@^00ScnE@KN5BNI!L6ay0=M1VBIWCJ6!R3OXP)X2ol#2my2%YaCr bN-hBE7ZG&wLN%2D015yANkvXXu0mjfR$Ap~ delta 1143 zcmV--1c>{q3ET;gbbsFi8w~^n^V$r|000BzNklJAS)%l!j9z3ei$Jq1!a~xh^+#nzWKjfKCiO=a1!YD=RF;(%RtRb?sqCej zuRU;^`rEH_@6Xw^slR*w7~kFB@AJFoo_p>&2Y8mzdq2Tb>VFZix4nqRKd_GN?I&K& ztR&k)XWPG8g@4DR!u{KaEFArN*z-|g?Q}!}maBJ!5wDFan9Ujh{5oJsv>k)qJ;&v zr(+a;rZN+^oX)erhG?{v9<3<`;T$HoKG3nzrYQ&?WPgFpxwujJk*cc7(iCzT!%h?w zoT(QD+n%j;Cm|_QC@1{OAFx{t+?YP(_709EhOuFD61W~o=CNU0mO@VM!o-yAo7OB+ zQ2T=;!Xwja#h7iZs!-!r^EjUCGv?uUqz9ThJG%SCdi#?<$RASG5Def~>*AG>;degZ zT|-sN41a*7CMNin3?^%-YQ`8j$uq$kfH|!W8@#HRU~UU0EhCjTq>c+B7PckhsnSfq zXAD#q@$j#?0Gm0Y^br6vTbST-4DC#+UU~v7HZsAb7#WADI*0MKg=2z?5IIX#7OLYs z6MO-YVj}F@FtBg4!3Btv5n)>a;9JWE=V9u6PJcwJ3SjmhCYTr-@|~#q04(ihCb%mK zU|la!b^ZV=dYRyl{tjnXdjllfnBY>W<1(B=x6f~9g0V(~>xrsjENnEkS;dQ5VEd=CqpkHqD{&%j2G0q#n``~Qi`LXxzz zd4KV6Z$4JGR3S+pA@E5C_&W9zzRv``i*#?-MZ?@(QjRl(h_oc4mRF1lo62)`U+th$ zr|~0)BcyEp3+dzB&i~dKxsl)xYdr9k<&RCAp)5v5D%?H6h`Oz`I4eU`(Z_mR!*5hV z0riUA5aU5hqK2$vuiH0eScm;T+!;Tt3V%ydyK%bv)HJ6#&;2Hs@VjAMfMin}&bDop zIoj+%Rb19ntLr_#Rt{lhYTBV58~7Kx_fcb8k9{O>Yn{yl_dQ+Yfo&z4pbUz=_|0`_ zI^h00aqa>roupcJZNRJdcOJO%s>#5QGK8bj7w=yc1mje>Z-1G2@#8N#jvPc9NpSom z0000bbVXQnWMOn=I%9HWVRU5xGB7bUEif}JGB;E)GdeIdIxsaWFflqXFnGx$6aWAK zC3HntbYx+4WjbwdWNBu305UK!H7zhREiyM$F*7v9O3`~ diff --git a/public/apple-touch-icon-72x72.png b/public/apple-touch-icon-72x72.png index 360ad6b514094f84183ddfbd69bf89489571983c..d2080d08e2beb3cba7bbe90c60fa7b77ab3888d8 100644 GIT binary patch delta 1294 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 diff --git a/public/apple-touch-icon-76x76.png b/public/apple-touch-icon-76x76.png index 25cd70ee50d909ebbc9f9ab443e8eed46ffb5586..47bd65a56d47828265739f2b88c2b2682c90d5f8 100644 GIT binary patch delta 1361 zcmV-X1+Mys473Z7bbsIi6cQ{Zi?zGQ000D8Nkl4V}00X3L4DK#plwl&tE773wV60gx}Ybg4lQBeuEm$p$t+Xt!9 zh-kD+P%v^6Vd*Zr$__LA&zS*s?aI!~@x{dR!oTdymow+`pMQTAgm>8B1NMGmugg>X zv_2E!4?Y-R#yY?C2immLkJ%ZqmNX3vHlGqz7;o))MT7P~sgZKwzLY|&T-}`sJpb+a?;A%~)lfK|wE|Z5{8|7ko9e013ENs9? zglJ=4eu_82=5{b(&0%P5X~kJHXAXzn6x8;-2yjE3bVu<_rE6nuH<@2?>j9 zRbXvLBQ@Zz?NE&I6>(nRzI|p>iZ#!Gx3wHjDP~^l>rI|g6Spa6{mM9B%8ZGM{nW72 z-IRJ5vw!ZI%FVcB!*OZxoOwIVKQ}te-Bx##DPuODe*&;te5U#!#0uYjsb{Pev0O21 znT~6uh6TG5Fw~nTQvnwAuwYkp06&RgeIP)dz=9P4=&p-ll^(R0n6NJZMoZ(g5BJh# z7L3aP2)Ikbz9qw*REIsqlPSbR!v@S5AJwv8)qi+0&1j`z38s(9CKl`(PG(Fu4Y!i@ zZ)U+RVt11JNYuX!v2_D1*e@t7caX@oXynZ#13QJndb+KVL4-RKLZ7i< zSbvY{%V=bdN6haQ17=Uf+U^kz?_n~7QNJ=^rYQh3UknWyThGdI$mWXUf07(cAtnZ_ zaQH=QH^HJh)MI@1(E6vP87#D_$C|K&9bHXBZWY1OIn|hX1Kyt`W-wba!Eyz)7?+PF zkp8^*p=%bwiqv9`vwmdwrPTU3m|(>Uuz&vhrDZ0mCh6QWj?|ntrLQW;OQPmy`B?qN zATM3$k(U_StCC2Wr`s>lZCSLO3eDc~-MKC~SVb7UL6>-<`qG*)G+rw%*!DBA+Tl8{ zNCx)Dl)EVKnRh|99h;0}f_|k>aEV?KDAFCj3K%}9d z!6A5RP80B~AWWJvZBXpe1A{+T)EE44;ZD1S_ei-e4gUVouT%U%KXX^zOPidVN5Yuf z2TXbU4;W7qm`!dYLI3~&C3Hntbbn-FbY(hYa%Ew3WdJfTF*YqQGA%MNR53U@G&DLh zI4dwQIxsNP;#_+G001R)MObuXVRU6WZEs|0W_bWIFfleQFfuJNFjO%(Iy5voGdL?S zF*-0XqQB(F00012dQ@0+Qek%>aB^>EX>4U6ba`-PAZc)PV*mhnoa6Eg2ug8QC@9KL z%gjmTQUC)Z3oc^|6C)E#lN19JAVh#P!(;;^vs56<*wo0x%)}hT2g`s+ph_+P>K74o T@rA4F+bcjwX zusVm1OmL`-1{M+7rc0ceF*xxLH*|}M8Imoo&Lw6zrx>>wBP47Zvq|DKLm)UDY%Y@V zBQs#o3`A%r3fc3WsJjZBcQog{D_JW(9MWX*qYB|MRS1R~B-fO*beNX78-4H;mG5_2LOEZizt} zY@lR|CNxyDtBLgQ#!qB%i`pf@nl=ToxMeqZ^JZ>Vu(}nlz__1V7pT`3Jme+7>Yw+5We>1h&syrm z4d5TlxzCHW+Bn5?e!)6pC$m%~JQntY3}!hdOMfz7C!?^9Ls;0@c8K5B2D|wQU1IVJ zJQik*ftA$7#BqQv??S^$$=a6{3Stkyc019q&q%oDK7Z>Etb_G>p2xz5*OT~7b|&sb z5)p9=4Qq#V^SK}{!FF8n1P!ZHlKAfhaS*0#!w4Go4GC9Nu>Q!K0LyY7jI$-ZOO@?=|RyDLMIQ`L*)ujxniU(=qZjNv(5lFlD8g zF}iKKr)OMe4Qh^C+#!fF0DEf$4XY+=>lL#gihluiibul=NqDL_)iAQi+j!W16929^ z*IyBlX+y*8kaPBkYBv#wc{J?t%Ow7gAo{_+9LK{98WR7lAa2bgA|DTH3@5c*EV-xQ zW1hytXwEKU{jqIer7ojkqwhe@{*wusv%?zEF#ARlAKt{ob;ym{hiI7X4VU}n`68II zbblKfW=)2{bTe@jU?1~nSbrjkf3=T^LojMxWgSQ)X#VfCzUO#_&^9)Atflkm95tlvf*OzjlVK*RsRfE? z#=@vIew&@j`E%45EHz?b6+s>bHlM;)^W0gUfiPQBSrDA==OaLSRn>VJ33 zd}=*^^Al!!YIPqY`}FjWMVe@)_+O}3RyX= z!B%GrY1MRgjq9%uw4icdu(QEa8GrpGW@U$eOp;H$v7pumtS5dd)=D05UK!H7zhREiyM$F*7ppnF*PkPGc7VVR30%iIxsXkFf}VMF*-0X36z_t00000NkvXXu0mjfFf*!x diff --git a/public/apple-touch-icon-precomposed.png b/public/apple-touch-icon-precomposed.png index d37f2828ac0ab0dfbcc05369db481090f6219632..0b6bb71456b29e89ba6d72b320b97f8dba3c949c 100644 GIT binary patch delta 4674 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 Ef+_3Iz5oCK delta 4944 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 P015yANkvXXu0mjfNx3B` delta 3528 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 - - - - - #2d89ef + + + + + #da532c diff --git a/public/favicon-16x16.png b/public/favicon-16x16.png index 03953f23ace9691cebf3b72d88a7f9f039894f0c..496df9f39aea57182e7082bbb2bf8c9c7067688b 100644 GIT binary patch delta 191 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 Ch1}l& literal 0 HcmV?d00001 diff --git a/public/favicon-32x32.png b/public/favicon-32x32.png index 80c79d7ae25d12ec658bff45e2f01ac80a91c638..c729437261223a29f0b9a4b5062a4d2645200625 100644 GIT binary patch delta 191 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 Oa3OD48rNL&c>G_R)Nb_v delta 3412 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 H+~WQXyaro5 diff --git a/public/mstile-310x150.png b/public/mstile-310x150.png index 8293e6f1abfbb76627ba192dd705f49097fa63da..2c17b9eee8c3690f0043cbbf5a4b2ebb2bf35820 100644 GIT binary patch literal 3828 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¯t_}jdM$l$_TES8+CS2A2rHQUBQccg) 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 literal 7946 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 KxK*#`7WY56@O*jz diff --git a/public/mstile-70x70.png b/public/mstile-70x70.png index 9f99178f611ad46aa93fa1c6d9a7d287575b2693..3f334b60a3c0a8c45a239732aa23c98cdf534fbc 100644 GIT binary patch delta 2359 zcmV-73CQ-k6QmQ6bbsIi6cQ{a{IZKt000O{Nkl%hUu@DGCV#-%c0s$L?!46>WuJOk%-km&PU+&D@g`LgrjDL4D|9Lrg&z;?K{xf?& z&OP^n2M-=Rc<|uCg9i^DJb3Wn!NbHy0c+So7ZG9%(#tn|$gi2rWTy?Y2hF@i5Y2E6 zbCQ>7CdX;>GKE{-Mj^ffeEnc}oFR*}Ohjw_ux!UCX%ZArVY@d*V^J7g6P)1A`7=9soku8l+8OI8W1j{0WBe7r z;#+d?Gs$UJQo}k+&wn=+P8*zF_<7%g`~Cbl6Gk{W5}a$8xQud@D+Gy9NrP!XyNy-{ zZOsTa>VJCn1N??2Dk!3WO8&ql-SZD|ztiTX8-BJ*4sK_rLH~?lic{#c!Rf|ax`cZj zEHvpK)s6rDlqoZu>pm7UUC8fp%%qplWjiUzo!Z6>Xc#Zu`6XWd3XfTcn{ zNxMm3L6cN!W6*5`%;HWVA0}kd-$|{IWBfmJhJQFkKr_>Xd_tjLNRg1QW$q8)907NW zCT@fdlQxGXQmKy~w-J!X0wE7ck-u>i(=3(x8E_i`! zP=C%ercq7_L&VZ&jQtVRdYKNfoj-<~tdwPK!Ht+%!reBM(hkxA+kw+o<6fuJ(%rex{2+~0aAGr+E!45ta zeL@x?m!9yR zOJQk;{fxHJJtmFPsnGA@l2kg%b+-}V6VEiFmbblm?z{uh7~nx z#Z;%0uiZyLK$^((DO>mjA_*dxxzzyY2q>dk$X67B4L{3;oM*@4z1;-F(If)Qn8Dpb z)}*?wA)sDLW$IVxmoY=gA!$V58h-*F5KWw>90lAbz4krsBcN2u^N0~N>C3oBDxG!T zU!Z_eAx8M5j*5 zS1Go(0X91bSSp)#%0qt{}iKHo`)?Voj)7iUmOhHEtuIMoNBcQ_KUF zOPwGTO0h$i5YQ~1siqj_<`}k2#4?#2=?nq)h!)_wVok6>mm3Nrie4hC3CL%ekgqEu z0Rh7+A6AA;vzUM?8ihQnXaP!eu>c4v0%loFz#UWxIjk7xml}>eaDUxUxL$Jb9G6Y{ zGDCJ~uiF~IMoB)XNRTf#EQ9s9Ybe~nY9WW&p{Oyyk`lMZjS&mg)kQ@sq zNOLaZu#SK(DLgu%aewPXTOYrYHb`q|{6l#J2F#~NSMN({)R1AMnuAfzeXO9AK0arc zGJrXgr+Gr!8w6kSQi28VMTRz@nA(Zl3Ka844vU1=DF5R}hP_9H{DLnGJ41r}Ji+%> z=}r>3ah$>l-r-gL#&i6Z=81JWSQA@Kr#M~aWs%%8g@^c$u7Bav&=_Tt@@<>SBkU!1 zi`@Zn&P$^R$FYRA1ZG}jJ8!U=j|nUEA4-`4;|Q>hT_&nj*WaCXdmMF^&i%Q0wMzl< z8}PH5oeU>=|BFsLK8{T(x!=WuCL&);@_0mzFt6Jc9=ja^97w_a3#Pt*Is22k^E&7G z7Y}7NKyIZQoPUx+sJe@dh66Gd@lWO_tUtmzF3>|4=ea~Xopxl3C5tNBEk6BIrqiE% zyq%zKj4s~fr_@Z`jWGcZT5|t5_nN+=jP`eF+zTHZ3qREiy1v zF*rIjG&(amD=;xSFfatj?{feE09SfcSaechcOY6Cgx@G{a;ABePT>%h=S&#LUDT#0SfO dNT5nC0O}VJbn-$ql>h(=002ovPDHLkV1n+lMfm^# delta 2399 zcmV-l3840*6S@~ISNiAHUzs7atnC0d|TqqI$ErM4mu@k7-<lxy3XPurW5+0c`L3vKPGj^&$4zGc(6#$Jv?jj(_HRI%oegXa4V-*)!+z zp9A>t;lqayA3l8e@ZrOU4<9~!OnWe&k8n3T8DoOO?B!>CgO70$XS(f~GxVGI7Y@*f z2+wgRo2a?%pS|Q~ax*V*VqD~A4@p5I?WbMzbNDm|d3)?~+tV*cGneID zz%u3T+ z1J?0*b~7nG$x$BSnlbBAo=)rOljI@Ja+{4+@)|erjFQYrHUq5W-n8kH?=s(QMpgxQ zl-(23ImuVq%2C6wNk$o;;ELz7>_fND#UU4cwFBHPJ>Mjc@ds>V8D}$}<@^b+>7IXxUw7NzOw$i?k3?`E zs}1&F=mdD11#WwsX#tk7Q_ySY-6s1MUH|WAcKPAn=VK-2i}b77X_LJ{8rAjUu=fO5 zFB;%}>@^x0z)C557MDCG01L5NWX_?@RG&KwS1i)O>NdlPZRb!Eq3nAt;0TxMpfEc1Cdm~Dv+z3X!CO{MBh;$Hn3IXJ)?Vz1r zx_>YlWHBC*vX$7x-)Updm;sbw4ZfwjpaEawMSL;UsbLgdS_c0Tj?bX77Qe*fI^hTK zK6=NznTH0{nBIvHMufi!JgdFrwAYy;U%~Bc(=C5Y1&6Y7WXK{u!4FL{{8K>(Yu#pJ zo&E~$V=M#YNixPqGv}EjjUY>~6ZdDVI)7EyY07ZsGdKs;U%rwtMDa3CX3jN7z5>*+ z4bP&?bhiZF!$FK77X`?}Y%IVkEHsoN2GEWW0?0uG?bwgEw2}1hJuL(Pn1ki0M;@y2 zm^2Xn54K1#0ALQ5;%`_kUD%J`<4s&b1T&x^ftZ$b#$)@W*dRrEv?%O9)~)-#u76(& z%RHR#3b&$rEH#P_h5Z1oNx4(nEw2d>!1yzbDO>Y6;vyZ!`*yqIya4kszKT1HKBY$~ zpHAU)T6JcX0JUNyIEawK9+Vcv4r-ya>dYzu>cvnu1l3$`5ypd@!g$YqcN`XgGteM1 zeTXQERAGFm(}7PtCjbhO8p!lP)qlb_V>}3A0Jg0LxFh_xb<>%>UK zX#tX8N&tm@fz%JARMs;B)FKti)UUALg9RcTl6nN55#RyQ#8KG`xKDcRdpsuqOOT55 zNMOKZFU7r5_LAngzd$}pL^_VJ$zCTdm?Uw*374D|KpuR@6#c+uC=%>z~YQ00E=| z9U~Yr*=r<;deP-=0fu3o*O3>*E-M?!EEgaswecg0j<6i*|EU&DqsA-~Kc$@$D2yC7Wc0mBlm)?MnaMNU$ z`-yQlv;g9y0F5FtD2XGAfliGS7*hmG8(_0TfYpLjFItU878(L)iajO(gIFUnZHhIa zCf%A~87e&{04k;6$5zGq?po<12oy+jhaM52Njy`UySdb$-!hS~Gk-YJ9RcnYEx;|s znqa;zHWY{|z7p9i0P}E<$lOxQ1QZ%x`LJ@zGk8LO1TW*d$zE!R4(;_?BUmq`k89=t`MHK=upXykfgBNlb=W8} zVeD5Fxx)~ybqx-|0e=Blf*n{YvPbcuqL6;?KkeKk5ap0e(-~ zAWf2gQXPQ-a2b1a)graFJ5oX;zRtGuHhreQSPAPZQ~qn;$bEx*&dPP6>hZZrG4~Q zv2_ABuW}z>;(so_#jwKu21`tJ6>=*Nn50tSk8blGce%#Wxj!kivDr{lkQ@09BWYg$ zoZHOD-QF=J`kj2xB;+5`JRXq@^F=x|J$5_#g*-L|`d!9vKiBeTT36oU75<$MSvw)p zDy)14XH8+Mx)a+q-2oX~fj?u}gyo~Sj4t$`6IXBzZGY&{9EcQ46RcpH#ixJXc={6q z{Obf|6YS*6{3a`zKTS^tV)e!vzkp$j{it=w`D$8~Xhld6To zXwgjTKgf~BpGgejI)?EXUc + + + +Created by potrace 1.11, written by Peter Selinger 2001-2013 + + + + + diff --git a/resources/views/errors/FireflyException.twig b/resources/views/errors/FireflyException.twig index b77ee64798..ce2e5801ab 100644 --- a/resources/views/errors/FireflyException.twig +++ b/resources/views/errors/FireflyException.twig @@ -13,24 +13,7 @@ - - - - - - - - - - - - - - - - - - + {% include('partials/favicons.twig') %} diff --git a/resources/views/layout/default.twig b/resources/views/layout/default.twig index 7ee974b939..700f9b11dc 100644 --- a/resources/views/layout/default.twig +++ b/resources/views/layout/default.twig @@ -30,24 +30,7 @@ - - - - - - - - - - - - - - - - - - + {% include('partials/favicons.twig') %} diff --git a/resources/views/layout/empty.twig b/resources/views/layout/empty.twig index 8f4a0faad0..0e82247ef3 100644 --- a/resources/views/layout/empty.twig +++ b/resources/views/layout/empty.twig @@ -17,24 +17,7 @@ - - - - - - - - - - - - - - - - - - + {% include('partials/favicons.twig') %} diff --git a/resources/views/layout/guest.twig b/resources/views/layout/guest.twig index 8b59e6af25..61c936f989 100644 --- a/resources/views/layout/guest.twig +++ b/resources/views/layout/guest.twig @@ -18,24 +18,7 @@ - - - - - - - - - - - - - - - - - - + {% include('partials/favicons.twig') %} diff --git a/resources/views/partials/favicons.twig b/resources/views/partials/favicons.twig new file mode 100644 index 0000000000..ae4feef043 --- /dev/null +++ b/resources/views/partials/favicons.twig @@ -0,0 +1,18 @@ + + + + + + + + + + + + + + + + + + \ No newline at end of file From 317075aa6dc4375a9e1e998b13255bb05b48b4e9 Mon Sep 17 00:00:00 2001 From: James Cole Date: Sat, 20 Feb 2016 18:48:06 +0100 Subject: [PATCH 03/15] Oops. --- resources/views/partials/favicons.twig | 32 +++++++++++++------------- 1 file changed, 16 insertions(+), 16 deletions(-) diff --git a/resources/views/partials/favicons.twig b/resources/views/partials/favicons.twig index ae4feef043..868737260f 100644 --- a/resources/views/partials/favicons.twig +++ b/resources/views/partials/favicons.twig @@ -1,18 +1,18 @@ - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + - + \ No newline at end of file From 28fd719ce3d71f1ea26fd16bd5b2d3e63a857a84 Mon Sep 17 00:00:00 2001 From: James Cole Date: Tue, 23 Feb 2016 06:17:04 +0100 Subject: [PATCH 04/15] New file systems. --- config/filesystems.php | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/config/filesystems.php b/config/filesystems.php index 3fffcf0a2f..20f5c4d2e3 100644 --- a/config/filesystems.php +++ b/config/filesystems.php @@ -48,6 +48,15 @@ return [ 'root' => storage_path('app'), ], + 'upload' => [ + 'driver' => 'local', + 'root' => storage_path('upload'), + ], + 'export' => [ + 'driver' => 'local', + 'root' => storage_path('export'), + ], + 'ftp' => [ 'driver' => 'ftp', 'host' => 'ftp.example.com', From deeeb064886a4729df692b34b1227a1b897beed2 Mon Sep 17 00:00:00 2001 From: James Cole Date: Tue, 23 Feb 2016 06:39:01 +0100 Subject: [PATCH 05/15] Added debug info to the export routine. --- app/Export/Collector/AttachmentCollector.php | 15 +++++++++++---- app/Export/Collector/UploadCollector.php | 11 +++++++++-- app/Export/ConfigurationFile.php | 3 +++ app/Export/Processor.php | 17 +++++++++++++++++ app/Http/Controllers/ExportController.php | 5 +++-- app/Models/ExportJob.php | 2 ++ .../Attachment/AttachmentRepository.php | 11 +++++++++++ .../AttachmentRepositoryInterface.php | 6 ++++++ 8 files changed, 62 insertions(+), 8 deletions(-) diff --git a/app/Export/Collector/AttachmentCollector.php b/app/Export/Collector/AttachmentCollector.php index 706fc12ab8..818c2f011f 100644 --- a/app/Export/Collector/AttachmentCollector.php +++ b/app/Export/Collector/AttachmentCollector.php @@ -11,11 +11,11 @@ declare(strict_types = 1); namespace FireflyIII\Export\Collector; use Amount; -use Auth; use Crypt; use FireflyIII\Models\Attachment; use FireflyIII\Models\ExportJob; use FireflyIII\Models\TransactionJournal; +use FireflyIII\Repositories\Attachment\AttachmentRepositoryInterface; use Illuminate\Contracts\Encryption\DecryptException; use Log; @@ -29,6 +29,9 @@ class AttachmentCollector extends BasicCollector implements CollectorInterface /** @var string */ private $explanationString = ''; + /** @var AttachmentRepositoryInterface */ + private $repository; + /** * AttachmentCollector constructor. * @@ -36,6 +39,8 @@ class AttachmentCollector extends BasicCollector implements CollectorInterface */ public function __construct(ExportJob $job) { + $this->repository = app('FireflyIII\Repositories\Attachment\AttachmentRepositoryInterface'); + parent::__construct($job); } @@ -45,26 +50,27 @@ class AttachmentCollector extends BasicCollector implements CollectorInterface public function run() { // grab all the users attachments: - $attachments = Auth::user()->attachments()->get(); + $attachments = $this->repository->get(); Log::debug('Found ' . $attachments->count() . ' attachments.'); /** @var Attachment $attachment */ foreach ($attachments as $attachment) { $originalFile = storage_path('upload') . DIRECTORY_SEPARATOR . 'at-' . $attachment->id . '.data'; + Log::debug('Original file is at "' . $originalFile . '".'); if (file_exists($originalFile)) { - Log::debug('Stored 1 attachment'); try { $decrypted = Crypt::decrypt(file_get_contents($originalFile)); $newFile = storage_path('export') . DIRECTORY_SEPARATOR . $this->job->key . '-Attachment nr. ' . $attachment->id . ' - ' . $attachment->filename; file_put_contents($newFile, $decrypted); $this->getFiles()->push($newFile); + Log::debug('Stored file content in new file "' . $newFile . '", which will be in the final zip file.'); // explain: $this->explain($attachment); } catch (DecryptException $e) { - Log::error('Catchable error: could not decrypt attachment #' . $attachment->id); + Log::error('Catchable error: could not decrypt attachment #' . $attachment->id . ' because: ' . $e->getMessage()); } } @@ -73,6 +79,7 @@ class AttachmentCollector extends BasicCollector implements CollectorInterface // put the explanation string in a file and attach it as well. $explanationFile = storage_path('export') . DIRECTORY_SEPARATOR . $this->job->key . '-Source of all your attachments explained.txt'; file_put_contents($explanationFile, $this->explanationString); + Log::debug('Also put explanation file "' . $explanationFile . '" in the zip.'); $this->getFiles()->push($explanationFile); } diff --git a/app/Export/Collector/UploadCollector.php b/app/Export/Collector/UploadCollector.php index 817385fc93..b791064a48 100644 --- a/app/Export/Collector/UploadCollector.php +++ b/app/Export/Collector/UploadCollector.php @@ -15,6 +15,7 @@ use Crypt; use FireflyIII\Models\ExportJob; use Illuminate\Contracts\Encryption\DecryptException; use Log; + /** * Class UploadCollector * @@ -41,11 +42,14 @@ class UploadCollector extends BasicCollector implements CollectorInterface // grab upload directory. $path = storage_path('upload'); $files = scandir($path); + Log::debug('Found ' . count($files) . ' in the upload directory.'); // only allow old uploads for this user: $expected = 'csv-upload-' . Auth::user()->id . '-'; - $len = strlen($expected); + Log::debug('Searching for files that start with: "' . $expected . '".'); + $len = strlen($expected); foreach ($files as $entry) { if (substr($entry, 0, $len) === $expected) { + Log::debug($entry . ' is part of this users original uploads.'); try { // this is an original upload. $parts = explode('-', str_replace(['.csv.encrypted', $expected], '', $entry)); @@ -55,14 +59,17 @@ class UploadCollector extends BasicCollector implements CollectorInterface $content = Crypt::decrypt(file_get_contents($path . DIRECTORY_SEPARATOR . $entry)); $fullPath = storage_path('export') . DIRECTORY_SEPARATOR . $this->job->key . '-' . $newFileName; + Log::debug('Will put "' . $fullPath . '" in the zip file.'); // write to file: file_put_contents($fullPath, $content); // add entry to set: $this->getFiles()->push($fullPath); } catch (DecryptException $e) { - Log::error('Could not decrypt old CSV import file ' . $entry . '. Skipped.'); + Log::error('Could not decrypt old CSV import file ' . $entry . '. Skipped because ' . $e->getMessage()); } + } else { + Log::debug($entry . ' is not part of this users original uploads.'); } } } diff --git a/app/Export/ConfigurationFile.php b/app/Export/ConfigurationFile.php index a7c989b8d9..c588ca2713 100644 --- a/app/Export/ConfigurationFile.php +++ b/app/Export/ConfigurationFile.php @@ -11,6 +11,7 @@ declare(strict_types = 1); namespace FireflyIII\Export; use FireflyIII\Models\ExportJob; +use Log; /** * Class ConfigurationFile @@ -53,6 +54,8 @@ class ConfigurationFile } $file = storage_path('export') . DIRECTORY_SEPARATOR . $this->job->key . '-configuration.json'; + Log::debug('Created JSON config file.'); + Log::debug('Will put "' . $file . '" in the ZIP file.'); file_put_contents($file, json_encode($configuration, JSON_PRETTY_PRINT)); return $file; diff --git a/app/Export/Processor.php b/app/Export/Processor.php index b1092a71c9..547efa123a 100644 --- a/app/Export/Processor.php +++ b/app/Export/Processor.php @@ -16,6 +16,7 @@ use FireflyIII\Exceptions\FireflyException; use FireflyIII\Models\ExportJob; use FireflyIII\Models\TransactionJournal; use Illuminate\Support\Collection; +use Log; use ZipArchive; /** @@ -88,6 +89,13 @@ class Processor $args = [$this->accounts, Auth::user(), $this->settings['startDate'], $this->settings['endDate']]; $journalCollector = app('FireflyIII\Export\JournalCollector', $args); $this->journals = $journalCollector->collect(); + Log::debug( + 'Collected ' . + $this->journals->count() . ' journals (between ' . + $this->settings['startDate']->format('Y-m-d') . ' and ' . + $this->settings['endDate']->format('Y-m-d') + . ').' + ); } public function collectOldUploads() @@ -103,10 +111,13 @@ class Processor */ public function convertJournals() { + $count = 0; /** @var TransactionJournal $journal */ foreach ($this->journals as $journal) { $this->exportEntries->push(Entry::fromJournal($journal)); + $count++; } + Log::debug('Converted ' . $count . ' journals to "Entry" objects.'); } public function createConfigFile() @@ -119,6 +130,7 @@ class Processor { $zip = new ZipArchive; $filename = storage_path('export') . DIRECTORY_SEPARATOR . $this->job->key . '.zip'; + Log::debug('Will create zip file at ' . $filename); if ($zip->open($filename, ZipArchive::CREATE) !== true) { throw new FireflyException('Cannot store zip file.'); @@ -127,6 +139,7 @@ class Processor $search = storage_path('export') . DIRECTORY_SEPARATOR . $this->job->key . '-'; /** @var string $file */ foreach ($this->getFiles() as $file) { + Log::debug('Will add "' . $file . '" to zip file.'); $zipName = str_replace($search, '', $file); $zip->addFile($file, $zipName); } @@ -134,8 +147,10 @@ class Processor // delete the files: foreach ($this->getFiles() as $file) { + Log::debug('Will now delete file "' . $file . '".'); unlink($file); } + Log::debug('Done!'); } /** @@ -145,9 +160,11 @@ class Processor { $exporterClass = Config::get('firefly.export_formats.' . $this->exportFormat); $exporter = app($exporterClass, [$this->job]); + Log::debug('Going to export ' . $this->exportEntries->count() . ' export entries into ' . $this->exportFormat . ' format.'); $exporter->setEntries($this->exportEntries); $exporter->run(); $this->files->push($exporter->getFileName()); + Log::debug('Added "' . $exporter->getFileName() . '" to the list of files to include in the zip.'); } /** diff --git a/app/Http/Controllers/ExportController.php b/app/Http/Controllers/ExportController.php index 27e65214af..f7fab1f043 100644 --- a/app/Http/Controllers/ExportController.php +++ b/app/Http/Controllers/ExportController.php @@ -19,6 +19,7 @@ use FireflyIII\Http\Requests\ExportFormRequest; use FireflyIII\Models\ExportJob; use FireflyIII\Repositories\Account\AccountRepositoryInterface as ARI; use FireflyIII\Repositories\ExportJob\ExportJobRepositoryInterface as EJRI; +use Log; use Preferences; use Response; use View; @@ -51,7 +52,7 @@ class ExportController extends Controller $quoted = sprintf('"%s"', addcslashes($name, '"\\')); $job->change('export_downloaded'); - + Log::debug('Will send user file "' . $file . '".'); return response(file_get_contents($file), 200) ->header('Content-Description', 'File Transfer') @@ -96,7 +97,7 @@ class ExportController extends Controller $checked = array_keys($accountList); $formats = array_keys(Config::get('firefly.export_formats')); $defaultFormat = Preferences::get('export_format', Config::get('firefly.default_export_format'))->data; - $first = session('first')->format('Y-m-d'); + $first = Carbon::create()->subWeek()->format('Y-m-d'); $today = Carbon::create()->format('Y-m-d'); return view('export.index', compact('job', 'checked', 'accountList', 'formats', 'defaultFormat', 'first', 'today')); diff --git a/app/Models/ExportJob.php b/app/Models/ExportJob.php index a03e1bca94..17583ef18c 100644 --- a/app/Models/ExportJob.php +++ b/app/Models/ExportJob.php @@ -12,6 +12,7 @@ namespace FireflyIII\Models; use Auth; use Illuminate\Database\Eloquent\Model; +use Log; use Symfony\Component\HttpKernel\Exception\NotFoundHttpException; /** @@ -50,6 +51,7 @@ class ExportJob extends Model */ public function change($status) { + Log::debug('Job ' . $this->key . ' to status "' . $status . '".'); $this->status = $status; $this->save(); } diff --git a/app/Repositories/Attachment/AttachmentRepository.php b/app/Repositories/Attachment/AttachmentRepository.php index d8520d0d54..5165d497f8 100644 --- a/app/Repositories/Attachment/AttachmentRepository.php +++ b/app/Repositories/Attachment/AttachmentRepository.php @@ -3,7 +3,9 @@ declare(strict_types = 1); namespace FireflyIII\Repositories\Attachment; +use Auth; use FireflyIII\Models\Attachment; +use Illuminate\Support\Collection; /** * Class AttachmentRepository @@ -26,9 +28,18 @@ class AttachmentRepository implements AttachmentRepositoryInterface $file = $helper->getAttachmentLocation($attachment); unlink($file); $attachment->delete(); + return true; } + /** + * @return Collection + */ + public function get(): Collection + { + return Auth::user()->attachments()->get(); + } + /** * @param Attachment $attachment * @param array $data diff --git a/app/Repositories/Attachment/AttachmentRepositoryInterface.php b/app/Repositories/Attachment/AttachmentRepositoryInterface.php index 0cd01dff73..2c25be8baa 100644 --- a/app/Repositories/Attachment/AttachmentRepositoryInterface.php +++ b/app/Repositories/Attachment/AttachmentRepositoryInterface.php @@ -4,6 +4,7 @@ declare(strict_types = 1); namespace FireflyIII\Repositories\Attachment; use FireflyIII\Models\Attachment; +use Illuminate\Support\Collection; /** * Interface AttachmentRepositoryInterface @@ -20,6 +21,11 @@ interface AttachmentRepositoryInterface */ public function destroy(Attachment $attachment): bool; + /** + * @return Collection + */ + public function get(): Collection; + /** * @param Attachment $attachment * @param array $attachmentData From 155801ab2b8dbb2be282a8d206a9bbb8a043cb54 Mon Sep 17 00:00:00 2001 From: James Cole Date: Tue, 23 Feb 2016 06:54:16 +0100 Subject: [PATCH 06/15] Some extra logging. --- app/Export/Processor.php | 12 ++++++++++-- 1 file changed, 10 insertions(+), 2 deletions(-) diff --git a/app/Export/Processor.php b/app/Export/Processor.php index 547efa123a..21370039d8 100644 --- a/app/Export/Processor.php +++ b/app/Export/Processor.php @@ -12,6 +12,7 @@ namespace FireflyIII\Export; use Auth; use Config; +use ErrorException; use FireflyIII\Exceptions\FireflyException; use FireflyIII\Models\ExportJob; use FireflyIII\Models\TransactionJournal; @@ -141,14 +142,21 @@ class Processor foreach ($this->getFiles() as $file) { Log::debug('Will add "' . $file . '" to zip file.'); $zipName = str_replace($search, '', $file); - $zip->addFile($file, $zipName); + $result = $zip->addFile($file, $zipName); + if (!$result) { + Log::error('Could not add "' . $file . '" into zip file as "' . $zipName . '".'); + } } $zip->close(); // delete the files: foreach ($this->getFiles() as $file) { Log::debug('Will now delete file "' . $file . '".'); - unlink($file); + try { + unlink($file); + } catch (ErrorException $e) { + Log::error('Cannot unlink file "' . $file . '" because: ' . $e->getMessage()); + } } Log::debug('Done!'); } From 0c9c0f2032bffe17fc591143602e03da40570244 Mon Sep 17 00:00:00 2001 From: James Cole Date: Tue, 23 Feb 2016 06:54:51 +0100 Subject: [PATCH 07/15] Simplified the attachment collector. --- app/Export/Collector/AttachmentCollector.php | 94 ++++++++++---- app/Models/Attachment.php | 127 ++++++++++--------- 2 files changed, 136 insertions(+), 85 deletions(-) diff --git a/app/Export/Collector/AttachmentCollector.php b/app/Export/Collector/AttachmentCollector.php index 818c2f011f..2f67d299c7 100644 --- a/app/Export/Collector/AttachmentCollector.php +++ b/app/Export/Collector/AttachmentCollector.php @@ -17,7 +17,9 @@ use FireflyIII\Models\ExportJob; use FireflyIII\Models\TransactionJournal; use FireflyIII\Repositories\Attachment\AttachmentRepositoryInterface; use Illuminate\Contracts\Encryption\DecryptException; +use Illuminate\Support\Collection; use Log; +use Storage; /** * Class AttachmentCollector @@ -28,9 +30,12 @@ class AttachmentCollector extends BasicCollector implements CollectorInterface { /** @var string */ private $explanationString = ''; - + /** @var \Illuminate\Contracts\Filesystem\Filesystem */ + private $exportDisk; /** @var AttachmentRepositoryInterface */ private $repository; + /** @var \Illuminate\Contracts\Filesystem\Filesystem */ + private $uploadDisk; /** * AttachmentCollector constructor. @@ -40,6 +45,9 @@ class AttachmentCollector extends BasicCollector implements CollectorInterface public function __construct(ExportJob $job) { $this->repository = app('FireflyIII\Repositories\Attachment\AttachmentRepositoryInterface'); + // make storage: + $this->uploadDisk = Storage::disk('upload'); + $this->exportDisk = Storage::disk('export'); parent::__construct($job); } @@ -50,37 +58,18 @@ class AttachmentCollector extends BasicCollector implements CollectorInterface public function run() { // grab all the users attachments: - $attachments = $this->repository->get(); - - Log::debug('Found ' . $attachments->count() . ' attachments.'); + $attachments = $this->getAttachments(); /** @var Attachment $attachment */ foreach ($attachments as $attachment) { - $originalFile = storage_path('upload') . DIRECTORY_SEPARATOR . 'at-' . $attachment->id . '.data'; - Log::debug('Original file is at "' . $originalFile . '".'); - if (file_exists($originalFile)) { - try { - $decrypted = Crypt::decrypt(file_get_contents($originalFile)); - $newFile = storage_path('export') . DIRECTORY_SEPARATOR . $this->job->key . '-Attachment nr. ' . $attachment->id . ' - ' - . $attachment->filename; - file_put_contents($newFile, $decrypted); - $this->getFiles()->push($newFile); - Log::debug('Stored file content in new file "' . $newFile . '", which will be in the final zip file.'); - - // explain: - $this->explain($attachment); - } catch (DecryptException $e) { - Log::error('Catchable error: could not decrypt attachment #' . $attachment->id . ' because: ' . $e->getMessage()); - } - - } + $this->exportAttachment($attachment); } // put the explanation string in a file and attach it as well. - $explanationFile = storage_path('export') . DIRECTORY_SEPARATOR . $this->job->key . '-Source of all your attachments explained.txt'; - file_put_contents($explanationFile, $this->explanationString); - Log::debug('Also put explanation file "' . $explanationFile . '" in the zip.'); - $this->getFiles()->push($explanationFile); + $file = $this->job->key . '-Source of all your attachments explained.txt'; + $this->exportDisk->put($file, $this->explanationString); + Log::debug('Also put explanation file "' . $file . '" in the zip.'); + $this->getFiles()->push($file); } /** @@ -103,4 +92,57 @@ class AttachmentCollector extends BasicCollector implements CollectorInterface $this->explanationString .= $string; } + + /** + * @param Attachment $attachment + * + * @return bool + */ + private function exportAttachment(Attachment $attachment): bool + { + $file = $attachment->fileName(); + Log::debug('Original file is at "' . $file . '".'); + if ($this->uploadDisk->exists($file)) { + try { + $decrypted = Crypt::decrypt($this->uploadDisk->get($file)); + $exportFile = $this->exportFileName($attachment); + $this->exportDisk->put($exportFile, $decrypted); + $this->getFiles()->push($exportFile); + Log::debug('Stored file content in new file "' . $exportFile . '", which will be in the final zip file.'); + + // explain: + $this->explain($attachment); + } catch (DecryptException $e) { + Log::error('Catchable error: could not decrypt attachment #' . $attachment->id . ' because: ' . $e->getMessage()); + } + + } + + return true; + } + + /** + * Returns the new file name for the export file. + * + * @param $attachment + * + * @return string + */ + private function exportFileName($attachment): string + { + + return sprintf('%s-Attachment nr. %s - %s', $this->job->key, strval($attachment->id), $attachment->filename); + } + + /** + * @return Collection + */ + private function getAttachments(): Collection + { + $attachments = $this->repository->get(); + + Log::debug('Found ' . $attachments->count() . ' attachments.'); + + return $attachments; + } } diff --git a/app/Models/Attachment.php b/app/Models/Attachment.php index 4eeaad603c..8397fda56d 100644 --- a/app/Models/Attachment.php +++ b/app/Models/Attachment.php @@ -36,6 +36,22 @@ class Attachment extends Model protected $fillable = ['attachable_id', 'attachable_type', 'user_id', 'md5', 'filename', 'mime', 'title', 'notes', 'description', 'size', 'uploaded']; + /** + * @param Attachment $value + * + * @return Attachment + */ + public static function routeBinder(Attachment $value) + { + if (Auth::check()) { + + if ($value->user_id == Auth::user()->id) { + return $value; + } + } + throw new NotFoundHttpException; + } + /** * Get all of the owning imageable models. */ @@ -45,14 +61,30 @@ class Attachment extends Model } /** - * @codeCoverageIgnore - * @return \Illuminate\Database\Eloquent\Relations\BelongsTo + * Returns the expected filename for this attachment. + * + * @return string */ - public function user() + public function fileName(): string { - return $this->belongsTo('FireflyIII\User'); + return sprintf('at-%s.data', strval($this->id)); } + /** + * @codeCoverageIgnore + * + * @param $value + * + * @return null|string + */ + public function getDescriptionAttribute($value) + { + if (is_null($value)) { + return null; + } + + return Crypt::decrypt($value); + } /** * @codeCoverageIgnore @@ -70,14 +102,6 @@ class Attachment extends Model return Crypt::decrypt($value); } - /** - * @param string $value - */ - public function setFilenameAttribute($value) - { - $this->attributes['filename'] = Crypt::encrypt($value); - } - /** * @codeCoverageIgnore * @@ -95,11 +119,19 @@ class Attachment extends Model } /** - * @param string $value + * @codeCoverageIgnore + * + * @param $value + * + * @return null|string */ - public function setMimeAttribute($value) + public function getNotesAttribute($value) { - $this->attributes['mime'] = Crypt::encrypt($value); + if (is_null($value)) { + return null; + } + + return Crypt::decrypt($value); } /** @@ -118,30 +150,6 @@ class Attachment extends Model return Crypt::decrypt($value); } - /** - * @param string $value - */ - public function setTitleAttribute($value) - { - $this->attributes['title'] = Crypt::encrypt($value); - } - - /** - * @codeCoverageIgnore - * - * @param $value - * - * @return null|string - */ - public function getDescriptionAttribute($value) - { - if (is_null($value)) { - return null; - } - - return Crypt::decrypt($value); - } - /** * @param string $value */ @@ -151,19 +159,19 @@ class Attachment extends Model } /** - * @codeCoverageIgnore - * - * @param $value - * - * @return null|string + * @param string $value */ - public function getNotesAttribute($value) + public function setFilenameAttribute($value) { - if (is_null($value)) { - return null; - } + $this->attributes['filename'] = Crypt::encrypt($value); + } - return Crypt::decrypt($value); + /** + * @param string $value + */ + public function setMimeAttribute($value) + { + $this->attributes['mime'] = Crypt::encrypt($value); } /** @@ -175,19 +183,20 @@ class Attachment extends Model } /** - * @param Attachment $value - * - * @return Attachment + * @param string $value */ - public static function routeBinder(Attachment $value) + public function setTitleAttribute($value) { - if (Auth::check()) { + $this->attributes['title'] = Crypt::encrypt($value); + } - if ($value->user_id == Auth::user()->id) { - return $value; - } - } - throw new NotFoundHttpException; + /** + * @codeCoverageIgnore + * @return \Illuminate\Database\Eloquent\Relations\BelongsTo + */ + public function user() + { + return $this->belongsTo('FireflyIII\User'); } } From aeaebd082f7ad24d844a2a351926d06dbe65ad0a Mon Sep 17 00:00:00 2001 From: James Cole Date: Tue, 23 Feb 2016 07:05:08 +0100 Subject: [PATCH 08/15] Cleaned up upload collector. --- app/Export/Collector/UploadCollector.php | 97 +++++++++++++++++------- 1 file changed, 70 insertions(+), 27 deletions(-) diff --git a/app/Export/Collector/UploadCollector.php b/app/Export/Collector/UploadCollector.php index b791064a48..48cd660287 100644 --- a/app/Export/Collector/UploadCollector.php +++ b/app/Export/Collector/UploadCollector.php @@ -15,6 +15,7 @@ use Crypt; use FireflyIII\Models\ExportJob; use Illuminate\Contracts\Encryption\DecryptException; use Log; +use Storage; /** * Class UploadCollector @@ -23,6 +24,12 @@ use Log; */ class UploadCollector extends BasicCollector implements CollectorInterface { + /** @var string */ + private $expected; + /** @var \Illuminate\Contracts\Filesystem\Filesystem */ + private $exportDisk; + /** @var \Illuminate\Contracts\Filesystem\Filesystem */ + private $uploadDisk; /** * AttachmentCollector constructor. @@ -32,6 +39,11 @@ class UploadCollector extends BasicCollector implements CollectorInterface public function __construct(ExportJob $job) { parent::__construct($job); + + // make storage: + $this->uploadDisk = Storage::disk('upload'); + $this->exportDisk = Storage::disk('export'); + $this->expected = 'csv-upload-' . Auth::user()->id . '-'; } /** @@ -40,37 +52,68 @@ class UploadCollector extends BasicCollector implements CollectorInterface public function run() { // grab upload directory. - $path = storage_path('upload'); - $files = scandir($path); - Log::debug('Found ' . count($files) . ' in the upload directory.'); - // only allow old uploads for this user: - $expected = 'csv-upload-' . Auth::user()->id . '-'; - Log::debug('Searching for files that start with: "' . $expected . '".'); - $len = strlen($expected); + $files = $this->uploadDisk->files(); + Log::debug('Found ' . count($files) . ' files in the upload directory.'); + foreach ($files as $entry) { - if (substr($entry, 0, $len) === $expected) { - Log::debug($entry . ' is part of this users original uploads.'); - try { - // this is an original upload. - $parts = explode('-', str_replace(['.csv.encrypted', $expected], '', $entry)); - $originalUpload = intval($parts[1]); - $date = date('Y-m-d \a\t H-i-s', $originalUpload); - $newFileName = 'Old CSV import dated ' . $date . '.csv'; - $content = Crypt::decrypt(file_get_contents($path . DIRECTORY_SEPARATOR . $entry)); - $fullPath = storage_path('export') . DIRECTORY_SEPARATOR . $this->job->key . '-' . $newFileName; + $this->processOldUpload($entry); + } + } - Log::debug('Will put "' . $fullPath . '" in the zip file.'); - // write to file: - file_put_contents($fullPath, $content); + /** + * @param string $entry + * + * @return string + */ + private function getOriginalUploadDate(string $entry): string + { + // this is an original upload. + $parts = explode('-', str_replace(['.csv.encrypted', $this->expected], '', $entry)); + $originalUpload = intval($parts[1]); + $date = date('Y-m-d \a\t H-i-s', $originalUpload); - // add entry to set: - $this->getFiles()->push($fullPath); - } catch (DecryptException $e) { - Log::error('Could not decrypt old CSV import file ' . $entry . '. Skipped because ' . $e->getMessage()); - } - } else { - Log::debug($entry . ' is not part of this users original uploads.'); + return $date; + } + + /** + * @param string $entry + * + * @return bool + */ + private function isValidFile(string $entry): bool + { + $len = strlen($this->expected); + if (substr($entry, 0, $len) === $this->expected) { + Log::debug($entry . ' is part of this users original uploads.'); + + return true; + } + Log::debug($entry . ' is not part of this users original uploads.'); + + return false; + } + + /** + * @param $entry + */ + private function processOldUpload(string $entry) + { + $content = ''; + + if ($this->isValidFile($entry)) { + try { + $content = Crypt::decrypt($this->uploadDisk->get($entry)); + } catch (DecryptException $e) { + Log::error('Could not decrypt old CSV import file ' . $entry . '. Skipped because ' . $e->getMessage()); } } + if (strlen($content) > 0) { + // continue with file: + $date = $this->getOriginalUploadDate($entry); + $file = $this->job->key . '-Old CSV import dated ' . $date . '.csv'; + Log::debug('Will put "' . $file . '" in the zip file.'); + $this->exportDisk->put($file, $content); + $this->getFiles()->push($file); + } } } From d259df9a47b11280fabde0f3af00ae79aff33628 Mon Sep 17 00:00:00 2001 From: James Cole Date: Tue, 23 Feb 2016 07:05:18 +0100 Subject: [PATCH 09/15] Fixed a small documentation bug. --- app/Support/Amount.php | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/app/Support/Amount.php b/app/Support/Amount.php index 3eb21e4522..49f5f6d0cc 100644 --- a/app/Support/Amount.php +++ b/app/Support/Amount.php @@ -63,8 +63,8 @@ class Amount /** * - * @param TransactionJournal $journal - * @param bool $coloured + * @param \FireflyIII\Models\TransactionJournal $journal + * @param bool $coloured * * @return string */ From 6b00f5a97dacaac9c9fad3a541adba8968249a11 Mon Sep 17 00:00:00 2001 From: James Cole Date: Tue, 23 Feb 2016 07:07:14 +0100 Subject: [PATCH 10/15] Updated config file maker. --- app/Export/ConfigurationFile.php | 11 +++++++---- 1 file changed, 7 insertions(+), 4 deletions(-) diff --git a/app/Export/ConfigurationFile.php b/app/Export/ConfigurationFile.php index c588ca2713..c78e6501b7 100644 --- a/app/Export/ConfigurationFile.php +++ b/app/Export/ConfigurationFile.php @@ -12,6 +12,7 @@ namespace FireflyIII\Export; use FireflyIII\Models\ExportJob; use Log; +use Storage; /** * Class ConfigurationFile @@ -20,6 +21,8 @@ use Log; */ class ConfigurationFile { + /** @var \Illuminate\Contracts\Filesystem\Filesystem */ + private $exportDisk; /** @var ExportJob */ private $job; @@ -30,7 +33,8 @@ class ConfigurationFile */ public function __construct(ExportJob $job) { - $this->job = $job; + $this->job = $job; + $this->exportDisk = Storage::disk('export'); } /** @@ -52,11 +56,10 @@ class ConfigurationFile foreach ($fields as $field) { $configuration['roles'][] = $types[$field]; } - - $file = storage_path('export') . DIRECTORY_SEPARATOR . $this->job->key . '-configuration.json'; + $file = $this->job->key . '-configuration.json'; Log::debug('Created JSON config file.'); Log::debug('Will put "' . $file . '" in the ZIP file.'); - file_put_contents($file, json_encode($configuration, JSON_PRETTY_PRINT)); + $this->exportDisk->put($file, json_encode($configuration, JSON_PRETTY_PRINT)); return $file; } From 08b4c9ea5cf7f725230438f4aefcd96b8025e5ce Mon Sep 17 00:00:00 2001 From: James Cole Date: Tue, 23 Feb 2016 07:27:29 +0100 Subject: [PATCH 11/15] Use export disk for zip file. --- app/Export/Exporter/CsvExporter.php | 15 +++++++-------- app/Export/Processor.php | 29 +++++++++++++---------------- 2 files changed, 20 insertions(+), 24 deletions(-) diff --git a/app/Export/Exporter/CsvExporter.php b/app/Export/Exporter/CsvExporter.php index 9a8d414a06..f0d2675cf8 100644 --- a/app/Export/Exporter/CsvExporter.php +++ b/app/Export/Exporter/CsvExporter.php @@ -14,6 +14,7 @@ use FireflyIII\Export\Entry; use FireflyIII\Models\ExportJob; use League\Csv\Writer; use SplFileObject; +use Storage; /** * Class CsvExporter @@ -25,9 +26,6 @@ class CsvExporter extends BasicExporter implements ExporterInterface /** @var string */ private $fileName; - /** @var resource */ - private $handler; - /** * CsvExporter constructor. * @@ -36,6 +34,7 @@ class CsvExporter extends BasicExporter implements ExporterInterface public function __construct(ExportJob $job) { parent::__construct($job); + } /** @@ -54,9 +53,11 @@ class CsvExporter extends BasicExporter implements ExporterInterface // create temporary file: $this->tempFile(); + // necessary for CSV writer: + $fullPath = storage_path('export') . DIRECTORY_SEPARATOR . $this->fileName; + // create CSV writer: - $writer = Writer::createFromPath(new SplFileObject($this->fileName, 'a+'), 'w'); - //the $writer object open mode will be 'w'!! + $writer = Writer::createFromPath(new SplFileObject($fullPath, 'a+'), 'w'); // all rows: $rows = []; @@ -76,8 +77,6 @@ class CsvExporter extends BasicExporter implements ExporterInterface private function tempFile() { - $fileName = $this->job->key . '-records.csv'; - $this->fileName = storage_path('export') . DIRECTORY_SEPARATOR . $fileName; - $this->handler = fopen($this->fileName, 'w'); + $this->fileName = $this->job->key . '-records.csv'; } } diff --git a/app/Export/Processor.php b/app/Export/Processor.php index 21370039d8..5681a2aca9 100644 --- a/app/Export/Processor.php +++ b/app/Export/Processor.php @@ -12,12 +12,12 @@ namespace FireflyIII\Export; use Auth; use Config; -use ErrorException; use FireflyIII\Exceptions\FireflyException; use FireflyIII\Models\ExportJob; use FireflyIII\Models\TransactionJournal; use Illuminate\Support\Collection; use Log; +use Storage; use ZipArchive; /** @@ -130,33 +130,30 @@ class Processor public function createZipFile() { $zip = new ZipArchive; - $filename = storage_path('export') . DIRECTORY_SEPARATOR . $this->job->key . '.zip'; - Log::debug('Will create zip file at ' . $filename); + $file = $this->job->key . '.zip'; + $fullPath = storage_path('export') . '/' . $file; + Log::debug('Will create zip file at ' . $fullPath); - if ($zip->open($filename, ZipArchive::CREATE) !== true) { + if ($zip->open($fullPath, ZipArchive::CREATE) !== true) { throw new FireflyException('Cannot store zip file.'); } // for each file in the collection, add it to the zip file. - $search = storage_path('export') . DIRECTORY_SEPARATOR . $this->job->key . '-'; - /** @var string $file */ - foreach ($this->getFiles() as $file) { - Log::debug('Will add "' . $file . '" to zip file.'); - $zipName = str_replace($search, '', $file); - $result = $zip->addFile($file, $zipName); + $disk = Storage::disk('export'); + foreach ($this->getFiles() as $entry) { + // is part of this job? + $zipFileName = str_replace($this->job->key . '-', '', $entry); + $result = $zip->addFromString($zipFileName, $disk->get($entry)); if (!$result) { - Log::error('Could not add "' . $file . '" into zip file as "' . $zipName . '".'); + Log::error('Could not add "' . $entry . '" into zip file as "' . $zipFileName . '".'); } } + $zip->close(); // delete the files: foreach ($this->getFiles() as $file) { Log::debug('Will now delete file "' . $file . '".'); - try { - unlink($file); - } catch (ErrorException $e) { - Log::error('Cannot unlink file "' . $file . '" because: ' . $e->getMessage()); - } + $disk->delete($file); } Log::debug('Done!'); } From 537b4ae003e361bc38fd24697715c6343a373502 Mon Sep 17 00:00:00 2001 From: James Cole Date: Tue, 23 Feb 2016 07:27:52 +0100 Subject: [PATCH 12/15] Fix translation. --- resources/lang/nl_NL/firefly.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/resources/lang/nl_NL/firefly.php b/resources/lang/nl_NL/firefly.php index 85be6e27a2..825880e100 100755 --- a/resources/lang/nl_NL/firefly.php +++ b/resources/lang/nl_NL/firefly.php @@ -75,7 +75,7 @@ return [ 'export_status_created_zip_file' => 'Zipbestand gemaakt!', 'export_status_finished' => 'Klaar met exportbestand! Hoera!', 'export_data_please_wait' => 'Een ogenblik geduld...', - 'attachment_explanation' => 'Het bestand \':attachment_name\' (#:attachment_id) werd oorspronkelijk geüpload naar :type (Engels) \':description\' (#:journal_id), met datum :datum en bedrag :bedrag.', + 'attachment_explanation' => 'Het bestand \':attachment_name\' (#:attachment_id) werd oorspronkelijk geüpload naar (Engels) :type \':description\' (#:journal_id), met datum :date en bedrag :amount.', // rules 'rules' => 'Regels', From 3f829a3114dc925cc0f3bdc18f3baf52f89e046b Mon Sep 17 00:00:00 2001 From: James Cole Date: Tue, 23 Feb 2016 07:31:01 +0100 Subject: [PATCH 13/15] Restore original functionality. --- app/Http/Controllers/ExportController.php | 2 +- resources/lang/en_US/firefly.php | 1 + 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/app/Http/Controllers/ExportController.php b/app/Http/Controllers/ExportController.php index f7fab1f043..b0f15e5d1a 100644 --- a/app/Http/Controllers/ExportController.php +++ b/app/Http/Controllers/ExportController.php @@ -97,7 +97,7 @@ class ExportController extends Controller $checked = array_keys($accountList); $formats = array_keys(Config::get('firefly.export_formats')); $defaultFormat = Preferences::get('export_format', Config::get('firefly.default_export_format'))->data; - $first = Carbon::create()->subWeek()->format('Y-m-d'); + $first = session('first')->format('Y-m-d'); $today = Carbon::create()->format('Y-m-d'); return view('export.index', compact('job', 'checked', 'accountList', 'formats', 'defaultFormat', 'first', 'today')); diff --git a/resources/lang/en_US/firefly.php b/resources/lang/en_US/firefly.php index 08f1bf31b7..b6b8f96d18 100644 --- a/resources/lang/en_US/firefly.php +++ b/resources/lang/en_US/firefly.php @@ -58,6 +58,7 @@ return [ 'include_config_help' => 'For easy re-import into Firefly III', 'include_old_uploads_help' => 'Firefly III does not throw away the original CSV files you have imported in the past. You can include them in your export.', 'do_export' => 'Export', + 'export_status_never_started' => 'The export has not started yet', 'export_status_make_exporter' => 'Creating exporter thing...', 'export_status_collecting_journals' => 'Collecting your transactions...', 'export_status_collected_journals' => 'Collected your transactions!', From a3bf30a77b29afef598b618bf9d78bf9a636beb9 Mon Sep 17 00:00:00 2001 From: James Cole Date: Tue, 23 Feb 2016 09:12:21 +0100 Subject: [PATCH 14/15] Remove file_get / file_put combi for #193 --- app/Helpers/Attachments/AttachmentHelper.php | 15 +++++++++------ 1 file changed, 9 insertions(+), 6 deletions(-) diff --git a/app/Helpers/Attachments/AttachmentHelper.php b/app/Helpers/Attachments/AttachmentHelper.php index 08e9086af4..d23e74b35f 100644 --- a/app/Helpers/Attachments/AttachmentHelper.php +++ b/app/Helpers/Attachments/AttachmentHelper.php @@ -10,6 +10,7 @@ use Illuminate\Database\Eloquent\Model; use Illuminate\Support\MessageBag; use Input; use Log; +use Storage; use Symfony\Component\HttpFoundation\File\UploadedFile; use TypeError; @@ -30,6 +31,9 @@ class AttachmentHelper implements AttachmentHelperInterface /** @var int */ protected $maxUploadSize; + /** @var \Illuminate\Contracts\Filesystem\Filesystem */ + protected $uploadDisk; + /** * */ @@ -39,6 +43,7 @@ class AttachmentHelper implements AttachmentHelperInterface $this->allowedMimes = Config::get('firefly.allowedMimes'); $this->errors = new MessageBag; $this->messages = new MessageBag; + $this->uploadDisk = Storage::disk('upload'); } /** @@ -148,15 +153,13 @@ class AttachmentHelper implements AttachmentHelperInterface $attachment->uploaded = 0; $attachment->save(); - $path = $file->getRealPath(); // encrypt and move file to storage. - $content = file_get_contents($path); + $fileObject = $file->openFile('r'); + $fileObject->rewind(); + $content = $fileObject->fread($file->getSize()); $encrypted = Crypt::encrypt($content); // store it: - $upload = $this->getAttachmentLocation($attachment); - if (is_writable(dirname($upload))) { - file_put_contents($upload, $encrypted); - } + $this->uploadDisk->put($attachment->fileName(), $encrypted); $attachment->uploaded = 1; // update attachment $attachment->save(); From ad8d945c1d97ad3c59349509a779de8e051c2ff0 Mon Sep 17 00:00:00 2001 From: James Cole Date: Tue, 23 Feb 2016 09:22:18 +0100 Subject: [PATCH 15/15] Make sure all the users accounts are included so internal transfers are ignored. [skip ci] --- app/Http/Controllers/Chart/CategoryController.php | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/app/Http/Controllers/Chart/CategoryController.php b/app/Http/Controllers/Chart/CategoryController.php index 409d20a21a..bdefe371f0 100644 --- a/app/Http/Controllers/Chart/CategoryController.php +++ b/app/Http/Controllers/Chart/CategoryController.php @@ -7,6 +7,7 @@ namespace FireflyIII\Http\Controllers\Chart; use Carbon\Carbon; use FireflyIII\Http\Controllers\Controller; use FireflyIII\Models\Category; +use FireflyIII\Repositories\Account\AccountRepositoryInterface as ARI; use FireflyIII\Repositories\Category\CategoryRepositoryInterface as CRI; use FireflyIII\Repositories\Category\SingleCategoryRepositoryInterface as SCRI; use FireflyIII\Support\CacheProperties; @@ -153,7 +154,7 @@ class CategoryController extends Controller * * @return \Symfony\Component\HttpFoundation\Response */ - public function frontpage(CRI $repository) + public function frontpage(CRI $repository, ARI $accountRepository) { $start = session('start', Carbon::now()->startOfMonth()); @@ -170,8 +171,9 @@ class CategoryController extends Controller } // get data for categories (and "no category"): - $set = $repository->spentForAccountsPerMonth(new Collection, $start, $end); - $outside = $repository->sumSpentNoCategory(new Collection, $start, $end); + $accounts = $accountRepository->getAccounts(['Default account', 'Asset account', 'Cash account']); + $set = $repository->spentForAccountsPerMonth($accounts, $start, $end); + $outside = $repository->sumSpentNoCategory($accounts, $start, $end); // this is a "fake" entry for the "no category" entry. $entry = new stdClass();