mirror of
				https://github.com/firefly-iii/firefly-iii.git
				synced 2025-10-31 10:47:00 +00:00 
			
		
		
		
	Compare commits
	
		
			473 Commits
		
	
	
		
	
	| Author | SHA1 | Date | |
|---|---|---|---|
|  | bd5c790043 | ||
|  | 2ae3cf79e4 | ||
|  | fb122ba097 | ||
|  | 0c104cd86c | ||
|  | a687f4ad68 | ||
|  | 228f42cf04 | ||
|  | 6d4956b574 | ||
|  | 0c7b652a70 | ||
|  | d35470a79e | ||
|  | 719d610be3 | ||
|  | 07ae64693e | ||
|  | 0ccc1271a6 | ||
|  | 26fa2b0b74 | ||
|  | 6f64c19c32 | ||
|  | e3e0e12fef | ||
|  | 0312ba8ad7 | ||
|  | 2ad8e7f343 | ||
|  | d6298d9f05 | ||
|  | 89be30c4b9 | ||
|  | 6bcfea1de4 | ||
|  | e8c9554dd6 | ||
|  | 02272f7db0 | ||
|  | 5a73e79475 | ||
|  | 7f4ecd40ce | ||
|  | 7c950c3022 | ||
|  | dbf019135a | ||
|  | e504ee82e5 | ||
|  | 780a15fe4f | ||
|  | abb249643f | ||
|  | 086eccaf4a | ||
|  | 871033501a | ||
|  | ccd727488f | ||
|  | aa59d0f082 | ||
|  | 5d12f53283 | ||
|  | 59c005875a | ||
|  | 06d22e843a | ||
|  | 4fa5f4e5a3 | ||
|  | 67ea825d4a | ||
|  | a616e06f9d | ||
|  | b7752928a4 | ||
|  | ca096852a5 | ||
|  | ea2c48bca5 | ||
|  | a722dc4235 | ||
|  | dbbf0ff5e4 | ||
|  | a941519db5 | ||
|  | d4ba014a8a | ||
|  | d193a6aec4 | ||
|  | 1f0fdf3da7 | ||
|  | b705240faa | ||
|  | 662b832274 | ||
|  | aed7e6d289 | ||
|  | f7a1201d02 | ||
|  | 4d5bdd25a8 | ||
|  | 4a90ce35f2 | ||
|  | 02f5eddd14 | ||
|  | 5ca4f1b181 | ||
|  | ec7ef3a813 | ||
|  | 49ff6febe5 | ||
|  | 2d66a9212f | ||
|  | 44fb307da4 | ||
|  | cfc2181a48 | ||
|  | cf4a846312 | ||
|  | 633b357d7b | ||
|  | b96d67a54e | ||
|  | 5b83931b01 | ||
|  | f22b54de30 | ||
|  | a3306bb26f | ||
|  | 0adacac269 | ||
|  | 7359ed2ba2 | ||
|  | 5a5f4e8161 | ||
|  | b886cc1333 | ||
|  | 9299efd086 | ||
|  | 1502aa3b20 | ||
|  | 73e32ecdcb | ||
|  | ac8776aea4 | ||
|  | 7b41c5b301 | ||
|  | 369839e012 | ||
|  | 8fde16422e | ||
|  | f1462dbd3d | ||
|  | 5dad569d62 | ||
|  | c424bb097d | ||
|  | e4b1760b20 | ||
|  | 780e365a78 | ||
|  | 3d1523a060 | ||
|  | ff403dfa2e | ||
|  | 89834baf01 | ||
|  | b8699422c8 | ||
|  | 6bc772d640 | ||
|  | 0712f30a51 | ||
|  | 9116796d90 | ||
|  | a95fdb903b | ||
|  | 2ca6421206 | ||
|  | cd076cc069 | ||
|  | 46482bdae1 | ||
|  | 5189c897be | ||
|  | 2c7d25d472 | ||
|  | 0da370c42d | ||
|  | 6f036d9120 | ||
|  | 260bbd79fd | ||
|  | 37ad6a3a62 | ||
|  | aa25007431 | ||
|  | 8b33ec1339 | ||
|  | cede11ecea | ||
|  | 2b4088c5f7 | ||
|  | d872484607 | ||
|  | f3f2160d96 | ||
|  | bcdb849b46 | ||
|  | 5846431b34 | ||
|  | 0217d9396a | ||
|  | c99e233026 | ||
|  | f670d930f3 | ||
|  | 0237d78f61 | ||
|  | 5665f127aa | ||
|  | 76386dad7d | ||
|  | 42072fdda4 | ||
|  | fc80f828be | ||
|  | d05a1e0260 | ||
|  | b315882f58 | ||
|  | 2f2f907ffe | ||
|  | 10492e3b2f | ||
|  | 8e08ff2d39 | ||
|  | e78a59a8a8 | ||
|  | cbe47a9dcc | ||
|  | a1056147d8 | ||
|  | 8692590600 | ||
|  | 57345113b5 | ||
|  | 52f02cb9eb | ||
|  | 5d4dcd7e4b | ||
|  | 7d1f4d8907 | ||
|  | a76241c7ba | ||
|  | bdc6678341 | ||
|  | c99b7e927d | ||
|  | 1675a0d442 | ||
|  | c0d2cd8962 | ||
|  | 146c9fd947 | ||
|  | 666e9897ea | ||
|  | 81d70bd811 | ||
|  | f6f8bb7fd1 | ||
|  | 7c3aaf7b7c | ||
|  | 32ea28f783 | ||
|  | 17f365941b | ||
|  | c2216843d8 | ||
|  | 339fb5099f | ||
|  | cf56707b02 | ||
|  | 19f38aa6ed | ||
|  | 9f69e112d0 | ||
|  | 8eb4259be0 | ||
|  | d3a1f43cbb | ||
|  | 18b06ff283 | ||
|  | 53addcf99a | ||
|  | 0fa4d75a47 | ||
|  | 2ef86c3339 | ||
|  | d48c3a6d2f | ||
|  | 2260ede559 | ||
|  | 5690a44c38 | ||
|  | e36a9fda1b | ||
|  | 10f195d334 | ||
|  | 54afc6ca8c | ||
|  | 2e67bd3b78 | ||
|  | f27eb084c7 | ||
|  | 7629dfd54a | ||
|  | f62fd18b72 | ||
|  | c6b60ff6b4 | ||
|  | e9655e6d86 | ||
|  | 3bca9b06f8 | ||
|  | d97fdc3393 | ||
|  | 7dc72f98bf | ||
|  | da00179066 | ||
|  | 89910031cd | ||
|  | 5676aeac80 | ||
|  | b0b9055e2e | ||
|  | c0aefed764 | ||
|  | e2ec9ca5fb | ||
|  | 8e38f5c2c0 | ||
|  | 99b2858863 | ||
|  | b43669e731 | ||
|  | 3bc9905715 | ||
|  | c55aebd005 | ||
|  | 55c331f536 | ||
|  | ce236284f4 | ||
|  | c24cac68f6 | ||
|  | db149ca6e1 | ||
|  | 0502f2a4a5 | ||
|  | f13df7e605 | ||
|  | 36a6981329 | ||
|  | 7abcdea816 | ||
|  | 0509e54a95 | ||
|  | b8893bcad7 | ||
|  | c9356c1237 | ||
|  | 2d7b7c2f3f | ||
|  | d0db1117f7 | ||
|  | e287e76db5 | ||
|  | 8c28c4b5ac | ||
|  | f048e943f8 | ||
|  | 12a84572e2 | ||
|  | c8de1d3372 | ||
|  | 234e3f4ca5 | ||
|  | 7749fb1a0b | ||
|  | f55d4e32c0 | ||
|  | cfd98a33fe | ||
|  | 7bdf20fee5 | ||
|  | e906fa3653 | ||
|  | 57cf7f6f0d | ||
|  | d378e7e897 | ||
|  | a8e666db34 | ||
|  | 7b46339a5d | ||
|  | 20aa6e429b | ||
|  | 7ba11a57a8 | ||
|  | 49de4f2200 | ||
|  | 5d01955133 | ||
|  | 7591f3fa29 | ||
|  | 89f8f9b45b | ||
|  | 59f5b38dca | ||
|  | 5b0e61033c | ||
|  | 096af00a72 | ||
|  | dca2dc4600 | ||
|  | 96b482dac5 | ||
|  | e05664f34f | ||
|  | 72cca5ccbf | ||
|  | 0b9be029ac | ||
|  | 91701473af | ||
|  | ad6a9a7df7 | ||
|  | 32b6ded008 | ||
|  | 4f2d0a0322 | ||
|  | 793cfcb2c5 | ||
|  | 3a71bd01fb | ||
|  | a1d99c1954 | ||
|  | 19a874b274 | ||
|  | b95dd5c238 | ||
|  | 7c84af2370 | ||
|  | db1c27d833 | ||
|  | 636cd84f4f | ||
|  | f2d4fae813 | ||
|  | 986c9ab20a | ||
|  | cd7e222b72 | ||
|  | 50b599b1a9 | ||
|  | 1d162edb59 | ||
|  | 7bdd4ddeab | ||
|  | ae6e5a5599 | ||
|  | 1222184b68 | ||
|  | 18f779c6de | ||
|  | 138f67581c | ||
|  | 597d6ac513 | ||
|  | 3ab25c2e8c | ||
|  | b11d97ba4e | ||
|  | 080c810131 | ||
|  | 56bc79d64e | ||
|  | 72d2c9d600 | ||
|  | 0374c32236 | ||
|  | d73cd4b515 | ||
|  | 54e3e3f051 | ||
|  | abf218fc21 | ||
|  | dcf90b6159 | ||
|  | 1cf91c78f8 | ||
|  | 968abd26e8 | ||
|  | aa05f7a2d2 | ||
|  | 181c23b07c | ||
|  | 955cde3ed9 | ||
|  | 477a3c7eb2 | ||
|  | f4b66b980b | ||
|  | 281de63e0d | ||
|  | c19a700662 | ||
|  | fc011ba1d9 | ||
|  | b941f590e0 | ||
|  | 8f4db78ff2 | ||
|  | 4b4dc2e298 | ||
|  | 2de19547ca | ||
|  | 5a058491b0 | ||
|  | 6743d99d9b | ||
|  | 35a5ec78c3 | ||
|  | 3440c3e77a | ||
|  | dd17f06362 | ||
|  | 8a15cb3a34 | ||
|  | 4a548ac282 | ||
|  | d22353b13d | ||
|  | c18046c25d | ||
|  | 4a12d4d156 | ||
|  | 20044427b4 | ||
|  | 073dedd483 | ||
|  | 06c25c913c | ||
|  | 08d06cf465 | ||
|  | 1e9eb843c0 | ||
|  | 78a5dae2a0 | ||
|  | 19443a5b34 | ||
|  | 74acc90702 | ||
|  | 349f580371 | ||
|  | f019d33a03 | ||
|  | c7af25ac38 | ||
|  | b52bd59cea | ||
|  | 332d32c319 | ||
|  | 2f824ba1a8 | ||
|  | a6b09acd5e | ||
|  | d4779c8c8f | ||
|  | ba01c4bbe8 | ||
|  | ddc1d81665 | ||
|  | 790aeb3c46 | ||
|  | 6ed5be10b1 | ||
|  | a7b8470d9e | ||
|  | 2a05cc382f | ||
|  | 1e10a6ce1b | ||
|  | 7645ef55c2 | ||
|  | 6ce200b60d | ||
|  | d782e28906 | ||
|  | da3bd31fb8 | ||
|  | aa3ed40430 | ||
|  | ad7e564f14 | ||
|  | f23ee2dac5 | ||
|  | 1962f74439 | ||
|  | 0064d060ea | ||
|  | e47e6b1958 | ||
|  | 4c04415e80 | ||
|  | 3654e75b8c | ||
|  | 66fa73aea4 | ||
|  | df87d03f32 | ||
|  | 3fbe851a0b | ||
|  | d1b2e63950 | ||
|  | 34fd8cf751 | ||
|  | f1fe90fce0 | ||
|  | 2ba6fa0dda | ||
|  | f2928e3d7d | ||
|  | 895ab9c5d8 | ||
|  | fb07c68132 | ||
|  | 68e7d45f63 | ||
|  | 49e302e1bc | ||
|  | b33ca786ae | ||
|  | dc77d8edda | ||
|  | c339a183b9 | ||
|  | f263795a99 | ||
|  | e9e771e57b | ||
|  | fbb9d7c6b4 | ||
|  | 10abd7b0ae | ||
|  | 3de36901b8 | ||
|  | 5b4967acb9 | ||
|  | 0a007b1e6e | ||
|  | 4ad68b7dfa | ||
|  | 73aef1b9a4 | ||
|  | dcfea20973 | ||
|  | 9b6766d3b2 | ||
|  | b8bc8e2c47 | ||
|  | 039e3aa34c | ||
|  | 551ff109c9 | ||
|  | 664451d0c6 | ||
|  | 4031057bc0 | ||
|  | fcf9b782c1 | ||
|  | d693d382b9 | ||
|  | 0a1b6c7793 | ||
|  | 5acba2bddf | ||
|  | 883b16fad1 | ||
|  | ef48b3e751 | ||
|  | 3c956e7e98 | ||
|  | 519ea271a9 | ||
|  | 09d5160404 | ||
|  | 97dcf03334 | ||
|  | 896a804a72 | ||
|  | 656bb5043d | ||
|  | e953becbae | ||
|  | 6c9901b919 | ||
|  | ff45c94106 | ||
|  | a8a3fbeef4 | ||
|  | dae8092ecd | ||
|  | 70110208fc | ||
|  | 217ca98933 | ||
|  | c2945c532e | ||
|  | ea750576b3 | ||
|  | 82538ba4fc | ||
|  | 2b2f37a8c9 | ||
|  | 4db2ec60e0 | ||
|  | 7d88d35556 | ||
|  | 3c3e91ff48 | ||
|  | 039e8d6e17 | ||
|  | 50bf79ab18 | ||
|  | 467c6762fa | ||
|  | 740f4e403f | ||
|  | 5664d51695 | ||
|  | b195a61498 | ||
|  | 94e6816bf6 | ||
|  | ebf97f710f | ||
|  | 714b54ed06 | ||
|  | 620c5f515e | ||
|  | c06fd12b07 | ||
|  | 2c206bba64 | ||
|  | 04953b5645 | ||
|  | 1732ce63f3 | ||
|  | dd44a1e517 | ||
|  | 9f26757e8a | ||
|  | a9c8c8384d | ||
|  | 69019d5215 | ||
|  | 96411b17e9 | ||
|  | 5a093b58d8 | ||
|  | 470b3e0973 | ||
|  | dc251c216c | ||
|  | ae9ef61f80 | ||
|  | d9ca7b7277 | ||
|  | 0c99248deb | ||
|  | 1aae84a4d0 | ||
|  | 528da3f08e | ||
|  | 9c507f7f62 | ||
|  | 07da2fdda3 | ||
|  | ca3366544e | ||
|  | ccee7b483c | ||
|  | 5903133e3b | ||
|  | 5bf520b6ed | ||
|  | a47da92d81 | ||
|  | 63f84ae7b1 | ||
|  | 4d6bc55723 | ||
|  | 9bb4df4cc3 | ||
|  | c47a5379ae | ||
|  | cde9c4a2bc | ||
|  | 5a560b42ef | ||
|  | 50874c9cf7 | ||
|  | 6f984aa591 | ||
|  | 274162afcd | ||
|  | 6bd23d897f | ||
|  | 73f29ebf69 | ||
|  | cabcb9c6d0 | ||
|  | 116f7ed613 | ||
|  | 6ef0eb73d0 | ||
|  | 7f4feb0cfc | ||
|  | 626f7357bb | ||
|  | 690c9203c8 | ||
|  | 1209f3b39a | ||
|  | a4524b3c2c | ||
|  | a3cbdadb39 | ||
|  | 9e3c5fd984 | ||
|  | 7d80ac37a6 | ||
|  | f74b9ba7ab | ||
|  | 3ac240dc1c | ||
|  | d233b3f24f | ||
|  | 19fff681d2 | ||
|  | bc7c3bb9b3 | ||
|  | 57be7f2905 | ||
|  | 1c0da454db | ||
|  | b541f7b944 | ||
|  | 6e84326583 | ||
|  | ca14496e4e | ||
|  | 480d65fc1f | ||
|  | 6bddb63b45 | ||
|  | c5142aeba5 | ||
|  | 38d9f10672 | ||
|  | 937394af7a | ||
|  | fe10955eb9 | ||
|  | ccda71ff8e | ||
|  | cd75224cdd | ||
|  | 1c2089b8a3 | ||
|  | 3ead4d4587 | ||
|  | f2b71bc280 | ||
|  | f027d71136 | ||
|  | fa41d6df04 | ||
|  | d2bb65bf04 | ||
|  | b5be1b11d1 | ||
|  | 9fb049991f | ||
|  | fba847dd28 | ||
|  | b33883b334 | ||
|  | f74a6dffca | ||
|  | 7390e20218 | ||
|  | 9646dc439e | ||
|  | 554c63b9c7 | ||
|  | 24d8640e9b | ||
|  | ea151d069c | ||
|  | f140d2f37a | ||
|  | 4e163c4bda | ||
|  | ddcf8b892b | ||
|  | 49138eb03a | ||
|  | 71b63bd33b | ||
|  | 88348f59c2 | ||
|  | 7eb5643204 | ||
|  | 565cb6d79e | ||
|  | c0d715c78a | ||
|  | a3d0355ddd | ||
|  | bc4e06568d | ||
|  | 8acb9f4056 | ||
|  | 9cbbd581ee | ||
|  | fdc9467218 | 
| @@ -1,8 +1,23 @@ | ||||
| #!/bin/bash | ||||
|  | ||||
| # make sure the correct directories exists (suggested by @chrif): | ||||
| mkdir -p $FIREFLY_PATH/storage/app | ||||
| mkdir -p $FIREFLY_PATH/storage/app/public | ||||
| mkdir -p $FIREFLY_PATH/storage/build | ||||
| mkdir -p $FIREFLY_PATH/storage/database | ||||
| mkdir -p $FIREFLY_PATH/storage/debugbar | ||||
| mkdir -p $FIREFLY_PATH/storage/export | ||||
| mkdir -p $FIREFLY_PATH/storage/framework/cache | ||||
| mkdir -p $FIREFLY_PATH/storage/framework/sessions | ||||
| mkdir -p $FIREFLY_PATH/storage/framework/testing | ||||
| mkdir -p $FIREFLY_PATH/storage/framework/views | ||||
| mkdir -p $FIREFLY_PATH/storage/logs | ||||
| mkdir -p $FIREFLY_PATH/storage/upload | ||||
|  | ||||
|  | ||||
| # make sure we own the volumes: | ||||
| chown -R www-data:www-data -R $FIREFLY_PATH/storage/export $FIREFLY_PATH/storage/upload $FIREFLY_PATH/storage/logs $FIREFLY_PATH/storage/cache | ||||
| chmod -R 775 $FIREFLY_PATH/storage/export $FIREFLY_PATH/storage/upload $FIREFLY_PATH/storage/upload $FIREFLY_PATH/storage/logs $FIREFLY_PATH/storage/cache | ||||
| chown -R www-data:www-data -R $FIREFLY_PATH/storage | ||||
| chmod -R 775 $FIREFLY_PATH/storage | ||||
|  | ||||
| # remove any lingering files that may break upgrades: | ||||
| rm -f $FIREFLY_PATH/storage/logs/laravel.log | ||||
|   | ||||
| @@ -1,4 +1,3 @@ | ||||
| # Ignore composer specific files and vendor folder | ||||
| composer.phar | ||||
| composer.lock | ||||
| vendor | ||||
|   | ||||
| @@ -50,6 +50,7 @@ COOKIE_DOMAIN= | ||||
| COOKIE_SECURE=false | ||||
|  | ||||
| # If you want Firefly III to mail you, update these settings | ||||
| # For instructions, see: https://firefly-iii.readthedocs.io/en/latest/installation/mail.html | ||||
| MAIL_DRIVER=${MAIL_DRIVER} | ||||
| MAIL_HOST=${MAIL_HOST} | ||||
| MAIL_PORT=${MAIL_PORT} | ||||
| @@ -58,6 +59,12 @@ MAIL_USERNAME=${MAIL_USERNAME} | ||||
| MAIL_PASSWORD=${MAIL_PASSWORD} | ||||
| MAIL_ENCRYPTION=${MAIL_ENCRYPTION} | ||||
|  | ||||
| # Other mail drivers: | ||||
| MAILGUN_DOMAIN=${MAILGUN_DOMAIN} | ||||
| MAILGUN_SECRET=${MAILGUN_SECRET} | ||||
| MANDRILL_SECRET=${MANDRILL_SECRET} | ||||
| SPARKPOST_SECRET=${SPARKPOST_SECRET} | ||||
|  | ||||
| # Firefly III can send you the following messages | ||||
| SEND_REGISTRATION_MAIL=true | ||||
| SEND_ERROR_MESSAGE=false | ||||
| @@ -95,4 +102,5 @@ DEMO_PASSWORD= | ||||
| IS_DOCKER=true | ||||
| IS_SANDSTORM=false | ||||
| IS_HEROKU=false | ||||
| BUNQ_USE_SANDBOX=false | ||||
| TZ=${TZ} | ||||
|   | ||||
							
								
								
									
										10
									
								
								.env.example
									
									
									
									
									
								
							
							
						
						
									
										10
									
								
								.env.example
									
									
									
									
									
								
							| @@ -54,6 +54,7 @@ COOKIE_DOMAIN= | ||||
| COOKIE_SECURE=false | ||||
|  | ||||
| # If you want Firefly III to mail you, update these settings | ||||
| # For instructions, see: https://firefly-iii.readthedocs.io/en/latest/installation/mail.html | ||||
| MAIL_DRIVER=log | ||||
| MAIL_HOST=smtp.mailtrap.io | ||||
| MAIL_PORT=2525 | ||||
| @@ -62,6 +63,12 @@ MAIL_USERNAME=null | ||||
| MAIL_PASSWORD=null | ||||
| MAIL_ENCRYPTION=null | ||||
|  | ||||
| # Other mail drivers: | ||||
| MAILGUN_DOMAIN= | ||||
| MAILGUN_SECRET= | ||||
| MANDRILL_SECRET= | ||||
| SPARKPOST_SECRET= | ||||
|  | ||||
| # Firefly III can send you the following messages | ||||
| SEND_REGISTRATION_MAIL=true | ||||
| SEND_ERROR_MESSAGE=true | ||||
| @@ -98,4 +105,7 @@ DEMO_USERNAME= | ||||
| DEMO_PASSWORD= | ||||
| IS_DOCKER=false | ||||
| IS_SANDSTORM=false | ||||
| BUNQ_USE_SANDBOX=false | ||||
| IS_HEROKU=false | ||||
| MAILGUN_DOMAIN= | ||||
| MAILGUN_SECRET= | ||||
|   | ||||
							
								
								
									
										10
									
								
								.env.heroku
									
									
									
									
									
								
							
							
						
						
									
										10
									
								
								.env.heroku
									
									
									
									
									
								
							| @@ -54,6 +54,7 @@ COOKIE_DOMAIN= | ||||
| COOKIE_SECURE=false | ||||
|  | ||||
| # If you want Firefly III to mail you, update these settings | ||||
| # For instructions, see: https://firefly-iii.readthedocs.io/en/latest/installation/mail.html | ||||
| MAIL_DRIVER=log | ||||
| MAIL_HOST=smtp.mailtrap.io | ||||
| MAIL_PORT=2525 | ||||
| @@ -62,6 +63,12 @@ MAIL_USERNAME=null | ||||
| MAIL_PASSWORD=null | ||||
| MAIL_ENCRYPTION=null | ||||
|  | ||||
| # Other mail drivers: | ||||
| MAILGUN_DOMAIN= | ||||
| MAILGUN_SECRET= | ||||
| MANDRILL_SECRET= | ||||
| SPARKPOST_SECRET= | ||||
|  | ||||
| # Firefly III can send you the following messages | ||||
| SEND_REGISTRATION_MAIL=true | ||||
| SEND_ERROR_MESSAGE=true | ||||
| @@ -98,4 +105,7 @@ DEMO_USERNAME= | ||||
| DEMO_PASSWORD= | ||||
| IS_DOCKER=false | ||||
| IS_SANDSTORM=false | ||||
| BUNQ_USE_SANDBOX=false | ||||
| IS_HEROKU=true | ||||
| MAILGUN_DOMAIN= | ||||
| MAILGUN_SECRET= | ||||
|   | ||||
| @@ -54,6 +54,7 @@ COOKIE_DOMAIN= | ||||
| COOKIE_SECURE=false | ||||
|  | ||||
| # If you want Firefly III to mail you, update these settings | ||||
| # For instructions, see: https://firefly-iii.readthedocs.io/en/latest/installation/mail.html | ||||
| MAIL_DRIVER=log | ||||
| MAIL_HOST=smtp.mailtrap.io | ||||
| MAIL_PORT=2525 | ||||
| @@ -62,6 +63,12 @@ MAIL_USERNAME=null | ||||
| MAIL_PASSWORD=null | ||||
| MAIL_ENCRYPTION=null | ||||
|  | ||||
| # Other mail drivers: | ||||
| MAILGUN_DOMAIN= | ||||
| MAILGUN_SECRET= | ||||
| MANDRILL_SECRET= | ||||
| SPARKPOST_SECRET= | ||||
|  | ||||
| # Firefly III can send you the following messages | ||||
| SEND_REGISTRATION_MAIL=true | ||||
| SEND_ERROR_MESSAGE=true | ||||
| @@ -98,4 +105,7 @@ DEMO_USERNAME= | ||||
| DEMO_PASSWORD= | ||||
| IS_DOCKER=false | ||||
| IS_SANDSTORM=true | ||||
| BUNQ_USE_SANDBOX=false | ||||
| IS_HEROKU=false | ||||
| MAILGUN_DOMAIN= | ||||
| MAILGUN_SECRET= | ||||
|   | ||||
							
								
								
									
										12
									
								
								.env.testing
									
									
									
									
									
								
							
							
						
						
									
										12
									
								
								.env.testing
									
									
									
									
									
								
							| @@ -49,6 +49,7 @@ COOKIE_DOMAIN= | ||||
| COOKIE_SECURE=false | ||||
|  | ||||
| # If you want Firefly III to mail you, update these settings | ||||
| # For instructions, see: https://firefly-iii.readthedocs.io/en/latest/installation/mail.html | ||||
| MAIL_DRIVER=log | ||||
| MAIL_HOST=smtp.mailtrap.io | ||||
| MAIL_PORT=2525 | ||||
| @@ -57,9 +58,11 @@ MAIL_USERNAME=null | ||||
| MAIL_PASSWORD=null | ||||
| MAIL_ENCRYPTION=null | ||||
|  | ||||
| # Firefly III can send you the following messages | ||||
| SEND_REGISTRATION_MAIL=true | ||||
| SEND_ERROR_MESSAGE=false | ||||
| # Other mail drivers: | ||||
| MAILGUN_DOMAIN= | ||||
| MAILGUN_SECRET= | ||||
| MANDRILL_SECRET= | ||||
| SPARKPOST_SECRET= | ||||
|  | ||||
|  | ||||
| # Set a Mapbox API key here (see mapbox.com) so there might be a map available at various places. | ||||
| @@ -94,4 +97,7 @@ DEMO_USERNAME= | ||||
| DEMO_PASSWORD= | ||||
| IS_DOCKER=false | ||||
| IS_SANDSTORM=false | ||||
| BUNQ_USE_SANDBOX=true | ||||
| IS_HEROKU=false | ||||
| MAILGUN_DOMAIN= | ||||
| MAILGUN_SECRET= | ||||
|   | ||||
							
								
								
									
										22
									
								
								.github/ISSUE_TEMPLATE/Bug_report.md
									
									
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										22
									
								
								.github/ISSUE_TEMPLATE/Bug_report.md
									
									
									
									
										vendored
									
									
										Normal file
									
								
							| @@ -0,0 +1,22 @@ | ||||
| --- | ||||
| name: Bug report | ||||
| about: Create a report to help Firefly III improve | ||||
|  | ||||
| --- | ||||
|  | ||||
| **Bug description** | ||||
| I am running Firefly III version x.x.x | ||||
|  | ||||
| (please give a clear and concise description of what the bug is) | ||||
|  | ||||
| **Steps to reproduce** | ||||
| What do you need to do to trigger this bug? | ||||
|  | ||||
| **Extra info** | ||||
| Please add extra info here, such as OS, browser, and the output from the /debug page of your Firefly III installation (click the version at the bottom). | ||||
|  | ||||
| **Bonus points** | ||||
| Earn bonus points by: | ||||
|  | ||||
| - Post a stacktrace from your log files | ||||
| - Add a screenshot | ||||
							
								
								
									
										27
									
								
								.github/ISSUE_TEMPLATE/Custom.md
									
									
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										27
									
								
								.github/ISSUE_TEMPLATE/Custom.md
									
									
									
									
										vendored
									
									
										Normal file
									
								
							| @@ -0,0 +1,27 @@ | ||||
| --- | ||||
| name: I have a question or a problem | ||||
| about: Ask away! | ||||
|  | ||||
| --- | ||||
|  | ||||
| I am running Firefly III version x.x.x | ||||
|  | ||||
| **Description** | ||||
|  | ||||
|  | ||||
|  | ||||
| **Steps to reproduce**  | ||||
| (if relevant of course) | ||||
|  | ||||
|  | ||||
|  | ||||
| **Extra info** | ||||
| Please add extra info here, such as OS, browser, and the output from the `/debug`-page of your Firefly III installation (click the version at the bottom).  | ||||
|  | ||||
|  | ||||
|  | ||||
| **Bonus points** | ||||
| Earn bonus points by: | ||||
|  | ||||
| - Add a screenshot | ||||
| - Replicate the problem on the demo site https://demo.firefly-iii.org/ | ||||
							
								
								
									
										21
									
								
								.github/ISSUE_TEMPLATE/Feature_request.md
									
									
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										21
									
								
								.github/ISSUE_TEMPLATE/Feature_request.md
									
									
									
									
										vendored
									
									
										Normal file
									
								
							| @@ -0,0 +1,21 @@ | ||||
| --- | ||||
| name: Feature request | ||||
| about: Suggest an idea or feature for Firefly III | ||||
|  | ||||
| --- | ||||
|  | ||||
| **Description** | ||||
| Please describe your feature request: | ||||
|  | ||||
| - I would like Firefly III to do X. | ||||
| - What if you would add feature Y? | ||||
| - Firefly III doesn't do Z. | ||||
|  | ||||
| **Solution** | ||||
| Describe what your feature would add to Firefly III. | ||||
|  | ||||
| **What are alternatives?** | ||||
| Please describe what alternatives currently exist. | ||||
|  | ||||
| **Additional context** | ||||
| Add any other context or screenshots about the feature request here. | ||||
							
								
								
									
										11
									
								
								.github/issue_template.md
									
									
									
									
										vendored
									
									
								
							
							
						
						
									
										11
									
								
								.github/issue_template.md
									
									
									
									
										vendored
									
									
								
							| @@ -1,11 +0,0 @@ | ||||
| I am running Firefly III version x.x.x  | ||||
|  | ||||
| #### Description of my issue: | ||||
|  | ||||
| #### Steps to reproduce  | ||||
|  | ||||
| (please include if this problem also exists on the demo site) | ||||
|  | ||||
| #### Other important details (log files, system info): | ||||
|  | ||||
| Please click the version number in the right corner of any Firefly III page to get debug information.  | ||||
							
								
								
									
										3
									
								
								.github/stale.yml
									
									
									
									
										vendored
									
									
								
							
							
						
						
									
										3
									
								
								.github/stale.yml
									
									
									
									
										vendored
									
									
								
							| @@ -1,7 +1,7 @@ | ||||
| # Configuration for probot-stale - https://github.com/probot/stale | ||||
|  | ||||
| # Number of days of inactivity before an Issue or Pull Request becomes stale | ||||
| daysUntilStale: 30 | ||||
| daysUntilStale: 14 | ||||
|  | ||||
| # Number of days of inactivity before a stale Issue or Pull Request is closed. | ||||
| # Set to false to disable. If disabled, issues still need to be closed manually, but will remain marked as stale. | ||||
| @@ -12,6 +12,7 @@ daysUntilClose: 7 | ||||
| exemptLabels: | ||||
|   - enhancement | ||||
|   - feature | ||||
|   - bug | ||||
|  | ||||
| # Set to true to ignore issues in a project (defaults to false) | ||||
| exemptProjects: false | ||||
|   | ||||
							
								
								
									
										9
									
								
								.sandstorm/Vagrantfile
									
									
									
									
										vendored
									
									
								
							
							
						
						
									
										9
									
								
								.sandstorm/Vagrantfile
									
									
									
									
										vendored
									
									
								
							| @@ -9,9 +9,16 @@ VM_NAME = File.basename(File.dirname(File.dirname(__FILE__))) + "_sandstorm_#{Ti | ||||
| # Vagrantfile API/syntax version. Don't touch unless you know what you're doing! | ||||
| VAGRANTFILE_API_VERSION = "2" | ||||
|  | ||||
| # ugly hack to prevent hashicorp's bitrot. See https://github.com/hashicorp/vagrant/issues/9442 | ||||
| # this setting is required for pre-2.0 vagrant, but causes an error as of 2.0.3, | ||||
| # remove entirely when confident nobody uses vagrant 1.x for anything. | ||||
| unless Vagrant::DEFAULT_SERVER_URL.frozen? | ||||
|   Vagrant::DEFAULT_SERVER_URL.replace('https://vagrantcloud.com') | ||||
| end | ||||
|  | ||||
| Vagrant.configure(VAGRANTFILE_API_VERSION) do |config| | ||||
|   # Base on the Sandstorm snapshots of the official Debian 8 (jessie) box. | ||||
|   config.vm.box = "sandstorm/debian-jessie64" | ||||
|   config.vm.box = "debian/contrib-jessie64" | ||||
|  | ||||
|   if Vagrant.has_plugin?("vagrant-vbguest") then | ||||
|     # vagrant-vbguest is a Vagrant plugin that upgrades | ||||
|   | ||||
| @@ -1,7 +1,73 @@ | ||||
| # 4.7.5.3 | ||||
| - [Issue 1527](https://github.com/firefly-iii/firefly-iii/issues/1527), fixed views for transactions without a budget. | ||||
| - [Issue 1553](https://github.com/firefly-iii/firefly-iii/issues/1553), report could not handle transactions before the first one in the system. | ||||
| - [Issue 1549](https://github.com/firefly-iii/firefly-iii/issues/1549) update a budget will also update any rules that refer to that budget. | ||||
| - [Issue 1530](https://github.com/firefly-iii/firefly-iii/issues/1530), fix issue with bill chart. | ||||
| - [Issue 1563](https://github.com/firefly-iii/firefly-iii/issues/1563), fix piggy bank suggested amount | ||||
| - [Issue 1571](https://github.com/firefly-iii/firefly-iii/issues/1571), fix OAuth in Sandstorm | ||||
| - [Issue 1568](https://github.com/firefly-iii/firefly-iii/issues/1568), bug in Sandstorm user code. | ||||
| - [Issue 1569](https://github.com/firefly-iii/firefly-iii/issues/1569), optimized Sandstorm build by [ocdtrekkie](https://github.com/ocdtrekkie) | ||||
| - Fixed a bug where transfers would be stored inversely when using the CSV import. | ||||
| - Retired the "Rabobank description"-fix, because it is no longer necessary. | ||||
| - Fixed a bug where users could not delete budget limits in the API. | ||||
| - Piggy bank notes are visible again. | ||||
|  | ||||
| # 4.7.5.1 | ||||
| - [Issue 1531](https://github.com/firefly-iii/firefly-iii/issues/1531), the database routine incorrectly reports empty categories. | ||||
| - [Issue 1532](https://github.com/firefly-iii/firefly-iii/issues/1532), broken dropdown for autosuggest things. | ||||
| - [Issue 1533](https://github.com/firefly-iii/firefly-iii/issues/1533), fix where the import could not import category names. | ||||
| - [Issue 1538](https://github.com/firefly-iii/firefly-iii/issues/1538), fix a bug where Spectre would not work when ignoring rules. | ||||
| - [Issue 1542](https://github.com/firefly-iii/firefly-iii/issues/1542), fix a bug where the importer was incapable of generating new currencies. | ||||
| - [Issue 1541](https://github.com/firefly-iii/firefly-iii/issues/1541), no longer ignore composer.lock in Docker ignore. | ||||
| - Bills are stored inactive. | ||||
|  | ||||
| # 4.7.5 | ||||
| - A new feature called "recurring transactions" that will make Firefly III automatically create transactions for you. | ||||
| - New API end points for attachments, available budgets, budgets, budget limits, categories, configuration, currency exchange rates, journal links, link types, piggy banks, preferences, recurring transactions, rules, rule groups and tags. | ||||
| - Added support for YunoHost. | ||||
| - The 2FA secret is visible so you can type it into 2FA apps. | ||||
| - Bunq and Spectre imports will now ask to apply rules. | ||||
| - Sandstorm users can now make API keys. | ||||
| - Various typo's in the English translations. [issue 1493](https://github.com/firefly-iii/firefly-iii/issues/1493) | ||||
| - Bug where Spectre was never called [issue 1492](https://github.com/firefly-iii/firefly-iii/issues/1492) | ||||
| - Clear cache after journal is created through API [issue 1483](https://github.com/firefly-iii/firefly-iii/issues/1483) | ||||
| - Make sure docker directories exist [issue 1500](https://github.com/firefly-iii/firefly-iii/issues/1500) | ||||
| - Broken link to bill edit [issue 1505](https://github.com/firefly-iii/firefly-iii/issues/1505) | ||||
| - Several bugs in the editing of split transactions [issue 1509](https://github.com/firefly-iii/firefly-iii/issues/1509) | ||||
| - Import routine ignored formatting of several date fields [issue 1510](https://github.com/firefly-iii/firefly-iii/issues/1510) | ||||
| - Piggy bank events now show the correct currency [issue 1446](https://github.com/firefly-iii/firefly-iii/issues/1446) | ||||
| - Inactive accounts are no longer suggested [issue 1463](https://github.com/firefly-iii/firefly-iii/issues/1463) | ||||
| - Some income / expense charts are less confusing [issue 1518](https://github.com/firefly-iii/firefly-iii/issues/1518) | ||||
| - Validation bug in multi-currency create view [issue 1521](https://github.com/firefly-iii/firefly-iii/issues/1521) | ||||
|  | ||||
| # 4.7.4 | ||||
| - [Issue 1409](https://github.com/firefly-iii/firefly-iii/issues/1409), add Indian Rupee and explain that users can do this themselves [issue 1413](https://github.com/firefly-iii/firefly-iii/issues/1413) | ||||
| - [Issue 1445](https://github.com/firefly-iii/firefly-iii/issues/1445), upgrade Curl in Docker image. | ||||
| - [Issue 1386](https://github.com/firefly-iii/firefly-iii/issues/1386), quick links to often used pages. | ||||
| - [Issue 1405](https://github.com/firefly-iii/firefly-iii/issues/1405), show proposed amount to piggy banks. | ||||
| - [Issue 1416](https://github.com/firefly-iii/firefly-iii/issues/1416), ability to delete lost attachments. | ||||
| - A completely rewritten import routine that can handle bunq (thanks everybody for testing!), CSV files and Spectre. Please make sure you read about this at http://bit.ly/FF3-new-import | ||||
| - [Issue 1392](https://github.com/firefly-iii/firefly-iii/issues/1392), explicitly mention rules are inactive (when they are). | ||||
| - [Issue 1406](https://github.com/firefly-iii/firefly-iii/issues/1406), bill conversion to rules will be smarter about the rules they create. | ||||
| - [Issue 1369](https://github.com/firefly-iii/firefly-iii/issues/1369), you can now properly order piggy banks again. | ||||
| - [Issue 1389](https://github.com/firefly-iii/firefly-iii/issues/1389), null-pointer in the import routine. | ||||
| - [Issue 1400](https://github.com/firefly-iii/firefly-iii/issues/1400), missing translation. | ||||
| - [Issue 1403](https://github.com/firefly-iii/firefly-iii/issues/1403), bill would always be marked as inactive in edit screen. | ||||
| - [Issue 1418](https://github.com/firefly-iii/firefly-iii/issues/1418), missing note text on bill page. | ||||
| - Export routine would break when encountering un-decryptable files. | ||||
| - [Issue 1425](https://github.com/firefly-iii/firefly-iii/issues/1425), empty fields when edit multiple transactions at once. | ||||
| - [Issue 1449](https://github.com/firefly-iii/firefly-iii/issues/1449), bad calculations in "budget left to spend" view. | ||||
| - [Issue 1451](https://github.com/firefly-iii/firefly-iii/issues/1451), same but in another view. | ||||
| - [Issue 1453](https://github.com/firefly-iii/firefly-iii/issues/1453), same as [issue 1403](https://github.com/firefly-iii/firefly-iii/issues/1403). | ||||
| - [Issue 1455](https://github.com/firefly-iii/firefly-iii/issues/1455), could add income to a budget. | ||||
| - [Issue 1442](https://github.com/firefly-iii/firefly-iii/issues/1442), issues with editing a split deposit. | ||||
| - [Issue 1452](https://github.com/firefly-iii/firefly-iii/issues/1452), date range problems with tags. | ||||
| - [Issue 1458](https://github.com/firefly-iii/firefly-iii/issues/1458), same for transactions. | ||||
| - [Issue 1415](https://github.com/firefly-iii/firefly-iii/issues/1415), will email you when OAuth2 keys are generated. | ||||
|  | ||||
| # 4.7.3.2 | ||||
| - Forgot to increase the version number :(. | ||||
|  | ||||
|  | ||||
| # 4.7.3.1 | ||||
| - Fixed a critical bug where the rules-engine would fire inadvertently. | ||||
|  | ||||
|   | ||||
| @@ -9,6 +9,10 @@ CURL_OPTS="--silent --show-error" | ||||
| echo localhost > /etc/hostname | ||||
| hostname localhost | ||||
|  | ||||
| # Install curl that is needed below. | ||||
| apt-get update | ||||
| apt-get install -y curl | ||||
|  | ||||
| # The following line copies stderr through stderr to cat without accidentally leaving it in the | ||||
| # output file. Be careful when changing. See: https://github.com/sandstorm-io/vagrant-spk/pull/159 | ||||
| curl $CURL_OPTS https://install.sandstorm.io/ 2>&1 > /host-dot-sandstorm/caches/install.sh | cat | ||||
|   | ||||
										
											
												File diff suppressed because it is too large
												Load Diff
											
										
									
								
							| @@ -15,8 +15,8 @@ const pkgdef :Spk.PackageDefinition = ( | ||||
|  | ||||
|   manifest = ( | ||||
|     appTitle = (defaultText = "Firefly III"), | ||||
|     appVersion = 12, | ||||
|     appMarketingVersion = (defaultText = "4.7.3.2"), | ||||
|     appVersion = 15, | ||||
|     appMarketingVersion = (defaultText = "4.7.5.3"), | ||||
|  | ||||
|     actions = [ | ||||
|       # Define your "new document" handlers here. | ||||
| @@ -65,9 +65,9 @@ const pkgdef :Spk.PackageDefinition = ( | ||||
|         # Sizes are given in device-independent pixels, so if you took these | ||||
|         # screenshots on a Retina-style high DPI screen, divide each dimension by two. | ||||
|  | ||||
|         (width = 1291, height = 800, png = embed "screenshots/screenshot-1.png"), | ||||
|         (width = 1291, height = 800, png = embed "screenshots/screenshot-2.png"), | ||||
|         (width = 1291, height = 800, png = embed "screenshots/screenshot-3.png"), | ||||
|         (width = 1290, height = 800, png = embed "screenshots/screenshot-1.png"), | ||||
|         (width = 1290, height = 800, png = embed "screenshots/screenshot-2.png"), | ||||
|         (width = 1290, height = 800, png = embed "screenshots/screenshot-3.png"), | ||||
|  | ||||
|       ], | ||||
|       changeLog = (defaultText = embed "changelog.md"), | ||||
|   | ||||
										
											Binary file not shown.
										
									
								
							| Before Width: | Height: | Size: 120 KiB After Width: | Height: | Size: 173 KiB | 
										
											Binary file not shown.
										
									
								
							| Before Width: | Height: | Size: 122 KiB After Width: | Height: | Size: 171 KiB | 
										
											Binary file not shown.
										
									
								
							| Before Width: | Height: | Size: 107 KiB After Width: | Height: | Size: 163 KiB | 
| @@ -14,10 +14,7 @@ apt-get install -y python-software-properties software-properties-common | ||||
|  | ||||
| # install all languages | ||||
| sed -i 's/# de_DE.UTF-8 UTF-8/de_DE.UTF-8 UTF-8/g' /etc/locale.gen | ||||
|  | ||||
| sed -i 's/# es_ES.UTF-8 UTF-8/es_ES.UTF-8 UTF-8/g' /etc/locale.gen | ||||
| sed -i 's/# fr_FR.UTF-8 UTF-8/fr_FR.UTF-8 UTF-8/g' /etc/locale.gen | ||||
| sed -i 's/# id_ID.UTF-8 UTF-8/id_ID.UTF-8 UTF-8/g' /etc/locale.gen | ||||
| sed -i 's/# it_IT.UTF-8 UTF-8/it_IT.UTF-8 UTF-8/g' /etc/locale.gen | ||||
| sed -i 's/# nl_NL.UTF-8 UTF-8/nl_NL.UTF-8 UTF-8/g' /etc/locale.gen | ||||
| sed -i 's/# pl_PL.UTF-8 UTF-8/pl_PL.UTF-8 UTF-8/g' /etc/locale.gen | ||||
| @@ -35,7 +32,7 @@ apt-key adv --keyserver keyserver.ubuntu.com --recv-keys E9C74FEEA2098A6E | ||||
| add-apt-repository "deb http://packages.dotdeb.org jessie all" | ||||
|  | ||||
| # add another repos | ||||
| apt-get install apt-transport-https lsb-release ca-certificates | ||||
| apt-get install -y apt-transport-https lsb-release ca-certificates | ||||
| wget -O /etc/apt/trusted.gpg.d/php.gpg https://packages.sury.org/php/apt.gpg | ||||
| echo "deb https://packages.sury.org/php/ $(lsb_release -sc) main" > /etc/apt/sources.list.d/php.list | ||||
|  | ||||
|   | ||||
| @@ -1,7 +1,6 @@ | ||||
| language: php | ||||
| php: | ||||
|   - 7.1 | ||||
|   - 7.2 | ||||
|   - 7.1.18 | ||||
|  | ||||
| cache: | ||||
|     directories: | ||||
| @@ -14,7 +13,6 @@ install: | ||||
|   - cp .env.testing .env | ||||
|   - php artisan clear-compiled | ||||
|   - php artisan env | ||||
|   - cp .env.testing .env | ||||
|   - wget -q https://github.com/firefly-iii/test-data/raw/master/storage/database.sqlite -O storage/database/database.sqlite | ||||
|   - mkdir -p build/logs | ||||
|  | ||||
|   | ||||
							
								
								
									
										44
									
								
								Dockerfile
									
									
									
									
									
								
							
							
						
						
									
										44
									
								
								Dockerfile
									
									
									
									
									
								
							| @@ -3,6 +3,8 @@ FROM php:7.1-apache | ||||
|  | ||||
| # set working dir | ||||
| ENV FIREFLY_PATH /var/www/firefly-iii | ||||
| ENV CURL_VERSION 7.60.0 | ||||
| ENV OPENSSL_VERSION 1.1.1-pre6 | ||||
| WORKDIR $FIREFLY_PATH | ||||
| ADD . $FIREFLY_PATH | ||||
|  | ||||
| @@ -11,7 +13,8 @@ RUN apt-get update -y && \ | ||||
|     apt-get install -y --no-install-recommends libcurl4-openssl-dev \ | ||||
|                                                zlib1g-dev \ | ||||
|                                                libjpeg62-turbo-dev \ | ||||
|                                                libpng12-dev \ | ||||
|                                                wget \ | ||||
|                                                libpng-dev \ | ||||
|                                                libicu-dev \ | ||||
|                                                libedit-dev \ | ||||
|                                                libtidy-dev \ | ||||
| @@ -20,15 +23,43 @@ RUN apt-get update -y && \ | ||||
|                                                libpq-dev \ | ||||
|                                                libbz2-dev \ | ||||
|                                                gettext-base \ | ||||
|                                                cron \ | ||||
|                                                locales && \ | ||||
|                                                apt-get clean && \ | ||||
|                                                rm -rf /var/lib/apt/lists/* | ||||
|  | ||||
| # Setup the Composer installer | ||||
| RUN curl -sS https://getcomposer.org/installer | php -- --install-dir=/usr/local/bin --filename=composer | ||||
|  | ||||
| # Install latest curl | ||||
| RUN cd /tmp && \ | ||||
|     wget https://www.openssl.org/source/openssl-${OPENSSL_VERSION}.tar.gz && \ | ||||
|     tar -xvf openssl-${OPENSSL_VERSION}.tar.gz && \ | ||||
|     cd openssl-${OPENSSL_VERSION} && \ | ||||
|     ./config && \ | ||||
|     make && \ | ||||
|     make install | ||||
|  | ||||
| RUN cd /tmp && \ | ||||
|     wget https://curl.haxx.se/download/curl-${CURL_VERSION}.tar.gz && \ | ||||
|     tar -xvf curl-${CURL_VERSION}.tar.gz && \ | ||||
|     cd curl-${CURL_VERSION} && \ | ||||
|     ./configure --with-ssl && \ | ||||
|     make && \ | ||||
|     make install | ||||
|  | ||||
|  | ||||
| # Create the log file to be able to run tail | ||||
| RUN touch /var/log/cron.log | ||||
|  | ||||
| # Setup cron job | ||||
| RUN (crontab -l ; echo "* * * * * root $FIREFLY_PATH/artisan schedule:run >> /var/log/cron.log") | crontab | ||||
|  | ||||
| # Install PHP exentions. | ||||
| RUN docker-php-ext-install -j$(nproc) curl gd intl json readline tidy zip bcmath xml mbstring pdo_sqlite pdo_mysql bz2 pdo_pgsql | ||||
|  | ||||
| # Generate locales supported by Firefly III | ||||
| RUN echo "de_DE.UTF-8 UTF-8\nen_US.UTF-8 UTF-8\nes_ES.UTF-8 UTF-8\nfr_FR.UTF-8 UTF-8\nid_ID.UTF-8 UTF-8\nit_IT.UTF-8 UTF-8\nnl_NL.UTF-8 UTF-8\npl_PL.UTF-8 UTF-8pt_BR.UTF-8 UTF-8ru_RU.UTF-8 UTF-8\ntr_TR.UTF-8 UTF-8\n\n" > /etc/locale.gen && locale-gen | ||||
| RUN echo "en_US.UTF-8 UTF-8\nde_DE.UTF-8 UTF-8\nfr_FR.UTF-8 UTF-8\nit_IT.UTF-8 UTF-8\nnl_NL.UTF-8 UTF-8\npl_PL.UTF-8 UTF-8\npt_BR.UTF-8 UTF-8\nru_RU.UTF-8 UTF-8\ntr_TR.UTF-8 UTF-8\n\n" > /etc/locale.gen && locale-gen | ||||
|  | ||||
| # copy Apache config to correct spot. | ||||
| COPY ./.deploy/docker/apache2.conf /etc/apache2/apache2.conf | ||||
| @@ -42,9 +73,6 @@ RUN a2enmod ssl | ||||
| # Create volumes for several directories: | ||||
| VOLUME $FIREFLY_PATH/storage/export $FIREFLY_PATH/storage/upload | ||||
|  | ||||
| # Setup the Composer installer | ||||
| RUN curl -sS https://getcomposer.org/installer | php -- --install-dir=/usr/local/bin --filename=composer | ||||
|  | ||||
| # Enable default site (Firefly III) | ||||
| COPY ./.deploy/docker/apache-firefly.conf /etc/apache2/sites-available/000-default.conf | ||||
|  | ||||
| @@ -57,5 +85,9 @@ RUN composer install --prefer-dist --no-dev --no-scripts --no-suggest | ||||
| # Expose port 80 | ||||
| EXPOSE 80 | ||||
|  | ||||
| # Run the command on container startup | ||||
| CMD cron | ||||
|  | ||||
| # Run entrypoint thing | ||||
| ENTRYPOINT [".deploy/docker/entrypoint.sh"] | ||||
| ENTRYPOINT [".deploy/docker/entrypoint.sh"] | ||||
|  | ||||
|   | ||||
| @@ -1,5 +1,5 @@ | ||||
| <?php | ||||
| declare(strict_types=1); | ||||
|  | ||||
| /** | ||||
|  * AboutController.php | ||||
|  * Copyright (c) 2018 thegrumpydictator@gmail.com | ||||
| @@ -20,25 +20,31 @@ declare(strict_types=1); | ||||
|  * along with Firefly III. If not, see <http://www.gnu.org/licenses/>. | ||||
|  */ | ||||
|  | ||||
| declare(strict_types=1); | ||||
|  | ||||
| namespace FireflyIII\Api\V1\Controllers; | ||||
|  | ||||
| use DB; | ||||
| use FireflyIII\Transformers\UserTransformer; | ||||
| use Illuminate\Http\JsonResponse; | ||||
| use Illuminate\Http\Request; | ||||
| use League\Fractal\Manager; | ||||
| use League\Fractal\Resource\Item; | ||||
| use League\Fractal\Serializer\JsonApiSerializer; | ||||
|  | ||||
| /** | ||||
|  * Class AboutController | ||||
|  * Returns basic information about this installation. | ||||
|  * | ||||
|  * Class AboutController. | ||||
|  */ | ||||
| class AboutController extends Controller | ||||
| { | ||||
|     /** | ||||
|      * @return \Illuminate\Http\JsonResponse | ||||
|      * Returns system information. | ||||
|      * | ||||
|      * @return JsonResponse | ||||
|      */ | ||||
|     public function about() | ||||
|     public function about(): JsonResponse | ||||
|     { | ||||
|         $search        = ['~', '#']; | ||||
|         $replace       = ['\~', '# ']; | ||||
| @@ -58,11 +64,13 @@ class AboutController extends Controller | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      * Returns information about the user. | ||||
|      * | ||||
|      * @param Request $request | ||||
|      * | ||||
|      * @return \Illuminate\Http\JsonResponse | ||||
|      * @return JsonResponse | ||||
|      */ | ||||
|     public function user(Request $request) | ||||
|     public function user(Request $request): JsonResponse | ||||
|     { | ||||
|         $manager = new Manager(); | ||||
|         $baseUrl = $request->getSchemeAndHttpHost() . '/api/v1'; | ||||
|   | ||||
| @@ -1,5 +1,4 @@ | ||||
| <?php | ||||
| declare(strict_types=1); | ||||
| /** | ||||
|  * AccountController.php | ||||
|  * Copyright (c) 2018 thegrumpydictator@gmail.com | ||||
| @@ -20,6 +19,7 @@ declare(strict_types=1); | ||||
|  * along with Firefly III. If not, see <http://www.gnu.org/licenses/>. | ||||
|  */ | ||||
|  | ||||
| declare(strict_types=1); | ||||
|  | ||||
| namespace FireflyIII\Api\V1\Controllers; | ||||
|  | ||||
| @@ -29,6 +29,8 @@ use FireflyIII\Models\AccountType; | ||||
| use FireflyIII\Repositories\Account\AccountRepositoryInterface; | ||||
| use FireflyIII\Repositories\Currency\CurrencyRepositoryInterface; | ||||
| use FireflyIII\Transformers\AccountTransformer; | ||||
| use FireflyIII\User; | ||||
| use Illuminate\Http\JsonResponse; | ||||
| use Illuminate\Http\Request; | ||||
| use Illuminate\Pagination\LengthAwarePaginator; | ||||
| use League\Fractal\Manager; | ||||
| @@ -36,34 +38,35 @@ use League\Fractal\Pagination\IlluminatePaginatorAdapter; | ||||
| use League\Fractal\Resource\Collection as FractalCollection; | ||||
| use League\Fractal\Resource\Item; | ||||
| use League\Fractal\Serializer\JsonApiSerializer; | ||||
| use Preferences; | ||||
|  | ||||
| /** | ||||
|  * Class AccountController | ||||
|  * Class AccountController. | ||||
|  * | ||||
|  * @SuppressWarnings(PHPMD.CouplingBetweenObjects) | ||||
|  */ | ||||
| class AccountController extends Controller | ||||
| { | ||||
|     /** @var CurrencyRepositoryInterface */ | ||||
|     /** @var CurrencyRepositoryInterface The currency repository */ | ||||
|     private $currencyRepository; | ||||
|     /** @var AccountRepositoryInterface */ | ||||
|     /** @var AccountRepositoryInterface The account repository */ | ||||
|     private $repository; | ||||
|  | ||||
|     /** | ||||
|      * AccountController constructor. | ||||
|      * | ||||
|      * @throws \FireflyIII\Exceptions\FireflyException | ||||
|      */ | ||||
|     public function __construct() | ||||
|     { | ||||
|         parent::__construct(); | ||||
|         $this->middleware( | ||||
|             function ($request, $next) { | ||||
|                 /** @var User $user */ | ||||
|                 $user = auth()->user(); | ||||
|                 // @var AccountRepositoryInterface repository | ||||
|                 $this->repository = app(AccountRepositoryInterface::class); | ||||
|                 $this->repository->setUser(auth()->user()); | ||||
|                 $this->repository->setUser($user); | ||||
|  | ||||
|                 $this->currencyRepository = app(CurrencyRepositoryInterface::class); | ||||
|                 $this->currencyRepository->setUser(auth()->user()); | ||||
|                 $this->currencyRepository->setUser($user); | ||||
|  | ||||
|                 return $next($request); | ||||
|             } | ||||
| @@ -75,9 +78,9 @@ class AccountController extends Controller | ||||
|      * | ||||
|      * @param \FireflyIII\Models\Account $account | ||||
|      * | ||||
|      * @return \Illuminate\Http\Response | ||||
|      * @return JsonResponse | ||||
|      */ | ||||
|     public function delete(Account $account) | ||||
|     public function delete(Account $account): JsonResponse | ||||
|     { | ||||
|         $this->repository->destroy($account, null); | ||||
|  | ||||
| @@ -89,12 +92,12 @@ class AccountController extends Controller | ||||
|      * | ||||
|      * @param Request $request | ||||
|      * | ||||
|      * @return \Illuminate\Http\JsonResponse | ||||
|      * @return JsonResponse | ||||
|      */ | ||||
|     public function index(Request $request) | ||||
|     public function index(Request $request): JsonResponse | ||||
|     { | ||||
|         // create some objects: | ||||
|         $manager = new Manager(); | ||||
|         $manager = new Manager; | ||||
|         $baseUrl = $request->getSchemeAndHttpHost() . '/api/v1'; | ||||
|  | ||||
|         // read type from URI | ||||
| @@ -103,7 +106,7 @@ class AccountController extends Controller | ||||
|  | ||||
|         // types to get, page size: | ||||
|         $types    = $this->mapTypes($this->parameters->get('type')); | ||||
|         $pageSize = (int)Preferences::getForUser(auth()->user(), 'listPageSize', 50)->data; | ||||
|         $pageSize = (int)app('preferences')->getForUser(auth()->user(), 'listPageSize', 50)->data; | ||||
|  | ||||
|         // get list of accounts. Count it and split it. | ||||
|         $collection = $this->repository->getAccountsByType($types); | ||||
| @@ -123,14 +126,16 @@ class AccountController extends Controller | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      * Show single instance. | ||||
|      * | ||||
|      * @param Request $request | ||||
|      * @param Account $account | ||||
|      * | ||||
|      * @return \Illuminate\Http\JsonResponse | ||||
|      */ | ||||
|     public function show(Request $request, Account $account) | ||||
|     public function show(Request $request, Account $account): JsonResponse | ||||
|     { | ||||
|         $manager = new Manager(); | ||||
|         $manager = new Manager; | ||||
|  | ||||
|         // add include parameter: | ||||
|         $include = $request->get('include') ?? ''; | ||||
| @@ -144,11 +149,13 @@ class AccountController extends Controller | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      * Store a new instance. | ||||
|      * | ||||
|      * @param AccountRequest $request | ||||
|      * | ||||
|      * @return \Illuminate\Http\JsonResponse | ||||
|      */ | ||||
|     public function store(AccountRequest $request) | ||||
|     public function store(AccountRequest $request): JsonResponse | ||||
|     { | ||||
|         $data = $request->getAll(); | ||||
|         // if currency ID is 0, find the currency by the code: | ||||
| @@ -157,7 +164,7 @@ class AccountController extends Controller | ||||
|             $data['currency_id'] = null === $currency ? 0 : $currency->id; | ||||
|         } | ||||
|         $account = $this->repository->store($data); | ||||
|         $manager = new Manager(); | ||||
|         $manager = new Manager; | ||||
|         $baseUrl = $request->getSchemeAndHttpHost() . '/api/v1'; | ||||
|         $manager->setSerializer(new JsonApiSerializer($baseUrl)); | ||||
|  | ||||
| @@ -174,7 +181,7 @@ class AccountController extends Controller | ||||
|      * | ||||
|      * @return \Illuminate\Http\JsonResponse | ||||
|      */ | ||||
|     public function update(AccountRequest $request, Account $account) | ||||
|     public function update(AccountRequest $request, Account $account): JsonResponse | ||||
|     { | ||||
|         $data = $request->getAll(); | ||||
|         // if currency ID is 0, find the currency by the code: | ||||
| @@ -185,7 +192,7 @@ class AccountController extends Controller | ||||
|         // set correct type: | ||||
|         $data['type'] = config('firefly.shortNamesByFullName.' . $account->accountType->type); | ||||
|         $this->repository->update($account, $data); | ||||
|         $manager = new Manager(); | ||||
|         $manager = new Manager; | ||||
|         $baseUrl = $request->getSchemeAndHttpHost() . '/api/v1'; | ||||
|         $manager->setSerializer(new JsonApiSerializer($baseUrl)); | ||||
|  | ||||
| @@ -195,52 +202,25 @@ class AccountController extends Controller | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      * All the available types. | ||||
|      * | ||||
|      * @param string $type | ||||
|      * | ||||
|      * @return array | ||||
|      */ | ||||
|     private function mapTypes(string $type): array | ||||
|     { | ||||
|         $types = [ | ||||
|             'all'                        => [ | ||||
|                 AccountType::DEFAULT, | ||||
|                 AccountType::CASH, | ||||
|                 AccountType::ASSET, | ||||
|                 AccountType::EXPENSE, | ||||
|                 AccountType::REVENUE, | ||||
|                 AccountType::INITIAL_BALANCE, | ||||
|                 AccountType::BENEFICIARY, | ||||
|                 AccountType::IMPORT, | ||||
|                 AccountType::RECONCILIATION, | ||||
|                 AccountType::LOAN, | ||||
|             ], | ||||
|             'asset'                      => [ | ||||
|                 AccountType::DEFAULT, | ||||
|                 AccountType::ASSET, | ||||
|             ], | ||||
|             'cash'                       => [ | ||||
|                 AccountType::CASH, | ||||
|             ], | ||||
|             'expense'                    => [ | ||||
|                 AccountType::EXPENSE, | ||||
|                 AccountType::BENEFICIARY, | ||||
|             ], | ||||
|             'revenue'                    => [ | ||||
|                 AccountType::REVENUE, | ||||
|             ], | ||||
|             'special'                    => [ | ||||
|                 AccountType::CASH, | ||||
|                 AccountType::INITIAL_BALANCE, | ||||
|                 AccountType::IMPORT, | ||||
|                 AccountType::RECONCILIATION, | ||||
|                 AccountType::LOAN, | ||||
|             ], | ||||
|             'hidden'                     => [ | ||||
|                 AccountType::INITIAL_BALANCE, | ||||
|                 AccountType::IMPORT, | ||||
|                 AccountType::RECONCILIATION, | ||||
|                 AccountType::LOAN, | ||||
|             ], | ||||
|         $types  = [ | ||||
|             'all'                        => [AccountType::DEFAULT, AccountType::CASH, AccountType::ASSET, AccountType::EXPENSE, AccountType::REVENUE, | ||||
|                                              AccountType::INITIAL_BALANCE, AccountType::BENEFICIARY, AccountType::IMPORT, AccountType::RECONCILIATION, | ||||
|                                              AccountType::LOAN,], | ||||
|             'asset'                      => [AccountType::DEFAULT, AccountType::ASSET,], | ||||
|             'cash'                       => [AccountType::CASH,], | ||||
|             'expense'                    => [AccountType::EXPENSE, AccountType::BENEFICIARY,], | ||||
|             'revenue'                    => [AccountType::REVENUE,], | ||||
|             'special'                    => [AccountType::CASH, AccountType::INITIAL_BALANCE, AccountType::IMPORT, AccountType::RECONCILIATION, | ||||
|                                              AccountType::LOAN,], | ||||
|             'hidden'                     => [AccountType::INITIAL_BALANCE, AccountType::IMPORT, AccountType::RECONCILIATION, AccountType::LOAN,], | ||||
|             AccountType::DEFAULT         => [AccountType::DEFAULT], | ||||
|             AccountType::CASH            => [AccountType::CASH], | ||||
|             AccountType::ASSET           => [AccountType::ASSET], | ||||
| @@ -252,10 +232,11 @@ class AccountController extends Controller | ||||
|             AccountType::RECONCILIATION  => [AccountType::RECONCILIATION], | ||||
|             AccountType::LOAN            => [AccountType::LOAN], | ||||
|         ]; | ||||
|         $return = $types['all']; | ||||
|         if (isset($types[$type])) { | ||||
|             return $types[$type]; | ||||
|             $return = $types[$type]; | ||||
|         } | ||||
|  | ||||
|         return $types['all']; // @codeCoverageIgnore | ||||
|         return $return; // @codeCoverageIgnore | ||||
|     } | ||||
| } | ||||
|   | ||||
							
								
								
									
										235
									
								
								app/Api/V1/Controllers/AttachmentController.php
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										235
									
								
								app/Api/V1/Controllers/AttachmentController.php
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,235 @@ | ||||
| <?php | ||||
| /** | ||||
|  * AttachmentController.php | ||||
|  * Copyright (c) 2018 thegrumpydictator@gmail.com | ||||
|  * | ||||
|  * This file is part of Firefly III. | ||||
|  * | ||||
|  * Firefly III is free software: you can redistribute it and/or modify | ||||
|  * it under the terms of the GNU General Public License as published by | ||||
|  * the Free Software Foundation, either version 3 of the License, or | ||||
|  * (at your option) any later version. | ||||
|  * | ||||
|  * Firefly III is distributed in the hope that it will be useful, | ||||
|  * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||||
|  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the | ||||
|  * GNU General Public License for more details. | ||||
|  * | ||||
|  * You should have received a copy of the GNU General Public License | ||||
|  * along with Firefly III. If not, see <http://www.gnu.org/licenses/>. | ||||
|  */ | ||||
|  | ||||
| declare(strict_types=1); | ||||
|  | ||||
| namespace FireflyIII\Api\V1\Controllers; | ||||
|  | ||||
| use FireflyIII\Api\V1\Requests\AttachmentRequest; | ||||
| use FireflyIII\Exceptions\FireflyException; | ||||
| use FireflyIII\Helpers\Attachments\AttachmentHelperInterface; | ||||
| use FireflyIII\Models\Attachment; | ||||
| use FireflyIII\Repositories\Attachment\AttachmentRepositoryInterface; | ||||
| use FireflyIII\Transformers\AttachmentTransformer; | ||||
| use FireflyIII\User; | ||||
| use Illuminate\Http\JsonResponse; | ||||
| use Illuminate\Http\Request; | ||||
| use Illuminate\Http\Response as LaravelResponse; | ||||
| use Illuminate\Pagination\LengthAwarePaginator; | ||||
| use League\Fractal\Manager; | ||||
| use League\Fractal\Pagination\IlluminatePaginatorAdapter; | ||||
| use League\Fractal\Resource\Collection as FractalCollection; | ||||
| use League\Fractal\Resource\Item; | ||||
| use League\Fractal\Serializer\JsonApiSerializer; | ||||
|  | ||||
| /** | ||||
|  * Class AttachmentController. | ||||
|  * | ||||
|  * @SuppressWarnings(PHPMD.CouplingBetweenObjects) | ||||
|  */ | ||||
| class AttachmentController extends Controller | ||||
| { | ||||
|     /** @var AttachmentRepositoryInterface The attachment repository */ | ||||
|     private $repository; | ||||
|  | ||||
|     /** | ||||
|      * AccountController constructor. | ||||
|      */ | ||||
|     public function __construct() | ||||
|     { | ||||
|         parent::__construct(); | ||||
|         $this->middleware( | ||||
|             function ($request, $next) { | ||||
|                 /** @var User $user */ | ||||
|                 $user             = auth()->user(); | ||||
|                 $this->repository = app(AttachmentRepositoryInterface::class); | ||||
|                 $this->repository->setUser($user); | ||||
|  | ||||
|                 return $next($request); | ||||
|             } | ||||
|         ); | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      * Remove the specified resource from storage. | ||||
|      * | ||||
|      * @param Attachment $attachment | ||||
|      * | ||||
|      * @return JsonResponse | ||||
|      */ | ||||
|     public function delete(Attachment $attachment): JsonResponse | ||||
|     { | ||||
|         $this->repository->destroy($attachment); | ||||
|  | ||||
|         return response()->json([], 204); | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      * Download an attachment. | ||||
|      * | ||||
|      * @param Attachment $attachment | ||||
|      * | ||||
|      * @return LaravelResponse | ||||
|      * @throws FireflyException | ||||
|      */ | ||||
|     public function download(Attachment $attachment): LaravelResponse | ||||
|     { | ||||
|         if (false === $attachment->uploaded) { | ||||
|             throw new FireflyException('No file has been uploaded for this attachment (yet).'); | ||||
|         } | ||||
|         if ($this->repository->exists($attachment)) { | ||||
|             $content = $this->repository->getContent($attachment); | ||||
|             $quoted  = sprintf('"%s"', addcslashes(basename($attachment->filename), '"\\')); | ||||
|  | ||||
|             /** @var LaravelResponse $response */ | ||||
|             $response = response($content, 200); | ||||
|             $response | ||||
|                 ->header('Content-Description', 'File Transfer') | ||||
|                 ->header('Content-Type', 'application/octet-stream') | ||||
|                 ->header('Content-Disposition', 'attachment; filename=' . $quoted) | ||||
|                 ->header('Content-Transfer-Encoding', 'binary') | ||||
|                 ->header('Connection', 'Keep-Alive') | ||||
|                 ->header('Expires', '0') | ||||
|                 ->header('Cache-Control', 'must-revalidate, post-check=0, pre-check=0') | ||||
|                 ->header('Pragma', 'public') | ||||
|                 ->header('Content-Length', \strlen($content)); | ||||
|  | ||||
|             return $response; | ||||
|         } | ||||
|         throw new FireflyException('Could not find the indicated attachment. The file is no longer there.'); | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      * Display a listing of the resource. | ||||
|      * | ||||
|      * @param Request $request | ||||
|      * | ||||
|      * @return JsonResponse | ||||
|      */ | ||||
|     public function index(Request $request): JsonResponse | ||||
|     { | ||||
|         // create some objects: | ||||
|         $manager = new Manager; | ||||
|         $baseUrl = $request->getSchemeAndHttpHost() . '/api/v1'; | ||||
|  | ||||
|         // types to get, page size: | ||||
|         $pageSize = (int)app('preferences')->getForUser(auth()->user(), 'listPageSize', 50)->data; | ||||
|  | ||||
|         // get list of accounts. Count it and split it. | ||||
|         $collection  = $this->repository->get(); | ||||
|         $count       = $collection->count(); | ||||
|         $attachments = $collection->slice(($this->parameters->get('page') - 1) * $pageSize, $pageSize); | ||||
|  | ||||
|         // make paginator: | ||||
|         $paginator = new LengthAwarePaginator($attachments, $count, $pageSize, $this->parameters->get('page')); | ||||
|         $paginator->setPath(route('api.v1.attachments.index') . $this->buildParams()); | ||||
|  | ||||
|         // present to user. | ||||
|         $manager->setSerializer(new JsonApiSerializer($baseUrl)); | ||||
|         $resource = new FractalCollection($attachments, new AttachmentTransformer($this->parameters), 'attachments'); | ||||
|         $resource->setPaginator(new IlluminatePaginatorAdapter($paginator)); | ||||
|  | ||||
|         return response()->json($manager->createData($resource)->toArray())->header('Content-Type', 'application/vnd.api+json'); | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      * Display the specified resource. | ||||
|      * | ||||
|      * @param Request    $request | ||||
|      * @param Attachment $attachment | ||||
|      * | ||||
|      * @return JsonResponse | ||||
|      */ | ||||
|     public function show(Request $request, Attachment $attachment): JsonResponse | ||||
|     { | ||||
|         $manager = new Manager; | ||||
|  | ||||
|         // add include parameter: | ||||
|         $include = $request->get('include') ?? ''; | ||||
|         $manager->parseIncludes($include); | ||||
|  | ||||
|         $baseUrl = $request->getSchemeAndHttpHost() . '/api/v1'; | ||||
|         $manager->setSerializer(new JsonApiSerializer($baseUrl)); | ||||
|         $resource = new Item($attachment, new AttachmentTransformer($this->parameters), 'attachments'); | ||||
|  | ||||
|         return response()->json($manager->createData($resource)->toArray())->header('Content-Type', 'application/vnd.api+json'); | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      * Store a newly created resource in storage. | ||||
|      * | ||||
|      * @param AttachmentRequest $request | ||||
|      * | ||||
|      * @return JsonResponse | ||||
|      * @throws FireflyException | ||||
|      */ | ||||
|     public function store(AttachmentRequest $request): JsonResponse | ||||
|     { | ||||
|         $data       = $request->getAll(); | ||||
|         $attachment = $this->repository->store($data); | ||||
|         $manager    = new Manager; | ||||
|         $baseUrl    = $request->getSchemeAndHttpHost() . '/api/v1'; | ||||
|         $manager->setSerializer(new JsonApiSerializer($baseUrl)); | ||||
|         $resource = new Item($attachment, new AttachmentTransformer($this->parameters), 'attachments'); | ||||
|  | ||||
|         return response()->json($manager->createData($resource)->toArray())->header('Content-Type', 'application/vnd.api+json'); | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      * Update the specified resource in storage. | ||||
|      * | ||||
|      * @param AttachmentRequest $request | ||||
|      * @param Attachment        $attachment | ||||
|      * | ||||
|      * @return JsonResponse | ||||
|      */ | ||||
|     public function update(AttachmentRequest $request, Attachment $attachment): JsonResponse | ||||
|     { | ||||
|         $data = $request->getAll(); | ||||
|         $this->repository->update($attachment, $data); | ||||
|         $manager = new Manager; | ||||
|         $baseUrl = $request->getSchemeAndHttpHost() . '/api/v1'; | ||||
|         $manager->setSerializer(new JsonApiSerializer($baseUrl)); | ||||
|  | ||||
|         $resource = new Item($attachment, new AttachmentTransformer($this->parameters), 'attachments'); | ||||
|  | ||||
|         return response()->json($manager->createData($resource)->toArray())->header('Content-Type', 'application/vnd.api+json'); | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      * Upload an attachment. | ||||
|      * | ||||
|      * @param Request    $request | ||||
|      * @param Attachment $attachment | ||||
|      * | ||||
|      * @return JsonResponse | ||||
|      */ | ||||
|     public function upload(Request $request, Attachment $attachment): JsonResponse | ||||
|     { | ||||
|         /** @var AttachmentHelperInterface $helper */ | ||||
|         $helper = app(AttachmentHelperInterface::class); | ||||
|         $body   = $request->getContent(); | ||||
|         $helper->saveAttachmentFromApi($attachment, $body); | ||||
|  | ||||
|         return response()->json([], 204); | ||||
|     } | ||||
|  | ||||
| } | ||||
							
								
								
									
										190
									
								
								app/Api/V1/Controllers/AvailableBudgetController.php
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										190
									
								
								app/Api/V1/Controllers/AvailableBudgetController.php
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,190 @@ | ||||
| <?php | ||||
| /** | ||||
|  * AvailableBudgetController.php | ||||
|  * Copyright (c) 2018 thegrumpydictator@gmail.com | ||||
|  * | ||||
|  * This file is part of Firefly III. | ||||
|  * | ||||
|  * Firefly III is free software: you can redistribute it and/or modify | ||||
|  * it under the terms of the GNU General Public License as published by | ||||
|  * the Free Software Foundation, either version 3 of the License, or | ||||
|  * (at your option) any later version. | ||||
|  * | ||||
|  * Firefly III is distributed in the hope that it will be useful, | ||||
|  * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||||
|  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the | ||||
|  * GNU General Public License for more details. | ||||
|  * | ||||
|  * You should have received a copy of the GNU General Public License | ||||
|  * along with Firefly III. If not, see <http://www.gnu.org/licenses/>. | ||||
|  */ | ||||
|  | ||||
| declare(strict_types=1); | ||||
|  | ||||
| namespace FireflyIII\Api\V1\Controllers; | ||||
|  | ||||
| use FireflyIII\Api\V1\Requests\AvailableBudgetRequest; | ||||
| use FireflyIII\Exceptions\FireflyException; | ||||
| use FireflyIII\Models\AvailableBudget; | ||||
| use FireflyIII\Repositories\Budget\BudgetRepositoryInterface; | ||||
| use FireflyIII\Repositories\Currency\CurrencyRepositoryInterface; | ||||
| use FireflyIII\Transformers\AvailableBudgetTransformer; | ||||
| use FireflyIII\User; | ||||
| use Illuminate\Http\JsonResponse; | ||||
| use Illuminate\Http\Request; | ||||
| use Illuminate\Pagination\LengthAwarePaginator; | ||||
| use League\Fractal\Manager; | ||||
| use League\Fractal\Pagination\IlluminatePaginatorAdapter; | ||||
| use League\Fractal\Resource\Collection as FractalCollection; | ||||
| use League\Fractal\Resource\Item; | ||||
| use League\Fractal\Serializer\JsonApiSerializer; | ||||
|  | ||||
| /** | ||||
|  * Class AvailableBudgetController. | ||||
|  * | ||||
|  * @SuppressWarnings(PHPMD.CouplingBetweenObjects) | ||||
|  */ | ||||
| class AvailableBudgetController extends Controller | ||||
| { | ||||
|     /** @var CurrencyRepositoryInterface The currency repository */ | ||||
|     private $currencyRepository; | ||||
|     /** @var BudgetRepositoryInterface The budget repository */ | ||||
|     private $repository; | ||||
|  | ||||
|     /** | ||||
|      * AccountController constructor. | ||||
|      */ | ||||
|     public function __construct() | ||||
|     { | ||||
|         parent::__construct(); | ||||
|         $this->middleware( | ||||
|             function ($request, $next) { | ||||
|                 /** @var User $user */ | ||||
|                 $user                     = auth()->user(); | ||||
|                 $this->repository         = app(BudgetRepositoryInterface::class); | ||||
|                 $this->currencyRepository = app(CurrencyRepositoryInterface::class); | ||||
|                 $this->repository->setUser($user); | ||||
|  | ||||
|                 return $next($request); | ||||
|             } | ||||
|         ); | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      * Remove the specified resource from storage. | ||||
|      * | ||||
|      * @param AvailableBudget $availableBudget | ||||
|      * | ||||
|      * @return JsonResponse | ||||
|      */ | ||||
|     public function delete(AvailableBudget $availableBudget): JsonResponse | ||||
|     { | ||||
|         $this->repository->destroyAvailableBudget($availableBudget); | ||||
|  | ||||
|         return response()->json([], 204); | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      * Display a listing of the resource. | ||||
|      * | ||||
|      * @param Request $request | ||||
|      * | ||||
|      * @return JsonResponse | ||||
|      */ | ||||
|     public function index(Request $request): JsonResponse | ||||
|     { | ||||
|         // create some objects: | ||||
|         $manager = new Manager; | ||||
|         $baseUrl = $request->getSchemeAndHttpHost() . '/api/v1'; | ||||
|  | ||||
|         // types to get, page size: | ||||
|         $pageSize = (int)app('preferences')->getForUser(auth()->user(), 'listPageSize', 50)->data; | ||||
|  | ||||
|         // get list of available budgets. Count it and split it. | ||||
|         $collection       = $this->repository->getAvailableBudgets(); | ||||
|         $count            = $collection->count(); | ||||
|         $availableBudgets = $collection->slice(($this->parameters->get('page') - 1) * $pageSize, $pageSize); | ||||
|  | ||||
|         // make paginator: | ||||
|         $paginator = new LengthAwarePaginator($availableBudgets, $count, $pageSize, $this->parameters->get('page')); | ||||
|         $paginator->setPath(route('api.v1.available_budgets.index') . $this->buildParams()); | ||||
|  | ||||
|         // present to user. | ||||
|         $manager->setSerializer(new JsonApiSerializer($baseUrl)); | ||||
|         $resource = new FractalCollection($availableBudgets, new AvailableBudgetTransformer($this->parameters), 'available_budgets'); | ||||
|         $resource->setPaginator(new IlluminatePaginatorAdapter($paginator)); | ||||
|  | ||||
|         return response()->json($manager->createData($resource)->toArray())->header('Content-Type', 'application/vnd.api+json'); | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      * Display the specified resource. | ||||
|      * | ||||
|      * @param Request          $request | ||||
|      * @param  AvailableBudget $availableBudget | ||||
|      * | ||||
|      * @return JsonResponse | ||||
|      */ | ||||
|     public function show(Request $request, AvailableBudget $availableBudget): JsonResponse | ||||
|     { | ||||
|  | ||||
|         $manager = new Manager; | ||||
|  | ||||
|         // add include parameter: | ||||
|         $include = $request->get('include') ?? ''; | ||||
|         $manager->parseIncludes($include); | ||||
|  | ||||
|         $baseUrl = $request->getSchemeAndHttpHost() . '/api/v1'; | ||||
|         $manager->setSerializer(new JsonApiSerializer($baseUrl)); | ||||
|         $resource = new Item($availableBudget, new AvailableBudgetTransformer($this->parameters), 'available_budgets'); | ||||
|  | ||||
|         return response()->json($manager->createData($resource)->toArray())->header('Content-Type', 'application/vnd.api+json'); | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      * Store a newly created resource in storage. | ||||
|      * | ||||
|      * @param AvailableBudgetRequest $request | ||||
|      * | ||||
|      * @return JsonResponse | ||||
|      * @throws FireflyException | ||||
|      */ | ||||
|     public function store(AvailableBudgetRequest $request): JsonResponse | ||||
|     { | ||||
|         $data     = $request->getAll(); | ||||
|         $currency = $this->currencyRepository->findNull($data['transaction_currency_id']); | ||||
|         if (null === $currency) { | ||||
|             throw new FireflyException('Could not find the indicated currency.'); | ||||
|         } | ||||
|         $availableBudget = $this->repository->setAvailableBudget($currency, $data['start_date'], $data['end_date'], $data['amount']); | ||||
|         $manager         = new Manager; | ||||
|         $baseUrl         = $request->getSchemeAndHttpHost() . '/api/v1'; | ||||
|         $manager->setSerializer(new JsonApiSerializer($baseUrl)); | ||||
|  | ||||
|         $resource = new Item($availableBudget, new AvailableBudgetTransformer($this->parameters), 'available_budgets'); | ||||
|  | ||||
|         return response()->json($manager->createData($resource)->toArray())->header('Content-Type', 'application/vnd.api+json'); | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      * Update the specified resource in storage. | ||||
|      * | ||||
|      * @param AvailableBudgetRequest $request | ||||
|      * @param AvailableBudget        $availableBudget | ||||
|      * | ||||
|      * @return JsonResponse | ||||
|      */ | ||||
|     public function update(AvailableBudgetRequest $request, AvailableBudget $availableBudget): JsonResponse | ||||
|     { | ||||
|         $data = $request->getAll(); | ||||
|         $this->repository->updateAvailableBudget($availableBudget, $data); | ||||
|         $manager = new Manager; | ||||
|         $baseUrl = $request->getSchemeAndHttpHost() . '/api/v1'; | ||||
|         $manager->setSerializer(new JsonApiSerializer($baseUrl)); | ||||
|  | ||||
|         $resource = new Item($availableBudget, new AvailableBudgetTransformer($this->parameters), 'available_budgets'); | ||||
|  | ||||
|         return response()->json($manager->createData($resource)->toArray())->header('Content-Type', 'application/vnd.api+json'); | ||||
|  | ||||
|     } | ||||
| } | ||||
| @@ -1,5 +1,5 @@ | ||||
| <?php | ||||
| declare(strict_types=1); | ||||
|  | ||||
| /** | ||||
|  * BillController.php | ||||
|  * Copyright (c) 2018 thegrumpydictator@gmail.com | ||||
| @@ -20,6 +20,8 @@ declare(strict_types=1); | ||||
|  * along with Firefly III. If not, see <http://www.gnu.org/licenses/>. | ||||
|  */ | ||||
|  | ||||
| declare(strict_types=1); | ||||
|  | ||||
| namespace FireflyIII\Api\V1\Controllers; | ||||
|  | ||||
| use FireflyIII\Api\V1\Requests\BillRequest; | ||||
| @@ -27,6 +29,7 @@ use FireflyIII\Exceptions\FireflyException; | ||||
| use FireflyIII\Models\Bill; | ||||
| use FireflyIII\Repositories\Bill\BillRepositoryInterface; | ||||
| use FireflyIII\Transformers\BillTransformer; | ||||
| use FireflyIII\User; | ||||
| use Illuminate\Http\JsonResponse; | ||||
| use Illuminate\Http\Request; | ||||
| use Illuminate\Support\Collection; | ||||
| @@ -35,29 +38,29 @@ use League\Fractal\Pagination\IlluminatePaginatorAdapter; | ||||
| use League\Fractal\Resource\Collection as FractalCollection; | ||||
| use League\Fractal\Resource\Item; | ||||
| use League\Fractal\Serializer\JsonApiSerializer; | ||||
| use Preferences; | ||||
|  | ||||
| /** | ||||
|  * Class BillController | ||||
|  * Class BillController. | ||||
|  */ | ||||
| class BillController extends Controller | ||||
| { | ||||
|     /** @var BillRepositoryInterface */ | ||||
|     /** @var BillRepositoryInterface The bill repository */ | ||||
|     private $repository; | ||||
|  | ||||
|     /** | ||||
|      * BillController constructor. | ||||
|      * | ||||
|      * @throws FireflyException | ||||
|      */ | ||||
|     public function __construct() | ||||
|     { | ||||
|         parent::__construct(); | ||||
|         $this->middleware( | ||||
|             function ($request, $next) { | ||||
|                 /** @var User $admin */ | ||||
|                 $admin = auth()->user(); | ||||
|  | ||||
|                 /** @var BillRepositoryInterface repository */ | ||||
|                 $this->repository = app(BillRepositoryInterface::class); | ||||
|                 $this->repository->setUser(auth()->user()); | ||||
|                 $this->repository->setUser($admin); | ||||
|  | ||||
|                 return $next($request); | ||||
|             } | ||||
| @@ -87,7 +90,7 @@ class BillController extends Controller | ||||
|      */ | ||||
|     public function index(Request $request): JsonResponse | ||||
|     { | ||||
|         $pageSize  = (int)Preferences::getForUser(auth()->user(), 'listPageSize', 50)->data; | ||||
|         $pageSize  = (int)app('preferences')->getForUser(auth()->user(), 'listPageSize', 50)->data; | ||||
|         $paginator = $this->repository->getPaginator($pageSize); | ||||
|         /** @var Collection $bills */ | ||||
|         $bills = $paginator->getCollection(); | ||||
| @@ -104,6 +107,8 @@ class BillController extends Controller | ||||
|  | ||||
|  | ||||
|     /** | ||||
|      * Show the specified bill. | ||||
|      * | ||||
|      * @param Request $request | ||||
|      * @param Bill    $bill | ||||
|      * | ||||
| @@ -125,6 +130,8 @@ class BillController extends Controller | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      * Store a bill. | ||||
|      * | ||||
|      * @param BillRequest $request | ||||
|      * | ||||
|      * @return JsonResponse | ||||
| @@ -148,6 +155,8 @@ class BillController extends Controller | ||||
|  | ||||
|  | ||||
|     /** | ||||
|      * Update a bill. | ||||
|      * | ||||
|      * @param BillRequest $request | ||||
|      * @param Bill        $bill | ||||
|      * | ||||
|   | ||||
							
								
								
									
										188
									
								
								app/Api/V1/Controllers/BudgetController.php
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										188
									
								
								app/Api/V1/Controllers/BudgetController.php
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,188 @@ | ||||
| <?php | ||||
| /** | ||||
|  * BudgetController.php | ||||
|  * Copyright (c) 2018 thegrumpydictator@gmail.com | ||||
|  * | ||||
|  * This file is part of Firefly III. | ||||
|  * | ||||
|  * Firefly III is free software: you can redistribute it and/or modify | ||||
|  * it under the terms of the GNU General Public License as published by | ||||
|  * the Free Software Foundation, either version 3 of the License, or | ||||
|  * (at your option) any later version. | ||||
|  * | ||||
|  * Firefly III is distributed in the hope that it will be useful, | ||||
|  * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||||
|  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the | ||||
|  * GNU General Public License for more details. | ||||
|  * | ||||
|  * You should have received a copy of the GNU General Public License | ||||
|  * along with Firefly III. If not, see <http://www.gnu.org/licenses/>. | ||||
|  */ | ||||
|  | ||||
| declare(strict_types=1); | ||||
|  | ||||
| namespace FireflyIII\Api\V1\Controllers; | ||||
|  | ||||
| use FireflyIII\Api\V1\Requests\BudgetRequest; | ||||
| use FireflyIII\Exceptions\FireflyException; | ||||
| use FireflyIII\Models\Budget; | ||||
| use FireflyIII\Repositories\Budget\BudgetRepositoryInterface; | ||||
| use FireflyIII\Transformers\BudgetTransformer; | ||||
| use FireflyIII\User; | ||||
| use Illuminate\Http\JsonResponse; | ||||
| use Illuminate\Http\Request; | ||||
| use Illuminate\Pagination\LengthAwarePaginator; | ||||
| use League\Fractal\Manager; | ||||
| use League\Fractal\Pagination\IlluminatePaginatorAdapter; | ||||
| use League\Fractal\Resource\Collection as FractalCollection; | ||||
| use League\Fractal\Resource\Item; | ||||
| use League\Fractal\Serializer\JsonApiSerializer; | ||||
|  | ||||
| /** | ||||
|  * Class BudgetController. | ||||
|  * | ||||
|  * @SuppressWarnings(PHPMD.CouplingBetweenObjects) | ||||
|  */ | ||||
| class BudgetController extends Controller | ||||
| { | ||||
|     /** @var BudgetRepositoryInterface The budget repository */ | ||||
|     private $repository; | ||||
|  | ||||
|     /** | ||||
|      * BudgetController constructor. | ||||
|      */ | ||||
|     public function __construct() | ||||
|     { | ||||
|         parent::__construct(); | ||||
|         $this->middleware( | ||||
|             function ($request, $next) { | ||||
|                 /** @var User $admin */ | ||||
|                 $admin = auth()->user(); | ||||
|  | ||||
|                 /** @var BudgetRepositoryInterface repository */ | ||||
|                 $this->repository = app(BudgetRepositoryInterface::class); | ||||
|                 $this->repository->setUser($admin); | ||||
|  | ||||
|                 return $next($request); | ||||
|             } | ||||
|         ); | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      * Remove the specified resource from storage. | ||||
|      * | ||||
|      * @param Budget $budget | ||||
|      * | ||||
|      * @return JsonResponse | ||||
|      */ | ||||
|     public function delete(Budget $budget): JsonResponse | ||||
|     { | ||||
|         $this->repository->destroy($budget); | ||||
|  | ||||
|         return response()->json([], 204); | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      * Display a listing of the resource. | ||||
|      * | ||||
|      * @param Request $request | ||||
|      * | ||||
|      * @return JsonResponse | ||||
|      */ | ||||
|     public function index(Request $request): JsonResponse | ||||
|     { | ||||
|         // create some objects: | ||||
|         $manager = new Manager; | ||||
|         $baseUrl = $request->getSchemeAndHttpHost() . '/api/v1'; | ||||
|  | ||||
|         // types to get, page size: | ||||
|         $pageSize = (int)app('preferences')->getForUser(auth()->user(), 'listPageSize', 50)->data; | ||||
|  | ||||
|         // get list of budgets. Count it and split it. | ||||
|         $collection = $this->repository->getBudgets(); | ||||
|         $count      = $collection->count(); | ||||
|         $budgets    = $collection->slice(($this->parameters->get('page') - 1) * $pageSize, $pageSize); | ||||
|  | ||||
|         // make paginator: | ||||
|         $paginator = new LengthAwarePaginator($budgets, $count, $pageSize, $this->parameters->get('page')); | ||||
|         $paginator->setPath(route('api.v1.budgets.index') . $this->buildParams()); | ||||
|  | ||||
|         // present to user. | ||||
|         $manager->setSerializer(new JsonApiSerializer($baseUrl)); | ||||
|         $resource = new FractalCollection($budgets, new BudgetTransformer($this->parameters), 'budgets'); | ||||
|         $resource->setPaginator(new IlluminatePaginatorAdapter($paginator)); | ||||
|  | ||||
|         return response()->json($manager->createData($resource)->toArray())->header('Content-Type', 'application/vnd.api+json'); | ||||
|     } | ||||
|  | ||||
|  | ||||
|     /** | ||||
|      * Show a budget. | ||||
|      * | ||||
|      * @param Request $request | ||||
|      * @param Budget  $budget | ||||
|      * | ||||
|      * @return JsonResponse | ||||
|      */ | ||||
|     public function show(Request $request, Budget $budget): JsonResponse | ||||
|     { | ||||
|         $manager = new Manager(); | ||||
|         // add include parameter: | ||||
|         $include = $request->get('include') ?? ''; | ||||
|         $manager->parseIncludes($include); | ||||
|  | ||||
|         $baseUrl = $request->getSchemeAndHttpHost() . '/api/v1'; | ||||
|         $manager->setSerializer(new JsonApiSerializer($baseUrl)); | ||||
|  | ||||
|         $resource = new Item($budget, new BudgetTransformer($this->parameters), 'budgets'); | ||||
|  | ||||
|         return response()->json($manager->createData($resource)->toArray())->header('Content-Type', 'application/vnd.api+json'); | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      * Store a budget. | ||||
|      * | ||||
|      * @param BudgetRequest $request | ||||
|      * | ||||
|      * @return JsonResponse | ||||
|      * @throws FireflyException | ||||
|      */ | ||||
|     public function store(BudgetRequest $request): JsonResponse | ||||
|     { | ||||
|         $budget = $this->repository->store($request->getAll()); | ||||
|         if (null !== $budget) { | ||||
|             $manager = new Manager(); | ||||
|             $baseUrl = $request->getSchemeAndHttpHost() . '/api/v1'; | ||||
|             $manager->setSerializer(new JsonApiSerializer($baseUrl)); | ||||
|  | ||||
|             $resource = new Item($budget, new BudgetTransformer($this->parameters), 'budgets'); | ||||
|  | ||||
|             return response()->json($manager->createData($resource)->toArray())->header('Content-Type', 'application/vnd.api+json'); | ||||
|         } | ||||
|         throw new FireflyException('Could not store new budget.'); // @codeCoverageIgnore | ||||
|     } | ||||
|  | ||||
|  | ||||
|     /** | ||||
|      * Update a budget. | ||||
|      * | ||||
|      * @param BudgetRequest $request | ||||
|      * @param Budget        $budget | ||||
|      * | ||||
|      * @return JsonResponse | ||||
|      */ | ||||
|     public function update(BudgetRequest $request, Budget $budget): JsonResponse | ||||
|     { | ||||
|         $data    = $request->getAll(); | ||||
|         $budget  = $this->repository->update($budget, $data); | ||||
|         $manager = new Manager(); | ||||
|         $baseUrl = $request->getSchemeAndHttpHost() . '/api/v1'; | ||||
|         $manager->setSerializer(new JsonApiSerializer($baseUrl)); | ||||
|  | ||||
|         $resource = new Item($budget, new BudgetTransformer($this->parameters), 'budgets'); | ||||
|  | ||||
|         return response()->json($manager->createData($resource)->toArray())->header('Content-Type', 'application/vnd.api+json'); | ||||
|  | ||||
|     } | ||||
|  | ||||
| } | ||||
							
								
								
									
										198
									
								
								app/Api/V1/Controllers/BudgetLimitController.php
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										198
									
								
								app/Api/V1/Controllers/BudgetLimitController.php
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,198 @@ | ||||
| <?php | ||||
| /** | ||||
|  * BudgetLimitController.php | ||||
|  * Copyright (c) 2018 thegrumpydictator@gmail.com | ||||
|  * | ||||
|  * This file is part of Firefly III. | ||||
|  * | ||||
|  * Firefly III is free software: you can redistribute it and/or modify | ||||
|  * it under the terms of the GNU General Public License as published by | ||||
|  * the Free Software Foundation, either version 3 of the License, or | ||||
|  * (at your option) any later version. | ||||
|  * | ||||
|  * Firefly III is distributed in the hope that it will be useful, | ||||
|  * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||||
|  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the | ||||
|  * GNU General Public License for more details. | ||||
|  * | ||||
|  * You should have received a copy of the GNU General Public License | ||||
|  * along with Firefly III. If not, see <http://www.gnu.org/licenses/>. | ||||
|  */ | ||||
|  | ||||
| declare(strict_types=1); | ||||
|  | ||||
| namespace FireflyIII\Api\V1\Controllers; | ||||
|  | ||||
|  | ||||
| use FireflyIII\Api\V1\Requests\BudgetLimitRequest; | ||||
| use FireflyIII\Exceptions\FireflyException; | ||||
| use FireflyIII\Models\BudgetLimit; | ||||
| use FireflyIII\Repositories\Budget\BudgetRepositoryInterface; | ||||
| use FireflyIII\Transformers\BudgetLimitTransformer; | ||||
| use FireflyIII\User; | ||||
| use Illuminate\Http\JsonResponse; | ||||
| use Illuminate\Http\Request; | ||||
| use Illuminate\Pagination\LengthAwarePaginator; | ||||
| use Illuminate\Support\Collection; | ||||
|  | ||||
| use League\Fractal\Manager; | ||||
| use League\Fractal\Pagination\IlluminatePaginatorAdapter; | ||||
| use League\Fractal\Resource\Collection as FractalCollection; | ||||
| use League\Fractal\Resource\Item; | ||||
| use League\Fractal\Serializer\JsonApiSerializer; | ||||
|  | ||||
|  | ||||
| /** | ||||
|  * Class BudgetLimitController. | ||||
|  * | ||||
|  * @SuppressWarnings(PHPMD.CouplingBetweenObjects) | ||||
|  */ | ||||
| class BudgetLimitController extends Controller | ||||
| { | ||||
|     /** @var BudgetRepositoryInterface The budget repository */ | ||||
|     private $repository; | ||||
|  | ||||
|     /** | ||||
|      * AccountController constructor. | ||||
|      */ | ||||
|     public function __construct() | ||||
|     { | ||||
|         parent::__construct(); | ||||
|         $this->middleware( | ||||
|             function ($request, $next) { | ||||
|                 /** @var User $user */ | ||||
|                 $user             = auth()->user(); | ||||
|                 $this->repository = app(BudgetRepositoryInterface::class); | ||||
|                 $this->repository->setUser($user); | ||||
|  | ||||
|                 return $next($request); | ||||
|             } | ||||
|         ); | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      * Remove the specified resource from storage. | ||||
|      * | ||||
|      * @param BudgetLimit $budgetLimit | ||||
|      * | ||||
|      * @return JsonResponse | ||||
|      */ | ||||
|     public function delete(BudgetLimit $budgetLimit): JsonResponse | ||||
|     { | ||||
|         $this->repository->destroyBudgetLimit($budgetLimit); | ||||
|  | ||||
|         return response()->json([], 204); | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      * Display a listing of the resource. | ||||
|      * | ||||
|      * @param Request $request | ||||
|      * | ||||
|      * @return JsonResponse | ||||
|      */ | ||||
|     public function index(Request $request): JsonResponse | ||||
|     { | ||||
|         $manager  = new Manager; | ||||
|         $baseUrl  = $request->getSchemeAndHttpHost() . '/api/v1'; | ||||
|         $budgetId = (int)($request->get('budget_id') ?? 0); | ||||
|         $budget   = $this->repository->findNull($budgetId); | ||||
|         $pageSize = (int)app('preferences')->getForUser(auth()->user(), 'listPageSize', 50)->data; | ||||
|         $this->parameters->set('budget_id', $budgetId); | ||||
|  | ||||
|         $collection = new Collection; | ||||
|         if (null === $budget) { | ||||
|             $collection = $this->repository->getAllBudgetLimits($this->parameters->get('start'), $this->parameters->get('end')); | ||||
|         } | ||||
|         if (null !== $budget) { | ||||
|             $collection = $this->repository->getBudgetLimits($budget, $this->parameters->get('start'), $this->parameters->get('end')); | ||||
|         } | ||||
|  | ||||
|         $count        = $collection->count(); | ||||
|         $budgetLimits = $collection->slice(($this->parameters->get('page') - 1) * $pageSize, $pageSize); | ||||
|         $paginator    = new LengthAwarePaginator($budgetLimits, $count, $pageSize, $this->parameters->get('page')); | ||||
|         $paginator->setPath(route('api.v1.budget_limits.index') . $this->buildParams()); | ||||
|  | ||||
|         $manager->setSerializer(new JsonApiSerializer($baseUrl)); | ||||
|         $resource = new FractalCollection($budgetLimits, new BudgetLimitTransformer($this->parameters), 'budget_limits'); | ||||
|         $resource->setPaginator(new IlluminatePaginatorAdapter($paginator)); | ||||
|  | ||||
|         return response()->json($manager->createData($resource)->toArray())->header('Content-Type', 'application/vnd.api+json'); | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      * Display the specified resource. | ||||
|      * | ||||
|      * @param Request     $request | ||||
|      * @param BudgetLimit $budgetLimit | ||||
|      * | ||||
|      * @return JsonResponse | ||||
|      */ | ||||
|     public function show(Request $request, BudgetLimit $budgetLimit): JsonResponse | ||||
|     { | ||||
|         $manager = new Manager; | ||||
|  | ||||
|         // add include parameter: | ||||
|         $include = $request->get('include') ?? ''; | ||||
|         $manager->parseIncludes($include); | ||||
|  | ||||
|         $baseUrl = $request->getSchemeAndHttpHost() . '/api/v1'; | ||||
|         $manager->setSerializer(new JsonApiSerializer($baseUrl)); | ||||
|         $resource = new Item($budgetLimit, new BudgetLimitTransformer($this->parameters), 'budget_limits'); | ||||
|  | ||||
|         return response()->json($manager->createData($resource)->toArray())->header('Content-Type', 'application/vnd.api+json'); | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      * Store a newly created resource in storage. | ||||
|      * | ||||
|      * @param BudgetLimitRequest $request | ||||
|      * | ||||
|      * @return JsonResponse | ||||
|      * @throws FireflyException | ||||
|      */ | ||||
|     public function store(BudgetLimitRequest $request): JsonResponse | ||||
|     { | ||||
|         $data   = $request->getAll(); | ||||
|         $budget = $this->repository->findNull($data['budget_id']); | ||||
|         if (null === $budget) { | ||||
|             throw new FireflyException('Unknown budget.'); | ||||
|         } | ||||
|         $data['budget'] = $budget; | ||||
|         $budgetLimit    = $this->repository->storeBudgetLimit($data); | ||||
|         $manager        = new Manager; | ||||
|         $baseUrl        = $request->getSchemeAndHttpHost() . '/api/v1'; | ||||
|         $manager->setSerializer(new JsonApiSerializer($baseUrl)); | ||||
|  | ||||
|         $resource = new Item($budgetLimit, new BudgetLimitTransformer($this->parameters), 'budget_limits'); | ||||
|  | ||||
|         return response()->json($manager->createData($resource)->toArray())->header('Content-Type', 'application/vnd.api+json'); | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      * Update the specified resource in storage. | ||||
|      * | ||||
|      * @param BudgetLimitRequest $request | ||||
|      * @param BudgetLimit        $budgetLimit | ||||
|      * | ||||
|      * @return JsonResponse | ||||
|      */ | ||||
|     public function update(BudgetLimitRequest $request, BudgetLimit $budgetLimit): JsonResponse | ||||
|     { | ||||
|         $data   = $request->getAll(); | ||||
|         $budget = $this->repository->findNull($data['budget_id']); | ||||
|         if (null === $budget) { | ||||
|             $budget = $budgetLimit->budget; | ||||
|         } | ||||
|         $data['budget'] = $budget; | ||||
|         $budgetLimit    = $this->repository->updateBudgetLimit($budgetLimit, $data); | ||||
|         $manager        = new Manager; | ||||
|         $baseUrl        = $request->getSchemeAndHttpHost() . '/api/v1'; | ||||
|         $manager->setSerializer(new JsonApiSerializer($baseUrl)); | ||||
|  | ||||
|         $resource = new Item($budgetLimit, new BudgetLimitTransformer($this->parameters), 'budget_limits'); | ||||
|  | ||||
|         return response()->json($manager->createData($resource)->toArray())->header('Content-Type', 'application/vnd.api+json'); | ||||
|  | ||||
|     } | ||||
| } | ||||
							
								
								
									
										188
									
								
								app/Api/V1/Controllers/CategoryController.php
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										188
									
								
								app/Api/V1/Controllers/CategoryController.php
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,188 @@ | ||||
| <?php | ||||
| /** | ||||
|  * CategoryController.php | ||||
|  * Copyright (c) 2018 thegrumpydictator@gmail.com | ||||
|  * | ||||
|  * This file is part of Firefly III. | ||||
|  * | ||||
|  * Firefly III is free software: you can redistribute it and/or modify | ||||
|  * it under the terms of the GNU General Public License as published by | ||||
|  * the Free Software Foundation, either version 3 of the License, or | ||||
|  * (at your option) any later version. | ||||
|  * | ||||
|  * Firefly III is distributed in the hope that it will be useful, | ||||
|  * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||||
|  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the | ||||
|  * GNU General Public License for more details. | ||||
|  * | ||||
|  * You should have received a copy of the GNU General Public License | ||||
|  * along with Firefly III. If not, see <http://www.gnu.org/licenses/>. | ||||
|  */ | ||||
|  | ||||
| declare(strict_types=1); | ||||
|  | ||||
| namespace FireflyIII\Api\V1\Controllers; | ||||
|  | ||||
| use FireflyIII\Api\V1\Requests\CategoryRequest; | ||||
| use FireflyIII\Exceptions\FireflyException; | ||||
| use FireflyIII\Models\Category; | ||||
| use FireflyIII\Repositories\Category\CategoryRepositoryInterface; | ||||
| use FireflyIII\Transformers\CategoryTransformer; | ||||
| use FireflyIII\User; | ||||
| use Illuminate\Http\JsonResponse; | ||||
| use Illuminate\Http\Request; | ||||
| use Illuminate\Pagination\LengthAwarePaginator; | ||||
| use League\Fractal\Manager; | ||||
| use League\Fractal\Pagination\IlluminatePaginatorAdapter; | ||||
| use League\Fractal\Resource\Collection as FractalCollection; | ||||
| use League\Fractal\Resource\Item; | ||||
| use League\Fractal\Serializer\JsonApiSerializer; | ||||
|  | ||||
| /** | ||||
|  * Class CategoryController. | ||||
|  * | ||||
|  * @SuppressWarnings(PHPMD.CouplingBetweenObjects) | ||||
|  */ | ||||
| class CategoryController extends Controller | ||||
| { | ||||
|     /** @var CategoryRepositoryInterface The category repository */ | ||||
|     private $repository; | ||||
|  | ||||
|     /** | ||||
|      * CategoryController constructor. | ||||
|      */ | ||||
|     public function __construct() | ||||
|     { | ||||
|         parent::__construct(); | ||||
|         $this->middleware( | ||||
|             function ($request, $next) { | ||||
|                 /** @var User $admin */ | ||||
|                 $admin = auth()->user(); | ||||
|  | ||||
|                 /** @var CategoryRepositoryInterface repository */ | ||||
|                 $this->repository = app(CategoryRepositoryInterface::class); | ||||
|                 $this->repository->setUser($admin); | ||||
|  | ||||
|                 return $next($request); | ||||
|             } | ||||
|         ); | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      * Remove the specified resource from storage. | ||||
|      * | ||||
|      * @param Category $category | ||||
|      * | ||||
|      * @return JsonResponse | ||||
|      */ | ||||
|     public function delete(Category $category): JsonResponse | ||||
|     { | ||||
|         $this->repository->destroy($category); | ||||
|  | ||||
|         return response()->json([], 204); | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      * Display a listing of the resource. | ||||
|      * | ||||
|      * @param Request $request | ||||
|      * | ||||
|      * @return JsonResponse | ||||
|      */ | ||||
|     public function index(Request $request): JsonResponse | ||||
|     { | ||||
|         // create some objects: | ||||
|         $manager = new Manager; | ||||
|         $baseUrl = $request->getSchemeAndHttpHost() . '/api/v1'; | ||||
|  | ||||
|         // types to get, page size: | ||||
|         $pageSize = (int)app('preferences')->getForUser(auth()->user(), 'listPageSize', 50)->data; | ||||
|  | ||||
|         // get list of budgets. Count it and split it. | ||||
|         $collection = $this->repository->getCategories(); | ||||
|         $count      = $collection->count(); | ||||
|         $categories = $collection->slice(($this->parameters->get('page') - 1) * $pageSize, $pageSize); | ||||
|  | ||||
|         // make paginator: | ||||
|         $paginator = new LengthAwarePaginator($categories, $count, $pageSize, $this->parameters->get('page')); | ||||
|         $paginator->setPath(route('api.v1.categories.index') . $this->buildParams()); | ||||
|  | ||||
|         // present to user. | ||||
|         $manager->setSerializer(new JsonApiSerializer($baseUrl)); | ||||
|         $resource = new FractalCollection($categories, new CategoryTransformer($this->parameters), 'categories'); | ||||
|         $resource->setPaginator(new IlluminatePaginatorAdapter($paginator)); | ||||
|  | ||||
|         return response()->json($manager->createData($resource)->toArray())->header('Content-Type', 'application/vnd.api+json'); | ||||
|     } | ||||
|  | ||||
|  | ||||
|     /** | ||||
|      * Show the category. | ||||
|      * | ||||
|      * @param Request  $request | ||||
|      * @param Category $category | ||||
|      * | ||||
|      * @return JsonResponse | ||||
|      */ | ||||
|     public function show(Request $request, Category $category): JsonResponse | ||||
|     { | ||||
|         $manager = new Manager(); | ||||
|         // add include parameter: | ||||
|         $include = $request->get('include') ?? ''; | ||||
|         $manager->parseIncludes($include); | ||||
|  | ||||
|         $baseUrl = $request->getSchemeAndHttpHost() . '/api/v1'; | ||||
|         $manager->setSerializer(new JsonApiSerializer($baseUrl)); | ||||
|  | ||||
|         $resource = new Item($category, new CategoryTransformer($this->parameters), 'categories'); | ||||
|  | ||||
|         return response()->json($manager->createData($resource)->toArray())->header('Content-Type', 'application/vnd.api+json'); | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      * Store new category. | ||||
|      * | ||||
|      * @param CategoryRequest $request | ||||
|      * | ||||
|      * @return JsonResponse | ||||
|      * @throws FireflyException | ||||
|      */ | ||||
|     public function store(CategoryRequest $request): JsonResponse | ||||
|     { | ||||
|         $category = $this->repository->store($request->getAll()); | ||||
|         if (null !== $category) { | ||||
|             $manager = new Manager(); | ||||
|             $baseUrl = $request->getSchemeAndHttpHost() . '/api/v1'; | ||||
|             $manager->setSerializer(new JsonApiSerializer($baseUrl)); | ||||
|  | ||||
|             $resource = new Item($category, new CategoryTransformer($this->parameters), 'categories'); | ||||
|  | ||||
|             return response()->json($manager->createData($resource)->toArray())->header('Content-Type', 'application/vnd.api+json'); | ||||
|         } | ||||
|         throw new FireflyException('Could not store new category.'); // @codeCoverageIgnore | ||||
|     } | ||||
|  | ||||
|  | ||||
|     /** | ||||
|      * Update the category. | ||||
|      * | ||||
|      * @param CategoryRequest $request | ||||
|      * @param Category        $category | ||||
|      * | ||||
|      * @return JsonResponse | ||||
|      */ | ||||
|     public function update(CategoryRequest $request, Category $category): JsonResponse | ||||
|     { | ||||
|         $data     = $request->getAll(); | ||||
|         $category = $this->repository->update($category, $data); | ||||
|         $manager  = new Manager(); | ||||
|         $baseUrl  = $request->getSchemeAndHttpHost() . '/api/v1'; | ||||
|         $manager->setSerializer(new JsonApiSerializer($baseUrl)); | ||||
|  | ||||
|         $resource = new Item($category, new CategoryTransformer($this->parameters), 'categories'); | ||||
|  | ||||
|         return response()->json($manager->createData($resource)->toArray())->header('Content-Type', 'application/vnd.api+json'); | ||||
|  | ||||
|     } | ||||
|  | ||||
| } | ||||
							
								
								
									
										135
									
								
								app/Api/V1/Controllers/ConfigurationController.php
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										135
									
								
								app/Api/V1/Controllers/ConfigurationController.php
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,135 @@ | ||||
| <?php | ||||
| /** | ||||
|  * ConfigurationController.php | ||||
|  * Copyright (c) 2018 thegrumpydictator@gmail.com | ||||
|  * | ||||
|  * This file is part of Firefly III. | ||||
|  * | ||||
|  * Firefly III is free software: you can redistribute it and/or modify | ||||
|  * it under the terms of the GNU General Public License as published by | ||||
|  * the Free Software Foundation, either version 3 of the License, or | ||||
|  * (at your option) any later version. | ||||
|  * | ||||
|  * Firefly III is distributed in the hope that it will be useful, | ||||
|  * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||||
|  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the | ||||
|  * GNU General Public License for more details. | ||||
|  * | ||||
|  * You should have received a copy of the GNU General Public License | ||||
|  * along with Firefly III. If not, see <http://www.gnu.org/licenses/>. | ||||
|  */ | ||||
|  | ||||
| declare(strict_types=1); | ||||
|  | ||||
| namespace FireflyIII\Api\V1\Controllers; | ||||
|  | ||||
| use FireflyIII\Exceptions\FireflyException; | ||||
| use FireflyIII\Models\Configuration; | ||||
| use FireflyIII\Repositories\User\UserRepositoryInterface; | ||||
| use FireflyIII\User; | ||||
| use Illuminate\Http\JsonResponse; | ||||
| use Illuminate\Http\Request; | ||||
|  | ||||
| /** | ||||
|  * Class ConfigurationController. | ||||
|  */ | ||||
| class ConfigurationController extends Controller | ||||
| { | ||||
|  | ||||
|  | ||||
|     /** @var UserRepositoryInterface The user repository */ | ||||
|     private $repository; | ||||
|  | ||||
|     /** | ||||
|      * BudgetController constructor. | ||||
|      */ | ||||
|     public function __construct() | ||||
|     { | ||||
|         parent::__construct(); | ||||
|         $this->middleware( | ||||
|             function ($request, $next) { | ||||
|                 /** @noinspection UnusedConstructorDependenciesInspection */ | ||||
|                 $this->repository = app(UserRepositoryInterface::class); | ||||
|                 /** @var User $admin */ | ||||
|                 $admin = auth()->user(); | ||||
|  | ||||
|                 if (!$this->repository->hasRole($admin, 'owner')) { | ||||
|                     throw new FireflyException('No access to method.'); // @codeCoverageIgnore | ||||
|                 } | ||||
|  | ||||
|                 return $next($request); | ||||
|             } | ||||
|         ); | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      * Show all configuration. | ||||
|      * | ||||
|      * @return JsonResponse | ||||
|      */ | ||||
|     public function index(): JsonResponse | ||||
|     { | ||||
|         $configData = $this->getConfigData(); | ||||
|  | ||||
|         return response()->json(['data' => $configData], 200)->header('Content-Type', 'application/vnd.api+json'); | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      * Update the configuration. | ||||
|      * | ||||
|      * @param Request $request | ||||
|      * | ||||
|      * @return JsonResponse | ||||
|      * @throws FireflyException | ||||
|      * @SuppressWarnings(PHPMD.CyclomaticComplexity) | ||||
|      */ | ||||
|     public function update(Request $request): JsonResponse | ||||
|     { | ||||
|         $name  = $request->get('name'); | ||||
|         $value = $request->get('value'); | ||||
|         $valid = ['is_demo_site', 'permission_update_check', 'single_user_mode']; | ||||
|         if (!\in_array($name, $valid, true)) { | ||||
|             throw new FireflyException('You cannot edit this configuration value.'); | ||||
|         } | ||||
|         $configValue = ''; | ||||
|         switch ($name) { | ||||
|             case 'is_demo_site': | ||||
|             case 'single_user_mode': | ||||
|                 $configValue = 'true' === $value; | ||||
|                 break; | ||||
|             case 'permission_update_check': | ||||
|                 $configValue = (int)$value >= -1 && (int)$value <= 1 ? (int)$value : -1; | ||||
|                 break; | ||||
|         } | ||||
|         app('fireflyconfig')->set($name, $configValue); | ||||
|         $configData = $this->getConfigData(); | ||||
|  | ||||
|         return response()->json(['data' => $configData], 200)->header('Content-Type', 'application/vnd.api+json'); | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      * Get all config values. | ||||
|      * | ||||
|      * @return array | ||||
|      * @SuppressWarnings(PHPMD.CyclomaticComplexity) | ||||
|      */ | ||||
|     private function getConfigData(): array | ||||
|     { | ||||
|         /** @var Configuration $isDemoSite */ | ||||
|         $isDemoSite = app('fireflyconfig')->get('is_demo_site'); | ||||
|         /** @var Configuration $updateCheck */ | ||||
|         $updateCheck = app('fireflyconfig')->get('permission_update_check'); | ||||
|         /** @var Configuration $lastCheck */ | ||||
|         $lastCheck = app('fireflyconfig')->get('last_update_check'); | ||||
|         /** @var Configuration $singleUser */ | ||||
|         $singleUser = app('fireflyconfig')->get('single_user_mode'); | ||||
|         $data       = [ | ||||
|             'is_demo_site'            => null === $isDemoSite ? null : $isDemoSite->data, | ||||
|             'permission_update_check' => null === $updateCheck ? null : (int)$updateCheck->data, | ||||
|             'last_update_check'       => null === $lastCheck ? null : (int)$lastCheck->data, | ||||
|             'single_user_mode'        => null === $singleUser ? null : $singleUser->data, | ||||
|         ]; | ||||
|  | ||||
|         return $data; | ||||
|     } | ||||
| } | ||||
| @@ -1,5 +1,5 @@ | ||||
| <?php | ||||
| declare(strict_types=1); | ||||
|  | ||||
| /** | ||||
|  * Controller.php | ||||
|  * Copyright (c) 2018 thegrumpydictator@gmail.com | ||||
| @@ -20,12 +20,12 @@ declare(strict_types=1); | ||||
|  * along with Firefly III. If not, see <http://www.gnu.org/licenses/>. | ||||
|  */ | ||||
|  | ||||
| declare(strict_types=1); | ||||
|  | ||||
| namespace FireflyIII\Api\V1\Controllers; | ||||
|  | ||||
| use Carbon\Carbon; | ||||
| use Carbon\Exceptions\InvalidDateException; | ||||
| use FireflyConfig; | ||||
| use FireflyIII\Exceptions\FireflyException; | ||||
| use Illuminate\Foundation\Auth\Access\AuthorizesRequests; | ||||
| use Illuminate\Foundation\Bus\DispatchesJobs; | ||||
| use Illuminate\Foundation\Validation\ValidatesRequests; | ||||
| @@ -37,12 +37,13 @@ use Symfony\Component\HttpFoundation\ParameterBag; | ||||
|  * Class Controller. | ||||
|  * | ||||
|  * @codeCoverageIgnore | ||||
|  * @SuppressWarnings(PHPMD.NumberOfChildren) | ||||
|  */ | ||||
| class Controller extends BaseController | ||||
| { | ||||
|     use AuthorizesRequests, DispatchesJobs, ValidatesRequests; | ||||
|  | ||||
|     /** @var ParameterBag */ | ||||
|     /** @var ParameterBag Parameters from the URI are stored here. */ | ||||
|     protected $parameters; | ||||
|  | ||||
|     /** | ||||
| @@ -56,39 +57,42 @@ class Controller extends BaseController | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      * Method to help build URI's. | ||||
|      * | ||||
|      * @return string | ||||
|      * | ||||
|      * @SuppressWarnings(PHPMD.CyclomaticComplexity) | ||||
|      */ | ||||
|     protected function buildParams(): string | ||||
|     { | ||||
|         $return = '?'; | ||||
|         $params = []; | ||||
|         foreach ($this->parameters as $key => $value) { | ||||
|             if ($key === 'page') { | ||||
|             if ('page' === $key) { | ||||
|                 continue; | ||||
|             } | ||||
|             if ($value instanceof Carbon) { | ||||
|                 $params[$key] = $value->format('Y-m-d'); | ||||
|                 continue; | ||||
|             } | ||||
|             if (!$value instanceof Carbon) { | ||||
|                 $params[$key] = $value; | ||||
|             } | ||||
|             $params[$key] = $value; | ||||
|         } | ||||
|         $return .= http_build_query($params); | ||||
|         if (\strlen($return) === 1) { | ||||
|             return ''; | ||||
|         } | ||||
|  | ||||
|         return $return; | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      * Method to grab all parameters from the URI. | ||||
|      * | ||||
|      * @return ParameterBag | ||||
|      * @SuppressWarnings(PHPMD.CyclomaticComplexity) | ||||
|      */ | ||||
|     private function getParameters(): ParameterBag | ||||
|     { | ||||
|         $bag  = new ParameterBag; | ||||
|         $page = (int)request()->get('page'); | ||||
|         if ($page === 0) { | ||||
|         if (0 === $page) { | ||||
|             $page = 1; | ||||
|         } | ||||
|         $bag->set('page', $page); | ||||
|   | ||||
| @@ -24,13 +24,13 @@ declare(strict_types=1); | ||||
|  | ||||
| namespace FireflyIII\Api\V1\Controllers; | ||||
|  | ||||
| use FireflyIII\Api\V1\Requests\BillRequest; | ||||
| use FireflyIII\Api\V1\Requests\CurrencyRequest; | ||||
| use FireflyIII\Exceptions\FireflyException; | ||||
| use FireflyIII\Models\TransactionCurrency; | ||||
| use FireflyIII\Repositories\Currency\CurrencyRepositoryInterface; | ||||
| use FireflyIII\Repositories\User\UserRepositoryInterface; | ||||
| use FireflyIII\Transformers\CurrencyTransformer; | ||||
| use FireflyIII\User; | ||||
| use Illuminate\Http\JsonResponse; | ||||
| use Illuminate\Http\Request; | ||||
| use Illuminate\Pagination\LengthAwarePaginator; | ||||
| @@ -39,32 +39,34 @@ use League\Fractal\Pagination\IlluminatePaginatorAdapter; | ||||
| use League\Fractal\Resource\Collection as FractalCollection; | ||||
| use League\Fractal\Resource\Item; | ||||
| use League\Fractal\Serializer\JsonApiSerializer; | ||||
| use Preferences; | ||||
|  | ||||
| /** | ||||
|  * Class CurrencyController | ||||
|  * Class CurrencyController. | ||||
|  * | ||||
|  * @SuppressWarnings(PHPMD.CouplingBetweenObjects) | ||||
|  */ | ||||
| class CurrencyController extends Controller | ||||
| { | ||||
|     /** @var CurrencyRepositoryInterface */ | ||||
|     /** @var CurrencyRepositoryInterface The currency repository */ | ||||
|     private $repository; | ||||
|     /** @var UserRepositoryInterface */ | ||||
|     /** @var UserRepositoryInterface The user repository */ | ||||
|     private $userRepository; | ||||
|  | ||||
|     /** | ||||
|      * CurrencyRepository constructor. | ||||
|      * | ||||
|      * @throws FireflyException | ||||
|      */ | ||||
|     public function __construct() | ||||
|     { | ||||
|         parent::__construct(); | ||||
|         $this->middleware( | ||||
|             function ($request, $next) { | ||||
|                 /** @var User $admin */ | ||||
|                 $admin = auth()->user(); | ||||
|  | ||||
|                 /** @var CurrencyRepositoryInterface repository */ | ||||
|                 $this->repository     = app(CurrencyRepositoryInterface::class); | ||||
|                 $this->userRepository = app(UserRepositoryInterface::class); | ||||
|                 $this->repository->setUser(auth()->user()); | ||||
|                 $this->repository->setUser($admin); | ||||
|  | ||||
|                 return $next($request); | ||||
|             } | ||||
| @@ -81,7 +83,10 @@ class CurrencyController extends Controller | ||||
|      */ | ||||
|     public function delete(TransactionCurrency $currency): JsonResponse | ||||
|     { | ||||
|         if (!$this->userRepository->hasRole(auth()->user(), 'owner')) { | ||||
|         /** @var User $admin */ | ||||
|         $admin = auth()->user(); | ||||
|  | ||||
|         if (!$this->userRepository->hasRole($admin, 'owner')) { | ||||
|             // access denied: | ||||
|             throw new FireflyException('No access to method, user is not owner.'); // @codeCoverageIgnore | ||||
|         } | ||||
| @@ -102,7 +107,7 @@ class CurrencyController extends Controller | ||||
|      */ | ||||
|     public function index(Request $request): JsonResponse | ||||
|     { | ||||
|         $pageSize   = (int)Preferences::getForUser(auth()->user(), 'listPageSize', 50)->data; | ||||
|         $pageSize   = (int)app('preferences')->getForUser(auth()->user(), 'listPageSize', 50)->data; | ||||
|         $collection = $this->repository->get(); | ||||
|         $count      = $collection->count(); | ||||
|         // slice them: | ||||
| @@ -125,6 +130,8 @@ class CurrencyController extends Controller | ||||
|  | ||||
|  | ||||
|     /** | ||||
|      * Show a currency. | ||||
|      * | ||||
|      * @param Request             $request | ||||
|      * @param TransactionCurrency $currency | ||||
|      * | ||||
| @@ -148,6 +155,8 @@ class CurrencyController extends Controller | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      * Store new currency. | ||||
|      * | ||||
|      * @param CurrencyRequest $request | ||||
|      * | ||||
|      * @return JsonResponse | ||||
| @@ -157,11 +166,11 @@ class CurrencyController extends Controller | ||||
|     { | ||||
|         $currency = $this->repository->store($request->getAll()); | ||||
|  | ||||
|         if ($request->boolean('default') === true) { | ||||
|             Preferences::set('currencyPreference', $currency->code); | ||||
|             Preferences::mark(); | ||||
|         } | ||||
|         if (null !== $currency) { | ||||
|             if (true === $request->boolean('default')) { | ||||
|                 app('preferences')->set('currencyPreference', $currency->code); | ||||
|                 app('preferences')->mark(); | ||||
|             } | ||||
|             $manager = new Manager(); | ||||
|             $baseUrl = $request->getSchemeAndHttpHost() . '/api/v1'; | ||||
|             $manager->setSerializer(new JsonApiSerializer($baseUrl)); | ||||
| @@ -178,7 +187,9 @@ class CurrencyController extends Controller | ||||
|  | ||||
|  | ||||
|     /** | ||||
|      * @param CurrencyRequest         $request | ||||
|      * Update a currency. | ||||
|      * | ||||
|      * @param CurrencyRequest     $request | ||||
|      * @param TransactionCurrency $currency | ||||
|      * | ||||
|      * @return JsonResponse | ||||
| @@ -188,9 +199,9 @@ class CurrencyController extends Controller | ||||
|         $data     = $request->getAll(); | ||||
|         $currency = $this->repository->update($currency, $data); | ||||
|  | ||||
|         if ($request->boolean('default') === true) { | ||||
|             Preferences::set('currencyPreference', $currency->code); | ||||
|             Preferences::mark(); | ||||
|         if (true === $request->boolean('default')) { | ||||
|             app('preferences')->set('currencyPreference', $currency->code); | ||||
|             app('preferences')->mark(); | ||||
|         } | ||||
|  | ||||
|         $manager = new Manager(); | ||||
|   | ||||
							
								
								
									
										111
									
								
								app/Api/V1/Controllers/CurrencyExchangeRateController.php
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										111
									
								
								app/Api/V1/Controllers/CurrencyExchangeRateController.php
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,111 @@ | ||||
| <?php | ||||
| /** | ||||
|  * CurrencyExchangeRateController.php | ||||
|  * Copyright (c) 2018 thegrumpydictator@gmail.com | ||||
|  * | ||||
|  * This file is part of Firefly III. | ||||
|  * | ||||
|  * Firefly III is free software: you can redistribute it and/or modify | ||||
|  * it under the terms of the GNU General Public License as published by | ||||
|  * the Free Software Foundation, either version 3 of the License, or | ||||
|  * (at your option) any later version. | ||||
|  * | ||||
|  * Firefly III is distributed in the hope that it will be useful, | ||||
|  * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||||
|  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the | ||||
|  * GNU General Public License for more details. | ||||
|  * | ||||
|  * You should have received a copy of the GNU General Public License | ||||
|  * along with Firefly III. If not, see <http://www.gnu.org/licenses/>. | ||||
|  */ | ||||
|  | ||||
| declare(strict_types=1); | ||||
|  | ||||
| namespace FireflyIII\Api\V1\Controllers; | ||||
|  | ||||
| use Carbon\Carbon; | ||||
| use FireflyIII\Exceptions\FireflyException; | ||||
| use FireflyIII\Repositories\Currency\CurrencyRepositoryInterface; | ||||
| use FireflyIII\Services\Currency\ExchangeRateInterface; | ||||
| use FireflyIII\Transformers\CurrencyExchangeRateTransformer; | ||||
| use FireflyIII\User; | ||||
| use Illuminate\Http\JsonResponse; | ||||
| use Illuminate\Http\Request; | ||||
| use League\Fractal\Manager; | ||||
| use League\Fractal\Resource\Item; | ||||
| use League\Fractal\Serializer\JsonApiSerializer; | ||||
|  | ||||
| /** | ||||
|  * Class CurrencyExchangeRateController | ||||
|  */ | ||||
| class CurrencyExchangeRateController extends Controller | ||||
| { | ||||
|     /** @var CurrencyRepositoryInterface The currency repository */ | ||||
|     private $repository; | ||||
|  | ||||
|     /** | ||||
|      * CurrencyExchangeRateController constructor. | ||||
|      */ | ||||
|     public function __construct() | ||||
|     { | ||||
|         parent::__construct(); | ||||
|         $this->middleware( | ||||
|             function ($request, $next) { | ||||
|                 /** @var User $admin */ | ||||
|                 $admin = auth()->user(); | ||||
|  | ||||
|                 $this->repository = app(CurrencyRepositoryInterface::class); | ||||
|                 $this->repository->setUser($admin); | ||||
|  | ||||
|                 return $next($request); | ||||
|             } | ||||
|         ); | ||||
|  | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      * Show an exchange rate. | ||||
|      * | ||||
|      * @param Request $request | ||||
|      * | ||||
|      * @return JsonResponse | ||||
|      * @throws FireflyException | ||||
|      */ | ||||
|     public function index(Request $request): JsonResponse | ||||
|     { | ||||
|         // create some objects: | ||||
|         $manager = new Manager; | ||||
|         $baseUrl = $request->getSchemeAndHttpHost() . '/api/v1'; | ||||
|         $manager->setSerializer(new JsonApiSerializer($baseUrl)); | ||||
|  | ||||
|         $fromCurrency = $this->repository->findByCodeNull($request->get('from') ?? 'EUR'); | ||||
|         $toCurrency   = $this->repository->findByCodeNull($request->get('to') ?? 'USD'); | ||||
|  | ||||
|         if (null === $fromCurrency) { | ||||
|             throw new FireflyException('Unknown source currency.'); | ||||
|         } | ||||
|         if (null === $toCurrency) { | ||||
|             throw new FireflyException('Unknown destination currency.'); | ||||
|         } | ||||
|  | ||||
|         $dateObj = Carbon::createFromFormat('Y-m-d', $request->get('date') ?? date('Y-m-d')); | ||||
|         $this->parameters->set('from', $fromCurrency->code); | ||||
|         $this->parameters->set('to', $toCurrency->code); | ||||
|         $this->parameters->set('date', $dateObj->format('Y-m-d')); | ||||
|  | ||||
|         $rate = $this->repository->getExchangeRate($fromCurrency, $toCurrency, $dateObj); | ||||
|         if (null === $rate) { | ||||
|             /** @var User $admin */ | ||||
|             $admin = auth()->user(); | ||||
|             // create service: | ||||
|             /** @var ExchangeRateInterface $service */ | ||||
|             $service = app(ExchangeRateInterface::class); | ||||
|             $service->setUser($admin); | ||||
|             $rate = $service->getRate($fromCurrency, $toCurrency, $dateObj); | ||||
|         } | ||||
|  | ||||
|         $resource = new Item($rate, new CurrencyExchangeRateTransformer($this->parameters), 'currency_exchange_rates'); | ||||
|  | ||||
|         return response()->json($manager->createData($resource)->toArray())->header('Content-Type', 'application/vnd.api+json'); | ||||
|     } | ||||
| } | ||||
							
								
								
									
										217
									
								
								app/Api/V1/Controllers/JournalLinkController.php
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										217
									
								
								app/Api/V1/Controllers/JournalLinkController.php
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,217 @@ | ||||
| <?php | ||||
| /** | ||||
|  * JournalLinkController.php | ||||
|  * Copyright (c) 2018 thegrumpydictator@gmail.com | ||||
|  * | ||||
|  * This file is part of Firefly III. | ||||
|  * | ||||
|  * Firefly III is free software: you can redistribute it and/or modify | ||||
|  * it under the terms of the GNU General Public License as published by | ||||
|  * the Free Software Foundation, either version 3 of the License, or | ||||
|  * (at your option) any later version. | ||||
|  * | ||||
|  * Firefly III is distributed in the hope that it will be useful, | ||||
|  * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||||
|  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the | ||||
|  * GNU General Public License for more details. | ||||
|  * | ||||
|  * You should have received a copy of the GNU General Public License | ||||
|  * along with Firefly III. If not, see <http://www.gnu.org/licenses/>. | ||||
|  */ | ||||
|  | ||||
| declare(strict_types=1); | ||||
|  | ||||
| namespace FireflyIII\Api\V1\Controllers; | ||||
|  | ||||
| use FireflyIII\Api\V1\Requests\JournalLinkRequest; | ||||
| use FireflyIII\Exceptions\FireflyException; | ||||
| use FireflyIII\Models\TransactionJournalLink; | ||||
| use FireflyIII\Repositories\Journal\JournalRepositoryInterface; | ||||
| use FireflyIII\Repositories\LinkType\LinkTypeRepositoryInterface; | ||||
| use FireflyIII\Transformers\JournalLinkTransformer; | ||||
| use FireflyIII\User; | ||||
| use Illuminate\Http\JsonResponse; | ||||
| use Illuminate\Http\Request; | ||||
| use Illuminate\Pagination\LengthAwarePaginator; | ||||
| use League\Fractal\Manager; | ||||
| use League\Fractal\Pagination\IlluminatePaginatorAdapter; | ||||
| use League\Fractal\Resource\Collection as FractalCollection; | ||||
| use League\Fractal\Resource\Item; | ||||
| use League\Fractal\Serializer\JsonApiSerializer; | ||||
|  | ||||
| /** | ||||
|  * Class JournalLinkController. | ||||
|  * | ||||
|  * @SuppressWarnings(PHPMD.CouplingBetweenObjects) | ||||
|  */ | ||||
| class JournalLinkController extends Controller | ||||
| { | ||||
|     /** @var JournalRepositoryInterface The journal repository */ | ||||
|     private $journalRepository; | ||||
|     /** @var LinkTypeRepositoryInterface The link type repository */ | ||||
|     private $repository; | ||||
|  | ||||
|     /** | ||||
|      * JournalLinkController constructor. | ||||
|      */ | ||||
|     public function __construct() | ||||
|     { | ||||
|         parent::__construct(); | ||||
|         $this->middleware( | ||||
|             function ($request, $next) { | ||||
|                 /** @var User $user */ | ||||
|                 $user = auth()->user(); | ||||
|  | ||||
|                 $this->repository        = app(LinkTypeRepositoryInterface::class); | ||||
|                 $this->journalRepository = app(JournalRepositoryInterface::class); | ||||
|  | ||||
|                 $this->repository->setUser($user); | ||||
|                 $this->journalRepository->setUser($user); | ||||
|  | ||||
|                 return $next($request); | ||||
|             } | ||||
|         ); | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      * Delete the resource. | ||||
|      * | ||||
|      * @param TransactionJournalLink $link | ||||
|      * | ||||
|      * @return JsonResponse | ||||
|      */ | ||||
|     public function delete(TransactionJournalLink $link): JsonResponse | ||||
|     { | ||||
|         $this->repository->destroyLink($link); | ||||
|  | ||||
|         return response()->json([], 204); | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      * List all of them. | ||||
|      * | ||||
|      * @param Request $request | ||||
|      * | ||||
|      * @return JsonResponse] | ||||
|      */ | ||||
|     public function index(Request $request): JsonResponse | ||||
|     { | ||||
|         // create some objects: | ||||
|         $manager = new Manager; | ||||
|         $baseUrl = $request->getSchemeAndHttpHost() . '/api/v1'; | ||||
|  | ||||
|         // read type from URI | ||||
|         $name = $request->get('name') ?? null; | ||||
|  | ||||
|         // types to get, page size: | ||||
|         $pageSize = (int)app('preferences')->getForUser(auth()->user(), 'listPageSize', 50)->data; | ||||
|  | ||||
|         $linkType = $this->repository->findByName($name); | ||||
|  | ||||
|         // get list of accounts. Count it and split it. | ||||
|         $collection   = $this->repository->getJournalLinks($linkType); | ||||
|         $count        = $collection->count(); | ||||
|         $journalLinks = $collection->slice(($this->parameters->get('page') - 1) * $pageSize, $pageSize); | ||||
|  | ||||
|         // make paginator: | ||||
|         $paginator = new LengthAwarePaginator($journalLinks, $count, $pageSize, $this->parameters->get('page')); | ||||
|         $paginator->setPath(route('api.v1.journal_links.index') . $this->buildParams()); | ||||
|  | ||||
|         // present to user. | ||||
|         $manager->setSerializer(new JsonApiSerializer($baseUrl)); | ||||
|         $resource = new FractalCollection($journalLinks, new JournalLinkTransformer($this->parameters), 'journal_links'); | ||||
|         $resource->setPaginator(new IlluminatePaginatorAdapter($paginator)); | ||||
|  | ||||
|         return response()->json($manager->createData($resource)->toArray())->header('Content-Type', 'application/vnd.api+json'); | ||||
|  | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      * List single resource. | ||||
|      * | ||||
|      * @param Request                $request | ||||
|      * @param TransactionJournalLink $journalLink | ||||
|      * | ||||
|      * @return JsonResponse | ||||
|      */ | ||||
|     public function show(Request $request, TransactionJournalLink $journalLink): JsonResponse | ||||
|     { | ||||
|         $manager = new Manager; | ||||
|  | ||||
|         // add include parameter: | ||||
|         $include = $request->get('include') ?? ''; | ||||
|         $manager->parseIncludes($include); | ||||
|  | ||||
|         $baseUrl = $request->getSchemeAndHttpHost() . '/api/v1'; | ||||
|         $manager->setSerializer(new JsonApiSerializer($baseUrl)); | ||||
|         $resource = new Item($journalLink, new JournalLinkTransformer($this->parameters), 'journal_links'); | ||||
|  | ||||
|         return response()->json($manager->createData($resource)->toArray())->header('Content-Type', 'application/vnd.api+json'); | ||||
|  | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      * Store new object. | ||||
|      * | ||||
|      * @param JournalLinkRequest $request | ||||
|      * | ||||
|      * @return JsonResponse | ||||
|      * @throws FireflyException | ||||
|      */ | ||||
|     public function store(JournalLinkRequest $request): JsonResponse | ||||
|     { | ||||
|         $manager = new Manager; | ||||
|  | ||||
|         // add include parameter: | ||||
|         $include = $request->get('include') ?? ''; | ||||
|         $manager->parseIncludes($include); | ||||
|  | ||||
|         $data    = $request->getAll(); | ||||
|         $inward  = $this->journalRepository->findNull($data['inward_id'] ?? 0); | ||||
|         $outward = $this->journalRepository->findNull($data['outward_id'] ?? 0); | ||||
|         if (null === $inward || null === $outward) { | ||||
|             throw new FireflyException('Source or destination is NULL.'); | ||||
|         } | ||||
|         $data['direction'] = 'inward'; | ||||
|  | ||||
|         $journalLink = $this->repository->storeLink($data, $inward, $outward); | ||||
|  | ||||
|         $resource = new Item($journalLink, new JournalLinkTransformer($this->parameters), 'journal_links'); | ||||
|  | ||||
|         return response()->json($manager->createData($resource)->toArray())->header('Content-Type', 'application/vnd.api+json'); | ||||
|  | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      * Update object. | ||||
|      * | ||||
|      * @param JournalLinkRequest     $request | ||||
|      * @param TransactionJournalLink $journalLink | ||||
|      * | ||||
|      * @return JsonResponse | ||||
|      * @throws FireflyException | ||||
|      */ | ||||
|     public function update(JournalLinkRequest $request, TransactionJournalLink $journalLink): JsonResponse | ||||
|     { | ||||
|         $manager = new Manager; | ||||
|  | ||||
|         // add include parameter: | ||||
|         $include = $request->get('include') ?? ''; | ||||
|         $manager->parseIncludes($include); | ||||
|  | ||||
|  | ||||
|         $data            = $request->getAll(); | ||||
|         $data['inward']  = $this->journalRepository->findNull($data['inward_id'] ?? 0); | ||||
|         $data['outward'] = $this->journalRepository->findNull($data['outward_id'] ?? 0); | ||||
|         if (null === $data['inward'] || null === $data['outward']) { | ||||
|             throw new FireflyException('Source or destination is NULL.'); | ||||
|         } | ||||
|         $data['direction'] = 'inward'; | ||||
|         $journalLink       = $this->repository->updateLink($journalLink, $data); | ||||
|  | ||||
|         $resource = new Item($journalLink, new JournalLinkTransformer($this->parameters), 'journal_links'); | ||||
|  | ||||
|         return response()->json($manager->createData($resource)->toArray())->header('Content-Type', 'application/vnd.api+json'); | ||||
|  | ||||
|     } | ||||
| } | ||||
							
								
								
									
										210
									
								
								app/Api/V1/Controllers/LinkTypeController.php
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										210
									
								
								app/Api/V1/Controllers/LinkTypeController.php
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,210 @@ | ||||
| <?php | ||||
| /** | ||||
|  * LinkTypeController.php | ||||
|  * Copyright (c) 2018 thegrumpydictator@gmail.com | ||||
|  * | ||||
|  * This file is part of Firefly III. | ||||
|  * | ||||
|  * Firefly III is free software: you can redistribute it and/or modify | ||||
|  * it under the terms of the GNU General Public License as published by | ||||
|  * the Free Software Foundation, either version 3 of the License, or | ||||
|  * (at your option) any later version. | ||||
|  * | ||||
|  * Firefly III is distributed in the hope that it will be useful, | ||||
|  * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||||
|  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the | ||||
|  * GNU General Public License for more details. | ||||
|  * | ||||
|  * You should have received a copy of the GNU General Public License | ||||
|  * along with Firefly III. If not, see <http://www.gnu.org/licenses/>. | ||||
|  */ | ||||
|  | ||||
| declare(strict_types=1); | ||||
|  | ||||
| namespace FireflyIII\Api\V1\Controllers; | ||||
|  | ||||
| use FireflyIII\Api\V1\Requests\LinkTypeRequest; | ||||
| use FireflyIII\Exceptions\FireflyException; | ||||
| use FireflyIII\Models\LinkType; | ||||
| use FireflyIII\Repositories\LinkType\LinkTypeRepositoryInterface; | ||||
| use FireflyIII\Repositories\User\UserRepositoryInterface; | ||||
| use FireflyIII\Transformers\LinkTypeTransformer; | ||||
| use FireflyIII\User; | ||||
| use Illuminate\Http\JsonResponse; | ||||
| use Illuminate\Http\Request; | ||||
| use Illuminate\Pagination\LengthAwarePaginator; | ||||
| use League\Fractal\Manager; | ||||
| use League\Fractal\Pagination\IlluminatePaginatorAdapter; | ||||
| use League\Fractal\Resource\Collection as FractalCollection; | ||||
| use League\Fractal\Resource\Item; | ||||
| use League\Fractal\Serializer\JsonApiSerializer; | ||||
|  | ||||
| /** | ||||
|  * Class LinkTypeController. | ||||
|  * | ||||
|  * @SuppressWarnings(PHPMD.CouplingBetweenObjects) | ||||
|  */ | ||||
| class LinkTypeController extends Controller | ||||
| { | ||||
|     /** @var LinkTypeRepositoryInterface The link type repository */ | ||||
|     private $repository; | ||||
|  | ||||
|     /** @var UserRepositoryInterface The user repository */ | ||||
|     private $userRepository; | ||||
|  | ||||
|     /** | ||||
|      * LinkTypeController constructor. | ||||
|      */ | ||||
|     public function __construct() | ||||
|     { | ||||
|         parent::__construct(); | ||||
|         $this->middleware( | ||||
|             function ($request, $next) { | ||||
|                 /** @var User $user */ | ||||
|                 $user                 = auth()->user(); | ||||
|                 $this->repository     = app(LinkTypeRepositoryInterface::class); | ||||
|                 $this->userRepository = app(UserRepositoryInterface::class); | ||||
|                 $this->repository->setUser($user); | ||||
|  | ||||
|                 return $next($request); | ||||
|             } | ||||
|         ); | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      * Delete the resource. | ||||
|      * | ||||
|      * @param LinkType $linkType | ||||
|      * | ||||
|      * @return JsonResponse | ||||
|      * @throws FireflyException | ||||
|      */ | ||||
|     public function delete(LinkType $linkType): JsonResponse | ||||
|     { | ||||
|         if (false === $linkType->editable) { | ||||
|             throw new FireflyException(sprintf('You cannot delete this link type (#%d, "%s")', $linkType->id, $linkType->name)); | ||||
|         } | ||||
|         $this->repository->destroy($linkType, null); | ||||
|  | ||||
|         return response()->json([], 204); | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      * List all of them. | ||||
|      * | ||||
|      * @param Request $request | ||||
|      * | ||||
|      * @return JsonResponse] | ||||
|      */ | ||||
|     public function index(Request $request): JsonResponse | ||||
|     { | ||||
|         // create some objects: | ||||
|         $manager  = new Manager; | ||||
|         $baseUrl  = $request->getSchemeAndHttpHost() . '/api/v1'; | ||||
|         $pageSize = (int)app('preferences')->getForUser(auth()->user(), 'listPageSize', 50)->data; | ||||
|  | ||||
|         // get list of accounts. Count it and split it. | ||||
|         $collection = $this->repository->get(); | ||||
|         $count      = $collection->count(); | ||||
|         $linkTypes  = $collection->slice(($this->parameters->get('page') - 1) * $pageSize, $pageSize); | ||||
|  | ||||
|         // make paginator: | ||||
|         $paginator = new LengthAwarePaginator($linkTypes, $count, $pageSize, $this->parameters->get('page')); | ||||
|         $paginator->setPath(route('api.v1.link_types.index') . $this->buildParams()); | ||||
|  | ||||
|         // present to user. | ||||
|         $manager->setSerializer(new JsonApiSerializer($baseUrl)); | ||||
|         $resource = new FractalCollection($linkTypes, new LinkTypeTransformer($this->parameters), 'link_types'); | ||||
|         $resource->setPaginator(new IlluminatePaginatorAdapter($paginator)); | ||||
|  | ||||
|         return response()->json($manager->createData($resource)->toArray())->header('Content-Type', 'application/vnd.api+json'); | ||||
|  | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      * List single resource. | ||||
|      * | ||||
|      * @param Request  $request | ||||
|      * @param LinkType $linkType | ||||
|      * | ||||
|      * @return JsonResponse | ||||
|      */ | ||||
|     public function show(Request $request, LinkType $linkType): JsonResponse | ||||
|     { | ||||
|         $manager = new Manager; | ||||
|  | ||||
|         // add include parameter: | ||||
|         $include = $request->get('include') ?? ''; | ||||
|         $manager->parseIncludes($include); | ||||
|  | ||||
|         $baseUrl = $request->getSchemeAndHttpHost() . '/api/v1'; | ||||
|         $manager->setSerializer(new JsonApiSerializer($baseUrl)); | ||||
|         $resource = new Item($linkType, new LinkTypeTransformer($this->parameters), 'link_types'); | ||||
|  | ||||
|         return response()->json($manager->createData($resource)->toArray())->header('Content-Type', 'application/vnd.api+json'); | ||||
|  | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      * Store new object. | ||||
|      * | ||||
|      * @param LinkTypeRequest $request | ||||
|      * | ||||
|      * @return JsonResponse | ||||
|      * @throws FireflyException | ||||
|      */ | ||||
|     public function store(LinkTypeRequest $request): JsonResponse | ||||
|     { | ||||
|         /** @var User $admin */ | ||||
|         $admin = auth()->user(); | ||||
|  | ||||
|         if (!$this->userRepository->hasRole($admin, 'owner')) { | ||||
|             throw new FireflyException('You need the "owner"-role to do this.'); | ||||
|         } | ||||
|         $data = $request->getAll(); | ||||
|         // if currency ID is 0, find the currency by the code: | ||||
|         $linkType = $this->repository->store($data); | ||||
|         $manager  = new Manager; | ||||
|         $baseUrl  = $request->getSchemeAndHttpHost() . '/api/v1'; | ||||
|         $manager->setSerializer(new JsonApiSerializer($baseUrl)); | ||||
|  | ||||
|         $resource = new Item($linkType, new LinkTypeTransformer($this->parameters), 'link_types'); | ||||
|  | ||||
|         return response()->json($manager->createData($resource)->toArray())->header('Content-Type', 'application/vnd.api+json'); | ||||
|  | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      * Update object. | ||||
|      * | ||||
|      * @param LinkTypeRequest $request | ||||
|      * @param LinkType        $linkType | ||||
|      * | ||||
|      * @return JsonResponse | ||||
|      * @throws FireflyException | ||||
|      */ | ||||
|     public function update(LinkTypeRequest $request, LinkType $linkType): JsonResponse | ||||
|     { | ||||
|         if (false === $linkType->editable) { | ||||
|             throw new FireflyException(sprintf('You cannot edit this link type (#%d, "%s")', $linkType->id, $linkType->name)); | ||||
|         } | ||||
|  | ||||
|         /** @var User $admin */ | ||||
|         $admin = auth()->user(); | ||||
|  | ||||
|         if (!$this->userRepository->hasRole($admin, 'owner')) { | ||||
|             throw new FireflyException('You need the "owner"-role to do this.'); | ||||
|         } | ||||
|  | ||||
|         $data = $request->getAll(); | ||||
|         $this->repository->update($linkType, $data); | ||||
|         $manager = new Manager; | ||||
|         $baseUrl = $request->getSchemeAndHttpHost() . '/api/v1'; | ||||
|         $manager->setSerializer(new JsonApiSerializer($baseUrl)); | ||||
|  | ||||
|         $resource = new Item($linkType, new LinkTypeTransformer($this->parameters), 'link_types'); | ||||
|  | ||||
|         return response()->json($manager->createData($resource)->toArray())->header('Content-Type', 'application/vnd.api+json'); | ||||
|  | ||||
|     } | ||||
| } | ||||
							
								
								
									
										188
									
								
								app/Api/V1/Controllers/PiggyBankController.php
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										188
									
								
								app/Api/V1/Controllers/PiggyBankController.php
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,188 @@ | ||||
| <?php | ||||
| /** | ||||
|  * PiggyBankController.php | ||||
|  * Copyright (c) 2018 thegrumpydictator@gmail.com | ||||
|  * | ||||
|  * This file is part of Firefly III. | ||||
|  * | ||||
|  * Firefly III is free software: you can redistribute it and/or modify | ||||
|  * it under the terms of the GNU General Public License as published by | ||||
|  * the Free Software Foundation, either version 3 of the License, or | ||||
|  * (at your option) any later version. | ||||
|  * | ||||
|  * Firefly III is distributed in the hope that it will be useful, | ||||
|  * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||||
|  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the | ||||
|  * GNU General Public License for more details. | ||||
|  * | ||||
|  * You should have received a copy of the GNU General Public License | ||||
|  * along with Firefly III. If not, see <http://www.gnu.org/licenses/>. | ||||
|  */ | ||||
|  | ||||
| declare(strict_types=1); | ||||
|  | ||||
| namespace FireflyIII\Api\V1\Controllers; | ||||
|  | ||||
| use FireflyIII\Api\V1\Requests\PiggyBankRequest; | ||||
| use FireflyIII\Exceptions\FireflyException; | ||||
| use FireflyIII\Models\PiggyBank; | ||||
| use FireflyIII\Repositories\PiggyBank\PiggyBankRepositoryInterface; | ||||
| use FireflyIII\Transformers\PiggyBankTransformer; | ||||
| use FireflyIII\User; | ||||
| use Illuminate\Http\JsonResponse; | ||||
| use Illuminate\Http\Request; | ||||
| use Illuminate\Pagination\LengthAwarePaginator; | ||||
| use League\Fractal\Manager; | ||||
| use League\Fractal\Pagination\IlluminatePaginatorAdapter; | ||||
| use League\Fractal\Resource\Collection as FractalCollection; | ||||
| use League\Fractal\Resource\Item; | ||||
| use League\Fractal\Serializer\JsonApiSerializer; | ||||
|  | ||||
| /** | ||||
|  * Class PiggyBankController. | ||||
|  * | ||||
|  * @SuppressWarnings(PHPMD.CouplingBetweenObjects) | ||||
|  */ | ||||
| class PiggyBankController extends Controller | ||||
| { | ||||
|  | ||||
|     /** @var PiggyBankRepositoryInterface The piggy bank repository */ | ||||
|     private $repository; | ||||
|  | ||||
|     /** | ||||
|      * PiggyBankController constructor. | ||||
|      */ | ||||
|     public function __construct() | ||||
|     { | ||||
|         parent::__construct(); | ||||
|         $this->middleware( | ||||
|             function ($request, $next) { | ||||
|                 /** @var User $admin */ | ||||
|                 $admin = auth()->user(); | ||||
|  | ||||
|                 $this->repository = app(PiggyBankRepositoryInterface::class); | ||||
|                 $this->repository->setUser($admin); | ||||
|  | ||||
|  | ||||
|                 return $next($request); | ||||
|             } | ||||
|         ); | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      * Delete the resource. | ||||
|      * | ||||
|      * @param PiggyBank $piggyBank | ||||
|      * | ||||
|      * @return JsonResponse | ||||
|      */ | ||||
|     public function delete(PiggyBank $piggyBank): JsonResponse | ||||
|     { | ||||
|         $this->repository->destroy($piggyBank); | ||||
|  | ||||
|         return response()->json([], 204); | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      * List all of them. | ||||
|      * | ||||
|      * @param Request $request | ||||
|      * | ||||
|      * @return JsonResponse] | ||||
|      */ | ||||
|     public function index(Request $request): JsonResponse | ||||
|     { | ||||
|         // create some objects: | ||||
|         $manager = new Manager; | ||||
|         $baseUrl = $request->getSchemeAndHttpHost() . '/api/v1'; | ||||
|  | ||||
|         // types to get, page size: | ||||
|         $pageSize = (int)app('preferences')->getForUser(auth()->user(), 'listPageSize', 50)->data; | ||||
|  | ||||
|         // get list of budgets. Count it and split it. | ||||
|         $collection = $this->repository->getPiggyBanks(); | ||||
|         $count      = $collection->count(); | ||||
|         $piggyBanks = $collection->slice(($this->parameters->get('page') - 1) * $pageSize, $pageSize); | ||||
|  | ||||
|         // make paginator: | ||||
|         $paginator = new LengthAwarePaginator($piggyBanks, $count, $pageSize, $this->parameters->get('page')); | ||||
|         $paginator->setPath(route('api.v1.piggy_banks.index') . $this->buildParams()); | ||||
|  | ||||
|         // present to user. | ||||
|         $manager->setSerializer(new JsonApiSerializer($baseUrl)); | ||||
|         $resource = new FractalCollection($piggyBanks, new PiggyBankTransformer($this->parameters), 'piggy_banks'); | ||||
|         $resource->setPaginator(new IlluminatePaginatorAdapter($paginator)); | ||||
|  | ||||
|         return response()->json($manager->createData($resource)->toArray())->header('Content-Type', 'application/vnd.api+json'); | ||||
|  | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      * List single resource. | ||||
|      * | ||||
|      * @param Request   $request | ||||
|      * @param PiggyBank $piggyBank | ||||
|      * | ||||
|      * @return JsonResponse | ||||
|      */ | ||||
|     public function show(Request $request, PiggyBank $piggyBank): JsonResponse | ||||
|     { | ||||
|         $manager = new Manager(); | ||||
|         // add include parameter: | ||||
|         $include = $request->get('include') ?? ''; | ||||
|         $manager->parseIncludes($include); | ||||
|  | ||||
|         $baseUrl = $request->getSchemeAndHttpHost() . '/api/v1'; | ||||
|         $manager->setSerializer(new JsonApiSerializer($baseUrl)); | ||||
|  | ||||
|         $resource = new Item($piggyBank, new PiggyBankTransformer($this->parameters), 'piggy_banks'); | ||||
|  | ||||
|         return response()->json($manager->createData($resource)->toArray())->header('Content-Type', 'application/vnd.api+json'); | ||||
|  | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      * Store new object. | ||||
|      * | ||||
|      * @param PiggyBankRequest $request | ||||
|      * | ||||
|      * @return JsonResponse | ||||
|      * @throws FireflyException | ||||
|      */ | ||||
|     public function store(PiggyBankRequest $request): JsonResponse | ||||
|     { | ||||
|         $piggyBank = $this->repository->store($request->getAll()); | ||||
|         if (null !== $piggyBank) { | ||||
|             $manager = new Manager(); | ||||
|             $baseUrl = $request->getSchemeAndHttpHost() . '/api/v1'; | ||||
|             $manager->setSerializer(new JsonApiSerializer($baseUrl)); | ||||
|  | ||||
|             $resource = new Item($piggyBank, new PiggyBankTransformer($this->parameters), 'piggy_banks'); | ||||
|  | ||||
|             return response()->json($manager->createData($resource)->toArray())->header('Content-Type', 'application/vnd.api+json'); | ||||
|         } | ||||
|         throw new FireflyException('Could not store new piggy bank.'); // @codeCoverageIgnore | ||||
|  | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      * Update piggy bank. | ||||
|      * | ||||
|      * @param PiggyBankRequest $request | ||||
|      * @param PiggyBank        $piggyBank | ||||
|      * | ||||
|      * @return JsonResponse | ||||
|      */ | ||||
|     public function update(PiggyBankRequest $request, PiggyBank $piggyBank): JsonResponse | ||||
|     { | ||||
|         $piggyBank = $this->repository->update($piggyBank, $request->getAll()); | ||||
|         $manager   = new Manager(); | ||||
|         $baseUrl   = $request->getSchemeAndHttpHost() . '/api/v1'; | ||||
|         $manager->setSerializer(new JsonApiSerializer($baseUrl)); | ||||
|  | ||||
|         $resource = new Item($piggyBank, new PiggyBankTransformer($this->parameters), 'piggy_banks'); | ||||
|  | ||||
|         return response()->json($manager->createData($resource)->toArray())->header('Content-Type', 'application/vnd.api+json'); | ||||
|  | ||||
|     } | ||||
| } | ||||
							
								
								
									
										145
									
								
								app/Api/V1/Controllers/PreferenceController.php
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										145
									
								
								app/Api/V1/Controllers/PreferenceController.php
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,145 @@ | ||||
| <?php | ||||
| /** | ||||
|  * PreferencesController.php | ||||
|  * Copyright (c) 2018 thegrumpydictator@gmail.com | ||||
|  * | ||||
|  * This file is part of Firefly III. | ||||
|  * | ||||
|  * Firefly III is free software: you can redistribute it and/or modify | ||||
|  * it under the terms of the GNU General Public License as published by | ||||
|  * the Free Software Foundation, either version 3 of the License, or | ||||
|  * (at your option) any later version. | ||||
|  * | ||||
|  * Firefly III is distributed in the hope that it will be useful, | ||||
|  * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||||
|  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the | ||||
|  * GNU General Public License for more details. | ||||
|  * | ||||
|  * You should have received a copy of the GNU General Public License | ||||
|  * along with Firefly III. If not, see <http://www.gnu.org/licenses/>. | ||||
|  */ | ||||
|  | ||||
| declare(strict_types=1); | ||||
|  | ||||
| namespace FireflyIII\Api\V1\Controllers; | ||||
|  | ||||
| use FireflyIII\Api\V1\Requests\PreferenceRequest; | ||||
| use FireflyIII\Models\Preference; | ||||
| use FireflyIII\Transformers\PreferenceTransformer; | ||||
| use FireflyIII\User; | ||||
| use Illuminate\Http\JsonResponse; | ||||
| use Illuminate\Http\Request; | ||||
| use Illuminate\Support\Collection; | ||||
| use League\Fractal\Manager; | ||||
| use League\Fractal\Resource\Collection as FractalCollection; | ||||
| use League\Fractal\Resource\Item; | ||||
| use League\Fractal\Serializer\JsonApiSerializer; | ||||
|  | ||||
| /** | ||||
|  * | ||||
|  * Class PreferenceController | ||||
|  */ | ||||
| class PreferenceController extends Controller | ||||
| { | ||||
|     /** | ||||
|      * List all of them. | ||||
|      * | ||||
|      * @param Request $request | ||||
|      * | ||||
|      * @return JsonResponse] | ||||
|      */ | ||||
|     public function index(Request $request): JsonResponse | ||||
|     { | ||||
|         /** @var User $user */ | ||||
|         $user        = auth()->user(); | ||||
|         $available   = [ | ||||
|             'language', 'customFiscalYear', 'fiscalYearStart', 'currencyPreference', | ||||
|             'transaction_journal_optional_fields', 'frontPageAccounts', 'viewRange', | ||||
|             'listPageSize, twoFactorAuthEnabled', | ||||
|         ]; | ||||
|         $preferences = new Collection; | ||||
|         foreach ($available as $name) { | ||||
|             $pref = app('preferences')->getForUser($user, $name); | ||||
|             if (null !== $pref) { | ||||
|                 $preferences->push($pref); | ||||
|             } | ||||
|         } | ||||
|  | ||||
|         // create some objects: | ||||
|         $manager = new Manager; | ||||
|         $baseUrl = $request->getSchemeAndHttpHost() . '/api/v1'; | ||||
|  | ||||
|         // present to user. | ||||
|         $manager->setSerializer(new JsonApiSerializer($baseUrl)); | ||||
|         $resource = new FractalCollection($preferences, new PreferenceTransformer($this->parameters), 'preferences'); | ||||
|  | ||||
|         return response()->json($manager->createData($resource)->toArray())->header('Content-Type', 'application/vnd.api+json'); | ||||
|  | ||||
|  | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      * List single resource. | ||||
|      * | ||||
|      * @param Request    $request | ||||
|      * @param Preference $preference | ||||
|      * | ||||
|      * @return JsonResponse | ||||
|      */ | ||||
|     public function show(Request $request, Preference $preference): JsonResponse | ||||
|     { | ||||
|         // create some objects: | ||||
|         $manager = new Manager; | ||||
|         $baseUrl = $request->getSchemeAndHttpHost() . '/api/v1'; | ||||
|  | ||||
|         // present to user. | ||||
|         $manager->setSerializer(new JsonApiSerializer($baseUrl)); | ||||
|         $resource = new Item($preference, new PreferenceTransformer($this->parameters), 'preferences'); | ||||
|  | ||||
|         return response()->json($manager->createData($resource)->toArray())->header('Content-Type', 'application/vnd.api+json'); | ||||
|  | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      * Update a preference. | ||||
|      * | ||||
|      * @param PreferenceRequest $request | ||||
|      * @param Preference        $preference | ||||
|      * | ||||
|      * @return JsonResponse | ||||
|      * @SuppressWarnings(PHPMD.CyclomaticComplexity) | ||||
|      */ | ||||
|     public function update(PreferenceRequest $request, Preference $preference): JsonResponse | ||||
|     { | ||||
|  | ||||
|         $data     = $request->getAll(); | ||||
|         $newValue = $data['data']; | ||||
|         switch ($preference->name) { | ||||
|             default: | ||||
|                 break; | ||||
|             case 'transaction_journal_optional_fields': | ||||
|             case 'frontPageAccounts': | ||||
|                 $newValue = explode(',', $data['data']); | ||||
|                 break; | ||||
|             case 'listPageSize': | ||||
|                 $newValue = (int)$data['data']; | ||||
|                 break; | ||||
|             case 'customFiscalYear': | ||||
|             case 'twoFactorAuthEnabled': | ||||
|                 $newValue = 1 === (int)$data['data']; | ||||
|                 break; | ||||
|         } | ||||
|         $result = app('preferences')->set($preference->name, $newValue); | ||||
|  | ||||
|         // create some objects: | ||||
|         $manager = new Manager; | ||||
|         $baseUrl = $request->getSchemeAndHttpHost() . '/api/v1'; | ||||
|  | ||||
|         // present to user. | ||||
|         $manager->setSerializer(new JsonApiSerializer($baseUrl)); | ||||
|         $resource = new Item($result, new PreferenceTransformer($this->parameters), 'preferences'); | ||||
|  | ||||
|         return response()->json($manager->createData($resource)->toArray())->header('Content-Type', 'application/vnd.api+json'); | ||||
|  | ||||
|     } | ||||
| } | ||||
							
								
								
									
										180
									
								
								app/Api/V1/Controllers/RecurrenceController.php
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										180
									
								
								app/Api/V1/Controllers/RecurrenceController.php
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,180 @@ | ||||
| <?php | ||||
| /** | ||||
|  * RecurrenceController.php | ||||
|  * Copyright (c) 2018 thegrumpydictator@gmail.com | ||||
|  * | ||||
|  * This file is part of Firefly III. | ||||
|  * | ||||
|  * Firefly III is free software: you can redistribute it and/or modify | ||||
|  * it under the terms of the GNU General Public License as published by | ||||
|  * the Free Software Foundation, either version 3 of the License, or | ||||
|  * (at your option) any later version. | ||||
|  * | ||||
|  * Firefly III is distributed in the hope that it will be useful, | ||||
|  * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||||
|  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the | ||||
|  * GNU General Public License for more details. | ||||
|  * | ||||
|  * You should have received a copy of the GNU General Public License | ||||
|  * along with Firefly III. If not, see <http://www.gnu.org/licenses/>. | ||||
|  */ | ||||
|  | ||||
| declare(strict_types=1); | ||||
|  | ||||
| namespace FireflyIII\Api\V1\Controllers; | ||||
|  | ||||
| use FireflyIII\Api\V1\Requests\RecurrenceRequest; | ||||
| use FireflyIII\Models\Recurrence; | ||||
| use FireflyIII\Repositories\Recurring\RecurringRepositoryInterface; | ||||
| use FireflyIII\Transformers\RecurrenceTransformer; | ||||
| use FireflyIII\User; | ||||
| use Illuminate\Http\JsonResponse; | ||||
| use Illuminate\Http\Request; | ||||
| use Illuminate\Pagination\LengthAwarePaginator; | ||||
| use League\Fractal\Manager; | ||||
| use League\Fractal\Pagination\IlluminatePaginatorAdapter; | ||||
| use League\Fractal\Resource\Collection as FractalCollection; | ||||
| use League\Fractal\Resource\Item; | ||||
| use League\Fractal\Serializer\JsonApiSerializer; | ||||
|  | ||||
| /** | ||||
|  * Class RecurrenceController | ||||
|  */ | ||||
| class RecurrenceController extends Controller | ||||
| { | ||||
|     /** @var RecurringRepositoryInterface The recurring transaction repository */ | ||||
|     private $repository; | ||||
|  | ||||
|     /** | ||||
|      * RecurrenceController constructor. | ||||
|      */ | ||||
|     public function __construct() | ||||
|     { | ||||
|         parent::__construct(); | ||||
|         $this->middleware( | ||||
|             function ($request, $next) { | ||||
|                 /** @var User $user */ | ||||
|                 $user = auth()->user(); | ||||
|  | ||||
|                 /** @var RecurringRepositoryInterface repository */ | ||||
|                 $this->repository = app(RecurringRepositoryInterface::class); | ||||
|                 $this->repository->setUser($user); | ||||
|  | ||||
|                 return $next($request); | ||||
|             } | ||||
|         ); | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      * Delete the resource. | ||||
|      * | ||||
|      * @param Recurrence $recurrence | ||||
|      * | ||||
|      * @return JsonResponse | ||||
|      */ | ||||
|     public function delete(Recurrence $recurrence): JsonResponse | ||||
|     { | ||||
|         $this->repository->destroy($recurrence); | ||||
|  | ||||
|         return response()->json([], 204); | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      * List all of them. | ||||
|      * | ||||
|      * @param Request $request | ||||
|      * | ||||
|      * @return JsonResponse] | ||||
|      */ | ||||
|     public function index(Request $request): JsonResponse | ||||
|     { | ||||
|         // create some objects: | ||||
|         $manager = new Manager; | ||||
|         $baseUrl = $request->getSchemeAndHttpHost() . '/api/v1'; | ||||
|  | ||||
|         // types to get, page size: | ||||
|         $pageSize = (int)app('preferences')->getForUser(auth()->user(), 'listPageSize', 50)->data; | ||||
|  | ||||
|         // get list of budgets. Count it and split it. | ||||
|         $collection = $this->repository->getAll(); | ||||
|         $count      = $collection->count(); | ||||
|         $piggyBanks = $collection->slice(($this->parameters->get('page') - 1) * $pageSize, $pageSize); | ||||
|  | ||||
|         // make paginator: | ||||
|         $paginator = new LengthAwarePaginator($piggyBanks, $count, $pageSize, $this->parameters->get('page')); | ||||
|         $paginator->setPath(route('api.v1.recurrences.index') . $this->buildParams()); | ||||
|  | ||||
|         // present to user. | ||||
|         $manager->setSerializer(new JsonApiSerializer($baseUrl)); | ||||
|         $resource = new FractalCollection($piggyBanks, new RecurrenceTransformer($this->parameters), 'recurrences'); | ||||
|         $resource->setPaginator(new IlluminatePaginatorAdapter($paginator)); | ||||
|  | ||||
|         return response()->json($manager->createData($resource)->toArray())->header('Content-Type', 'application/vnd.api+json'); | ||||
|  | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      * List single resource. | ||||
|      * | ||||
|      * @param Request    $request | ||||
|      * @param Recurrence $recurrence | ||||
|      * | ||||
|      * @return JsonResponse | ||||
|      */ | ||||
|     public function show(Request $request, Recurrence $recurrence): JsonResponse | ||||
|     { | ||||
|         $manager = new Manager(); | ||||
|         // add include parameter: | ||||
|         $include = $request->get('include') ?? ''; | ||||
|         $manager->parseIncludes($include); | ||||
|  | ||||
|         $baseUrl = $request->getSchemeAndHttpHost() . '/api/v1'; | ||||
|         $manager->setSerializer(new JsonApiSerializer($baseUrl)); | ||||
|  | ||||
|         $resource = new Item($recurrence, new RecurrenceTransformer($this->parameters), 'recurrences'); | ||||
|  | ||||
|         return response()->json($manager->createData($resource)->toArray())->header('Content-Type', 'application/vnd.api+json'); | ||||
|  | ||||
|  | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      * Store new object. | ||||
|      * | ||||
|      * @param RecurrenceRequest $request | ||||
|      * | ||||
|      * @return JsonResponse | ||||
|      */ | ||||
|     public function store(RecurrenceRequest $request): JsonResponse | ||||
|     { | ||||
|         $recurrence = $this->repository->store($request->getAll()); | ||||
|         $manager    = new Manager(); | ||||
|         $baseUrl    = $request->getSchemeAndHttpHost() . '/api/v1'; | ||||
|         $manager->setSerializer(new JsonApiSerializer($baseUrl)); | ||||
|         $resource = new Item($recurrence, new RecurrenceTransformer($this->parameters), 'recurrences'); | ||||
|  | ||||
|         return response()->json($manager->createData($resource)->toArray())->header('Content-Type', 'application/vnd.api+json'); | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      * Update single recurrence. | ||||
|      * | ||||
|      * @param RecurrenceRequest $request | ||||
|      * @param Recurrence        $recurrence | ||||
|      * | ||||
|      * @return JsonResponse | ||||
|      */ | ||||
|     public function update(RecurrenceRequest $request, Recurrence $recurrence): JsonResponse | ||||
|     { | ||||
|         $data     = $request->getAll(); | ||||
|         $category = $this->repository->update($recurrence, $data); | ||||
|         $manager  = new Manager(); | ||||
|         $baseUrl  = $request->getSchemeAndHttpHost() . '/api/v1'; | ||||
|         $manager->setSerializer(new JsonApiSerializer($baseUrl)); | ||||
|  | ||||
|         $resource = new Item($category, new RecurrenceTransformer($this->parameters), 'recurrences'); | ||||
|  | ||||
|         return response()->json($manager->createData($resource)->toArray())->header('Content-Type', 'application/vnd.api+json'); | ||||
|  | ||||
|     } | ||||
| } | ||||
							
								
								
									
										178
									
								
								app/Api/V1/Controllers/RuleController.php
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										178
									
								
								app/Api/V1/Controllers/RuleController.php
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,178 @@ | ||||
| <?php | ||||
| /** | ||||
|  * RuleController.php | ||||
|  * Copyright (c) 2018 thegrumpydictator@gmail.com | ||||
|  * | ||||
|  * This file is part of Firefly III. | ||||
|  * | ||||
|  * Firefly III is free software: you can redistribute it and/or modify | ||||
|  * it under the terms of the GNU General Public License as published by | ||||
|  * the Free Software Foundation, either version 3 of the License, or | ||||
|  * (at your option) any later version. | ||||
|  * | ||||
|  * Firefly III is distributed in the hope that it will be useful, | ||||
|  * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||||
|  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the | ||||
|  * GNU General Public License for more details. | ||||
|  * | ||||
|  * You should have received a copy of the GNU General Public License | ||||
|  * along with Firefly III. If not, see <http://www.gnu.org/licenses/>. | ||||
|  */ | ||||
|  | ||||
| declare(strict_types=1); | ||||
|  | ||||
| namespace FireflyIII\Api\V1\Controllers; | ||||
|  | ||||
| use FireflyIII\Api\V1\Requests\RuleRequest; | ||||
| use FireflyIII\Models\Rule; | ||||
| use FireflyIII\Repositories\Rule\RuleRepositoryInterface; | ||||
| use FireflyIII\Transformers\RuleTransformer; | ||||
| use FireflyIII\User; | ||||
| use Illuminate\Http\JsonResponse; | ||||
| use Illuminate\Http\Request; | ||||
| use Illuminate\Pagination\LengthAwarePaginator; | ||||
| use League\Fractal\Manager; | ||||
| use League\Fractal\Pagination\IlluminatePaginatorAdapter; | ||||
| use League\Fractal\Resource\Collection as FractalCollection; | ||||
| use League\Fractal\Resource\Item; | ||||
| use League\Fractal\Serializer\JsonApiSerializer; | ||||
|  | ||||
| /** | ||||
|  * Class RuleController | ||||
|  */ | ||||
| class RuleController extends Controller | ||||
| { | ||||
|     /** @var RuleRepositoryInterface The rule repository */ | ||||
|     private $ruleRepository; | ||||
|  | ||||
|     /** | ||||
|      * RuleController constructor. | ||||
|      */ | ||||
|     public function __construct() | ||||
|     { | ||||
|         parent::__construct(); | ||||
|         $this->middleware( | ||||
|             function ($request, $next) { | ||||
|                 /** @var User $user */ | ||||
|                 $user = auth()->user(); | ||||
|  | ||||
|                 $this->ruleRepository = app(RuleRepositoryInterface::class); | ||||
|                 $this->ruleRepository->setUser($user); | ||||
|  | ||||
|                 return $next($request); | ||||
|             } | ||||
|         ); | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      * Delete the resource. | ||||
|      * | ||||
|      * @param Rule $rule | ||||
|      * | ||||
|      * @return JsonResponse | ||||
|      */ | ||||
|     public function delete(Rule $rule): JsonResponse | ||||
|     { | ||||
|         $this->ruleRepository->destroy($rule); | ||||
|  | ||||
|         return response()->json([], 204); | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      * List all of them. | ||||
|      * | ||||
|      * @param Request $request | ||||
|      * | ||||
|      * @return JsonResponse] | ||||
|      */ | ||||
|     public function index(Request $request): JsonResponse | ||||
|     { | ||||
|         // create some objects: | ||||
|         $manager = new Manager; | ||||
|         $baseUrl = $request->getSchemeAndHttpHost() . '/api/v1'; | ||||
|  | ||||
|         // types to get, page size: | ||||
|         $pageSize = (int)app('preferences')->getForUser(auth()->user(), 'listPageSize', 50)->data; | ||||
|  | ||||
|         // get list of budgets. Count it and split it. | ||||
|         $collection = $this->ruleRepository->getAll(); | ||||
|         $count      = $collection->count(); | ||||
|         $rules      = $collection->slice(($this->parameters->get('page') - 1) * $pageSize, $pageSize); | ||||
|  | ||||
|         // make paginator: | ||||
|         $paginator = new LengthAwarePaginator($rules, $count, $pageSize, $this->parameters->get('page')); | ||||
|         $paginator->setPath(route('api.v1.piggy_banks.index') . $this->buildParams()); | ||||
|  | ||||
|         // present to user. | ||||
|         $manager->setSerializer(new JsonApiSerializer($baseUrl)); | ||||
|         $resource = new FractalCollection($rules, new RuleTransformer($this->parameters), 'rules'); | ||||
|         $resource->setPaginator(new IlluminatePaginatorAdapter($paginator)); | ||||
|  | ||||
|         return response()->json($manager->createData($resource)->toArray())->header('Content-Type', 'application/vnd.api+json'); | ||||
|  | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      * List single resource. | ||||
|      * | ||||
|      * @param Request $request | ||||
|      * @param Rule    $rule | ||||
|      * | ||||
|      * @return JsonResponse | ||||
|      */ | ||||
|     public function show(Request $request, Rule $rule): JsonResponse | ||||
|     { | ||||
|         $manager = new Manager(); | ||||
|         // add include parameter: | ||||
|         $include = $request->get('include') ?? ''; | ||||
|         $manager->parseIncludes($include); | ||||
|  | ||||
|         $baseUrl = $request->getSchemeAndHttpHost() . '/api/v1'; | ||||
|         $manager->setSerializer(new JsonApiSerializer($baseUrl)); | ||||
|  | ||||
|         $resource = new Item($rule, new RuleTransformer($this->parameters), 'rules'); | ||||
|  | ||||
|         return response()->json($manager->createData($resource)->toArray())->header('Content-Type', 'application/vnd.api+json'); | ||||
|  | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      * Store new object. | ||||
|      * | ||||
|      * @param RuleRequest $request | ||||
|      * | ||||
|      * @return JsonResponse | ||||
|      */ | ||||
|     public function store(RuleRequest $request): JsonResponse | ||||
|     { | ||||
|         $rule    = $this->ruleRepository->store($request->getAll()); | ||||
|         $manager = new Manager(); | ||||
|         $baseUrl = $request->getSchemeAndHttpHost() . '/api/v1'; | ||||
|         $manager->setSerializer(new JsonApiSerializer($baseUrl)); | ||||
|  | ||||
|         $resource = new Item($rule, new RuleTransformer($this->parameters), 'rules'); | ||||
|  | ||||
|         return response()->json($manager->createData($resource)->toArray())->header('Content-Type', 'application/vnd.api+json'); | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      * Update a rule. | ||||
|      * | ||||
|      * @param RuleRequest $request | ||||
|      * @param Rule        $rule | ||||
|      * | ||||
|      * @return JsonResponse | ||||
|      */ | ||||
|     public function update(RuleRequest $request, Rule $rule): JsonResponse | ||||
|     { | ||||
|         $rule    = $this->ruleRepository->update($rule, $request->getAll()); | ||||
|         $manager = new Manager(); | ||||
|         $baseUrl = $request->getSchemeAndHttpHost() . '/api/v1'; | ||||
|         $manager->setSerializer(new JsonApiSerializer($baseUrl)); | ||||
|  | ||||
|         $resource = new Item($rule, new RuleTransformer($this->parameters), 'rules'); | ||||
|  | ||||
|         return response()->json($manager->createData($resource)->toArray())->header('Content-Type', 'application/vnd.api+json'); | ||||
|  | ||||
|     } | ||||
| } | ||||
							
								
								
									
										179
									
								
								app/Api/V1/Controllers/RuleGroupController.php
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										179
									
								
								app/Api/V1/Controllers/RuleGroupController.php
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,179 @@ | ||||
| <?php | ||||
| /** | ||||
|  * RuleGroupController.php | ||||
|  * Copyright (c) 2018 thegrumpydictator@gmail.com | ||||
|  * | ||||
|  * This file is part of Firefly III. | ||||
|  * | ||||
|  * Firefly III is free software: you can redistribute it and/or modify | ||||
|  * it under the terms of the GNU General Public License as published by | ||||
|  * the Free Software Foundation, either version 3 of the License, or | ||||
|  * (at your option) any later version. | ||||
|  * | ||||
|  * Firefly III is distributed in the hope that it will be useful, | ||||
|  * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||||
|  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the | ||||
|  * GNU General Public License for more details. | ||||
|  * | ||||
|  * You should have received a copy of the GNU General Public License | ||||
|  * along with Firefly III. If not, see <http://www.gnu.org/licenses/>. | ||||
|  */ | ||||
|  | ||||
| declare(strict_types=1); | ||||
|  | ||||
| namespace FireflyIII\Api\V1\Controllers; | ||||
|  | ||||
| use FireflyIII\Api\V1\Requests\RuleGroupRequest; | ||||
| use FireflyIII\Models\RuleGroup; | ||||
| use FireflyIII\Repositories\RuleGroup\RuleGroupRepositoryInterface; | ||||
| use FireflyIII\Transformers\RuleGroupTransformer; | ||||
| use FireflyIII\User; | ||||
| use Illuminate\Http\JsonResponse; | ||||
| use Illuminate\Http\Request; | ||||
| use Illuminate\Pagination\LengthAwarePaginator; | ||||
| use League\Fractal\Manager; | ||||
| use League\Fractal\Pagination\IlluminatePaginatorAdapter; | ||||
| use League\Fractal\Resource\Collection as FractalCollection; | ||||
| use League\Fractal\Resource\Item; | ||||
| use League\Fractal\Serializer\JsonApiSerializer; | ||||
|  | ||||
|  | ||||
| /** | ||||
|  * Class RuleGroupController | ||||
|  */ | ||||
| class RuleGroupController extends Controller | ||||
| { | ||||
|     /** @var RuleGroupRepositoryInterface The rule group repository */ | ||||
|     private $ruleGroupRepository; | ||||
|  | ||||
|     /** | ||||
|      * RuleGroupController constructor. | ||||
|      */ | ||||
|     public function __construct() | ||||
|     { | ||||
|         parent::__construct(); | ||||
|         $this->middleware( | ||||
|             function ($request, $next) { | ||||
|                 /** @var User $user */ | ||||
|                 $user = auth()->user(); | ||||
|  | ||||
|                 $this->ruleGroupRepository = app(RuleGroupRepositoryInterface::class); | ||||
|                 $this->ruleGroupRepository->setUser($user); | ||||
|  | ||||
|                 return $next($request); | ||||
|             } | ||||
|         ); | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      * Delete the resource. | ||||
|      * | ||||
|      * @param RuleGroup $ruleGroup | ||||
|      * | ||||
|      * @return JsonResponse | ||||
|      */ | ||||
|     public function delete(RuleGroup $ruleGroup): JsonResponse | ||||
|     { | ||||
|         $this->ruleGroupRepository->destroy($ruleGroup, null); | ||||
|  | ||||
|         return response()->json([], 204); | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      * List all of them. | ||||
|      * | ||||
|      * @param Request $request | ||||
|      * | ||||
|      * @return JsonResponse] | ||||
|      */ | ||||
|     public function index(Request $request): JsonResponse | ||||
|     { | ||||
|         // create some objects: | ||||
|         $manager = new Manager; | ||||
|         $baseUrl = $request->getSchemeAndHttpHost() . '/api/v1'; | ||||
|  | ||||
|         // types to get, page size: | ||||
|         $pageSize = (int)app('preferences')->getForUser(auth()->user(), 'listPageSize', 50)->data; | ||||
|  | ||||
|         // get list of budgets. Count it and split it. | ||||
|         $collection = $this->ruleGroupRepository->get(); | ||||
|         $count      = $collection->count(); | ||||
|         $ruleGroups = $collection->slice(($this->parameters->get('page') - 1) * $pageSize, $pageSize); | ||||
|  | ||||
|         // make paginator: | ||||
|         $paginator = new LengthAwarePaginator($ruleGroups, $count, $pageSize, $this->parameters->get('page')); | ||||
|         $paginator->setPath(route('api.v1.rule_groups.index') . $this->buildParams()); | ||||
|  | ||||
|         // present to user. | ||||
|         $manager->setSerializer(new JsonApiSerializer($baseUrl)); | ||||
|         $resource = new FractalCollection($ruleGroups, new RuleGroupTransformer($this->parameters), 'rule_groups'); | ||||
|         $resource->setPaginator(new IlluminatePaginatorAdapter($paginator)); | ||||
|  | ||||
|         return response()->json($manager->createData($resource)->toArray())->header('Content-Type', 'application/vnd.api+json'); | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      * List single resource. | ||||
|      * | ||||
|      * @param Request   $request | ||||
|      * @param RuleGroup $ruleGroup | ||||
|      * | ||||
|      * @return JsonResponse | ||||
|      */ | ||||
|     public function show(Request $request, RuleGroup $ruleGroup): JsonResponse | ||||
|     { | ||||
|         $manager = new Manager(); | ||||
|         // add include parameter: | ||||
|         $include = $request->get('include') ?? ''; | ||||
|         $manager->parseIncludes($include); | ||||
|  | ||||
|         $baseUrl = $request->getSchemeAndHttpHost() . '/api/v1'; | ||||
|         $manager->setSerializer(new JsonApiSerializer($baseUrl)); | ||||
|  | ||||
|         $resource = new Item($ruleGroup, new RuleGroupTransformer($this->parameters), 'rule_groups'); | ||||
|  | ||||
|         return response()->json($manager->createData($resource)->toArray())->header('Content-Type', 'application/vnd.api+json'); | ||||
|  | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      * Store new object. | ||||
|      * | ||||
|      * @param RuleGroupRequest $request | ||||
|      * | ||||
|      * @return JsonResponse | ||||
|      */ | ||||
|     public function store(RuleGroupRequest $request): JsonResponse | ||||
|     { | ||||
|         $ruleGroup = $this->ruleGroupRepository->store($request->getAll()); | ||||
|         $manager   = new Manager(); | ||||
|         $baseUrl   = $request->getSchemeAndHttpHost() . '/api/v1'; | ||||
|         $manager->setSerializer(new JsonApiSerializer($baseUrl)); | ||||
|  | ||||
|         $resource = new Item($ruleGroup, new RuleGroupTransformer($this->parameters), 'rule_groups'); | ||||
|  | ||||
|         return response()->json($manager->createData($resource)->toArray())->header('Content-Type', 'application/vnd.api+json'); | ||||
|  | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      * Update a rule group. | ||||
|      * | ||||
|      * @param RuleGroupRequest $request | ||||
|      * @param RuleGroup        $ruleGroup | ||||
|      * | ||||
|      * @return JsonResponse | ||||
|      */ | ||||
|     public function update(RuleGroupRequest $request, RuleGroup $ruleGroup): JsonResponse | ||||
|     { | ||||
|         $ruleGroup = $this->ruleGroupRepository->update($ruleGroup, $request->getAll()); | ||||
|         $manager   = new Manager(); | ||||
|         $baseUrl   = $request->getSchemeAndHttpHost() . '/api/v1'; | ||||
|         $manager->setSerializer(new JsonApiSerializer($baseUrl)); | ||||
|  | ||||
|         $resource = new Item($ruleGroup, new RuleGroupTransformer($this->parameters), 'rule_groups'); | ||||
|  | ||||
|         return response()->json($manager->createData($resource)->toArray())->header('Content-Type', 'application/vnd.api+json'); | ||||
|  | ||||
|     } | ||||
| } | ||||
| @@ -1,5 +1,5 @@ | ||||
| <?php | ||||
| declare(strict_types=1); | ||||
|  | ||||
| /** | ||||
|  * TransactionController.php | ||||
|  * Copyright (c) 2018 thegrumpydictator@gmail.com | ||||
| @@ -20,10 +20,12 @@ declare(strict_types=1); | ||||
|  * along with Firefly III. If not, see <http://www.gnu.org/licenses/>. | ||||
|  */ | ||||
|  | ||||
| declare(strict_types=1); | ||||
|  | ||||
| namespace FireflyIII\Api\V1\Controllers; | ||||
|  | ||||
| use FireflyIII\Api\V1\Requests\TransactionRequest; | ||||
| use FireflyIII\Exceptions\FireflyException; | ||||
| use FireflyIII\Helpers\Collector\JournalCollectorInterface; | ||||
| use FireflyIII\Helpers\Filter\InternalTransferFilter; | ||||
| use FireflyIII\Helpers\Filter\NegativeAmountFilter; | ||||
| @@ -32,37 +34,39 @@ use FireflyIII\Models\Transaction; | ||||
| use FireflyIII\Models\TransactionType; | ||||
| use FireflyIII\Repositories\Journal\JournalRepositoryInterface; | ||||
| use FireflyIII\Transformers\TransactionTransformer; | ||||
| use FireflyIII\User; | ||||
| use Illuminate\Http\JsonResponse; | ||||
| use Illuminate\Http\Request; | ||||
| use Illuminate\Support\Collection; | ||||
| use League\Fractal\Manager; | ||||
| use League\Fractal\Pagination\IlluminatePaginatorAdapter; | ||||
| use League\Fractal\Resource\Collection as FractalCollection; | ||||
| use League\Fractal\Serializer\JsonApiSerializer; | ||||
| use Log; | ||||
| use Preferences; | ||||
|  | ||||
| /** | ||||
|  * Class TransactionController | ||||
|  * @SuppressWarnings(PHPMD.CouplingBetweenObjects) | ||||
|  */ | ||||
| class TransactionController extends Controller | ||||
| { | ||||
|  | ||||
|     /** @var JournalRepositoryInterface */ | ||||
|     /** @var JournalRepositoryInterface The journal repository */ | ||||
|     private $repository; | ||||
|  | ||||
|     /** | ||||
|      * TransactionController constructor. | ||||
|      * | ||||
|      * @throws \FireflyIII\Exceptions\FireflyException | ||||
|      */ | ||||
|     public function __construct() | ||||
|     { | ||||
|         parent::__construct(); | ||||
|         $this->middleware( | ||||
|             function ($request, $next) { | ||||
|                 /** @var User $admin */ | ||||
|                 $admin = auth()->user(); | ||||
|  | ||||
|                 /** @var JournalRepositoryInterface repository */ | ||||
|                 $this->repository = app(JournalRepositoryInterface::class); | ||||
|                 $this->repository->setUser(auth()->user()); | ||||
|                 $this->repository->setUser($admin); | ||||
|  | ||||
|                 return $next($request); | ||||
|             } | ||||
| @@ -74,9 +78,9 @@ class TransactionController extends Controller | ||||
|      * | ||||
|      * @param  \FireflyIII\Models\Transaction $transaction | ||||
|      * | ||||
|      * @return \Illuminate\Http\Response | ||||
|      * @return JsonResponse | ||||
|      */ | ||||
|     public function delete(Transaction $transaction) | ||||
|     public function delete(Transaction $transaction): JsonResponse | ||||
|     { | ||||
|         $journal = $transaction->transactionJournal; | ||||
|         $this->repository->destroy($journal); | ||||
| @@ -85,33 +89,32 @@ class TransactionController extends Controller | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      * Show all transactions. | ||||
|      * | ||||
|      * @param Request $request | ||||
|      * | ||||
|      * @return \Illuminate\Http\JsonResponse | ||||
|      * @return JsonResponse | ||||
|      */ | ||||
|     public function index(Request $request) | ||||
|     public function index(Request $request): JsonResponse | ||||
|     { | ||||
|         $pageSize = (int)Preferences::getForUser(auth()->user(), 'listPageSize', 50)->data; | ||||
|  | ||||
|         // read type from URI | ||||
|         $type = $request->get('type') ?? 'default'; | ||||
|         $pageSize = (int)app('preferences')->getForUser(auth()->user(), 'listPageSize', 50)->data; | ||||
|         $type     = $request->get('type') ?? 'default'; | ||||
|         $this->parameters->set('type', $type); | ||||
|  | ||||
|         // types to get, page size: | ||||
|         $types = $this->mapTypes($this->parameters->get('type')); | ||||
|  | ||||
|         $types   = $this->mapTypes($this->parameters->get('type')); | ||||
|         $manager = new Manager(); | ||||
|         $baseUrl = $request->getSchemeAndHttpHost() . '/api/v1'; | ||||
|         $manager->setSerializer(new JsonApiSerializer($baseUrl)); | ||||
|  | ||||
|         // collect transactions using the journal collector | ||||
|         /** @var User $admin */ | ||||
|         $admin = auth()->user(); | ||||
|         /** @var JournalCollectorInterface $collector */ | ||||
|         $collector = app(JournalCollectorInterface::class); | ||||
|         $collector->setUser(auth()->user()); | ||||
|         $collector->setUser($admin); | ||||
|         $collector->withOpposingAccount()->withCategoryInformation()->withBudgetInformation(); | ||||
|         $collector->setAllAssetAccounts(); | ||||
|  | ||||
|         // remove internal transfer filter: | ||||
|         if (\in_array(TransactionType::TRANSFER, $types)) { | ||||
|         if (\in_array(TransactionType::TRANSFER, $types, true)) { | ||||
|             $collector->removeFilter(InternalTransferFilter::class); | ||||
|         } | ||||
|  | ||||
| @@ -124,7 +127,6 @@ class TransactionController extends Controller | ||||
|         $paginator->setPath(route('api.v1.transactions.index') . $this->buildParams()); | ||||
|         $transactions = $paginator->getCollection(); | ||||
|  | ||||
|  | ||||
|         $resource = new FractalCollection($transactions, new TransactionTransformer($this->parameters), 'transactions'); | ||||
|         $resource->setPaginator(new IlluminatePaginatorAdapter($paginator)); | ||||
|  | ||||
| @@ -133,19 +135,23 @@ class TransactionController extends Controller | ||||
|  | ||||
|  | ||||
|     /** | ||||
|      * Show a single transaction. | ||||
|      * | ||||
|      * @param Request     $request | ||||
|      * @param Transaction $transaction | ||||
|      * @param string      $include | ||||
|      * | ||||
|      * @return \Illuminate\Http\JsonResponse | ||||
|      * @return JsonResponse | ||||
|      */ | ||||
|     public function show(Request $request, Transaction $transaction) | ||||
|     public function show(Request $request, Transaction $transaction, string $include = null): JsonResponse | ||||
|     { | ||||
|         $manager = new Manager(); | ||||
|         $baseUrl = $request->getSchemeAndHttpHost() . '/api/v1'; | ||||
|         $manager->setSerializer(new JsonApiSerializer($baseUrl)); | ||||
|  | ||||
|         // add include parameter: | ||||
|         $include = $request->get('include') ?? ''; | ||||
|         $include = $include ?? ''; | ||||
|         $include = $request->get('include') ?? $include; | ||||
|         $manager->parseIncludes($include); | ||||
|  | ||||
|         // collect transactions using the journal collector | ||||
| @@ -171,13 +177,16 @@ class TransactionController extends Controller | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      * Store a new transaction. | ||||
|      * | ||||
|      * @param TransactionRequest         $request | ||||
|      * | ||||
|      * @param JournalRepositoryInterface $repository | ||||
|      * | ||||
|      * @return \Illuminate\Http\JsonResponse | ||||
|      * @throws FireflyException | ||||
|      * @return JsonResponse | ||||
|      */ | ||||
|     public function store(TransactionRequest $request, JournalRepositoryInterface $repository) | ||||
|     public function store(TransactionRequest $request, JournalRepositoryInterface $repository): JsonResponse | ||||
|     { | ||||
|         $data         = $request->getAll(); | ||||
|         $data['user'] = auth()->user()->id; | ||||
| @@ -215,23 +224,21 @@ class TransactionController extends Controller | ||||
|  | ||||
|  | ||||
|     /** | ||||
|      * Update a transaction. | ||||
|      * | ||||
|      * @param TransactionRequest         $request | ||||
|      * @param JournalRepositoryInterface $repository | ||||
|      * @param Transaction                $transaction | ||||
|      * | ||||
|      * @return \Illuminate\Http\JsonResponse | ||||
|      * @return JsonResponse | ||||
|      */ | ||||
|     public function update(TransactionRequest $request, JournalRepositoryInterface $repository, Transaction $transaction) | ||||
|     public function update(TransactionRequest $request, JournalRepositoryInterface $repository, Transaction $transaction): JsonResponse | ||||
|     { | ||||
|         $data         = $request->getAll(); | ||||
|         $data['user'] = auth()->user()->id; | ||||
|  | ||||
|         Log::debug('Inside transaction update'); | ||||
|  | ||||
|         $journal = $repository->update($transaction->transactionJournal, $data); | ||||
|  | ||||
|         $manager = new Manager(); | ||||
|         $baseUrl = $request->getSchemeAndHttpHost() . '/api/v1'; | ||||
|         $journal      = $repository->update($transaction->transactionJournal, $data); | ||||
|         $manager      = new Manager(); | ||||
|         $baseUrl      = $request->getSchemeAndHttpHost() . '/api/v1'; | ||||
|         $manager->setSerializer(new JsonApiSerializer($baseUrl)); | ||||
|  | ||||
|         // add include parameter: | ||||
| @@ -263,72 +270,38 @@ class TransactionController extends Controller | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      * All the types you can request. | ||||
|      * | ||||
|      * @param string $type | ||||
|      * | ||||
|      * @return array | ||||
|      */ | ||||
|     private function mapTypes(string $type): array | ||||
|     { | ||||
|         $types = [ | ||||
|             'all'             => [ | ||||
|                 TransactionType::WITHDRAWAL, | ||||
|                 TransactionType::DEPOSIT, | ||||
|                 TransactionType::TRANSFER, | ||||
|                 TransactionType::OPENING_BALANCE, | ||||
|                 TransactionType::RECONCILIATION, | ||||
|             ], | ||||
|             'withdrawal'      => [ | ||||
|                 TransactionType::WITHDRAWAL, | ||||
|             ], | ||||
|             'withdrawals'     => [ | ||||
|                 TransactionType::WITHDRAWAL, | ||||
|             ], | ||||
|             'expense'         => [ | ||||
|                 TransactionType::WITHDRAWAL, | ||||
|             ], | ||||
|             'income'          => [ | ||||
|                 TransactionType::DEPOSIT, | ||||
|             ], | ||||
|             'deposit'         => [ | ||||
|                 TransactionType::DEPOSIT, | ||||
|             ], | ||||
|             'deposits'        => [ | ||||
|                 TransactionType::DEPOSIT, | ||||
|             ], | ||||
|             'transfer'        => [ | ||||
|                 TransactionType::TRANSFER, | ||||
|             ], | ||||
|             'transfers'       => [ | ||||
|                 TransactionType::TRANSFER, | ||||
|             ], | ||||
|             'opening_balance' => [ | ||||
|                 TransactionType::OPENING_BALANCE, | ||||
|             ], | ||||
|             'reconciliation'  => [ | ||||
|                 TransactionType::RECONCILIATION, | ||||
|             ], | ||||
|             'reconciliations' => [ | ||||
|                 TransactionType::RECONCILIATION, | ||||
|             ], | ||||
|             'special'         => [ | ||||
|                 TransactionType::OPENING_BALANCE, | ||||
|                 TransactionType::RECONCILIATION, | ||||
|             ], | ||||
|             'specials'        => [ | ||||
|                 TransactionType::OPENING_BALANCE, | ||||
|                 TransactionType::RECONCILIATION, | ||||
|             ], | ||||
|             'default'         => [ | ||||
|                 TransactionType::WITHDRAWAL, | ||||
|                 TransactionType::DEPOSIT, | ||||
|                 TransactionType::TRANSFER, | ||||
|             ], | ||||
|         $types  = [ | ||||
|             'all'             => [TransactionType::WITHDRAWAL, TransactionType::DEPOSIT, TransactionType::TRANSFER, TransactionType::OPENING_BALANCE, | ||||
|                                   TransactionType::RECONCILIATION,], | ||||
|             'withdrawal'      => [TransactionType::WITHDRAWAL,], | ||||
|             'withdrawals'     => [TransactionType::WITHDRAWAL,], | ||||
|             'expense'         => [TransactionType::WITHDRAWAL,], | ||||
|             'income'          => [TransactionType::DEPOSIT,], | ||||
|             'deposit'         => [TransactionType::DEPOSIT,], | ||||
|             'deposits'        => [TransactionType::DEPOSIT,], | ||||
|             'transfer'        => [TransactionType::TRANSFER,], | ||||
|             'transfers'       => [TransactionType::TRANSFER,], | ||||
|             'opening_balance' => [TransactionType::OPENING_BALANCE,], | ||||
|             'reconciliation'  => [TransactionType::RECONCILIATION,], | ||||
|             'reconciliations' => [TransactionType::RECONCILIATION,], | ||||
|             'special'         => [TransactionType::OPENING_BALANCE, TransactionType::RECONCILIATION,], | ||||
|             'specials'        => [TransactionType::OPENING_BALANCE, TransactionType::RECONCILIATION,], | ||||
|             'default'         => [TransactionType::WITHDRAWAL, TransactionType::DEPOSIT, TransactionType::TRANSFER,], | ||||
|         ]; | ||||
|         $return = $types['default']; | ||||
|         if (isset($types[$type])) { | ||||
|             return $types[$type]; | ||||
|             $return = $types[$type]; | ||||
|         } | ||||
|  | ||||
|         return $types['default']; // @codeCoverageIgnore | ||||
|         return $return; | ||||
|  | ||||
|     } | ||||
| } | ||||
|   | ||||
| @@ -1,5 +1,5 @@ | ||||
| <?php | ||||
| declare(strict_types=1); | ||||
|  | ||||
| /** | ||||
|  * UserController.php | ||||
|  * Copyright (c) 2018 thegrumpydictator@gmail.com | ||||
| @@ -20,6 +20,7 @@ declare(strict_types=1); | ||||
|  * along with Firefly III. If not, see <http://www.gnu.org/licenses/>. | ||||
|  */ | ||||
|  | ||||
| declare(strict_types=1); | ||||
|  | ||||
| namespace FireflyIII\Api\V1\Controllers; | ||||
|  | ||||
| @@ -28,6 +29,7 @@ use FireflyIII\Exceptions\FireflyException; | ||||
| use FireflyIII\Repositories\User\UserRepositoryInterface; | ||||
| use FireflyIII\Transformers\UserTransformer; | ||||
| use FireflyIII\User; | ||||
| use Illuminate\Http\JsonResponse; | ||||
| use Illuminate\Http\Request; | ||||
| use Illuminate\Pagination\LengthAwarePaginator; | ||||
| use League\Fractal\Manager; | ||||
| @@ -35,22 +37,21 @@ use League\Fractal\Pagination\IlluminatePaginatorAdapter; | ||||
| use League\Fractal\Resource\Collection as FractalCollection; | ||||
| use League\Fractal\Resource\Item; | ||||
| use League\Fractal\Serializer\JsonApiSerializer; | ||||
| use Preferences; | ||||
|  | ||||
|  | ||||
| /** | ||||
|  * Class UserController | ||||
|  * Class UserController. | ||||
|  * | ||||
|  * @SuppressWarnings(PHPMD.CouplingBetweenObjects) | ||||
|  */ | ||||
| class UserController extends Controller | ||||
| { | ||||
|  | ||||
|     /** @var UserRepositoryInterface */ | ||||
|     /** @var UserRepositoryInterface The user repository */ | ||||
|     private $repository; | ||||
|  | ||||
|     /** | ||||
|      * UserController constructor. | ||||
|      * | ||||
|      * @throws \FireflyIII\Exceptions\FireflyException | ||||
|      */ | ||||
|     public function __construct() | ||||
|     { | ||||
| @@ -70,12 +71,14 @@ class UserController extends Controller | ||||
|      * | ||||
|      * @param  \FireflyIII\User $user | ||||
|      * | ||||
|      * @return \Illuminate\Http\Response | ||||
|      * @return JsonResponse | ||||
|      * @throws FireflyException | ||||
|      */ | ||||
|     public function delete(User $user) | ||||
|     public function delete(User $user): JsonResponse | ||||
|     { | ||||
|         if (auth()->user()->hasRole('owner')) { | ||||
|         /** @var User $admin */ | ||||
|         $admin = auth()->user(); | ||||
|         if ($this->repository->hasRole($admin, 'owner')) { | ||||
|             $this->repository->destroy($user); | ||||
|  | ||||
|             return response()->json([], 204); | ||||
| @@ -88,12 +91,12 @@ class UserController extends Controller | ||||
|      * | ||||
|      * @param Request $request | ||||
|      * | ||||
|      * @return \Illuminate\Http\JsonResponse | ||||
|      * @return JsonResponse | ||||
|      */ | ||||
|     public function index(Request $request) | ||||
|     public function index(Request $request): JsonResponse | ||||
|     { | ||||
|         // user preferences | ||||
|         $pageSize = (int)Preferences::getForUser(auth()->user(), 'listPageSize', 50)->data; | ||||
|         $pageSize = (int)app('preferences')->getForUser(auth()->user(), 'listPageSize', 50)->data; | ||||
|  | ||||
|         // make manager | ||||
|         $manager = new Manager(); | ||||
| @@ -117,12 +120,14 @@ class UserController extends Controller | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      * Show a single user. | ||||
|      * | ||||
|      * @param Request $request | ||||
|      * @param User    $user | ||||
|      * | ||||
|      * @return \Illuminate\Http\JsonResponse | ||||
|      * @return JsonResponse | ||||
|      */ | ||||
|     public function show(Request $request, User $user) | ||||
|     public function show(Request $request, User $user): JsonResponse | ||||
|     { | ||||
|         // make manager | ||||
|         $manager = new Manager(); | ||||
| @@ -140,11 +145,13 @@ class UserController extends Controller | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      * Store a new user. | ||||
|      * | ||||
|      * @param UserRequest $request | ||||
|      * | ||||
|      * @return \Illuminate\Http\JsonResponse | ||||
|      * @return JsonResponse | ||||
|      */ | ||||
|     public function store(UserRequest $request) | ||||
|     public function store(UserRequest $request): JsonResponse | ||||
|     { | ||||
|         $data = $request->getAll(); | ||||
|         $user = $this->repository->store($data); | ||||
| @@ -165,12 +172,14 @@ class UserController extends Controller | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      * Update a user. | ||||
|      * | ||||
|      * @param UserRequest $request | ||||
|      * @param User        $user | ||||
|      * | ||||
|      * @return \Illuminate\Http\JsonResponse | ||||
|      * @return JsonResponse | ||||
|      */ | ||||
|     public function update(UserRequest $request, User $user) | ||||
|     public function update(UserRequest $request, User $user): JsonResponse | ||||
|     { | ||||
|         $data = $request->getAll(); | ||||
|         $user = $this->repository->update($user, $data); | ||||
|   | ||||
| @@ -1,5 +1,5 @@ | ||||
| <?php | ||||
| declare(strict_types=1); | ||||
|  | ||||
| /** | ||||
|  * AccountRequest.php | ||||
|  * Copyright (c) 2018 thegrumpydictator@gmail.com | ||||
| @@ -20,9 +20,9 @@ declare(strict_types=1); | ||||
|  * along with Firefly III. If not, see <http://www.gnu.org/licenses/>. | ||||
|  */ | ||||
|  | ||||
| declare(strict_types=1); | ||||
|  | ||||
| namespace FireflyIII\Api\V1\Requests; | ||||
|  | ||||
| /** | ||||
|  * Class AccountRequest | ||||
|  */ | ||||
| @@ -30,6 +30,8 @@ class AccountRequest extends Request | ||||
| { | ||||
|  | ||||
|     /** | ||||
|      * Authorize logged in users. | ||||
|      * | ||||
|      * @return bool | ||||
|      */ | ||||
|     public function authorize(): bool | ||||
| @@ -39,6 +41,8 @@ class AccountRequest extends Request | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      * Get all data from the request. | ||||
|      * | ||||
|      * @return array | ||||
|      */ | ||||
|     public function getAll(): array | ||||
| @@ -66,6 +70,8 @@ class AccountRequest extends Request | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      * The rules that the incoming request must be matched against. | ||||
|      * | ||||
|      * @return array | ||||
|      */ | ||||
|     public function rules(): array | ||||
|   | ||||
							
								
								
									
										97
									
								
								app/Api/V1/Requests/AttachmentRequest.php
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										97
									
								
								app/Api/V1/Requests/AttachmentRequest.php
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,97 @@ | ||||
| <?php | ||||
| /** | ||||
|  * AttachmentRequest.php | ||||
|  * Copyright (c) 2018 thegrumpydictator@gmail.com | ||||
|  * | ||||
|  * This file is part of Firefly III. | ||||
|  * | ||||
|  * Firefly III is free software: you can redistribute it and/or modify | ||||
|  * it under the terms of the GNU General Public License as published by | ||||
|  * the Free Software Foundation, either version 3 of the License, or | ||||
|  * (at your option) any later version. | ||||
|  * | ||||
|  * Firefly III is distributed in the hope that it will be useful, | ||||
|  * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||||
|  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the | ||||
|  * GNU General Public License for more details. | ||||
|  * | ||||
|  * You should have received a copy of the GNU General Public License | ||||
|  * along with Firefly III. If not, see <http://www.gnu.org/licenses/>. | ||||
|  */ | ||||
|  | ||||
| declare(strict_types=1); | ||||
|  | ||||
| namespace FireflyIII\Api\V1\Requests; | ||||
|  | ||||
| use FireflyIII\Models\Bill; | ||||
| use FireflyIII\Models\ImportJob; | ||||
| use FireflyIII\Models\TransactionJournal; | ||||
| use FireflyIII\Rules\IsValidAttachmentModel; | ||||
|  | ||||
| /** | ||||
|  * Class AttachmentRequest | ||||
|  */ | ||||
| class AttachmentRequest extends Request | ||||
| { | ||||
|     /** | ||||
|      * Authorize logged in users. | ||||
|      * | ||||
|      * @return bool | ||||
|      */ | ||||
|     public function authorize(): bool | ||||
|     { | ||||
|         // Only allow authenticated users | ||||
|         return auth()->check(); | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      * Get all data from the request. | ||||
|      * | ||||
|      * @return array | ||||
|      */ | ||||
|     public function getAll(): array | ||||
|     { | ||||
|         return [ | ||||
|             'filename' => $this->string('filename'), | ||||
|             'title'    => $this->string('title'), | ||||
|             'notes'    => $this->string('notes'), | ||||
|             'model'    => $this->string('model'), | ||||
|             'model_id' => $this->integer('model_id'), | ||||
|         ]; | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      * The rules that the incoming request must be matched against. | ||||
|      * | ||||
|      * @return array | ||||
|      */ | ||||
|     public function rules(): array | ||||
|     { | ||||
|         $models = implode( | ||||
|             ',', [ | ||||
|                    Bill::class, | ||||
|                    ImportJob::class, | ||||
|                    TransactionJournal::class, | ||||
|                ] | ||||
|         ); | ||||
|         $model  = $this->string('model'); | ||||
|         $rules  = [ | ||||
|             'filename' => 'required|between:1,255', | ||||
|             'title'    => 'between:1,255', | ||||
|             'notes'    => 'between:1,65000', | ||||
|             'model'    => sprintf('required|in:%s', $models), | ||||
|             'model_id' => ['required', 'numeric', new IsValidAttachmentModel($model)], | ||||
|         ]; | ||||
|         switch ($this->method()) { | ||||
|             default: | ||||
|                 break; | ||||
|             case 'PUT': | ||||
|             case 'PATCH': | ||||
|                 unset($rules['model'], $rules['model_id']); | ||||
|                 $rules['filename'] = 'between:1,255'; | ||||
|                 break; | ||||
|         } | ||||
|  | ||||
|         return $rules; | ||||
|     } | ||||
| } | ||||
							
								
								
									
										75
									
								
								app/Api/V1/Requests/AvailableBudgetRequest.php
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										75
									
								
								app/Api/V1/Requests/AvailableBudgetRequest.php
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,75 @@ | ||||
| <?php | ||||
| /** | ||||
|  * AvailableBudgetRequest.php | ||||
|  * Copyright (c) 2018 thegrumpydictator@gmail.com | ||||
|  * | ||||
|  * This file is part of Firefly III. | ||||
|  * | ||||
|  * Firefly III is free software: you can redistribute it and/or modify | ||||
|  * it under the terms of the GNU General Public License as published by | ||||
|  * the Free Software Foundation, either version 3 of the License, or | ||||
|  * (at your option) any later version. | ||||
|  * | ||||
|  * Firefly III is distributed in the hope that it will be useful, | ||||
|  * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||||
|  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the | ||||
|  * GNU General Public License for more details. | ||||
|  * | ||||
|  * You should have received a copy of the GNU General Public License | ||||
|  * along with Firefly III. If not, see <http://www.gnu.org/licenses/>. | ||||
|  */ | ||||
|  | ||||
| declare(strict_types=1); | ||||
|  | ||||
| namespace FireflyIII\Api\V1\Requests; | ||||
|  | ||||
| /** | ||||
|  * Class AvailableBudgetRequest | ||||
|  */ | ||||
| class AvailableBudgetRequest extends Request | ||||
| { | ||||
|     /** | ||||
|      * Authorize logged in users. | ||||
|      * | ||||
|      * @return bool | ||||
|      */ | ||||
|     public function authorize(): bool | ||||
|     { | ||||
|         // Only allow authenticated users | ||||
|         return auth()->check(); | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      * Get all data from the request. | ||||
|      * | ||||
|      * @return array | ||||
|      */ | ||||
|     public function getAll(): array | ||||
|     { | ||||
|         return [ | ||||
|             'transaction_currency_id' => $this->integer('transaction_currency_id'), | ||||
|             'amount'                  => $this->string('amount'), | ||||
|             'start_date'              => $this->date('start_date'), | ||||
|             'end_date'                => $this->date('end_date'), | ||||
|         ]; | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      * The rules that the incoming request must be matched against. | ||||
|      * | ||||
|      * @return array | ||||
|      */ | ||||
|     public function rules(): array | ||||
|     { | ||||
|         $rules = [ | ||||
|             'transaction_currency_id' => 'required|numeric|exists:transaction_currencies,id', | ||||
|             'amount'                  => 'required|numeric|more:0', | ||||
|             'start_date'              => 'required|date|before:end_date', | ||||
|             'end_date'                => 'required|date|after:start_date', | ||||
|         ]; | ||||
|  | ||||
|         return $rules; | ||||
|     } | ||||
|  | ||||
|  | ||||
| } | ||||
| @@ -1,5 +1,5 @@ | ||||
| <?php | ||||
| declare(strict_types=1); | ||||
|  | ||||
| /** | ||||
|  * BillRequest.php | ||||
|  * Copyright (c) 2018 thegrumpydictator@gmail.com | ||||
| @@ -20,6 +20,7 @@ declare(strict_types=1); | ||||
|  * along with Firefly III. If not, see <http://www.gnu.org/licenses/>. | ||||
|  */ | ||||
|  | ||||
| declare(strict_types=1); | ||||
|  | ||||
| namespace FireflyIII\Api\V1\Requests; | ||||
|  | ||||
| @@ -32,6 +33,8 @@ class BillRequest extends Request | ||||
| { | ||||
|  | ||||
|     /** | ||||
|      * Authorize logged in users. | ||||
|      * | ||||
|      * @return bool | ||||
|      */ | ||||
|     public function authorize(): bool | ||||
| @@ -41,6 +44,8 @@ class BillRequest extends Request | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      * Get all data from the request. | ||||
|      * | ||||
|      * @return array | ||||
|      */ | ||||
|     public function getAll(): array | ||||
| @@ -63,6 +68,8 @@ class BillRequest extends Request | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      * The rules that the incoming request must be matched against. | ||||
|      * | ||||
|      * @return array | ||||
|      */ | ||||
|     public function rules(): array | ||||
| @@ -85,8 +92,8 @@ class BillRequest extends Request | ||||
|                 break; | ||||
|             case 'PUT': | ||||
|             case 'PATCH': | ||||
|                 $bill           = $this->route()->parameter('bill'); | ||||
|                 $rules['name']  .= ',' . $bill->id; | ||||
|                 $bill          = $this->route()->parameter('bill'); | ||||
|                 $rules['name'] .= ',' . $bill->id; | ||||
|                 break; | ||||
|         } | ||||
|  | ||||
| @@ -108,7 +115,7 @@ class BillRequest extends Request | ||||
|                 $min  = (float)($data['amount_min'] ?? 0); | ||||
|                 $max  = (float)($data['amount_max'] ?? 0); | ||||
|                 if ($min > $max) { | ||||
|                     $validator->errors()->add('amount_min', trans('validation.amount_min_over_max')); | ||||
|                     $validator->errors()->add('amount_min', (string)trans('validation.amount_min_over_max')); | ||||
|                 } | ||||
|             } | ||||
|         ); | ||||
|   | ||||
							
								
								
									
										83
									
								
								app/Api/V1/Requests/BudgetLimitRequest.php
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										83
									
								
								app/Api/V1/Requests/BudgetLimitRequest.php
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,83 @@ | ||||
| <?php | ||||
| /** | ||||
|  * BudgetLimitRequest.php | ||||
|  * Copyright (c) 2018 thegrumpydictator@gmail.com | ||||
|  * | ||||
|  * This file is part of Firefly III. | ||||
|  * | ||||
|  * Firefly III is free software: you can redistribute it and/or modify | ||||
|  * it under the terms of the GNU General Public License as published by | ||||
|  * the Free Software Foundation, either version 3 of the License, or | ||||
|  * (at your option) any later version. | ||||
|  * | ||||
|  * Firefly III is distributed in the hope that it will be useful, | ||||
|  * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||||
|  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the | ||||
|  * GNU General Public License for more details. | ||||
|  * | ||||
|  * You should have received a copy of the GNU General Public License | ||||
|  * along with Firefly III. If not, see <http://www.gnu.org/licenses/>. | ||||
|  */ | ||||
|  | ||||
| declare(strict_types=1); | ||||
|  | ||||
| namespace FireflyIII\Api\V1\Requests; | ||||
|  | ||||
|  | ||||
| /** | ||||
|  * Class BudgetLimitRequest | ||||
|  */ | ||||
| class BudgetLimitRequest extends Request | ||||
| { | ||||
|     /** | ||||
|      * Authorize logged in users. | ||||
|      * | ||||
|      * @return bool | ||||
|      */ | ||||
|     public function authorize(): bool | ||||
|     { | ||||
|         // Only allow authenticated users | ||||
|         return auth()->check(); | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      * Get all data from the request. | ||||
|      * | ||||
|      * @return array | ||||
|      */ | ||||
|     public function getAll(): array | ||||
|     { | ||||
|         return [ | ||||
|             'budget_id'  => $this->integer('budget_id'), | ||||
|             'start_date' => $this->date('start_date'), | ||||
|             'end_date'   => $this->date('end_date'), | ||||
|             'amount'     => $this->string('amount'), | ||||
|         ]; | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      * The rules that the incoming request must be matched against. | ||||
|      * | ||||
|      * @return array | ||||
|      */ | ||||
|     public function rules(): array | ||||
|     { | ||||
|         $rules = [ | ||||
|             'budget_id'  => 'required|exists:budgets,id|belongsToUser:budgets,id', | ||||
|             'start_date' => 'required|before:end_date|date', | ||||
|             'end_date'   => 'required|after:start_date|date', | ||||
|             'amount'     => 'required|more:0', | ||||
|         ]; | ||||
|         switch ($this->method()) { | ||||
|             default: | ||||
|                 break; | ||||
|             case 'PUT': | ||||
|             case 'PATCH': | ||||
|                 $rules['budget_id'] = 'required|exists:budgets,id|belongsToUser:budgets,id'; | ||||
|                 break; | ||||
|         } | ||||
|  | ||||
|         return $rules; | ||||
|     } | ||||
|  | ||||
| } | ||||
							
								
								
									
										82
									
								
								app/Api/V1/Requests/BudgetRequest.php
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										82
									
								
								app/Api/V1/Requests/BudgetRequest.php
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,82 @@ | ||||
| <?php | ||||
| /** | ||||
|  * BudgetRequest.php | ||||
|  * Copyright (c) 2018 thegrumpydictator@gmail.com | ||||
|  * | ||||
|  * This file is part of Firefly III. | ||||
|  * | ||||
|  * Firefly III is free software: you can redistribute it and/or modify | ||||
|  * it under the terms of the GNU General Public License as published by | ||||
|  * the Free Software Foundation, either version 3 of the License, or | ||||
|  * (at your option) any later version. | ||||
|  * | ||||
|  * Firefly III is distributed in the hope that it will be useful, | ||||
|  * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||||
|  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the | ||||
|  * GNU General Public License for more details. | ||||
|  * | ||||
|  * You should have received a copy of the GNU General Public License | ||||
|  * along with Firefly III. If not, see <http://www.gnu.org/licenses/>. | ||||
|  */ | ||||
|  | ||||
| declare(strict_types=1); | ||||
|  | ||||
| namespace FireflyIII\Api\V1\Requests; | ||||
|  | ||||
| use FireflyIII\Models\Budget; | ||||
|  | ||||
| /** | ||||
|  * Class BudgetRequest | ||||
|  */ | ||||
| class BudgetRequest extends Request | ||||
| { | ||||
|     /** | ||||
|      * Authorize logged in users. | ||||
|      * | ||||
|      * @return bool | ||||
|      */ | ||||
|     public function authorize(): bool | ||||
|     { | ||||
|         // Only allow authenticated users | ||||
|         return auth()->check(); | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      * Get all data from the request. | ||||
|      * | ||||
|      * @return array | ||||
|      */ | ||||
|     public function getAll(): array | ||||
|     { | ||||
|         return [ | ||||
|             'name'   => $this->string('name'), | ||||
|             'active' => $this->boolean('active'), | ||||
|             'order'  => 0, | ||||
|         ]; | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      * The rules that the incoming request must be matched against. | ||||
|      * | ||||
|      * @return array | ||||
|      */ | ||||
|     public function rules(): array | ||||
|     { | ||||
|         $rules = [ | ||||
|             'name'   => 'required|between:1,100|uniqueObjectForUser:budgets,name', | ||||
|             'active' => 'required|boolean', | ||||
|         ]; | ||||
|         switch ($this->method()) { | ||||
|             default: | ||||
|                 break; | ||||
|             case 'PUT': | ||||
|             case 'PATCH': | ||||
|                 /** @var Budget $budget */ | ||||
|                 $budget        = $this->route()->parameter('budget'); | ||||
|                 $rules['name'] = sprintf('required|between:1,100|uniqueObjectForUser:budgets,name,%d', $budget->id); | ||||
|                 break; | ||||
|         } | ||||
|  | ||||
|         return $rules; | ||||
|     } | ||||
| } | ||||
							
								
								
									
										81
									
								
								app/Api/V1/Requests/CategoryRequest.php
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										81
									
								
								app/Api/V1/Requests/CategoryRequest.php
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,81 @@ | ||||
| <?php | ||||
| /** | ||||
|  * CategoryRequest.php | ||||
|  * Copyright (c) 2018 thegrumpydictator@gmail.com | ||||
|  * | ||||
|  * This file is part of Firefly III. | ||||
|  * | ||||
|  * Firefly III is free software: you can redistribute it and/or modify | ||||
|  * it under the terms of the GNU General Public License as published by | ||||
|  * the Free Software Foundation, either version 3 of the License, or | ||||
|  * (at your option) any later version. | ||||
|  * | ||||
|  * Firefly III is distributed in the hope that it will be useful, | ||||
|  * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||||
|  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the | ||||
|  * GNU General Public License for more details. | ||||
|  * | ||||
|  * You should have received a copy of the GNU General Public License | ||||
|  * along with Firefly III. If not, see <http://www.gnu.org/licenses/>. | ||||
|  */ | ||||
|  | ||||
| declare(strict_types=1); | ||||
|  | ||||
| namespace FireflyIII\Api\V1\Requests; | ||||
|  | ||||
| use FireflyIII\Models\Category; | ||||
|  | ||||
| /** | ||||
|  * Class CategoryRequest | ||||
|  */ | ||||
| class CategoryRequest extends Request | ||||
| { | ||||
|     /** | ||||
|      * Authorize logged in users. | ||||
|      * | ||||
|      * @return bool | ||||
|      */ | ||||
|     public function authorize(): bool | ||||
|     { | ||||
|         // Only allow authenticated users | ||||
|         return auth()->check(); | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      * Get all data from the request. | ||||
|      * | ||||
|      * @return array | ||||
|      */ | ||||
|     public function getAll(): array | ||||
|     { | ||||
|         return [ | ||||
|             'name'   => $this->string('name'), | ||||
|             'active' => $this->boolean('active'), | ||||
|         ]; | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      * The rules that the incoming request must be matched against. | ||||
|      * | ||||
|      * @return array | ||||
|      */ | ||||
|     public function rules(): array | ||||
|     { | ||||
|         $rules = [ | ||||
|             'name'   => 'required|between:1,100|uniqueObjectForUser:categories,name', | ||||
|             'active' => 'required|boolean', | ||||
|         ]; | ||||
|         switch ($this->method()) { | ||||
|             default: | ||||
|                 break; | ||||
|             case 'PUT': | ||||
|             case 'PATCH': | ||||
|                 /** @var Category $category */ | ||||
|                 $category      = $this->route()->parameter('category'); | ||||
|                 $rules['name'] = sprintf('required|between:1,100|uniqueObjectForUser:categories,name,%d', $category->id); | ||||
|                 break; | ||||
|         } | ||||
|  | ||||
|         return $rules; | ||||
|     } | ||||
| } | ||||
| @@ -30,6 +30,8 @@ namespace FireflyIII\Api\V1\Requests; | ||||
| class CurrencyRequest extends Request | ||||
| { | ||||
|     /** | ||||
|      * Authorize logged in users. | ||||
|      * | ||||
|      * @return bool | ||||
|      */ | ||||
|     public function authorize(): bool | ||||
| @@ -39,9 +41,11 @@ class CurrencyRequest extends Request | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      * Get all data from the request. | ||||
|      * | ||||
|      * @return array | ||||
|      */ | ||||
|     public function getAll() | ||||
|     public function getAll(): array | ||||
|     { | ||||
|         return [ | ||||
|             'name'           => $this->string('name'), | ||||
| @@ -53,6 +57,8 @@ class CurrencyRequest extends Request | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      * The rules that the incoming request must be matched against. | ||||
|      * | ||||
|      * @return array | ||||
|      */ | ||||
|     public function rules(): array | ||||
| @@ -62,7 +68,7 @@ class CurrencyRequest extends Request | ||||
|             'code'           => 'required|between:3,3|unique:transaction_currencies,code', | ||||
|             'symbol'         => 'required|between:1,5|unique:transaction_currencies,symbol', | ||||
|             'decimal_places' => 'required|between:0,20|numeric|min:0|max:20', | ||||
|             'default'        => 'in:true,false', | ||||
|             'default'        => 'boolean', | ||||
|         ]; | ||||
|  | ||||
|         switch ($this->method()) { | ||||
| @@ -80,4 +86,4 @@ class CurrencyRequest extends Request | ||||
|         return $rules; | ||||
|  | ||||
|     } | ||||
| } | ||||
| } | ||||
|   | ||||
							
								
								
									
										75
									
								
								app/Api/V1/Requests/JournalLinkRequest.php
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										75
									
								
								app/Api/V1/Requests/JournalLinkRequest.php
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,75 @@ | ||||
| <?php | ||||
| /** | ||||
|  * JournalLinkRequest.php | ||||
|  * Copyright (c) 2018 thegrumpydictator@gmail.com | ||||
|  * | ||||
|  * This file is part of Firefly III. | ||||
|  * | ||||
|  * Firefly III is free software: you can redistribute it and/or modify | ||||
|  * it under the terms of the GNU General Public License as published by | ||||
|  * the Free Software Foundation, either version 3 of the License, or | ||||
|  * (at your option) any later version. | ||||
|  * | ||||
|  * Firefly III is distributed in the hope that it will be useful, | ||||
|  * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||||
|  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the | ||||
|  * GNU General Public License for more details. | ||||
|  * | ||||
|  * You should have received a copy of the GNU General Public License | ||||
|  * along with Firefly III. If not, see <http://www.gnu.org/licenses/>. | ||||
|  */ | ||||
|  | ||||
| declare(strict_types=1); | ||||
|  | ||||
| namespace FireflyIII\Api\V1\Requests; | ||||
|  | ||||
|  | ||||
| /** | ||||
|  * | ||||
|  * Class JournalLinkRequest | ||||
|  */ | ||||
| class JournalLinkRequest extends Request | ||||
| { | ||||
|     /** | ||||
|      * Authorize logged in users. | ||||
|      * | ||||
|      * @return bool | ||||
|      */ | ||||
|     public function authorize(): bool | ||||
|     { | ||||
|         // Only allow authenticated users | ||||
|         return auth()->check(); | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      * Get all data from the request. | ||||
|      * | ||||
|      * @return array | ||||
|      */ | ||||
|     public function getAll(): array | ||||
|     { | ||||
|         return [ | ||||
|             'link_type_id' => $this->integer('link_type_id'), | ||||
|             'inward_id'    => $this->integer('inward_id'), | ||||
|             'outward_id'   => $this->integer('outward_id'), | ||||
|             'notes'        => $this->string('notes'), | ||||
|         ]; | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      * | ||||
|      * The rules that the incoming request must be matched against. | ||||
|      * | ||||
|      * @return array | ||||
|      */ | ||||
|     public function rules(): array | ||||
|     { | ||||
|         return [ | ||||
|             'link_type_id' => 'required|exists:link_types,id', | ||||
|             'inward_id'    => 'required|belongsToUser:transaction_journals,id', | ||||
|             'outward_id'   => 'required|belongsToUser:transaction_journals,id', | ||||
|             'notes'        => 'between:0,65000', | ||||
|         ]; | ||||
|     } | ||||
|  | ||||
| } | ||||
							
								
								
									
										91
									
								
								app/Api/V1/Requests/LinkTypeRequest.php
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										91
									
								
								app/Api/V1/Requests/LinkTypeRequest.php
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,91 @@ | ||||
| <?php | ||||
| /** | ||||
|  * LinkTypeRequest.php | ||||
|  * Copyright (c) 2018 thegrumpydictator@gmail.com | ||||
|  * | ||||
|  * This file is part of Firefly III. | ||||
|  * | ||||
|  * Firefly III is free software: you can redistribute it and/or modify | ||||
|  * it under the terms of the GNU General Public License as published by | ||||
|  * the Free Software Foundation, either version 3 of the License, or | ||||
|  * (at your option) any later version. | ||||
|  * | ||||
|  * Firefly III is distributed in the hope that it will be useful, | ||||
|  * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||||
|  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the | ||||
|  * GNU General Public License for more details. | ||||
|  * | ||||
|  * You should have received a copy of the GNU General Public License | ||||
|  * along with Firefly III. If not, see <http://www.gnu.org/licenses/>. | ||||
|  */ | ||||
|  | ||||
| declare(strict_types=1); | ||||
|  | ||||
| namespace FireflyIII\Api\V1\Requests; | ||||
|  | ||||
| use FireflyIII\Models\LinkType; | ||||
| use Illuminate\Validation\Rule; | ||||
|  | ||||
| /** | ||||
|  * | ||||
|  * Class LinkTypeRequest | ||||
|  */ | ||||
| class LinkTypeRequest extends Request | ||||
| { | ||||
|     /** | ||||
|      * Authorize logged in users. | ||||
|      * | ||||
|      * @return bool | ||||
|      */ | ||||
|     public function authorize(): bool | ||||
|     { | ||||
|         // Only allow authenticated users | ||||
|         return auth()->check(); | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      * Get all data from the request. | ||||
|      * | ||||
|      * @return array | ||||
|      */ | ||||
|     public function getAll(): array | ||||
|     { | ||||
|         return [ | ||||
|             'name'    => $this->string('name'), | ||||
|             'outward' => $this->string('outward'), | ||||
|             'inward'  => $this->string('inward'), | ||||
|         ]; | ||||
|  | ||||
|  | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      * The rules that the incoming request must be matched against. | ||||
|      * | ||||
|      * @return array | ||||
|      */ | ||||
|     public function rules(): array | ||||
|     { | ||||
|         $rules = [ | ||||
|             'name'    => 'required|unique:link_types,name|min:1', | ||||
|             'outward' => 'required|unique:link_types,outward|min:1|different:inward', | ||||
|             'inward'  => 'required|unique:link_types,inward|min:1|different:outward', | ||||
|         ]; | ||||
|  | ||||
|  | ||||
|         switch ($this->method()) { | ||||
|             default: | ||||
|                 break; | ||||
|             case 'PUT': | ||||
|             case 'PATCH': | ||||
|                 /** @var LinkType $linkType */ | ||||
|                 $linkType         = $this->route()->parameter('linkType'); | ||||
|                 $rules['name']    = ['required', Rule::unique('link_types', 'name')->ignore($linkType->id), 'min:1']; | ||||
|                 $rules['outward'] = ['required', 'different:inward', Rule::unique('link_types', 'outward')->ignore($linkType->id), 'min:1']; | ||||
|                 $rules['inward']  = ['required', 'different:outward', Rule::unique('link_types', 'inward')->ignore($linkType->id), 'min:1']; | ||||
|                 break; | ||||
|         } | ||||
|  | ||||
|         return $rules; | ||||
|     } | ||||
| } | ||||
							
								
								
									
										96
									
								
								app/Api/V1/Requests/PiggyBankRequest.php
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										96
									
								
								app/Api/V1/Requests/PiggyBankRequest.php
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,96 @@ | ||||
| <?php | ||||
| /** | ||||
|  * PiggyBankRequest.php | ||||
|  * Copyright (c) 2018 thegrumpydictator@gmail.com | ||||
|  * | ||||
|  * This file is part of Firefly III. | ||||
|  * | ||||
|  * Firefly III is free software: you can redistribute it and/or modify | ||||
|  * it under the terms of the GNU General Public License as published by | ||||
|  * the Free Software Foundation, either version 3 of the License, or | ||||
|  * (at your option) any later version. | ||||
|  * | ||||
|  * Firefly III is distributed in the hope that it will be useful, | ||||
|  * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||||
|  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the | ||||
|  * GNU General Public License for more details. | ||||
|  * | ||||
|  * You should have received a copy of the GNU General Public License | ||||
|  * along with Firefly III. If not, see <http://www.gnu.org/licenses/>. | ||||
|  */ | ||||
|  | ||||
| declare(strict_types=1); | ||||
|  | ||||
| namespace FireflyIII\Api\V1\Requests; | ||||
|  | ||||
| use FireflyIII\Models\PiggyBank; | ||||
| use FireflyIII\Rules\IsAssetAccountId; | ||||
|  | ||||
| /** | ||||
|  * | ||||
|  * Class PiggyBankRequest | ||||
|  */ | ||||
| class PiggyBankRequest extends Request | ||||
| { | ||||
|     /** | ||||
|      * Authorize logged in users. | ||||
|      * | ||||
|      * @return bool | ||||
|      */ | ||||
|     public function authorize(): bool | ||||
|     { | ||||
|         // Only allow authenticated users | ||||
|         return auth()->check(); | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      * Get all data from the request. | ||||
|      * | ||||
|      * @return array | ||||
|      */ | ||||
|     public function getAll(): array | ||||
|     { | ||||
|         return [ | ||||
|             'name'           => $this->string('name'), | ||||
|             'account_id'     => $this->integer('account_id'), | ||||
|             'targetamount'   => $this->string('target_amount'), | ||||
|             'current_amount' => $this->string('current_amount'), | ||||
|             'start_date'     => $this->date('start_date'), | ||||
|             'target_date'    => $this->date('target_date'), | ||||
|             'note'           => $this->string('notes'), | ||||
|         ]; | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      * The rules that the incoming request must be matched against. | ||||
|      * | ||||
|      * @return array | ||||
|      */ | ||||
|     public function rules(): array | ||||
|     { | ||||
|         $rules = [ | ||||
|             'name'           => 'required|between:1,255|uniquePiggyBankForUser', | ||||
|             'account_id'     => ['required', 'belongsToUser:accounts', new IsAssetAccountId], | ||||
|             'target_amount'  => 'required|numeric|more:0', | ||||
|             'current_amount' => 'numeric|more:0|lte:target_amount', | ||||
|             'start_date'     => 'date|nullable', | ||||
|             'target_date'    => 'date|nullable', | ||||
|             'notes'          => 'max:65000', | ||||
|         ]; | ||||
|  | ||||
|         switch ($this->method()) { | ||||
|             default: | ||||
|                 break; | ||||
|             case 'PUT': | ||||
|             case 'PATCH': | ||||
|                 /** @var PiggyBank $piggyBank */ | ||||
|                 $piggyBank     = $this->route()->parameter('piggyBank'); | ||||
|                 $rules['name'] = 'required|between:1,255|uniquePiggyBankForUser:' . $piggyBank->id; | ||||
|                 break; | ||||
|         } | ||||
|  | ||||
|  | ||||
|         return $rules; | ||||
|     } | ||||
|  | ||||
| } | ||||
| @@ -1,8 +1,7 @@ | ||||
| <?php | ||||
| 
 | ||||
| /** | ||||
|  * BunqId.php | ||||
|  * Copyright (c) 2017 thegrumpydictator@gmail.com | ||||
|  * PreferenceRequest.php | ||||
|  * Copyright (c) 2018 thegrumpydictator@gmail.com | ||||
|  * | ||||
|  * This file is part of Firefly III. | ||||
|  * | ||||
| @@ -19,54 +18,52 @@ | ||||
|  * You should have received a copy of the GNU General Public License | ||||
|  * along with Firefly III. If not, see <http://www.gnu.org/licenses/>. | ||||
|  */ | ||||
| 
 | ||||
| declare(strict_types=1); | ||||
| 
 | ||||
| namespace FireflyIII\Services\Bunq\Id; | ||||
| namespace FireflyIII\Api\V1\Requests; | ||||
| 
 | ||||
| use Log; | ||||
| /** | ||||
|  * Class BunqId. | ||||
|  * | ||||
|  * Class PreferenceRequest | ||||
|  */ | ||||
| class BunqId | ||||
| class PreferenceRequest extends Request | ||||
| { | ||||
|     /** @var int */ | ||||
|     private $id = 0; | ||||
| 
 | ||||
| 
 | ||||
|     /** | ||||
|      * BunqId constructor. | ||||
|      * Authorize logged in users. | ||||
|      * | ||||
|      * @param null $data | ||||
|      * @return bool | ||||
|      */ | ||||
|     public function __construct($data = null) | ||||
|     public function authorize(): bool | ||||
|     { | ||||
|         if (null !== $data) { | ||||
|             $this->id = $data['id']; | ||||
|         } | ||||
|     } | ||||
| 
 | ||||
|     /** | ||||
|      * @return int | ||||
|      */ | ||||
|     public function getId(): int | ||||
|     { | ||||
|         return $this->id; | ||||
|     } | ||||
| 
 | ||||
|     /** | ||||
|      * @param int $id | ||||
|      */ | ||||
|     public function setId(int $id) | ||||
|     { | ||||
|         $this->id = $id; | ||||
|         // Only allow authenticated users
 | ||||
|         return auth()->check(); | ||||
|     } | ||||
| 
 | ||||
|     /** | ||||
|      * Get all data from the request. | ||||
|      * | ||||
|      * @return array | ||||
|      */ | ||||
|     public function toArray(): array | ||||
|     public function getAll(): array | ||||
|     { | ||||
|         return [ | ||||
|             'id' => $this->id, | ||||
|             'data' => $this->get('data'), | ||||
|         ]; | ||||
|     } | ||||
| 
 | ||||
|     /** | ||||
|      * The rules that the incoming request must be matched against. | ||||
|      * | ||||
|      * @return array | ||||
|      */ | ||||
|     public function rules(): array | ||||
|     { | ||||
|         return [ | ||||
|             'data' => 'required|between:1,65000', | ||||
|         ]; | ||||
|     } | ||||
| 
 | ||||
| } | ||||
							
								
								
									
										203
									
								
								app/Api/V1/Requests/RecurrenceRequest.php
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										203
									
								
								app/Api/V1/Requests/RecurrenceRequest.php
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,203 @@ | ||||
| <?php | ||||
| /** | ||||
|  * RecurrenceRequest.php | ||||
|  * Copyright (c) 2018 thegrumpydictator@gmail.com | ||||
|  * | ||||
|  * This file is part of Firefly III. | ||||
|  * | ||||
|  * Firefly III is free software: you can redistribute it and/or modify | ||||
|  * it under the terms of the GNU General Public License as published by | ||||
|  * the Free Software Foundation, either version 3 of the License, or | ||||
|  * (at your option) any later version. | ||||
|  * | ||||
|  * Firefly III is distributed in the hope that it will be useful, | ||||
|  * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||||
|  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the | ||||
|  * GNU General Public License for more details. | ||||
|  * | ||||
|  * You should have received a copy of the GNU General Public License | ||||
|  * along with Firefly III. If not, see <http://www.gnu.org/licenses/>. | ||||
|  */ | ||||
|  | ||||
| declare(strict_types=1); | ||||
|  | ||||
| namespace FireflyIII\Api\V1\Requests; | ||||
|  | ||||
| use Carbon\Carbon; | ||||
| use FireflyIII\Rules\BelongsUser; | ||||
| use FireflyIII\Validation\RecurrenceValidation; | ||||
| use FireflyIII\Validation\TransactionValidation; | ||||
| use Illuminate\Validation\Validator; | ||||
|  | ||||
| /** | ||||
|  * Class RecurrenceRequest | ||||
|  */ | ||||
| class RecurrenceRequest extends Request | ||||
| { | ||||
|     use RecurrenceValidation, TransactionValidation; | ||||
|  | ||||
|     /** | ||||
|      * Authorize logged in users. | ||||
|      * | ||||
|      * @return bool | ||||
|      */ | ||||
|     public function authorize(): bool | ||||
|     { | ||||
|         // Only allow authenticated users | ||||
|         return auth()->check(); | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      * Get all data from the request. | ||||
|      * | ||||
|      * @return array | ||||
|      */ | ||||
|     public function getAll(): array | ||||
|     { | ||||
|         $return = [ | ||||
|             'recurrence'   => [ | ||||
|                 'type'         => $this->string('type'), | ||||
|                 'title'        => $this->string('title'), | ||||
|                 'description'  => $this->string('description'), | ||||
|                 'first_date'   => $this->date('first_date'), | ||||
|                 'repeat_until' => $this->date('repeat_until'), | ||||
|                 'repetitions'  => $this->integer('nr_of_repetitions'), | ||||
|                 'apply_rules'  => $this->boolean('apply_rules'), | ||||
|                 'active'       => $this->boolean('active'), | ||||
|             ], | ||||
|             'meta'         => [ | ||||
|                 'piggy_bank_id'   => $this->integer('piggy_bank_id'), | ||||
|                 'piggy_bank_name' => $this->string('piggy_bank_name'), | ||||
|                 'tags'            => explode(',', $this->string('tags')), | ||||
|             ], | ||||
|             'transactions' => $this->getTransactionData(), | ||||
|             'repetitions'  => $this->getRepetitionData(), | ||||
|         ]; | ||||
|  | ||||
|         return $return; | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      * The rules that the incoming request must be matched against. | ||||
|      * | ||||
|      * @return array | ||||
|      */ | ||||
|     public function rules(): array | ||||
|     { | ||||
|         $today = Carbon::create()->addDay(); | ||||
|  | ||||
|         return [ | ||||
|             'type'                                 => 'required|in:withdrawal,transfer,deposit', | ||||
|             'title'                                => 'required|between:1,255|uniqueObjectForUser:recurrences,title', | ||||
|             'description'                          => 'between:1,65000', | ||||
|             'first_date'                           => sprintf('required|date|after:%s', $today->format('Y-m-d')), | ||||
|             'repeat_until'                         => sprintf('date|after:%s', $today->format('Y-m-d')), | ||||
|             'nr_of_repetitions'                    => 'numeric|between:1,31', | ||||
|             'apply_rules'                          => 'required|boolean', | ||||
|             'active'                               => 'required|boolean', | ||||
|             'tags'                                 => 'between:1,64000', | ||||
|             'piggy_bank_id'                        => 'numeric', | ||||
|             'repetitions.*.type'                   => 'required|in:daily,weekly,ndom,monthly,yearly', | ||||
|             'repetitions.*.moment'                 => 'between:0,10', | ||||
|             'repetitions.*.skip'                   => 'required|numeric|between:0,31', | ||||
|             'repetitions.*.weekend'                => 'required|numeric|min:1|max:4', | ||||
|             'transactions.*.currency_id'           => 'numeric|exists:transaction_currencies,id|required_without:transactions.*.currency_code', | ||||
|             'transactions.*.currency_code'         => 'min:3|max:3|exists:transaction_currencies,code|required_without:transactions.*.currency_id', | ||||
|             'transactions.*.foreign_amount'        => 'numeric|more:0', | ||||
|             'transactions.*.foreign_currency_id'   => 'numeric|exists:transaction_currencies,id', | ||||
|             'transactions.*.foreign_currency_code' => 'min:3|max:3|exists:transaction_currencies,code', | ||||
|             'transactions.*.budget_id'             => ['mustExist:budgets,id', new BelongsUser], | ||||
|             'transactions.*.category_name'         => 'between:1,255|nullable', | ||||
|             'transactions.*.source_id'             => ['numeric', 'nullable', new BelongsUser], | ||||
|             'transactions.*.source_name'           => 'between:1,255|nullable', | ||||
|             'transactions.*.destination_id'        => ['numeric', 'nullable', new BelongsUser], | ||||
|             'transactions.*.destination_name'      => 'between:1,255|nullable', | ||||
|             'transactions.*.amount'                => 'required|numeric|more:0', | ||||
|             'transactions.*.description'           => 'required|between:1,255', | ||||
|         ]; | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      * Configure the validator instance. | ||||
|      * | ||||
|      * @param  Validator $validator | ||||
|      * | ||||
|      * @return void | ||||
|      */ | ||||
|     public function withValidator(Validator $validator): void | ||||
|     { | ||||
|         $validator->after( | ||||
|             function (Validator $validator) { | ||||
|                 $this->validateOneTransaction($validator); | ||||
|                 $this->validateOneRepetition($validator); | ||||
|                 $this->validateRecurrenceRepetition($validator); | ||||
|                 $this->validateRepetitionMoment($validator); | ||||
|                 $this->validateForeignCurrencyInformation($validator); | ||||
|                 $this->validateAccountInformation($validator); | ||||
|             } | ||||
|         ); | ||||
|     } | ||||
|  | ||||
|  | ||||
|     /** | ||||
|      * Returns the repetition data as it is found in the submitted data. | ||||
|      * | ||||
|      * @return array | ||||
|      */ | ||||
|     private function getRepetitionData(): array | ||||
|     { | ||||
|         $return = []; | ||||
|         // repetition data: | ||||
|         /** @var array $repetitions */ | ||||
|         $repetitions = $this->get('repetitions'); | ||||
|         /** @var array $repetition */ | ||||
|         foreach ($repetitions as $repetition) { | ||||
|             $return[] = [ | ||||
|                 'type'    => $repetition['type'], | ||||
|                 'moment'  => $repetition['moment'], | ||||
|                 'skip'    => (int)$repetition['skip'], | ||||
|                 'weekend' => (int)$repetition['weekend'], | ||||
|             ]; | ||||
|         } | ||||
|  | ||||
|         return $return; | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      * Returns the transaction data as it is found in the submitted data. It's a complex method according to code | ||||
|      * standards but it just has a lot of ??-statements because of the fields that may or may not exist. | ||||
|      * | ||||
|      * @return array | ||||
|      * @SuppressWarnings(PHPMD.NPathComplexity) | ||||
|      * @SuppressWarnings(PHPMD.CyclomaticComplexity) | ||||
|      */ | ||||
|     private function getTransactionData(): array | ||||
|     { | ||||
|         $return = []; | ||||
|         // transaction data: | ||||
|         /** @var array $transactions */ | ||||
|         $transactions = $this->get('transactions'); | ||||
|         /** @var array $transaction */ | ||||
|         foreach ($transactions as $transaction) { | ||||
|             $return[] = [ | ||||
|                 'amount'                => $transaction['amount'], | ||||
|                 'currency_id'           => isset($transaction['currency_id']) ? (int)$transaction['currency_id'] : null, | ||||
|                 'currency_code'         => $transaction['currency_code'] ?? null, | ||||
|                 'foreign_amount'        => $transaction['foreign_amount'] ?? null, | ||||
|                 'foreign_currency_id'   => isset($transaction['foreign_currency_id']) ? (int)$transaction['foreign_currency_id'] : null, | ||||
|                 'foreign_currency_code' => $transaction['foreign_currency_code'] ?? null, | ||||
|                 'budget_id'             => isset($transaction['budget_id']) ? (int)$transaction['budget_id'] : null, | ||||
|                 'budget_name'           => $transaction['budget_name'] ?? null, | ||||
|                 'category_id'           => isset($transaction['category_id']) ? (int)$transaction['category_id'] : null, | ||||
|                 'category_name'         => $transaction['category_name'] ?? null, | ||||
|                 'source_id'             => isset($transaction['source_id']) ? (int)$transaction['source_id'] : null, | ||||
|                 'source_name'           => isset($transaction['source_name']) ? (string)$transaction['source_name'] : null, | ||||
|                 'destination_id'        => isset($transaction['destination_id']) ? (int)$transaction['destination_id'] : null, | ||||
|                 'destination_name'      => isset($transaction['destination_name']) ? (string)$transaction['destination_name'] : null, | ||||
|                 'description'           => $transaction['description'], | ||||
|             ]; | ||||
|         } | ||||
|  | ||||
|         return $return; | ||||
|     } | ||||
| } | ||||
| @@ -1,5 +1,5 @@ | ||||
| <?php | ||||
| declare(strict_types=1); | ||||
|  | ||||
| /** | ||||
|  * Request.php | ||||
|  * Copyright (c) 2018 thegrumpydictator@gmail.com | ||||
| @@ -20,12 +20,18 @@ declare(strict_types=1); | ||||
|  * along with Firefly III. If not, see <http://www.gnu.org/licenses/>. | ||||
|  */ | ||||
|  | ||||
| declare(strict_types=1); | ||||
|  | ||||
| namespace FireflyIII\Api\V1\Requests; | ||||
|  | ||||
| use FireflyIII\Http\Requests\Request as FireflyIIIRequest; | ||||
|  | ||||
| /** | ||||
|  * Class Request. | ||||
|  * | ||||
|  * Technically speaking this class does not have to be extended like this but who knows what the future brings. | ||||
|  * | ||||
|  * @SuppressWarnings(PHPMD.NumberOfChildren) | ||||
|  */ | ||||
| class Request extends FireflyIIIRequest | ||||
| { | ||||
|   | ||||
							
								
								
									
										85
									
								
								app/Api/V1/Requests/RuleGroupRequest.php
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										85
									
								
								app/Api/V1/Requests/RuleGroupRequest.php
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,85 @@ | ||||
| <?php | ||||
| /** | ||||
|  * RuleGroupRequest.php | ||||
|  * Copyright (c) 2018 thegrumpydictator@gmail.com | ||||
|  * | ||||
|  * This file is part of Firefly III. | ||||
|  * | ||||
|  * Firefly III is free software: you can redistribute it and/or modify | ||||
|  * it under the terms of the GNU General Public License as published by | ||||
|  * the Free Software Foundation, either version 3 of the License, or | ||||
|  * (at your option) any later version. | ||||
|  * | ||||
|  * Firefly III is distributed in the hope that it will be useful, | ||||
|  * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||||
|  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the | ||||
|  * GNU General Public License for more details. | ||||
|  * | ||||
|  * You should have received a copy of the GNU General Public License | ||||
|  * along with Firefly III. If not, see <http://www.gnu.org/licenses/>. | ||||
|  */ | ||||
|  | ||||
| declare(strict_types=1); | ||||
|  | ||||
| namespace FireflyIII\Api\V1\Requests; | ||||
|  | ||||
| use FireflyIII\Models\RuleGroup; | ||||
|  | ||||
|  | ||||
| /** | ||||
|  * | ||||
|  * Class RuleGroupRequest | ||||
|  */ | ||||
| class RuleGroupRequest extends Request | ||||
| { | ||||
|     /** | ||||
|      * Authorize logged in users. | ||||
|      * | ||||
|      * @return bool | ||||
|      */ | ||||
|     public function authorize(): bool | ||||
|     { | ||||
|         // Only allow authenticated users | ||||
|         return auth()->check(); | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      * Get all data from the request. | ||||
|      * | ||||
|      * @return array | ||||
|      */ | ||||
|     public function getAll(): array | ||||
|     { | ||||
|         return [ | ||||
|             'title'       => $this->string('title'), | ||||
|             'description' => $this->string('description'), | ||||
|             'active'      => $this->boolean('active'), | ||||
|         ]; | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      * The rules that the incoming request must be matched against. | ||||
|      * | ||||
|      * @return array | ||||
|      */ | ||||
|     public function rules(): array | ||||
|     { | ||||
|         $rules = [ | ||||
|             'title'       => 'required|between:1,100|uniqueObjectForUser:rule_groups,title', | ||||
|             'description' => 'between:1,5000|nullable', | ||||
|             'active'      => 'required|boolean', | ||||
|         ]; | ||||
|         switch ($this->method()) { | ||||
|             default: | ||||
|                 break; | ||||
|             case 'PUT': | ||||
|             case 'PATCH': | ||||
|                 /** @var RuleGroup $ruleGroup */ | ||||
|                 $ruleGroup      = $this->route()->parameter('ruleGroup'); | ||||
|                 $rules['title'] = 'required|between:1,100|uniqueObjectForUser:rule_groups,title,' . $ruleGroup->id; | ||||
|                 break; | ||||
|         } | ||||
|  | ||||
|         return $rules; | ||||
|     } | ||||
| } | ||||
							
								
								
									
										162
									
								
								app/Api/V1/Requests/RuleRequest.php
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										162
									
								
								app/Api/V1/Requests/RuleRequest.php
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,162 @@ | ||||
| <?php | ||||
| /** | ||||
|  * RuleRequest.php | ||||
|  * Copyright (c) 2018 thegrumpydictator@gmail.com | ||||
|  * | ||||
|  * This file is part of Firefly III. | ||||
|  * | ||||
|  * Firefly III is free software: you can redistribute it and/or modify | ||||
|  * it under the terms of the GNU General Public License as published by | ||||
|  * the Free Software Foundation, either version 3 of the License, or | ||||
|  * (at your option) any later version. | ||||
|  * | ||||
|  * Firefly III is distributed in the hope that it will be useful, | ||||
|  * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||||
|  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the | ||||
|  * GNU General Public License for more details. | ||||
|  * | ||||
|  * You should have received a copy of the GNU General Public License | ||||
|  * along with Firefly III. If not, see <http://www.gnu.org/licenses/>. | ||||
|  */ | ||||
|  | ||||
| declare(strict_types=1); | ||||
|  | ||||
| namespace FireflyIII\Api\V1\Requests; | ||||
|  | ||||
| use Illuminate\Validation\Validator; | ||||
|  | ||||
|  | ||||
| /** | ||||
|  * Class RuleRequest | ||||
|  */ | ||||
| class RuleRequest extends Request | ||||
| { | ||||
|     /** | ||||
|      * Authorize logged in users. | ||||
|      * | ||||
|      * @return bool | ||||
|      */ | ||||
|     public function authorize(): bool | ||||
|     { | ||||
|         // Only allow authenticated users | ||||
|         return auth()->check(); | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      * Get all data from the request. | ||||
|      * | ||||
|      * @return array | ||||
|      */ | ||||
|     public function getAll(): array | ||||
|     { | ||||
|         $data = [ | ||||
|             'title'            => $this->string('title'), | ||||
|             'description'      => $this->string('description'), | ||||
|             'rule_group_id'    => $this->integer('rule_group_id'), | ||||
|             'rule_group_title' => $this->string('rule_group_title'), | ||||
|             'trigger'          => $this->string('trigger'), | ||||
|             'strict'           => $this->boolean('strict'), | ||||
|             'stop-processing'  => $this->boolean('stop_processing'), | ||||
|             'active'           => $this->boolean('active'), | ||||
|             'rule-triggers'    => [], | ||||
|             'rule-actions'     => [], | ||||
|         ]; | ||||
|  | ||||
|         foreach ($this->get('rule-triggers') as $trigger) { | ||||
|             $data['rule-triggers'][] = [ | ||||
|                 'name'            => $trigger['name'], | ||||
|                 'value'           => $trigger['value'], | ||||
|                 'stop-processing' => 1 === (int)($trigger['stop-processing'] ?? 0), | ||||
|             ]; | ||||
|         } | ||||
|         foreach ($this->get('rule-actions') as $action) { | ||||
|             $data['rule-actions'][] = [ | ||||
|                 'name'            => $action['name'], | ||||
|                 'value'           => $action['value'], | ||||
|                 'stop-processing' => 1 === (int)($action['stop-processing'] ?? 0), | ||||
|             ]; | ||||
|         } | ||||
|  | ||||
|         return $data; | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      * The rules that the incoming request must be matched against. | ||||
|      * | ||||
|      * @return array | ||||
|      */ | ||||
|     public function rules(): array | ||||
|     { | ||||
|         $validTriggers = array_keys(config('firefly.rule-triggers')); | ||||
|         $validActions  = array_keys(config('firefly.rule-actions')); | ||||
|  | ||||
|         // some actions require text: | ||||
|         $contextActions = implode(',', config('firefly.rule-actions-text')); | ||||
|  | ||||
|         $rules = [ | ||||
|             'title'                           => 'required|between:1,100|uniqueObjectForUser:rules,title', | ||||
|             'description'                     => 'between:1,5000|nullable', | ||||
|             'rule_group_id'                   => 'required|belongsToUser:rule_groups|required_without:rule_group_title', | ||||
|             'rule_group_title'                => 'nullable|between:1,255|required_without:rule_group_id|belongsToUser:rule_groups,title', | ||||
|             'trigger'                         => 'required|in:store-journal,update-journal', | ||||
|             'rule-triggers.*.name'            => 'required|in:' . implode(',', $validTriggers), | ||||
|             'rule-triggers.*.stop-processing' => 'boolean', | ||||
|             'rule-triggers.*.value'           => 'required|min:1|ruleTriggerValue', // | ||||
|             'rule-actions.*.name'             => 'required|in:' . implode(',', $validActions), | ||||
|             'rule-actions.*.value'            => 'required_if:rule-action.*.type,' . $contextActions . '|ruleActionValue', | ||||
|             'rule-actions.*.stop-processing'  => 'boolean', | ||||
|             'strict'                          => 'required|boolean', | ||||
|             'stop_processing'                 => 'required|boolean', | ||||
|             'active'                          => 'required|boolean', | ||||
|         ]; | ||||
|  | ||||
|         return $rules; | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      * Configure the validator instance. | ||||
|      * | ||||
|      * @param  Validator $validator | ||||
|      * | ||||
|      * @return void | ||||
|      */ | ||||
|     public function withValidator(Validator $validator): void | ||||
|     { | ||||
|         $validator->after( | ||||
|             function (Validator $validator) { | ||||
|                 $this->atLeastOneTrigger($validator); | ||||
|                 $this->atLeastOneAction($validator); | ||||
|             } | ||||
|         ); | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      * Adds an error to the validator when there are no repetitions in the array of data. | ||||
|      * | ||||
|      * @param Validator $validator | ||||
|      */ | ||||
|     protected function atLeastOneAction(Validator $validator): void | ||||
|     { | ||||
|         $data        = $validator->getData(); | ||||
|         $repetitions = $data['rule-actions'] ?? []; | ||||
|         // need at least one transaction | ||||
|         if (0 === \count($repetitions)) { | ||||
|             $validator->errors()->add('title', (string)trans('validation.at_least_one_action')); | ||||
|         } | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      * Adds an error to the validator when there are no repetitions in the array of data. | ||||
|      * | ||||
|      * @param Validator $validator | ||||
|      */ | ||||
|     protected function atLeastOneTrigger(Validator $validator): void | ||||
|     { | ||||
|         $data        = $validator->getData(); | ||||
|         $repetitions = $data['rule-triggers'] ?? []; | ||||
|         // need at least one transaction | ||||
|         if (0 === \count($repetitions)) { | ||||
|             $validator->errors()->add('title', (string)trans('validation.at_least_one_trigger')); | ||||
|         } | ||||
|     } | ||||
| } | ||||
| @@ -1,5 +1,5 @@ | ||||
| <?php | ||||
| declare(strict_types=1); | ||||
|  | ||||
| /** | ||||
|  * TransactionRequest.php | ||||
|  * Copyright (c) 2018 thegrumpydictator@gmail.com | ||||
| @@ -20,15 +20,12 @@ declare(strict_types=1); | ||||
|  * along with Firefly III. If not, see <http://www.gnu.org/licenses/>. | ||||
|  */ | ||||
|  | ||||
| declare(strict_types=1); | ||||
|  | ||||
| namespace FireflyIII\Api\V1\Requests; | ||||
|  | ||||
| use FireflyIII\Exceptions\FireflyException; | ||||
| use FireflyIII\Models\Account; | ||||
| use FireflyIII\Models\AccountType; | ||||
| use FireflyIII\Models\Transaction; | ||||
| use FireflyIII\Repositories\Account\AccountRepositoryInterface; | ||||
| use FireflyIII\Rules\BelongsUser; | ||||
| use FireflyIII\Validation\TransactionValidation; | ||||
| use Illuminate\Validation\Validator; | ||||
|  | ||||
|  | ||||
| @@ -37,7 +34,11 @@ use Illuminate\Validation\Validator; | ||||
|  */ | ||||
| class TransactionRequest extends Request | ||||
| { | ||||
|     use TransactionValidation; | ||||
|  | ||||
|     /** | ||||
|      * Authorize logged in users. | ||||
|      * | ||||
|      * @return bool | ||||
|      */ | ||||
|     public function authorize(): bool | ||||
| @@ -47,12 +48,15 @@ class TransactionRequest extends Request | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      * Get all data. Is pretty complex because of all the ??-statements. | ||||
|      * | ||||
|      * @SuppressWarnings(PHPMD.CyclomaticComplexity) | ||||
|      * @SuppressWarnings(PHPMD.NPathComplexity) | ||||
|      * @return array | ||||
|      */ | ||||
|     public function getAll(): array | ||||
|     { | ||||
|         $data = [ | ||||
|             // basic fields for journal: | ||||
|             'type'               => $this->string('type'), | ||||
|             'date'               => $this->date('date'), | ||||
|             'description'        => $this->string('description'), | ||||
| @@ -61,8 +65,6 @@ class TransactionRequest extends Request | ||||
|             'bill_id'            => $this->integer('bill_id'), | ||||
|             'bill_name'          => $this->string('bill_name'), | ||||
|             'tags'               => explode(',', $this->string('tags')), | ||||
|  | ||||
|             // then, custom fields for journal | ||||
|             'interest_date'      => $this->date('interest_date'), | ||||
|             'book_date'          => $this->date('book_date'), | ||||
|             'process_date'       => $this->date('process_date'), | ||||
| @@ -71,39 +73,17 @@ class TransactionRequest extends Request | ||||
|             'invoice_date'       => $this->date('invoice_date'), | ||||
|             'internal_reference' => $this->string('internal_reference'), | ||||
|             'notes'              => $this->string('notes'), | ||||
|  | ||||
|             // then, transactions (see below). | ||||
|             'transactions'       => [], | ||||
|  | ||||
|             'transactions'       => $this->getTransactionData(), | ||||
|         ]; | ||||
|         foreach ($this->get('transactions') as $index => $transaction) { | ||||
|             $array                  = [ | ||||
|                 'description'           => $transaction['description'] ?? null, | ||||
|                 'amount'                => $transaction['amount'], | ||||
|                 'currency_id'           => isset($transaction['currency_id']) ? (int)$transaction['currency_id'] : null, | ||||
|                 'currency_code'         => $transaction['currency_code'] ?? null, | ||||
|                 'foreign_amount'        => $transaction['foreign_amount'] ?? null, | ||||
|                 'foreign_currency_id'   => isset($transaction['foreign_currency_id']) ? (int)$transaction['foreign_currency_id'] : null, | ||||
|                 'foreign_currency_code' => $transaction['foreign_currency_code'] ?? null, | ||||
|                 'budget_id'             => isset($transaction['budget_id']) ? (int)$transaction['budget_id'] : null, | ||||
|                 'budget_name'           => $transaction['budget_name'] ?? null, | ||||
|                 'category_id'           => isset($transaction['category_id']) ? (int)$transaction['category_id'] : null, | ||||
|                 'category_name'         => $transaction['category_name'] ?? null, | ||||
|                 'source_id'             => isset($transaction['source_id']) ? (int)$transaction['source_id'] : null, | ||||
|                 'source_name'           => isset($transaction['source_name']) ? (string)$transaction['source_name'] : null, | ||||
|                 'destination_id'        => isset($transaction['destination_id']) ? (int)$transaction['destination_id'] : null, | ||||
|                 'destination_name'      => isset($transaction['destination_name']) ? (string)$transaction['destination_name'] : null, | ||||
|                 'reconciled'            => $transaction['reconciled'] ?? false, | ||||
|                 'identifier'            => $index, | ||||
|             ]; | ||||
|             $data['transactions'][] = $array; | ||||
|         } | ||||
|  | ||||
|         return $data; | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      * The rules that the incoming request must be matched against. | ||||
|      * | ||||
|      * @return array | ||||
|      * @SuppressWarnings(PHPMD.ExcessiveMethodLength) | ||||
|      */ | ||||
|     public function rules(): array | ||||
|     { | ||||
| @@ -148,13 +128,8 @@ class TransactionRequest extends Request | ||||
|             'transactions.*.destination_name'      => 'between:1,255|nullable', | ||||
|         ]; | ||||
|  | ||||
|         switch ($this->method()) { | ||||
|             default: | ||||
|                 break; | ||||
|             case 'PUT': | ||||
|             case 'PATCH': | ||||
|                 unset($rules['type'], $rules['piggy_bank_id'], $rules['piggy_bank_name']); | ||||
|                 break; | ||||
|         if ('PUT' === $this->method()) { | ||||
|             unset($rules['type'], $rules['piggy_bank_id'], $rules['piggy_bank_name']); | ||||
|         } | ||||
|  | ||||
|         return $rules; | ||||
| @@ -173,11 +148,11 @@ class TransactionRequest extends Request | ||||
|     { | ||||
|         $validator->after( | ||||
|             function (Validator $validator) { | ||||
|                 $this->atLeastOneTransaction($validator); | ||||
|                 $this->checkValidDescriptions($validator); | ||||
|                 $this->equalToJournalDescription($validator); | ||||
|                 $this->emptySplitDescriptions($validator); | ||||
|                 $this->foreignCurrencyInformation($validator); | ||||
|                 $this->validateOneTransaction($validator); | ||||
|                 $this->validateDescriptions($validator); | ||||
|                 $this->validateJournalDescription($validator); | ||||
|                 $this->validateSplitDescriptions($validator); | ||||
|                 $this->validateForeignCurrencyInformation($validator); | ||||
|                 $this->validateAccountInformation($validator); | ||||
|                 $this->validateSplitAccounts($validator); | ||||
|             } | ||||
| @@ -185,329 +160,37 @@ class TransactionRequest extends Request | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      * Throws an error when this asset account is invalid. | ||||
|      * Get transaction data. | ||||
|      * | ||||
|      * @param Validator   $validator | ||||
|      * @param int|null    $accountId | ||||
|      * @param null|string $accountName | ||||
|      * @param string      $idField | ||||
|      * @param string      $nameField | ||||
|      * | ||||
|      * @return null|Account | ||||
|      * @SuppressWarnings(PHPMD.CyclomaticComplexity) | ||||
|      * @SuppressWarnings(PHPMD.NPathComplexity) | ||||
|      * @return array | ||||
|      */ | ||||
|     protected function assetAccountExists(Validator $validator, ?int $accountId, ?string $accountName, string $idField, string $nameField): ?Account | ||||
|     private function getTransactionData(): array | ||||
|     { | ||||
|  | ||||
|         $accountId   = (int)$accountId; | ||||
|         $accountName = (string)$accountName; | ||||
|         // both empty? hard exit. | ||||
|         if ($accountId < 1 && \strlen($accountName) === 0) { | ||||
|             $validator->errors()->add($idField, trans('validation.filled', ['attribute' => $idField])); | ||||
|  | ||||
|             return null; | ||||
|         } | ||||
|         // ID belongs to user and is asset account: | ||||
|         /** @var AccountRepositoryInterface $repository */ | ||||
|         $repository = app(AccountRepositoryInterface::class); | ||||
|         $repository->setUser(auth()->user()); | ||||
|         $set = $repository->getAccountsById([$accountId]); | ||||
|         if ($set->count() === 1) { | ||||
|             /** @var Account $first */ | ||||
|             $first = $set->first(); | ||||
|             if ($first->accountType->type !== AccountType::ASSET) { | ||||
|                 $validator->errors()->add($idField, trans('validation.belongs_user')); | ||||
|  | ||||
|                 return null; | ||||
|             } | ||||
|  | ||||
|             // we ignore the account name at this point. | ||||
|             return $first; | ||||
|         $return = []; | ||||
|         foreach ($this->get('transactions') as $index => $transaction) { | ||||
|             $return[] = [ | ||||
|                 'description'           => $transaction['description'] ?? null, | ||||
|                 'amount'                => $transaction['amount'], | ||||
|                 'currency_id'           => isset($transaction['currency_id']) ? (int)$transaction['currency_id'] : null, | ||||
|                 'currency_code'         => $transaction['currency_code'] ?? null, | ||||
|                 'foreign_amount'        => $transaction['foreign_amount'] ?? null, | ||||
|                 'foreign_currency_id'   => isset($transaction['foreign_currency_id']) ? (int)$transaction['foreign_currency_id'] : null, | ||||
|                 'foreign_currency_code' => $transaction['foreign_currency_code'] ?? null, | ||||
|                 'budget_id'             => isset($transaction['budget_id']) ? (int)$transaction['budget_id'] : null, | ||||
|                 'budget_name'           => $transaction['budget_name'] ?? null, | ||||
|                 'category_id'           => isset($transaction['category_id']) ? (int)$transaction['category_id'] : null, | ||||
|                 'category_name'         => $transaction['category_name'] ?? null, | ||||
|                 'source_id'             => isset($transaction['source_id']) ? (int)$transaction['source_id'] : null, | ||||
|                 'source_name'           => isset($transaction['source_name']) ? (string)$transaction['source_name'] : null, | ||||
|                 'destination_id'        => isset($transaction['destination_id']) ? (int)$transaction['destination_id'] : null, | ||||
|                 'destination_name'      => isset($transaction['destination_name']) ? (string)$transaction['destination_name'] : null, | ||||
|                 'reconciled'            => $transaction['reconciled'] ?? false, | ||||
|                 'identifier'            => $index, | ||||
|             ]; | ||||
|         } | ||||
|  | ||||
|         $account = $repository->findByName($accountName, [AccountType::ASSET]); | ||||
|         if (null === $account) { | ||||
|             $validator->errors()->add($nameField, trans('validation.belongs_user')); | ||||
|  | ||||
|             return null; | ||||
|         } | ||||
|  | ||||
|         return $account; | ||||
|         return $return; | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      * Adds an error to the validator when there are no transactions in the array of data. | ||||
|      * | ||||
|      * @param Validator $validator | ||||
|      */ | ||||
|     protected function atLeastOneTransaction(Validator $validator): void | ||||
|     { | ||||
|         $data         = $validator->getData(); | ||||
|         $transactions = $data['transactions'] ?? []; | ||||
|         // need at least one transaction | ||||
|         if (\count($transactions) === 0) { | ||||
|             $validator->errors()->add('description', trans('validation.at_least_one_transaction')); | ||||
|         } | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      * Adds an error to the "description" field when the user has submitted no descriptions and no | ||||
|      * journal description. | ||||
|      * | ||||
|      * @param Validator $validator | ||||
|      */ | ||||
|     protected function checkValidDescriptions(Validator $validator) | ||||
|     { | ||||
|         $data               = $validator->getData(); | ||||
|         $transactions       = $data['transactions'] ?? []; | ||||
|         $journalDescription = (string)($data['description'] ?? ''); | ||||
|         $validDescriptions  = 0; | ||||
|         foreach ($transactions as $index => $transaction) { | ||||
|             if (\strlen((string)($transaction['description'] ?? '')) > 0) { | ||||
|                 $validDescriptions++; | ||||
|             } | ||||
|         } | ||||
|  | ||||
|         // no valid descriptions and empty journal description? error. | ||||
|         if ($validDescriptions === 0 && \strlen($journalDescription) === 0) { | ||||
|             $validator->errors()->add('description', trans('validation.filled', ['attribute' => trans('validation.attributes.description')])); | ||||
|         } | ||||
|  | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      * Adds an error to the validator when the user submits a split transaction (more than 1 transactions) | ||||
|      * but does not give them a description. | ||||
|      * | ||||
|      * @param Validator $validator | ||||
|      */ | ||||
|     protected function emptySplitDescriptions(Validator $validator): void | ||||
|     { | ||||
|         $data         = $validator->getData(); | ||||
|         $transactions = $data['transactions'] ?? []; | ||||
|         foreach ($transactions as $index => $transaction) { | ||||
|             $description = (string)($transaction['description'] ?? ''); | ||||
|             // filled description is mandatory for split transactions. | ||||
|             if (\count($transactions) > 1 && \strlen($description) === 0) { | ||||
|                 $validator->errors()->add( | ||||
|                     'transactions.' . $index . '.description', | ||||
|                     trans('validation.filled', ['attribute' => trans('validation.attributes.transaction_description')]) | ||||
|                 ); | ||||
|             } | ||||
|         } | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      * Adds an error to the validator when any transaction descriptions are equal to the journal description. | ||||
|      * | ||||
|      * @param Validator $validator | ||||
|      */ | ||||
|     protected function equalToJournalDescription(Validator $validator): void | ||||
|     { | ||||
|         $data               = $validator->getData(); | ||||
|         $transactions       = $data['transactions'] ?? []; | ||||
|         $journalDescription = (string)($data['description'] ?? ''); | ||||
|         foreach ($transactions as $index => $transaction) { | ||||
|             $description = (string)($transaction['description'] ?? ''); | ||||
|             // description cannot be equal to journal description. | ||||
|             if ($description === $journalDescription) { | ||||
|                 $validator->errors()->add('transactions.' . $index . '.description', trans('validation.equal_description')); | ||||
|             } | ||||
|         } | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      * If the transactions contain foreign amounts, there must also be foreign currency information. | ||||
|      * | ||||
|      * @param Validator $validator | ||||
|      */ | ||||
|     protected function foreignCurrencyInformation(Validator $validator): void | ||||
|     { | ||||
|         $data         = $validator->getData(); | ||||
|         $transactions = $data['transactions'] ?? []; | ||||
|         foreach ($transactions as $index => $transaction) { | ||||
|             // must have currency info. | ||||
|             if (isset($transaction['foreign_amount']) | ||||
|                 && !(isset($transaction['foreign_currency_id']) | ||||
|                      || isset($transaction['foreign_currency_code']))) { | ||||
|                 $validator->errors()->add( | ||||
|                     'transactions.' . $index . '.foreign_amount', | ||||
|                     trans('validation.require_currency_info') | ||||
|                 ); | ||||
|             } | ||||
|         } | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      * Throws an error when the given opposing account (of type $type) is invalid. | ||||
|      * Empty data is allowed, system will default to cash. | ||||
|      * | ||||
|      * @param Validator   $validator | ||||
|      * @param string      $type | ||||
|      * @param int|null    $accountId | ||||
|      * @param null|string $accountName | ||||
|      * @param string      $idField | ||||
|      * | ||||
|      * @return null|Account | ||||
|      */ | ||||
|     protected function opposingAccountExists(Validator $validator, string $type, ?int $accountId, ?string $accountName, string $idField): ?Account | ||||
|     { | ||||
|         $accountId   = (int)$accountId; | ||||
|         $accountName = (string)$accountName; | ||||
|         // both empty? done! | ||||
|         if ($accountId < 1 && \strlen($accountName) === 0) { | ||||
|             return null; | ||||
|         } | ||||
|         if ($accountId !== 0) { | ||||
|             // ID belongs to user and is $type account: | ||||
|             /** @var AccountRepositoryInterface $repository */ | ||||
|             $repository = app(AccountRepositoryInterface::class); | ||||
|             $repository->setUser(auth()->user()); | ||||
|             $set = $repository->getAccountsById([$accountId]); | ||||
|             if ($set->count() === 1) { | ||||
|                 /** @var Account $first */ | ||||
|                 $first = $set->first(); | ||||
|                 if ($first->accountType->type !== $type) { | ||||
|                     $validator->errors()->add($idField, trans('validation.belongs_user')); | ||||
|  | ||||
|                     return null; | ||||
|                 } | ||||
|  | ||||
|                 // we ignore the account name at this point. | ||||
|                 return $first; | ||||
|             } | ||||
|         } | ||||
|  | ||||
|         // not having an opposing account by this name is NOT a problem. | ||||
|         return null; | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      * Validates the given account information. Switches on given transaction type. | ||||
|      * | ||||
|      * @param Validator $validator | ||||
|      * | ||||
|      * @throws FireflyException | ||||
|      */ | ||||
|     protected function validateAccountInformation(Validator $validator): void | ||||
|     { | ||||
|         $data         = $validator->getData(); | ||||
|         $transactions = $data['transactions'] ?? []; | ||||
|         if (!isset($data['type'])) { | ||||
|             // the journal may exist in the request: | ||||
|             /** @var Transaction $transaction */ | ||||
|             $transaction = $this->route()->parameter('transaction'); | ||||
|             if (null === $transaction) { | ||||
|                 return; // @codeCoverageIgnore | ||||
|             } | ||||
|             $data['type'] = strtolower($transaction->transactionJournal->transactionType->type); | ||||
|         } | ||||
|         foreach ($transactions as $index => $transaction) { | ||||
|             $sourceId           = isset($transaction['source_id']) ? (int)$transaction['source_id'] : null; | ||||
|             $sourceName         = $transaction['source_name'] ?? null; | ||||
|             $destinationId      = isset($transaction['destination_id']) ? (int)$transaction['destination_id'] : null; | ||||
|             $destinationName    = $transaction['destination_name'] ?? null; | ||||
|             $sourceAccount      = null; | ||||
|             $destinationAccount = null; | ||||
|             switch ($data['type']) { | ||||
|                 case 'withdrawal': | ||||
|                     $idField            = 'transactions.' . $index . '.source_id'; | ||||
|                     $nameField          = 'transactions.' . $index . '.source_name'; | ||||
|                     $sourceAccount      = $this->assetAccountExists($validator, $sourceId, $sourceName, $idField, $nameField); | ||||
|                     $idField            = 'transactions.' . $index . '.destination_id'; | ||||
|                     $destinationAccount = $this->opposingAccountExists($validator, AccountType::EXPENSE, $destinationId, $destinationName, $idField); | ||||
|                     break; | ||||
|                 case 'deposit': | ||||
|                     $idField       = 'transactions.' . $index . '.source_id'; | ||||
|                     $sourceAccount = $this->opposingAccountExists($validator, AccountType::REVENUE, $sourceId, $sourceName, $idField); | ||||
|  | ||||
|                     $idField            = 'transactions.' . $index . '.destination_id'; | ||||
|                     $nameField          = 'transactions.' . $index . '.destination_name'; | ||||
|                     $destinationAccount = $this->assetAccountExists($validator, $destinationId, $destinationName, $idField, $nameField); | ||||
|                     break; | ||||
|                 case 'transfer': | ||||
|                     $idField       = 'transactions.' . $index . '.source_id'; | ||||
|                     $nameField     = 'transactions.' . $index . '.source_name'; | ||||
|                     $sourceAccount = $this->assetAccountExists($validator, $sourceId, $sourceName, $idField, $nameField); | ||||
|  | ||||
|                     $idField            = 'transactions.' . $index . '.destination_id'; | ||||
|                     $nameField          = 'transactions.' . $index . '.destination_name'; | ||||
|                     $destinationAccount = $this->assetAccountExists($validator, $destinationId, $destinationName, $idField, $nameField); | ||||
|                     break; | ||||
|                 default: | ||||
|                     // @codeCoverageIgnoreStart | ||||
|                     throw new FireflyException( | ||||
|                         sprintf('The validator cannot handle transaction type "%s" in validateAccountInformation().', $data['type']) | ||||
|                     ); | ||||
|                 // @codeCoverageIgnoreEnd | ||||
|  | ||||
|             } | ||||
|             // add some errors in case of same account submitted: | ||||
|             if (null !== $sourceAccount && null !== $destinationAccount && $sourceAccount->id === $destinationAccount->id) { | ||||
|                 $validator->errors()->add($idField, trans('validation.source_equals_destination')); | ||||
|             } | ||||
|         } | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      * @param Validator $validator | ||||
|      * | ||||
|      * @throws FireflyException | ||||
|      */ | ||||
|     protected function validateSplitAccounts(Validator $validator) | ||||
|     { | ||||
|         $data  = $validator->getData(); | ||||
|         $count = isset($data['transactions']) ? \count($data['transactions']) : 0; | ||||
|         if ($count < 2) { | ||||
|             return; | ||||
|         } | ||||
|         // this is pretty much impossible: | ||||
|         // @codeCoverageIgnoreStart | ||||
|         if (!isset($data['type'])) { | ||||
|             // the journal may exist in the request: | ||||
|             /** @var Transaction $transaction */ | ||||
|             $transaction = $this->route()->parameter('transaction'); | ||||
|             if (null === $transaction) { | ||||
|                 return; | ||||
|             } | ||||
|             $data['type'] = strtolower($transaction->transactionJournal->transactionType->type); | ||||
|         } | ||||
|         // @codeCoverageIgnoreEnd | ||||
|  | ||||
|         // collect all source ID's and destination ID's, if present: | ||||
|         $sources      = []; | ||||
|         $destinations = []; | ||||
|  | ||||
|         foreach ($data['transactions'] as $transaction) { | ||||
|             $sources[]      = isset($transaction['source_id']) ? (int)$transaction['source_id'] : 0; | ||||
|             $destinations[] = isset($transaction['destination_id']) ? (int)$transaction['destination_id'] : 0; | ||||
|         } | ||||
|         $destinations = array_unique($destinations); | ||||
|         $sources      = array_unique($sources); | ||||
|         // switch on type: | ||||
|         switch ($data['type']) { | ||||
|             case 'withdrawal': | ||||
|                 if (\count($sources) > 1) { | ||||
|                     $validator->errors()->add('transactions.0.source_id', trans('validation.all_accounts_equal')); | ||||
|                 } | ||||
|                 break; | ||||
|             case 'deposit': | ||||
|                 if (\count($destinations) > 1) { | ||||
|                     $validator->errors()->add('transactions.0.destination_id', trans('validation.all_accounts_equal')); | ||||
|                 } | ||||
|                 break; | ||||
|             case 'transfer': | ||||
|                 if (\count($sources) > 1 || \count($destinations) > 1) { | ||||
|                     $validator->errors()->add('transactions.0.source_id', trans('validation.all_accounts_equal')); | ||||
|                     $validator->errors()->add('transactions.0.destination_id', trans('validation.all_accounts_equal')); | ||||
|                 } | ||||
|                 break; | ||||
|             default: | ||||
|                 // @codeCoverageIgnoreStart | ||||
|                 throw new FireflyException( | ||||
|                     sprintf('The validator cannot handle transaction type "%s" in validateSplitAccounts().', $data['type']) | ||||
|                 ); | ||||
|             // @codeCoverageIgnoreEnd | ||||
|         } | ||||
|     } | ||||
|  | ||||
| } | ||||
|   | ||||
| @@ -1,5 +1,5 @@ | ||||
| <?php | ||||
| declare(strict_types=1); | ||||
|  | ||||
| /** | ||||
|  * UserRequest.php | ||||
|  * Copyright (c) 2018 thegrumpydictator@gmail.com | ||||
| @@ -20,9 +20,11 @@ declare(strict_types=1); | ||||
|  * along with Firefly III. If not, see <http://www.gnu.org/licenses/>. | ||||
|  */ | ||||
|  | ||||
| declare(strict_types=1); | ||||
|  | ||||
| namespace FireflyIII\Api\V1\Requests; | ||||
|  | ||||
| use FireflyIII\Repositories\User\UserRepositoryInterface; | ||||
| use FireflyIII\User; | ||||
|  | ||||
|  | ||||
| @@ -32,24 +34,32 @@ use FireflyIII\User; | ||||
| class UserRequest extends Request | ||||
| { | ||||
|     /** | ||||
|      * Authorize logged in users. | ||||
|      * | ||||
|      * @return bool | ||||
|      */ | ||||
|     public function authorize(): bool | ||||
|     { | ||||
|         $result = false; | ||||
|         // Only allow authenticated users | ||||
|         if (!auth()->check()) { | ||||
|             return false; // @codeCoverageIgnore | ||||
|         } | ||||
|         /** @var User $user */ | ||||
|         $user = auth()->user(); | ||||
|         if (!$user->hasRole('owner')) { | ||||
|             return false; // @codeCoverageIgnore | ||||
|         if (auth()->check()) { | ||||
|             /** @var User $user */ | ||||
|             $user = auth()->user(); | ||||
|  | ||||
|             /** @var UserRepositoryInterface $repository */ | ||||
|             $repository = app(UserRepositoryInterface::class); | ||||
|  | ||||
|             if ($repository->hasRole($user, 'owner')) { | ||||
|                 $result = true; // @codeCoverageIgnore | ||||
|             } | ||||
|         } | ||||
|  | ||||
|         return true; | ||||
|         return $result; | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      * Get all data from the request. | ||||
|      * | ||||
|      * @return array | ||||
|      */ | ||||
|     public function getAll(): array | ||||
| @@ -64,6 +74,8 @@ class UserRequest extends Request | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      * The rules that the incoming request must be matched against. | ||||
|      * | ||||
|      * @return array | ||||
|      */ | ||||
|     public function rules(): array | ||||
|   | ||||
| @@ -1,8 +1,7 @@ | ||||
| <?php | ||||
| declare(strict_types=1); | ||||
| /** | ||||
|  * CreateExport.php | ||||
|  * Copyright (c) 2017 thegrumpydictator@gmail.com | ||||
|  * Copyright (c) 2018 thegrumpydictator@gmail.com | ||||
|  * | ||||
|  * This file is part of Firefly III. | ||||
|  * | ||||
| @@ -20,6 +19,10 @@ declare(strict_types=1); | ||||
|  * along with Firefly III. If not, see <http://www.gnu.org/licenses/>. | ||||
|  */ | ||||
|  | ||||
| /** @noinspection MultipleReturnStatementsInspection */ | ||||
|  | ||||
| declare(strict_types=1); | ||||
|  | ||||
| namespace FireflyIII\Console\Commands; | ||||
|  | ||||
| use Carbon\Carbon; | ||||
| @@ -40,6 +43,7 @@ use Storage; | ||||
| class CreateExport extends Command | ||||
| { | ||||
|     use VerifiesAccessToken; | ||||
|  | ||||
|     /** | ||||
|      * The console command description. | ||||
|      * | ||||
| @@ -62,9 +66,11 @@ class CreateExport extends Command | ||||
|     /** | ||||
|      * Execute the console command. | ||||
|      * | ||||
|      * @return mixed | ||||
|      * @return int | ||||
|      * @SuppressWarnings(PHPMD.CyclomaticComplexity) | ||||
|      * @SuppressWarnings(PHPMD.ExcessiveMethodLength) | ||||
|      */ | ||||
|     public function handle() | ||||
|     public function handle(): int | ||||
|     { | ||||
|         if (!$this->verifyAccessToken()) { | ||||
|             $this->error('Invalid access token.'); | ||||
| @@ -84,6 +90,9 @@ class CreateExport extends Command | ||||
|  | ||||
|         // set user | ||||
|         $user = $userRepository->findNull((int)$this->option('user')); | ||||
|         if (null === $user) { | ||||
|             return 1; | ||||
|         } | ||||
|         $jobRepository->setUser($user); | ||||
|         $journalRepository->setUser($user); | ||||
|         $accountRepository->setUser($user); | ||||
|   | ||||
| @@ -1,8 +1,7 @@ | ||||
| <?php | ||||
| declare(strict_types=1); | ||||
| /** | ||||
|  * CreateImport.php | ||||
|  * Copyright (c) 2017 thegrumpydictator@gmail.com | ||||
|  * Copyright (c) 2018 thegrumpydictator@gmail.com | ||||
|  * | ||||
|  * This file is part of Firefly III. | ||||
|  * | ||||
| @@ -20,17 +19,21 @@ declare(strict_types=1); | ||||
|  * along with Firefly III. If not, see <http://www.gnu.org/licenses/>. | ||||
|  */ | ||||
|  | ||||
| /** @noinspection MultipleReturnStatementsInspection */ | ||||
|  | ||||
| declare(strict_types=1); | ||||
|  | ||||
| namespace FireflyIII\Console\Commands; | ||||
|  | ||||
| use Exception; | ||||
| use FireflyIII\Exceptions\FireflyException; | ||||
| use FireflyIII\Import\Prerequisites\PrerequisitesInterface; | ||||
| use FireflyIII\Import\Routine\RoutineInterface; | ||||
| use FireflyIII\Import\Storage\ImportArrayStorage; | ||||
| use FireflyIII\Repositories\ImportJob\ImportJobRepositoryInterface; | ||||
| use FireflyIII\Repositories\User\UserRepositoryInterface; | ||||
| use FireflyIII\Services\Internal\File\EncryptService; | ||||
| use Illuminate\Console\Command; | ||||
| use Illuminate\Support\MessageBag; | ||||
| use Log; | ||||
| use Preferences; | ||||
|  | ||||
| /** | ||||
|  * Class CreateImport. | ||||
| @@ -52,18 +55,17 @@ class CreateImport extends Command | ||||
|      */ | ||||
|     protected $signature | ||||
|         = 'firefly:create-import | ||||
|                             {file : The file to import.} | ||||
|                             {configuration : The configuration file to use for the import.} | ||||
|                             {file? : The file to import.} | ||||
|                             {configuration? : The configuration file to use for the import.} | ||||
|                             {--type=csv : The file type of the import.} | ||||
|                             {--user= : The user ID that the import should import for.} | ||||
|                             {--provider=file : The file type of the import.} | ||||
|                             {--user=1 : The user ID that the import should import for.} | ||||
|                             {--token= : The user\'s access token.} | ||||
|                             {--start : Starts the job immediately.}'; | ||||
|  | ||||
|     /** | ||||
|      * Run the command. | ||||
|      * | ||||
|      * @noinspection MultipleReturnStatementsInspection | ||||
|      * | ||||
|      * @throws FireflyException | ||||
|      */ | ||||
|     public function handle(): int | ||||
| @@ -74,79 +76,162 @@ class CreateImport extends Command | ||||
|             return 1; | ||||
|         } | ||||
|         /** @var UserRepositoryInterface $userRepository */ | ||||
|         $userRepository = app(UserRepositoryInterface::class); | ||||
|         $file           = $this->argument('file'); | ||||
|         $configuration  = $this->argument('configuration'); | ||||
|         $user           = $userRepository->findNull((int)$this->option('user')); | ||||
|         $cwd            = getcwd(); | ||||
|         $type           = strtolower($this->option('type')); | ||||
|         $userRepository    = app(UserRepositoryInterface::class); | ||||
|         $file              = (string)$this->argument('file'); | ||||
|         $configuration     = (string)$this->argument('configuration'); | ||||
|         $user              = $userRepository->findNull((int)$this->option('user')); | ||||
|         $cwd               = getcwd(); | ||||
|         $provider          = strtolower((string)$this->option('provider')); | ||||
|         $configurationData = []; | ||||
|  | ||||
|         if (null === $user) { | ||||
|             $this->errorLine('User is NULL.'); | ||||
|  | ||||
|             return 1; | ||||
|         } | ||||
|  | ||||
|         if (!$this->validArguments()) { | ||||
|             $this->errorLine('Invalid arguments.'); | ||||
|  | ||||
|             return 1; | ||||
|         } | ||||
|         if (\strlen($configuration) > 0) { | ||||
|             $configurationData = json_decode(file_get_contents($configuration), true); | ||||
|             if (null === $configurationData) { | ||||
|                 $this->errorLine(sprintf('Firefly III cannot read the contents of configuration file "%s" (working directory: "%s").', $configuration, $cwd)); | ||||
|  | ||||
|         $configurationData = json_decode(file_get_contents($configuration), true); | ||||
|         if (null === $configurationData) { | ||||
|             $this->errorLine(sprintf('Firefly III cannot read the contents of configuration file "%s" (working directory: "%s").', $configuration, $cwd)); | ||||
|  | ||||
|             return 1; | ||||
|                 return 1; | ||||
|             } | ||||
|         } | ||||
|  | ||||
|  | ||||
|         $this->infoLine(sprintf('Going to create a job to import file: %s', $file)); | ||||
|         $this->infoLine(sprintf('Using configuration file: %s', $configuration)); | ||||
|         $this->infoLine(sprintf('Import into user: #%d (%s)', $user->id, $user->email)); | ||||
|         $this->infoLine(sprintf('Type of import: %s', $type)); | ||||
|         $this->infoLine(sprintf('Type of import: %s', $provider)); | ||||
|  | ||||
|         /** @var ImportJobRepositoryInterface $jobRepository */ | ||||
|         $jobRepository = app(ImportJobRepositoryInterface::class); | ||||
|         $jobRepository->setUser($user); | ||||
|         $job = $jobRepository->create($type); | ||||
|         $this->infoLine(sprintf('Created job "%s"', $job->key)); | ||||
|         $importJob = $jobRepository->create($provider); | ||||
|         $this->infoLine(sprintf('Created job "%s"', $importJob->key)); | ||||
|  | ||||
|         /** @var EncryptService $service */ | ||||
|         $service = app(EncryptService::class); | ||||
|         $service->encrypt($file, $job->key); | ||||
|  | ||||
|         $this->infoLine('Stored import data...'); | ||||
|  | ||||
|         $jobRepository->setConfiguration($job, $configurationData); | ||||
|         $jobRepository->updateStatus($job, 'configured'); | ||||
|         $this->infoLine('Stored configuration...'); | ||||
|  | ||||
|         if (true === $this->option('start')) { | ||||
|             $this->infoLine('The import will start in a moment. This process is not visible...'); | ||||
|             Log::debug('Go for import!'); | ||||
|  | ||||
|             // normally would refer to other firefly:start-import but that doesn't seem to work all to well... | ||||
|  | ||||
|             // start the actual routine: | ||||
|             $type      = 'csv' === $job->file_type ? 'file' : $job->file_type; | ||||
|             $key       = sprintf('import.routine.%s', $type); | ||||
|             $className = config($key); | ||||
|             if (null === $className || !class_exists($className)) { | ||||
|                 throw new FireflyException(sprintf('Cannot find import routine class for job of type "%s".', $type)); // @codeCoverageIgnore | ||||
|         // make sure that job has no prerequisites. | ||||
|         if ((bool)config(sprintf('import.has_prereq.%s', $provider))) { | ||||
|             // make prerequisites thing. | ||||
|             $class = (string)config(sprintf('import.prerequisites.%s', $provider)); | ||||
|             if (!class_exists($class)) { | ||||
|                 throw new FireflyException(sprintf('No class to handle prerequisites for "%s".', $provider)); // @codeCoverageIgnore | ||||
|             } | ||||
|             /** @var RoutineInterface $routine */ | ||||
|             $routine = app($className); | ||||
|             $routine->setJob($job); | ||||
|             $routine->run(); | ||||
|             /** @var PrerequisitesInterface $object */ | ||||
|             $object = app($class); | ||||
|             $object->setUser($user); | ||||
|             if (!$object->isComplete()) { | ||||
|                 $this->errorLine(sprintf('Import provider "%s" has prerequisites that can only be filled in using the browser.', $provider)); | ||||
|  | ||||
|             // give feedback. | ||||
|             /** @var MessageBag $error */ | ||||
|             foreach ($routine->getErrors() as $index => $error) { | ||||
|                 $this->errorLine(sprintf('Error importing line #%d: %s', $index, $error)); | ||||
|                 return 1; | ||||
|             } | ||||
|             $this->infoLine( | ||||
|                 sprintf( | ||||
|                     'The import has finished. %d transactions have been imported out of %d records.', $routine->getJournals()->count(), $routine->getLines() | ||||
|                 ) | ||||
|             ); | ||||
|         } | ||||
|  | ||||
|         // store file as attachment. | ||||
|         if (\strlen($file) > 0) { | ||||
|             $messages = $jobRepository->storeCLIUpload($importJob, 'import_file', $file); | ||||
|             if ($messages->count() > 0) { | ||||
|                 $this->errorLine($messages->first()); | ||||
|  | ||||
|                 return 1; | ||||
|             } | ||||
|             $this->infoLine('File content saved.'); | ||||
|         } | ||||
|  | ||||
|         $this->infoLine('Job configuration saved.'); | ||||
|         $jobRepository->setConfiguration($importJob, $configurationData); | ||||
|         $jobRepository->setStatus($importJob, 'ready_to_run'); | ||||
|  | ||||
|  | ||||
|         if (true === $this->option('start')) { | ||||
|             $this->infoLine('The has started. The process is not visible. Please wait.'); | ||||
|             Log::debug('Go for import!'); | ||||
|  | ||||
|             // run it! | ||||
|             $key       = sprintf('import.routine.%s', $provider); | ||||
|             $className = config($key); | ||||
|             if (null === $className || !class_exists($className)) { | ||||
|                 // @codeCoverageIgnoreStart | ||||
|                 $this->errorLine(sprintf('No routine for provider "%s"', $provider)); | ||||
|  | ||||
|                 return 1; | ||||
|                 // @codeCoverageIgnoreEnd | ||||
|             } | ||||
|  | ||||
|             // keep repeating this call until job lands on "provider_finished" | ||||
|             $valid = ['provider_finished']; | ||||
|             $count = 0; | ||||
|             while (!\in_array($importJob->status, $valid, true) && $count < 6) { | ||||
|                 Log::debug(sprintf('Now in loop #%d.', $count + 1)); | ||||
|                 /** @var RoutineInterface $routine */ | ||||
|                 $routine = app($className); | ||||
|                 $routine->setImportJob($importJob); | ||||
|                 try { | ||||
|                     $routine->run(); | ||||
|                 } catch (FireflyException|Exception $e) { | ||||
|                     $message = 'The import routine crashed: ' . $e->getMessage(); | ||||
|                     Log::error($message); | ||||
|                     Log::error($e->getTraceAsString()); | ||||
|  | ||||
|                     // set job errored out: | ||||
|                     $jobRepository->setStatus($importJob, 'error'); | ||||
|                     $this->errorLine($message); | ||||
|  | ||||
|                     return 1; | ||||
|                 } | ||||
|                 $count++; | ||||
|             } | ||||
|             if ('provider_finished' === $importJob->status) { | ||||
|                 $this->infoLine('Import has finished. Please wait for storage of data.'); | ||||
|                 // set job to be storing data: | ||||
|                 $jobRepository->setStatus($importJob, 'storing_data'); | ||||
|  | ||||
|                 /** @var ImportArrayStorage $storage */ | ||||
|                 $storage = app(ImportArrayStorage::class); | ||||
|                 $storage->setImportJob($importJob); | ||||
|  | ||||
|                 try { | ||||
|                     $storage->store(); | ||||
|                 } catch (FireflyException|Exception $e) { | ||||
|                     $message = 'The import routine crashed: ' . $e->getMessage(); | ||||
|                     Log::error($message); | ||||
|                     Log::error($e->getTraceAsString()); | ||||
|  | ||||
|                     // set job errored out: | ||||
|                     $jobRepository->setStatus($importJob, 'error'); | ||||
|                     $this->errorLine($message); | ||||
|  | ||||
|                     return 1; | ||||
|                 } | ||||
|                 // set storage to be finished: | ||||
|                 $jobRepository->setStatus($importJob, 'storage_finished'); | ||||
|             } | ||||
|  | ||||
|             // give feedback: | ||||
|             $this->infoLine('Job has finished.'); | ||||
|             if (null !== $importJob->tag) { | ||||
|                 $this->infoLine(sprintf('%d transaction(s) have been imported.', $importJob->tag->transactionJournals->count())); | ||||
|                 $this->infoLine(sprintf('You can find your transactions under tag "%s"', $importJob->tag->tag)); | ||||
|             } | ||||
|  | ||||
|             if (null === $importJob->tag) { | ||||
|                 $this->errorLine('No transactions have been imported :(.'); | ||||
|             } | ||||
|             if (\count($importJob->errors) > 0) { | ||||
|                 $this->infoLine(sprintf('%d error(s) occurred:', \count($importJob->errors))); | ||||
|                 foreach ($importJob->errors as $err) { | ||||
|                     $this->errorLine('- ' . $err); | ||||
|                 } | ||||
|             } | ||||
|         } | ||||
|         // clear cache for user: | ||||
|         Preferences::setForUser($user, 'lastActivity', microtime()); | ||||
|         app('preferences')->setForUser($user, 'lastActivity', microtime()); | ||||
|  | ||||
|         return 0; | ||||
|     } | ||||
| @@ -180,25 +265,33 @@ class CreateImport extends Command | ||||
|      */ | ||||
|     private function validArguments(): bool | ||||
|     { | ||||
|         $file          = $this->argument('file'); | ||||
|         $configuration = $this->argument('configuration'); | ||||
|         $file          = (string)$this->argument('file'); | ||||
|         $configuration = (string)$this->argument('configuration'); | ||||
|         $cwd           = getcwd(); | ||||
|         $validTypes    = config('import.options.file.import_formats'); | ||||
|         $type          = strtolower($this->option('type')); | ||||
|         $provider      = strtolower($this->option('provider')); | ||||
|         $enabled       = (bool)config(sprintf('import.enabled.%s', $provider)); | ||||
|  | ||||
|         if (!\in_array($type, $validTypes, true)) { | ||||
|         if (false === $enabled) { | ||||
|             $this->errorLine(sprintf('Provider "%s" is not enabled.', $provider)); | ||||
|  | ||||
|             return false; | ||||
|         } | ||||
|  | ||||
|         if ('file' === $provider && !\in_array($type, $validTypes, true)) { | ||||
|             $this->errorLine(sprintf('Cannot import file of type "%s"', $type)); | ||||
|  | ||||
|             return false; | ||||
|         } | ||||
|  | ||||
|         if (!file_exists($file)) { | ||||
|         if ('file' === $provider && !file_exists($file)) { | ||||
|             $this->errorLine(sprintf('Firefly III cannot find file "%s" (working directory: "%s").', $file, $cwd)); | ||||
|  | ||||
|             return false; | ||||
|         } | ||||
|  | ||||
|         if (!file_exists($configuration)) { | ||||
|         if ('file' === $provider && !file_exists($configuration)) { | ||||
|             $this->errorLine(sprintf('Firefly III cannot find configuration file "%s" (working directory: "%s").', $configuration, $cwd)); | ||||
|  | ||||
|             return false; | ||||
|   | ||||
| @@ -1,8 +1,7 @@ | ||||
| <?php | ||||
| declare(strict_types=1); | ||||
| /** | ||||
|  * DecryptAttachment.php | ||||
|  * Copyright (c) 2017 thegrumpydictator@gmail.com | ||||
|  * Copyright (c) 2018 thegrumpydictator@gmail.com | ||||
|  * | ||||
|  * This file is part of Firefly III. | ||||
|  * | ||||
| @@ -20,6 +19,10 @@ declare(strict_types=1); | ||||
|  * along with Firefly III. If not, see <http://www.gnu.org/licenses/>. | ||||
|  */ | ||||
|  | ||||
| /** @noinspection MultipleReturnStatementsInspection */ | ||||
|  | ||||
| declare(strict_types=1); | ||||
|  | ||||
| namespace FireflyIII\Console\Commands; | ||||
|  | ||||
| use FireflyIII\Repositories\Attachment\AttachmentRepositoryInterface; | ||||
| @@ -49,44 +52,45 @@ class DecryptAttachment extends Command | ||||
|  | ||||
|     /** | ||||
|      * Execute the console command. | ||||
|      * | ||||
|      * @SuppressWarnings(PHPMD.CyclomaticComplexity) // it's five its fine. | ||||
|      * @SuppressWarnings(PHPMD.CyclomaticComplexity) | ||||
|      * @SuppressWarnings(PHPMD.ExcessiveMethodLength) | ||||
|      * | ||||
|      * @return int | ||||
|      */ | ||||
|     public function handle() | ||||
|     public function handle(): int | ||||
|     { | ||||
|         /** @var AttachmentRepositoryInterface $repository */ | ||||
|         $repository     = app(AttachmentRepositoryInterface::class); | ||||
|         $attachmentId   = (int)$this->argument('id'); | ||||
|         $attachment     = $repository->findWithoutUser($attachmentId); | ||||
|         $attachmentName = trim($this->argument('name')); | ||||
|         $storagePath    = realpath(trim($this->argument('directory'))); | ||||
|         if (null === $attachment->id) { | ||||
|         $attachmentName = trim((string)$this->argument('name')); | ||||
|         $storagePath    = realpath(trim((string)$this->argument('directory'))); | ||||
|         if (null === $attachment) { | ||||
|             $this->error(sprintf('No attachment with id #%d', $attachmentId)); | ||||
|             Log::error(sprintf('DecryptAttachment: No attachment with id #%d', $attachmentId)); | ||||
|  | ||||
|             return; | ||||
|             return 1; | ||||
|         } | ||||
|  | ||||
|         if ($attachmentName !== $attachment->filename) { | ||||
|             $this->error('File name does not match.'); | ||||
|             Log::error('DecryptAttachment: File name does not match.'); | ||||
|  | ||||
|             return; | ||||
|             return 1; | ||||
|         } | ||||
|  | ||||
|         if (!is_dir($storagePath)) { | ||||
|             $this->error(sprintf('Path "%s" is not a directory.', $storagePath)); | ||||
|             Log::error(sprintf('DecryptAttachment: Path "%s" is not a directory.', $storagePath)); | ||||
|  | ||||
|             return; | ||||
|             return 1; | ||||
|         } | ||||
|  | ||||
|         if (!is_writable($storagePath)) { | ||||
|             $this->error(sprintf('Path "%s" is not writable.', $storagePath)); | ||||
|             Log::error(sprintf('DecryptAttachment: Path "%s" is not writable.', $storagePath)); | ||||
|  | ||||
|             return; | ||||
|             return 1; | ||||
|         } | ||||
|  | ||||
|         $fullPath = $storagePath . DIRECTORY_SEPARATOR . $attachment->filename; | ||||
| @@ -96,9 +100,10 @@ class DecryptAttachment extends Command | ||||
|         if (false === $result) { | ||||
|             $this->error('Could not write to file.'); | ||||
|  | ||||
|             return; | ||||
|             return 1; | ||||
|         } | ||||
|         $this->info(sprintf('%d bytes written. Exiting now..', $result)); | ||||
|  | ||||
|         return 0; | ||||
|     } | ||||
| } | ||||
|   | ||||
| @@ -1,8 +1,7 @@ | ||||
| <?php | ||||
| declare(strict_types=1); | ||||
| /** | ||||
|  * EncryptFile.php | ||||
|  * Copyright (c) 2017 thegrumpydictator@gmail.com | ||||
|  * Copyright (c) 2018 thegrumpydictator@gmail.com | ||||
|  * | ||||
|  * This file is part of Firefly III. | ||||
|  * | ||||
| @@ -20,6 +19,8 @@ declare(strict_types=1); | ||||
|  * along with Firefly III. If not, see <http://www.gnu.org/licenses/>. | ||||
|  */ | ||||
|  | ||||
| declare(strict_types=1); | ||||
|  | ||||
| namespace FireflyIII\Console\Commands; | ||||
|  | ||||
| use FireflyIII\Exceptions\FireflyException; | ||||
|   | ||||
| @@ -1,8 +1,7 @@ | ||||
| <?php | ||||
| declare(strict_types=1); | ||||
| /** | ||||
|  * Import.php | ||||
|  * Copyright (c) 2017 thegrumpydictator@gmail.com | ||||
|  * Copyright (c) 2018 thegrumpydictator@gmail.com | ||||
|  * | ||||
|  * This file is part of Firefly III. | ||||
|  * | ||||
| @@ -20,13 +19,18 @@ declare(strict_types=1); | ||||
|  * along with Firefly III. If not, see <http://www.gnu.org/licenses/>. | ||||
|  */ | ||||
|  | ||||
| /** @noinspection MultipleReturnStatementsInspection */ | ||||
| /** @noinspection PhpDynamicAsStaticMethodCallInspection */ | ||||
|  | ||||
| declare(strict_types=1); | ||||
|  | ||||
| namespace FireflyIII\Console\Commands; | ||||
|  | ||||
| use FireflyIII\Exceptions\FireflyException; | ||||
| use FireflyIII\Import\Routine\RoutineInterface; | ||||
| use FireflyIII\Models\ImportJob; | ||||
| use FireflyIII\Models\Tag; | ||||
| use Illuminate\Console\Command; | ||||
| use Illuminate\Support\MessageBag; | ||||
| use Log; | ||||
|  | ||||
| /** | ||||
| @@ -50,23 +54,26 @@ class Import extends Command | ||||
|  | ||||
|     /** | ||||
|      * Run the import routine. | ||||
|      * @SuppressWarnings(PHPMD.CyclomaticComplexity) | ||||
|      * @SuppressWarnings(PHPMD.ExcessiveMethodLength) | ||||
|      * | ||||
|      * @throws FireflyException | ||||
|      */ | ||||
|     public function handle() | ||||
|     public function handle(): int | ||||
|     { | ||||
|         Log::debug('Start start-import command'); | ||||
|         $jobKey = $this->argument('key'); | ||||
|         $jobKey = (string)$this->argument('key'); | ||||
|         /** @var ImportJob $job */ | ||||
|         $job    = ImportJob::where('key', $jobKey)->first(); | ||||
|         if (null === $job) { | ||||
|             $this->errorLine(sprintf('No job found with key "%s"', $jobKey)); | ||||
|  | ||||
|             return; | ||||
|             return 1; | ||||
|         } | ||||
|         if (!$this->isValid($job)) { | ||||
|             $this->errorLine('Job is not valid for some reason. Exit.'); | ||||
|  | ||||
|             return; | ||||
|             return 1; | ||||
|         } | ||||
|  | ||||
|         $this->infoLine(sprintf('Going to import job with key "%s" of type "%s"', $job->key, $job->file_type)); | ||||
| @@ -81,21 +88,32 @@ class Import extends Command | ||||
|  | ||||
|         /** @var RoutineInterface $routine */ | ||||
|         $routine = app($className); | ||||
|         $routine->setJob($job); | ||||
|         $routine->setImportJob($job); | ||||
|         $routine->run(); | ||||
|  | ||||
|         /** @var MessageBag $error */ | ||||
|         foreach ($routine->getErrors() as $index => $error) { | ||||
|         /** | ||||
|          * @var int    $index | ||||
|          * @var string $error | ||||
|          */ | ||||
|         foreach ($job->errors as $index => $error) { | ||||
|             $this->errorLine(sprintf('Error importing line #%d: %s', $index, $error)); | ||||
|         } | ||||
|  | ||||
|         $this->infoLine( | ||||
|             sprintf('The import has finished. %d transactions have been imported out of %d records.', $routine->getJournals()->count(), $routine->getLines()) | ||||
|         ); | ||||
|         /** @var Tag $tag */ | ||||
|         $tag   = $job->tag()->first(); | ||||
|         $count = 0; | ||||
|         if (null === $tag) { | ||||
|             $count = $tag->transactionJournals()->count(); | ||||
|         } | ||||
|  | ||||
|         $this->infoLine(sprintf('The import has finished. %d transactions have been imported.', $count)); | ||||
|  | ||||
|         return 0; | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      * Displays an error. | ||||
|      * | ||||
|      * @param string     $message | ||||
|      * @param array|null $data | ||||
|      */ | ||||
| @@ -107,6 +125,8 @@ class Import extends Command | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      * Displays an informational message. | ||||
|      * | ||||
|      * @param string $message | ||||
|      * @param array  $data | ||||
|      */ | ||||
|   | ||||
| @@ -1,8 +1,7 @@ | ||||
| <?php | ||||
| declare(strict_types=1); | ||||
| /** | ||||
|  * ScanAttachments.php | ||||
|  * Copyright (c) 2017 thegrumpydictator@gmail.com | ||||
|  * Copyright (c) 2018 thegrumpydictator@gmail.com | ||||
|  * | ||||
|  * This file is part of Firefly III. | ||||
|  * | ||||
| @@ -20,6 +19,10 @@ declare(strict_types=1); | ||||
|  * along with Firefly III. If not, see <http://www.gnu.org/licenses/>. | ||||
|  */ | ||||
|  | ||||
| /** @noinspection PhpDynamicAsStaticMethodCallInspection */ | ||||
|  | ||||
| declare(strict_types=1); | ||||
|  | ||||
| namespace FireflyIII\Console\Commands; | ||||
|  | ||||
| use Crypt; | ||||
| @@ -51,7 +54,7 @@ class ScanAttachments extends Command | ||||
|     /** | ||||
|      * Execute the console command. | ||||
|      */ | ||||
|     public function handle() | ||||
|     public function handle(): int | ||||
|     { | ||||
|         $attachments = Attachment::get(); | ||||
|         $disk        = Storage::disk('upload'); | ||||
| @@ -61,13 +64,13 @@ class ScanAttachments extends Command | ||||
|             try { | ||||
|                 $content = $disk->get($fileName); | ||||
|             } catch (FileNotFoundException $e) { | ||||
|                 $this->error(sprintf('Could not find data for attachment #%d', $attachment->id)); | ||||
|                 $this->error(sprintf('Could not find data for attachment #%d: %s', $attachment->id, $e->getMessage())); | ||||
|                 continue; | ||||
|             } | ||||
|             try { | ||||
|                 $decrypted = Crypt::decrypt($content); | ||||
|             } catch (DecryptException $e) { | ||||
|                 $this->error(sprintf('Could not decrypt data of attachment #%d', $attachment->id)); | ||||
|                 $this->error(sprintf('Could not decrypt data of attachment #%d: %s', $attachment->id, $e->getMessage())); | ||||
|                 continue; | ||||
|             } | ||||
|             $tmpfname = tempnam(sys_get_temp_dir(), 'FireflyIII'); | ||||
| @@ -79,5 +82,6 @@ class ScanAttachments extends Command | ||||
|             $attachment->save(); | ||||
|             $this->line(sprintf('Fixed attachment #%d', $attachment->id)); | ||||
|         } | ||||
|         return 0; | ||||
|     } | ||||
| } | ||||
|   | ||||
| @@ -1,8 +1,8 @@ | ||||
| <?php | ||||
| declare(strict_types=1); | ||||
|  | ||||
| /** | ||||
|  * UpgradeDatabase.php | ||||
|  * Copyright (c) 2017 thegrumpydictator@gmail.com | ||||
|  * Copyright (c) 2018 thegrumpydictator@gmail.com | ||||
|  * | ||||
|  * This file is part of Firefly III. | ||||
|  * | ||||
| @@ -20,6 +20,12 @@ declare(strict_types=1); | ||||
|  * along with Firefly III. If not, see <http://www.gnu.org/licenses/>. | ||||
|  */ | ||||
|  | ||||
| /** @noinspection MultipleReturnStatementsInspection */ | ||||
| /** @noinspection PhpStaticAsDynamicMethodCallInspection */ | ||||
| /** @noinspection PhpDynamicAsStaticMethodCallInspection */ | ||||
|  | ||||
| declare(strict_types=1); | ||||
|  | ||||
| namespace FireflyIII\Console\Commands; | ||||
|  | ||||
| use DB; | ||||
| @@ -40,22 +46,23 @@ use FireflyIII\Models\TransactionCurrency; | ||||
| use FireflyIII\Models\TransactionJournal; | ||||
| use FireflyIII\Models\TransactionJournalMeta; | ||||
| use FireflyIII\Models\TransactionType; | ||||
| use FireflyIII\Repositories\Account\AccountRepositoryInterface; | ||||
| use FireflyIII\Repositories\Currency\CurrencyRepositoryInterface; | ||||
| use FireflyIII\Repositories\Journal\JournalRepositoryInterface; | ||||
| use FireflyIII\User; | ||||
| use Illuminate\Console\Command; | ||||
| use Illuminate\Database\QueryException; | ||||
| use Illuminate\Support\Collection; | ||||
| use Log; | ||||
| use Preferences; | ||||
| use Schema; | ||||
| use UnexpectedValueException; | ||||
|  | ||||
| /** | ||||
|  * Class UpgradeDatabase. | ||||
|  * | ||||
|  * Upgrade user database. | ||||
|  * | ||||
|  * | ||||
|  * @SuppressWarnings(PHPMD.CouplingBetweenObjects) // it just touches a lot of things. | ||||
|  * @SuppressWarnings(PHPMD.ExcessiveClassComplexity) | ||||
|  * @SuppressWarnings(PHPMD.CouplingBetweenObjects) | ||||
|  */ | ||||
| class UpgradeDatabase extends Command | ||||
| { | ||||
| @@ -75,7 +82,7 @@ class UpgradeDatabase extends Command | ||||
|     /** | ||||
|      * Execute the console command. | ||||
|      */ | ||||
|     public function handle() | ||||
|     public function handle(): int | ||||
|     { | ||||
|         $this->setTransactionIdentifier(); | ||||
|         $this->updateAccountCurrencies(); | ||||
| @@ -89,22 +96,39 @@ class UpgradeDatabase extends Command | ||||
|         $this->migrateBillsToRules(); | ||||
|  | ||||
|         $this->info('Firefly III database is up to date.'); | ||||
|  | ||||
|         return 0; | ||||
|     } | ||||
|  | ||||
|     public function migrateBillsToRules() | ||||
|     /** | ||||
|      * Since it is one routine these warnings make sense and should be supressed. | ||||
|      * | ||||
|      * @SuppressWarnings(PHPMD.CyclomaticComplexity) | ||||
|      * @SuppressWarnings(PHPMD.ExcessiveMethodLength) | ||||
|      * @SuppressWarnings(PHPMD.NPathComplexity) | ||||
|      */ | ||||
|     public function migrateBillsToRules(): void | ||||
|     { | ||||
|         foreach (User::get() as $user) { | ||||
|             /** @var Preference $lang */ | ||||
|             $lang               = Preferences::getForUser($user, 'language', 'en_US'); | ||||
|             $lang               = app('preferences')->getForUser($user, 'language', 'en_US'); | ||||
|             $groupName          = (string)trans('firefly.rulegroup_for_bills_title', [], $lang->data); | ||||
|             $ruleGroup          = $user->ruleGroups()->where('title', $groupName)->first(); | ||||
|             $currencyPreference = Preferences::getForUser($user, 'currencyPreference', config('firefly.default_currency', 'EUR')); | ||||
|             $currency           = TransactionCurrency::where('code', $currencyPreference->data)->first(); | ||||
|             $currencyPreference = app('preferences')->getForUser($user, 'currencyPreference', config('firefly.default_currency', 'EUR')); | ||||
|  | ||||
|             if (null === $currencyPreference) { | ||||
|                 $this->error('User has no currency preference. Impossible.'); | ||||
|  | ||||
|                 return; | ||||
|             } | ||||
|  | ||||
|             $currency = TransactionCurrency::where('code', $currencyPreference->data)->first(); | ||||
|             if (null === $currency) { | ||||
|                 $this->line('Fall back to default currency in migrateBillsToRules().'); | ||||
|                 $currency = app('amount')->getDefaultCurrency(); | ||||
|             } | ||||
|  | ||||
|             if ($ruleGroup === null) { | ||||
|             if (null === $ruleGroup) { | ||||
|                 $array     = RuleGroup::get(['order'])->pluck('order')->toArray(); | ||||
|                 $order     = \count($array) > 0 ? max($array) + 1 : 1; | ||||
|                 $ruleGroup = RuleGroup::create( | ||||
| @@ -124,7 +148,7 @@ class UpgradeDatabase extends Command | ||||
|             $collection = $user->bills()->get(); | ||||
|             /** @var Bill $bill */ | ||||
|             foreach ($collection as $bill) { | ||||
|                 if ($bill->match !== 'MIGRATED_TO_RULES') { | ||||
|                 if ('MIGRATED_TO_RULES' !== $bill->match) { | ||||
|                     $rule = Rule::create( | ||||
|                         [ | ||||
|                             'user_id'         => $user->id, | ||||
| @@ -159,28 +183,41 @@ class UpgradeDatabase extends Command | ||||
|                             'order'           => 2, | ||||
|                         ] | ||||
|                     ); | ||||
|  | ||||
|                     // add triggers for amounts: | ||||
|                     RuleTrigger::create( | ||||
|                         [ | ||||
|                             'rule_id'         => $rule->id, | ||||
|                             'trigger_type'    => 'amount_less', | ||||
|                             'trigger_value'   => round($bill->amount_max, $currency->decimal_places), | ||||
|                             'active'          => 1, | ||||
|                             'stop_processing' => 0, | ||||
|                             'order'           => 3, | ||||
|                         ] | ||||
|                     ); | ||||
|                     RuleTrigger::create( | ||||
|                         [ | ||||
|                             'rule_id'         => $rule->id, | ||||
|                             'trigger_type'    => 'amount_more', | ||||
|                             'trigger_value'   => round($bill->amount_min, $currency->decimal_places), | ||||
|                             'active'          => 1, | ||||
|                             'stop_processing' => 0, | ||||
|                             'order'           => 4, | ||||
|                         ] | ||||
|                     ); | ||||
|                     if ($bill->amount_max !== $bill->amount_min) { | ||||
|                         // add triggers for amounts: | ||||
|                         RuleTrigger::create( | ||||
|                             [ | ||||
|                                 'rule_id'         => $rule->id, | ||||
|                                 'trigger_type'    => 'amount_less', | ||||
|                                 'trigger_value'   => round($bill->amount_max, $currency->decimal_places), | ||||
|                                 'active'          => 1, | ||||
|                                 'stop_processing' => 0, | ||||
|                                 'order'           => 3, | ||||
|                             ] | ||||
|                         ); | ||||
|                         RuleTrigger::create( | ||||
|                             [ | ||||
|                                 'rule_id'         => $rule->id, | ||||
|                                 'trigger_type'    => 'amount_more', | ||||
|                                 'trigger_value'   => round((float)$bill->amount_min, $currency->decimal_places), | ||||
|                                 'active'          => 1, | ||||
|                                 'stop_processing' => 0, | ||||
|                                 'order'           => 4, | ||||
|                             ] | ||||
|                         ); | ||||
|                     } | ||||
|                     if ($bill->amount_max === $bill->amount_min) { | ||||
|                         RuleTrigger::create( | ||||
|                             [ | ||||
|                                 'rule_id'         => $rule->id, | ||||
|                                 'trigger_type'    => 'amount_exactly', | ||||
|                                 'trigger_value'   => round((float)$bill->amount_min, $currency->decimal_places), | ||||
|                                 'active'          => 1, | ||||
|                                 'stop_processing' => 0, | ||||
|                                 'order'           => 3, | ||||
|                             ] | ||||
|                         ); | ||||
|                     } | ||||
|  | ||||
|                     // create action | ||||
|                     RuleAction::create( | ||||
| @@ -245,23 +282,29 @@ class UpgradeDatabase extends Command | ||||
|     /** | ||||
|      * Each (asset) account must have a reference to a preferred currency. If the account does not have one, it's forced upon the account. | ||||
|      * | ||||
|      * @SuppressWarnings(PHPMD.CyclomaticComplexity) // it's seven but it can't really be helped. | ||||
|      * @SuppressWarnings(PHPMD.CyclomaticComplexity) | ||||
|      * @SuppressWarnings(PHPMD.ExcessiveMethodLength) | ||||
|      */ | ||||
|     public function updateAccountCurrencies(): void | ||||
|     { | ||||
|         $accounts = Account::leftJoin('account_types', 'account_types.id', '=', 'accounts.account_type_id') | ||||
|                            ->whereIn('account_types.type', [AccountType::DEFAULT, AccountType::ASSET])->get(['accounts.*']); | ||||
|  | ||||
|         /** @var AccountRepositoryInterface $repository */ | ||||
|         $repository = app(AccountRepositoryInterface::class); | ||||
|         $accounts->each( | ||||
|             function (Account $account) { | ||||
|             function (Account $account) use ($repository) { | ||||
|                 $repository->setUser($account->user); | ||||
|                 // get users preference, fall back to system pref. | ||||
|                 $defaultCurrencyCode = Preferences::getForUser($account->user, 'currencyPreference', config('firefly.default_currency', 'EUR'))->data; | ||||
|                 $defaultCurrencyCode = app('preferences')->getForUser($account->user, 'currencyPreference', config('firefly.default_currency', 'EUR'))->data; | ||||
|                 $defaultCurrency     = TransactionCurrency::where('code', $defaultCurrencyCode)->first(); | ||||
|                 $accountCurrency     = (int)$account->getMeta('currency_id'); | ||||
|                 $accountCurrency     = (int)$repository->getMetaValue($account, 'currency_id'); | ||||
|                 $openingBalance      = $account->getOpeningBalance(); | ||||
|                 $obCurrency          = (int)$openingBalance->transaction_currency_id; | ||||
|  | ||||
|                 if (null === $defaultCurrency) { | ||||
|                     throw new UnexpectedValueException('The default currency is NULL, and this is more or less impossible.'); | ||||
|                 } | ||||
|  | ||||
|                 // both 0? set to default currency: | ||||
|                 if (0 === $accountCurrency && 0 === $obCurrency) { | ||||
|                     AccountMeta::where('account_id', $account->id)->where('name', 'currency_id')->forceDelete(); | ||||
| @@ -302,19 +345,22 @@ class UpgradeDatabase extends Command | ||||
|      * Both source and destination must match the respective currency preference of the related asset account. | ||||
|      * So FF3 must verify all transactions. | ||||
|      * | ||||
|      * @SuppressWarnings(PHPMD.CyclomaticComplexity) | ||||
|      * @SuppressWarnings(PHPMD.ExcessiveMethodLength) | ||||
|      */ | ||||
|     public function updateOtherCurrencies(): void | ||||
|     { | ||||
|         /** @var CurrencyRepositoryInterface $repository */ | ||||
|         $repository = app(CurrencyRepositoryInterface::class); | ||||
|         $set        = TransactionJournal | ||||
|         /** @var AccountRepositoryInterface $accountRepos */ | ||||
|         $accountRepos = app(AccountRepositoryInterface::class); | ||||
|         $set          = TransactionJournal | ||||
|             ::leftJoin('transaction_types', 'transaction_types.id', '=', 'transaction_journals.transaction_type_id') | ||||
|             ->whereIn('transaction_types.type', [TransactionType::WITHDRAWAL, TransactionType::DEPOSIT, TransactionType::OPENING_BALANCE]) | ||||
|             ->get(['transaction_journals.*']); | ||||
|  | ||||
|         $set->each( | ||||
|             function (TransactionJournal $journal) use ($repository) { | ||||
|             function (TransactionJournal $journal) use ($repository, $accountRepos) { | ||||
|                 // get the transaction with the asset account in it: | ||||
|                 /** @var Transaction $transaction */ | ||||
|                 $transaction = $journal->transactions() | ||||
| @@ -324,9 +370,13 @@ class UpgradeDatabase extends Command | ||||
|                 if (null === $transaction) { | ||||
|                     return; | ||||
|                 } | ||||
|                 $accountRepos->setUser($journal->user); | ||||
|                 /** @var Account $account */ | ||||
|                 $account      = $transaction->account; | ||||
|                 $currency     = $repository->find((int)$account->getMeta('currency_id')); | ||||
|                 $account  = $transaction->account; | ||||
|                 $currency = $repository->findNull((int)$accountRepos->getMetaValue($account, 'currency_id')); | ||||
|                 if (null === $currency) { | ||||
|                     return; | ||||
|                 } | ||||
|                 $transactions = $journal->transactions()->get(); | ||||
|                 $transactions->each( | ||||
|                     function (Transaction $transaction) use ($currency) { | ||||
| @@ -362,7 +412,7 @@ class UpgradeDatabase extends Command | ||||
|      * Both source and destination must match the respective currency preference. So FF3 must verify ALL | ||||
|      * transactions. | ||||
|      */ | ||||
|     public function updateTransferCurrencies() | ||||
|     public function updateTransferCurrencies(): void | ||||
|     { | ||||
|         $set = TransactionJournal | ||||
|             ::leftJoin('transaction_types', 'transaction_types.id', '=', 'transaction_journals.transaction_type_id') | ||||
| @@ -434,6 +484,7 @@ class UpgradeDatabase extends Command | ||||
|      */ | ||||
|     private function migrateNotes(): void | ||||
|     { | ||||
|         /** @noinspection PhpUndefinedMethodInspection */ | ||||
|         $set = TransactionJournalMeta::whereName('notes')->get(); | ||||
|         /** @var TransactionJournalMeta $meta */ | ||||
|         foreach ($set as $meta) { | ||||
| @@ -464,8 +515,15 @@ class UpgradeDatabase extends Command | ||||
|     { | ||||
|         /** @var CurrencyRepositoryInterface $repository */ | ||||
|         $repository = app(CurrencyRepositoryInterface::class); | ||||
|         $currency   = $repository->find((int)$transaction->account->getMeta('currency_id')); | ||||
|         $journal    = $transaction->transactionJournal; | ||||
|         /** @var AccountRepositoryInterface $accountRepos */ | ||||
|         $accountRepos = app(AccountRepositoryInterface::class); | ||||
|         $accountRepos->setUser($transaction->account->user); | ||||
|         $currency = $repository->findNull((int)$accountRepos->getMetaValue($transaction->account, 'currency_id')); | ||||
|         $journal  = $transaction->transactionJournal; | ||||
|  | ||||
|         if (null === $currency) { | ||||
|             return; | ||||
|         } | ||||
|  | ||||
|         if (!((int)$currency->id === (int)$journal->transaction_currency_id)) { | ||||
|             $this->line( | ||||
| @@ -534,11 +592,11 @@ class UpgradeDatabase extends Command | ||||
|      * | ||||
|      * The transaction that is sent to this function MUST be the source transaction (amount negative). | ||||
|      * | ||||
|      * Method is long and complex bit I'm taking it for granted. | ||||
|      * Method is long and complex but I'll allow it. https://imgur.com/gallery/dVDJiez | ||||
|      * | ||||
|      * @SuppressWarnings(PHPMD.CyclomaticComplexity) | ||||
|      * @SuppressWarnings(PHPMD.ExcessiveMethodLength) | ||||
|      * @SuppressWarnings(PHPMD.NPathComplexity) | ||||
|      * @SuppressWarnings(PHPMD.CyclomaticComplexity) | ||||
|      * | ||||
|      * @param Transaction $transaction | ||||
|      */ | ||||
| @@ -546,7 +604,14 @@ class UpgradeDatabase extends Command | ||||
|     { | ||||
|         /** @var CurrencyRepositoryInterface $repository */ | ||||
|         $repository = app(CurrencyRepositoryInterface::class); | ||||
|         $currency   = $repository->findNull((int)$transaction->account->getMeta('currency_id')); | ||||
|         /** @var AccountRepositoryInterface $accountRepos */ | ||||
|         $accountRepos = app(AccountRepositoryInterface::class); | ||||
|         /** @var JournalRepositoryInterface $journalRepos */ | ||||
|         $journalRepos = app(JournalRepositoryInterface::class); | ||||
|  | ||||
|         $accountRepos->setUser($transaction->account->user); | ||||
|         $journalRepos->setUser($transaction->account->user); | ||||
|         $currency = $repository->findNull((int)$accountRepos->getMetaValue($transaction->account, 'currency_id')); | ||||
|  | ||||
|         if (null === $currency) { | ||||
|             Log::error(sprintf('Account #%d ("%s") must have currency preference but has none.', $transaction->account->id, $transaction->account->name)); | ||||
| @@ -582,7 +647,7 @@ class UpgradeDatabase extends Command | ||||
|         $journal = $transaction->transactionJournal; | ||||
|         /** @var Transaction $opposing */ | ||||
|         $opposing         = $journal->transactions()->where('amount', '>', 0)->where('identifier', $transaction->identifier)->first(); | ||||
|         $opposingCurrency = $repository->findNull((int)$opposing->account->getMeta('currency_id')); | ||||
|         $opposingCurrency = $repository->findNull((int)$accountRepos->getMetaValue($opposing->account, 'currency_id')); | ||||
|  | ||||
|         if (null === $opposingCurrency) { | ||||
|             Log::error(sprintf('Account #%d ("%s") must have currency preference but has none.', $opposing->account->id, $opposing->account->name)); | ||||
| @@ -600,12 +665,16 @@ class UpgradeDatabase extends Command | ||||
|             $opposing->transaction_currency_id = $currency->id; | ||||
|             $transaction->save(); | ||||
|             $opposing->save(); | ||||
|             Log::debug(sprintf('Currency for account "%s" is %s, and currency for account "%s" is also | ||||
|             Log::debug( | ||||
|                 sprintf( | ||||
|                     'Currency for account "%s" is %s, and currency for account "%s" is also | ||||
|              %s, so %s #%d (#%d and #%d) has been verified to be to %s exclusively.', | ||||
|                                $opposing->account->name, $opposingCurrency->code, | ||||
|                                $transaction->account->name, $transaction->transactionCurrency->code, | ||||
|                                $journal->transactionType->type, $journal->id, | ||||
|                                $transaction->id, $opposing->id, $currency->code)); | ||||
|                     $opposing->account->name, $opposingCurrency->code, | ||||
|                     $transaction->account->name, $transaction->transactionCurrency->code, | ||||
|                     $journal->transactionType->type, $journal->id, | ||||
|                     $transaction->id, $opposing->id, $currency->code | ||||
|                 ) | ||||
|             ); | ||||
|  | ||||
|             return; | ||||
|         } | ||||
| @@ -634,7 +703,7 @@ class UpgradeDatabase extends Command | ||||
|  | ||||
|         // when both are zero, try to grab it from journal: | ||||
|         if (null === $opposing->foreign_amount && null === $transaction->foreign_amount) { | ||||
|             $foreignAmount = $journal->getMeta('foreign_amount'); | ||||
|             $foreignAmount = $journalRepos->getMetaField($journal, 'foreign_amount'); | ||||
|             if (null === $foreignAmount) { | ||||
|                 Log::debug(sprintf('Journal #%d has missing foreign currency data, forced to do 1:1 conversion :(.', $transaction->transaction_journal_id)); | ||||
|                 $transaction->foreign_amount = bcmul((string)$transaction->amount, '-1'); | ||||
|   | ||||
| @@ -1,8 +1,7 @@ | ||||
| <?php | ||||
| declare(strict_types=1); | ||||
| /** | ||||
|  * UpgradeFireflyInstructions.php | ||||
|  * Copyright (c) 2017 thegrumpydictator@gmail.com | ||||
|  * Copyright (c) 2018 thegrumpydictator@gmail.com | ||||
|  * | ||||
|  * This file is part of Firefly III. | ||||
|  * | ||||
| @@ -20,6 +19,8 @@ declare(strict_types=1); | ||||
|  * along with Firefly III. If not, see <http://www.gnu.org/licenses/>. | ||||
|  */ | ||||
|  | ||||
| declare(strict_types=1); | ||||
|  | ||||
| namespace FireflyIII\Console\Commands; | ||||
|  | ||||
| use Illuminate\Console\Command; | ||||
| @@ -45,14 +46,15 @@ class UpgradeFireflyInstructions extends Command | ||||
|     /** | ||||
|      * Execute the console command. | ||||
|      */ | ||||
|     public function handle() | ||||
|     public function handle(): int | ||||
|     { | ||||
|         if ('update' === $this->argument('task')) { | ||||
|         if ('update' === (string)$this->argument('task')) { | ||||
|             $this->updateInstructions(); | ||||
|         } | ||||
|         if ('install' === $this->argument('task')) { | ||||
|         if ('install' === (string)$this->argument('task')) { | ||||
|             $this->installInstructions(); | ||||
|         } | ||||
|         return 0; | ||||
|     } | ||||
|  | ||||
|     /** | ||||
| @@ -60,7 +62,7 @@ class UpgradeFireflyInstructions extends Command | ||||
|      * | ||||
|      * @param string $text | ||||
|      */ | ||||
|     private function boxed(string $text) | ||||
|     private function boxed(string $text): void | ||||
|     { | ||||
|         $parts = explode("\n", wordwrap($text)); | ||||
|         foreach ($parts as $string) { | ||||
| @@ -73,7 +75,7 @@ class UpgradeFireflyInstructions extends Command | ||||
|      * | ||||
|      * @param string $text | ||||
|      */ | ||||
|     private function boxedInfo(string $text) | ||||
|     private function boxedInfo(string $text): void | ||||
|     { | ||||
|         $parts = explode("\n", wordwrap($text)); | ||||
|         foreach ($parts as $string) { | ||||
| @@ -84,7 +86,7 @@ class UpgradeFireflyInstructions extends Command | ||||
|     /** | ||||
|      * Render instructions. | ||||
|      */ | ||||
|     private function installInstructions() | ||||
|     private function installInstructions(): void | ||||
|     { | ||||
|         /** @var string $version */ | ||||
|         $version = config('firefly.version'); | ||||
| @@ -92,8 +94,7 @@ class UpgradeFireflyInstructions extends Command | ||||
|         $text    = ''; | ||||
|         foreach (array_keys($config) as $compare) { | ||||
|             // if string starts with: | ||||
|             $len = \strlen($compare); | ||||
|             if (substr($version, 0, $len) === $compare) { | ||||
|             if (0 === strpos($version, $compare)) { | ||||
|                 $text = $config[$compare]; | ||||
|             } | ||||
|         } | ||||
| @@ -118,7 +119,7 @@ class UpgradeFireflyInstructions extends Command | ||||
|     /** | ||||
|      * Show a line. | ||||
|      */ | ||||
|     private function showLine() | ||||
|     private function showLine(): void | ||||
|     { | ||||
|         $line = '+'; | ||||
|         for ($i = 0; $i < 78; ++$i) { | ||||
| @@ -131,7 +132,7 @@ class UpgradeFireflyInstructions extends Command | ||||
|     /** | ||||
|      * Render upgrade instructions. | ||||
|      */ | ||||
|     private function updateInstructions() | ||||
|     private function updateInstructions(): void | ||||
|     { | ||||
|         /** @var string $version */ | ||||
|         $version = config('firefly.version'); | ||||
| @@ -139,8 +140,7 @@ class UpgradeFireflyInstructions extends Command | ||||
|         $text    = ''; | ||||
|         foreach (array_keys($config) as $compare) { | ||||
|             // if string starts with: | ||||
|             $len = \strlen($compare); | ||||
|             if (substr($version, 0, $len) === $compare) { | ||||
|             if (0 === strpos($version, $compare)) { | ||||
|                 $text = $config[$compare]; | ||||
|             } | ||||
|         } | ||||
|   | ||||
| @@ -1,9 +1,7 @@ | ||||
| <?php | ||||
| declare(strict_types=1); | ||||
|  | ||||
| /** | ||||
|  * UseEncryption.php | ||||
|  * Copyright (c) 2017 thegrumpydictator@gmail.com | ||||
|  * Copyright (c) 2018 thegrumpydictator@gmail.com | ||||
|  * | ||||
|  * This file is part of Firefly III. | ||||
|  * | ||||
| @@ -21,6 +19,8 @@ declare(strict_types=1); | ||||
|  * along with Firefly III. If not, see <http://www.gnu.org/licenses/>. | ||||
|  */ | ||||
|  | ||||
| declare(strict_types=1); | ||||
|  | ||||
| namespace FireflyIII\Console\Commands; | ||||
|  | ||||
| use Illuminate\Console\Command; | ||||
| @@ -47,12 +47,12 @@ class UseEncryption extends Command | ||||
|     /** | ||||
|      * Execute the console command. | ||||
|      */ | ||||
|     public function handle() | ||||
|     public function handle(): int | ||||
|     { | ||||
|         if (config('firefly.encryption') === true) { | ||||
|         if (true === config('firefly.encryption')) { | ||||
|             $this->info('Firefly III configuration calls for encrypted data.'); | ||||
|         } | ||||
|         if (config('firefly.encryption') === false) { | ||||
|         if (false === config('firefly.encryption')) { | ||||
|             $this->info('Firefly III configuration calls for unencrypted data.'); | ||||
|         } | ||||
|         $this->handleObjects('Account', 'name', 'encrypted'); | ||||
| @@ -62,6 +62,7 @@ class UseEncryption extends Command | ||||
|         $this->handleObjects('Category', 'name', 'encrypted'); | ||||
|         $this->handleObjects('PiggyBank', 'name', 'encrypted'); | ||||
|         $this->handleObjects('TransactionJournal', 'description', 'encrypted'); | ||||
|         return 0; | ||||
|     } | ||||
|  | ||||
|     /** | ||||
| @@ -71,18 +72,21 @@ class UseEncryption extends Command | ||||
|      * @param string $field | ||||
|      * @param string $indicator | ||||
|      */ | ||||
|     public function handleObjects(string $class, string $field, string $indicator) | ||||
|     public function handleObjects(string $class, string $field, string $indicator): void | ||||
|     { | ||||
|         $fqn     = sprintf('FireflyIII\Models\%s', $class); | ||||
|         $encrypt = config('firefly.encryption') === true ? 0 : 1; | ||||
|         $set     = $fqn::where($indicator, $encrypt)->get(); | ||||
|         $encrypt = true === config('firefly.encryption') ? 0 : 1; | ||||
|         /** @noinspection PhpUndefinedMethodInspection */ | ||||
|         $set = $fqn::where($indicator, $encrypt)->get(); | ||||
|  | ||||
|         foreach ($set as $entry) { | ||||
|             $newName       = $entry->$field; | ||||
|             $entry->$field = $newName; | ||||
|             /** @noinspection PhpUndefinedMethodInspection */ | ||||
|             $entry->save(); | ||||
|         } | ||||
|  | ||||
|         /** @noinspection PhpUndefinedMethodInspection */ | ||||
|         $this->line(sprintf('Updated %d %s.', $set->count(), strtolower(Str::plural($class)))); | ||||
|     } | ||||
| } | ||||
|   | ||||
| @@ -1,8 +1,7 @@ | ||||
| <?php | ||||
| declare(strict_types=1); | ||||
| /** | ||||
|  * VerifiesAccessToken.php | ||||
|  * Copyright (c) 2017 thegrumpydictator@gmail.com | ||||
|  * Copyright (c) 2018 thegrumpydictator@gmail.com | ||||
|  * | ||||
|  * This file is part of Firefly III. | ||||
|  * | ||||
| @@ -20,11 +19,12 @@ declare(strict_types=1); | ||||
|  * along with Firefly III. If not, see <http://www.gnu.org/licenses/>. | ||||
|  */ | ||||
|  | ||||
| declare(strict_types=1); | ||||
|  | ||||
| namespace FireflyIII\Console\Commands; | ||||
|  | ||||
| use FireflyIII\Repositories\User\UserRepositoryInterface; | ||||
| use Log; | ||||
| use Preferences; | ||||
|  | ||||
| /** | ||||
|  * Trait VerifiesAccessToken. | ||||
| @@ -60,7 +60,7 @@ trait VerifiesAccessToken | ||||
|  | ||||
|             return false; | ||||
|         } | ||||
|         $accessToken = Preferences::getForUser($user, 'access_token', null); | ||||
|         $accessToken = app('preferences')->getForUser($user, 'access_token', null); | ||||
|         if (null === $accessToken) { | ||||
|             Log::error(sprintf('User #%d has no access token, so cannot access command line options.', $userId)); | ||||
|  | ||||
|   | ||||
| @@ -1,8 +1,7 @@ | ||||
| <?php | ||||
| declare(strict_types=1); | ||||
| /** | ||||
|  * VerifyDatabase.php | ||||
|  * Copyright (c) 2017 thegrumpydictator@gmail.com | ||||
|  * Copyright (c) 2018 thegrumpydictator@gmail.com | ||||
|  * | ||||
|  * This file is part of Firefly III. | ||||
|  * | ||||
| @@ -20,6 +19,10 @@ declare(strict_types=1); | ||||
|  * along with Firefly III. If not, see <http://www.gnu.org/licenses/>. | ||||
|  */ | ||||
|  | ||||
| /** @noinspection PhpDynamicAsStaticMethodCallInspection */ | ||||
|  | ||||
| declare(strict_types=1); | ||||
|  | ||||
| namespace FireflyIII\Console\Commands; | ||||
|  | ||||
| use Crypt; | ||||
| @@ -27,6 +30,7 @@ use DB; | ||||
| use FireflyIII\Models\Account; | ||||
| use FireflyIII\Models\AccountType; | ||||
| use FireflyIII\Models\Budget; | ||||
| use FireflyIII\Models\Category; | ||||
| use FireflyIII\Models\LinkType; | ||||
| use FireflyIII\Models\PiggyBankEvent; | ||||
| use FireflyIII\Models\Transaction; | ||||
| @@ -37,13 +41,14 @@ use FireflyIII\User; | ||||
| use Illuminate\Console\Command; | ||||
| use Illuminate\Contracts\Encryption\DecryptException; | ||||
| use Illuminate\Database\Eloquent\Builder; | ||||
| use Preferences; | ||||
| use Log; | ||||
| use Schema; | ||||
| use stdClass; | ||||
|  | ||||
| /** | ||||
|  * Class VerifyDatabase. | ||||
|  * | ||||
|  * @SuppressWarnings(PHPMD.ExcessiveClassComplexity) | ||||
|  * @SuppressWarnings(PHPMD.CouplingBetweenObjects) | ||||
|  */ | ||||
| class VerifyDatabase extends Command | ||||
| @@ -64,15 +69,15 @@ class VerifyDatabase extends Command | ||||
|     /** | ||||
|      * Execute the console command. | ||||
|      */ | ||||
|     public function handle() | ||||
|     public function handle(): int | ||||
|     { | ||||
|         // if table does not exist, return false | ||||
|         if (!Schema::hasTable('users')) { | ||||
|             return; | ||||
|             return 1; | ||||
|         } | ||||
|  | ||||
|         $this->reportObject('budget'); | ||||
|         $this->reportObject('category'); | ||||
|         $this->reportEmptyBudgets(); | ||||
|         $this->reportEmptyCategories(); | ||||
|         $this->reportObject('tag'); | ||||
|         $this->reportAccounts(); | ||||
|         $this->reportBudgetLimits(); | ||||
| @@ -88,6 +93,9 @@ class VerifyDatabase extends Command | ||||
|         $this->createAccessTokens(); | ||||
|         $this->fixDoubleAmounts(); | ||||
|         $this->fixBadMeta(); | ||||
|         $this->removeBills(); | ||||
|  | ||||
|         return 0; | ||||
|     } | ||||
|  | ||||
|     /** | ||||
| @@ -99,10 +107,10 @@ class VerifyDatabase extends Command | ||||
|         $users = User::get(); | ||||
|         /** @var User $user */ | ||||
|         foreach ($users as $user) { | ||||
|             $pref = Preferences::getForUser($user, 'access_token', null); | ||||
|             $pref = app('preferences')->getForUser($user, 'access_token', null); | ||||
|             if (null === $pref) { | ||||
|                 $token = $user->generateAccessToken(); | ||||
|                 Preferences::setForUser($user, 'access_token', $token); | ||||
|                 app('preferences')->setForUser($user, 'access_token', $token); | ||||
|                 $this->line(sprintf('Generated access token for user %s', $user->email)); | ||||
|                 ++$count; | ||||
|             } | ||||
| @@ -142,9 +150,10 @@ class VerifyDatabase extends Command | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      * Fix the situation where the matching transactions | ||||
|      * of a journal somehow have non-matching categories | ||||
|      * or budgets | ||||
|      * Fix the situation where the matching transactions of a journal somehow have non-matching categories or budgets. | ||||
|      * | ||||
|      * @SuppressWarnings(PHPMD.CyclomaticComplexity) | ||||
|      * @SuppressWarnings(PHPMD.ExcessiveMethodLength) | ||||
|      */ | ||||
|     private function fixBadMeta(): void | ||||
|     { | ||||
| @@ -162,7 +171,8 @@ class VerifyDatabase extends Command | ||||
|             if (isset($results[$key]) && $results[$key] !== $category) { | ||||
|                 $this->error( | ||||
|                     sprintf( | ||||
|                         'Transaction #%d referred to the wrong category. Was category #%d but is fixed to be category #%d.', $obj->transaction_journal_id, $category, $results[$key] | ||||
|                         'Transaction #%d referred to the wrong category. Was category #%d but is fixed to be category #%d.', $obj->transaction_journal_id, | ||||
|                         $category, $results[$key] | ||||
|                     ) | ||||
|                 ); | ||||
|                 DB::table('category_transaction')->where('id', $obj->ct_id)->update(['category_id' => $results[$key]]); | ||||
| @@ -182,14 +192,15 @@ class VerifyDatabase extends Command | ||||
|             ->get(['transactions.id', 'transaction_journal_id', 'identifier', 'budget_transaction.budget_id', 'budget_transaction.id as ct_id']); | ||||
|         $results = []; | ||||
|         foreach ($set as $obj) { | ||||
|             $key      = $obj->transaction_journal_id . '-' . $obj->identifier; | ||||
|             $key    = $obj->transaction_journal_id . '-' . $obj->identifier; | ||||
|             $budget = (int)$obj->budget_id; | ||||
|  | ||||
|             // value exists and is not budget: | ||||
|             if (isset($results[$key]) && $results[$key] !== $budget) { | ||||
|                 $this->error( | ||||
|                     sprintf( | ||||
|                         'Transaction #%d referred to the wrong budget. Was budget #%d but is fixed to be budget #%d.', $obj->transaction_journal_id, $budget, $results[$key] | ||||
|                         'Transaction #%d referred to the wrong budget. Was budget #%d but is fixed to be budget #%d.', $obj->transaction_journal_id, $budget, | ||||
|                         $results[$key] | ||||
|                     ) | ||||
|                 ); | ||||
|                 DB::table('budget_transaction')->where('id', $obj->ct_id)->update(['budget_id' => $results[$key]]); | ||||
| @@ -203,6 +214,12 @@ class VerifyDatabase extends Command | ||||
|         } | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      * Makes sure amounts are stored correctly. | ||||
|      * | ||||
|      * @SuppressWarnings(PHPMD.CyclomaticComplexity) | ||||
|      * @SuppressWarnings(PHPMD.ExcessiveMethodLength) | ||||
|      */ | ||||
|     private function fixDoubleAmounts(): void | ||||
|     { | ||||
|         $count = 0; | ||||
| @@ -251,6 +268,23 @@ class VerifyDatabase extends Command | ||||
|         } | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      * Removes bills from journals that should not have bills. | ||||
|      */ | ||||
|     private function removeBills(): void | ||||
|     { | ||||
|         /** @var TransactionType $withdrawal */ | ||||
|         $withdrawal = TransactionType::where('type', TransactionType::WITHDRAWAL)->first(); | ||||
|         $journals   = TransactionJournal::whereNotNull('bill_id') | ||||
|                                         ->where('transaction_type_id', '!=', $withdrawal->id)->get(); | ||||
|         /** @var TransactionJournal $journal */ | ||||
|         foreach ($journals as $journal) { | ||||
|             $this->line(sprintf('Transaction journal #%d should not be linked to bill #%d.', $journal->id, $journal->bill_id)); | ||||
|             $journal->bill_id = null; | ||||
|             $journal->save(); | ||||
|         } | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      * Eeport (and fix) piggy banks. Make sure there are only transfers linked to piggy bank events. | ||||
|      */ | ||||
| @@ -283,7 +317,7 @@ class VerifyDatabase extends Command | ||||
|     /** | ||||
|      * Reports on accounts with no transactions. | ||||
|      */ | ||||
|     private function reportAccounts() | ||||
|     private function reportAccounts(): void | ||||
|     { | ||||
|         $set = Account::leftJoin('transactions', 'transactions.account_id', '=', 'accounts.id') | ||||
|                       ->leftJoin('users', 'accounts.user_id', '=', 'users.id') | ||||
| @@ -356,6 +390,82 @@ class VerifyDatabase extends Command | ||||
|         } | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      * Report on budgets with no transactions or journals. | ||||
|      */ | ||||
|     private function reportEmptyBudgets(): void | ||||
|     { | ||||
|         $set = Budget::leftJoin('budget_transaction_journal', 'budgets.id', '=', 'budget_transaction_journal.budget_id') | ||||
|                      ->leftJoin('users', 'budgets.user_id', '=', 'users.id') | ||||
|                      ->distinct() | ||||
|                      ->whereNull('budget_transaction_journal.budget_id') | ||||
|                      ->whereNull('budgets.deleted_at') | ||||
|                      ->get(['budgets.id', 'budgets.name', 'budgets.user_id', 'users.email']); | ||||
|  | ||||
|         /** @var stdClass $entry */ | ||||
|         foreach ($set as $entry) { | ||||
|             $objName = $entry->name; | ||||
|             try { | ||||
|                 $objName = Crypt::decrypt($objName); | ||||
|             } catch (DecryptException $e) { | ||||
|                 // it probably was not encrypted. | ||||
|                 Log::debug(sprintf('Not a problem: %s', $e->getMessage())); | ||||
|             } | ||||
|  | ||||
|             // also count the transactions: | ||||
|             $countTransactions = DB::table('budget_transaction')->where('budget_id', $entry->id)->count(); | ||||
|  | ||||
|             if (0 === $countTransactions) { | ||||
|                 $line = sprintf( | ||||
|                     'User #%d (%s) has budget #%d ("%s") which has no transactions.', | ||||
|                     $entry->user_id, | ||||
|                     $entry->email, | ||||
|                     $entry->id, | ||||
|                     $objName | ||||
|                 ); | ||||
|                 $this->line($line); | ||||
|             } | ||||
|         } | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      * Report on categories with no transactions or journals. | ||||
|      */ | ||||
|     private function reportEmptyCategories(): void | ||||
|     { | ||||
|         $set = Category::leftJoin('category_transaction_journal', 'categories.id', '=', 'category_transaction_journal.category_id') | ||||
|                        ->leftJoin('users', 'categories.user_id', '=', 'users.id') | ||||
|                        ->distinct() | ||||
|                        ->whereNull('category_transaction_journal.category_id') | ||||
|                        ->whereNull('categories.deleted_at') | ||||
|                        ->get(['categories.id', 'categories.name', 'categories.user_id', 'users.email']); | ||||
|  | ||||
|         /** @var stdClass $entry */ | ||||
|         foreach ($set as $entry) { | ||||
|             $objName = $entry->name; | ||||
|             try { | ||||
|                 $objName = Crypt::decrypt($objName); | ||||
|             } catch (DecryptException $e) { | ||||
|                 // it probably was not encrypted. | ||||
|                 Log::debug(sprintf('Not a problem: %s', $e->getMessage())); | ||||
|             } | ||||
|  | ||||
|             // also count the transactions: | ||||
|             $countTransactions = DB::table('category_transaction')->where('category_id', $entry->id)->count(); | ||||
|  | ||||
|             if (0 === $countTransactions) { | ||||
|                 $line = sprintf( | ||||
|                     'User #%d (%s) has category #%d ("%s") which has no transactions.', | ||||
|                     $entry->user_id, | ||||
|                     $entry->email, | ||||
|                     $entry->id, | ||||
|                     $objName | ||||
|                 ); | ||||
|                 $this->line($line); | ||||
|             } | ||||
|         } | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      * Report on journals with bad account types linked to them. | ||||
|      */ | ||||
| @@ -461,12 +571,13 @@ class VerifyDatabase extends Command | ||||
|         $plural = str_plural($name); | ||||
|         $class  = sprintf('FireflyIII\Models\%s', ucfirst($name)); | ||||
|         $field  = 'tag' === $name ? 'tag' : 'name'; | ||||
|         $set    = $class::leftJoin($name . '_transaction_journal', $plural . '.id', '=', $name . '_transaction_journal.' . $name . '_id') | ||||
|                         ->leftJoin('users', $plural . '.user_id', '=', 'users.id') | ||||
|                         ->distinct() | ||||
|                         ->whereNull($name . '_transaction_journal.' . $name . '_id') | ||||
|                         ->whereNull($plural . '.deleted_at') | ||||
|                         ->get([$plural . '.id', $plural . '.' . $field . ' as name', $plural . '.user_id', 'users.email']); | ||||
|         /** @noinspection PhpUndefinedMethodInspection */ | ||||
|         $set = $class::leftJoin($name . '_transaction_journal', $plural . '.id', '=', $name . '_transaction_journal.' . $name . '_id') | ||||
|                      ->leftJoin('users', $plural . '.user_id', '=', 'users.id') | ||||
|                      ->distinct() | ||||
|                      ->whereNull($name . '_transaction_journal.' . $name . '_id') | ||||
|                      ->whereNull($plural . '.deleted_at') | ||||
|                      ->get([$plural . '.id', $plural . '.' . $field . ' as name', $plural . '.user_id', 'users.email']); | ||||
|  | ||||
|         /** @var stdClass $entry */ | ||||
|         foreach ($set as $entry) { | ||||
| @@ -475,6 +586,7 @@ class VerifyDatabase extends Command | ||||
|                 $objName = Crypt::decrypt($objName); | ||||
|             } catch (DecryptException $e) { | ||||
|                 // it probably was not encrypted. | ||||
|                 Log::debug(sprintf('Not a problem: %s', $e->getMessage())); | ||||
|             } | ||||
|  | ||||
|             $line = sprintf( | ||||
| @@ -502,7 +614,8 @@ class VerifyDatabase extends Command | ||||
|             $sum = (string)$user->transactions()->sum('amount'); | ||||
|             if (0 !== bccomp($sum, '0')) { | ||||
|                 $this->error('Error: Transactions for user #' . $user->id . ' (' . $user->email . ') are off by ' . $sum . '!'); | ||||
|             } else { | ||||
|             } | ||||
|             if (0 === bccomp($sum, '0')) { | ||||
|                 $this->info(sprintf('Amount integrity OK for user #%d', $user->id)); | ||||
|             } | ||||
|         } | ||||
| @@ -532,7 +645,7 @@ class VerifyDatabase extends Command | ||||
|     /** | ||||
|      * Report on transfers that have budgets. | ||||
|      */ | ||||
|     private function reportTransfersBudgets() | ||||
|     private function reportTransfersBudgets(): void | ||||
|     { | ||||
|         $set = TransactionJournal::distinct() | ||||
|                                  ->leftJoin('transaction_types', 'transaction_types.id', '=', 'transaction_journals.transaction_type_id') | ||||
|   | ||||
| @@ -1,8 +1,8 @@ | ||||
| <?php | ||||
| declare(strict_types=1); | ||||
|  | ||||
| /** | ||||
|  * Kernel.php | ||||
|  * Copyright (c) 2017 thegrumpydictator@gmail.com | ||||
|  * Copyright (c) 2018 thegrumpydictator@gmail.com | ||||
|  * | ||||
|  * This file is part of Firefly III. | ||||
|  * | ||||
| @@ -20,32 +20,28 @@ declare(strict_types=1); | ||||
|  * along with Firefly III. If not, see <http://www.gnu.org/licenses/>. | ||||
|  */ | ||||
|  | ||||
| declare(strict_types=1); | ||||
|  | ||||
| namespace FireflyIII\Console; | ||||
|  | ||||
| use Carbon\Carbon; | ||||
| use FireflyIII\Jobs\CreateRecurringTransactions; | ||||
| use Illuminate\Console\Scheduling\Schedule; | ||||
| use Illuminate\Foundation\Console\Kernel as ConsoleKernel; | ||||
|  | ||||
| /** | ||||
|  * File to make sure commnds work. | ||||
|  * File to make sure commands work. | ||||
|  */ | ||||
| class Kernel extends ConsoleKernel | ||||
| { | ||||
|     /** | ||||
|      * The Artisan commands provided by your application. | ||||
|      * | ||||
|      * @var array | ||||
|      */ | ||||
|     protected $commands | ||||
|         = [ | ||||
|         ]; | ||||
|  | ||||
|     /** | ||||
|      * Register the commands for the application. | ||||
|      */ | ||||
|     protected function commands() | ||||
|     protected function commands(): void | ||||
|     { | ||||
|         $this->load(__DIR__ . '/Commands'); | ||||
|  | ||||
|         /** @noinspection PhpIncludeInspection */ | ||||
|         require base_path('routes/console.php'); | ||||
|     } | ||||
|  | ||||
| @@ -53,10 +49,9 @@ class Kernel extends ConsoleKernel | ||||
|      * Define the application's command schedule. | ||||
|      * | ||||
|      * @param \Illuminate\Console\Scheduling\Schedule $schedule | ||||
|      * | ||||
|      * @SuppressWarnings(PHPMD.UnusedFormalParameter) | ||||
|      */ | ||||
|     protected function schedule(Schedule $schedule) | ||||
|     protected function schedule(Schedule $schedule): void | ||||
|     { | ||||
|         $schedule->job(new CreateRecurringTransactions(new Carbon))->daily(); | ||||
|     } | ||||
| } | ||||
|   | ||||
| @@ -1,8 +1,8 @@ | ||||
| <?php | ||||
| declare(strict_types=1); | ||||
|  | ||||
| /** | ||||
|  * AdminRequestedTestMessage.php | ||||
|  * Copyright (c) 2017 thegrumpydictator@gmail.com | ||||
|  * Copyright (c) 2018 thegrumpydictator@gmail.com | ||||
|  * | ||||
|  * This file is part of Firefly III. | ||||
|  * | ||||
| @@ -20,6 +20,8 @@ declare(strict_types=1); | ||||
|  * along with Firefly III. If not, see <http://www.gnu.org/licenses/>. | ||||
|  */ | ||||
|  | ||||
| declare(strict_types=1); | ||||
|  | ||||
| namespace FireflyIII\Events; | ||||
|  | ||||
| use FireflyIII\User; | ||||
| @@ -33,13 +35,9 @@ class AdminRequestedTestMessage extends Event | ||||
| { | ||||
|     use SerializesModels; | ||||
|  | ||||
|     /** | ||||
|      * @var string | ||||
|      */ | ||||
|     /** @var string The users IP address */ | ||||
|     public $ipAddress; | ||||
|     /** | ||||
|      * @var User | ||||
|      */ | ||||
|     /** @var User The user */ | ||||
|     public $user; | ||||
|  | ||||
|     /** | ||||
|   | ||||
| @@ -1,8 +1,8 @@ | ||||
| <?php | ||||
| declare(strict_types=1); | ||||
|  | ||||
| /** | ||||
|  * Event.php | ||||
|  * Copyright (c) 2017 thegrumpydictator@gmail.com | ||||
|  * Copyright (c) 2018 thegrumpydictator@gmail.com | ||||
|  * | ||||
|  * This file is part of Firefly III. | ||||
|  * | ||||
| @@ -20,6 +20,8 @@ declare(strict_types=1); | ||||
|  * along with Firefly III. If not, see <http://www.gnu.org/licenses/>. | ||||
|  */ | ||||
|  | ||||
| declare(strict_types=1); | ||||
|  | ||||
| namespace FireflyIII\Events; | ||||
|  | ||||
| /** | ||||
|   | ||||
| @@ -1,8 +1,8 @@ | ||||
| <?php | ||||
| declare(strict_types=1); | ||||
|  | ||||
| /** | ||||
|  * RegisteredUser.php | ||||
|  * Copyright (c) 2017 thegrumpydictator@gmail.com | ||||
|  * Copyright (c) 2018 thegrumpydictator@gmail.com | ||||
|  * | ||||
|  * This file is part of Firefly III. | ||||
|  * | ||||
| @@ -20,6 +20,8 @@ declare(strict_types=1); | ||||
|  * along with Firefly III. If not, see <http://www.gnu.org/licenses/>. | ||||
|  */ | ||||
|  | ||||
| declare(strict_types=1); | ||||
|  | ||||
| namespace FireflyIII\Events; | ||||
|  | ||||
| use FireflyIII\User; | ||||
| @@ -32,13 +34,9 @@ class RegisteredUser extends Event | ||||
| { | ||||
|     use SerializesModels; | ||||
|  | ||||
|     /** | ||||
|      * @var string | ||||
|      */ | ||||
|     /** @var string The users IP address */ | ||||
|     public $ipAddress; | ||||
|     /** | ||||
|      * @var User | ||||
|      */ | ||||
|     /** @var User The user */ | ||||
|     public $user; | ||||
|  | ||||
|     /** | ||||
|   | ||||
| @@ -1,8 +1,8 @@ | ||||
| <?php | ||||
| declare(strict_types=1); | ||||
|  | ||||
| /** | ||||
|  * RequestedNewPassword.php | ||||
|  * Copyright (c) 2017 thegrumpydictator@gmail.com | ||||
|  * Copyright (c) 2018 thegrumpydictator@gmail.com | ||||
|  * | ||||
|  * This file is part of Firefly III. | ||||
|  * | ||||
| @@ -20,6 +20,8 @@ declare(strict_types=1); | ||||
|  * along with Firefly III. If not, see <http://www.gnu.org/licenses/>. | ||||
|  */ | ||||
|  | ||||
| declare(strict_types=1); | ||||
|  | ||||
| namespace FireflyIII\Events; | ||||
|  | ||||
| use FireflyIII\User; | ||||
| @@ -32,18 +34,12 @@ class RequestedNewPassword extends Event | ||||
| { | ||||
|     use SerializesModels; | ||||
|  | ||||
|     /** | ||||
|      * @var string | ||||
|      */ | ||||
|     /** @var string The users IP address */ | ||||
|     public $ipAddress; | ||||
|     /** | ||||
|      * @var string | ||||
|      */ | ||||
|     public $token; | ||||
|     /** | ||||
|      * @var User | ||||
|      */ | ||||
|     /** @var User The user */ | ||||
|     public $user; | ||||
|     /** @var string The token */ | ||||
|     public $token; | ||||
|  | ||||
|     /** | ||||
|      * Create a new event instance. This event is triggered when a users tries to reset his or her password. | ||||
|   | ||||
							
								
								
									
										66
									
								
								app/Events/RequestedReportOnJournals.php
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										66
									
								
								app/Events/RequestedReportOnJournals.php
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,66 @@ | ||||
| <?php | ||||
| declare(strict_types=1); | ||||
| /** | ||||
|  * RequestedReportOnJournals.php | ||||
|  * Copyright (c) 2018 thegrumpydictator@gmail.com | ||||
|  * | ||||
|  * This file is part of Firefly III. | ||||
|  * | ||||
|  * Firefly III is free software: you can redistribute it and/or modify | ||||
|  * it under the terms of the GNU General Public License as published by | ||||
|  * the Free Software Foundation, either version 3 of the License, or | ||||
|  * (at your option) any later version. | ||||
|  * | ||||
|  * Firefly III is distributed in the hope that it will be useful, | ||||
|  * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||||
|  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the | ||||
|  * GNU General Public License for more details. | ||||
|  * | ||||
|  * You should have received a copy of the GNU General Public License | ||||
|  * along with Firefly III. If not, see <http://www.gnu.org/licenses/>. | ||||
|  */ | ||||
|  | ||||
| namespace FireflyIII\Events; | ||||
|  | ||||
| use Illuminate\Broadcasting\InteractsWithSockets; | ||||
| use Illuminate\Broadcasting\PrivateChannel; | ||||
| use Illuminate\Foundation\Events\Dispatchable; | ||||
| use Illuminate\Queue\SerializesModels; | ||||
| use Illuminate\Support\Collection; | ||||
| use Log; | ||||
|  | ||||
| /** | ||||
|  * Class RequestedReportOnJournals | ||||
|  */ | ||||
| class RequestedReportOnJournals | ||||
| { | ||||
|     use Dispatchable, InteractsWithSockets, SerializesModels; | ||||
|  | ||||
|     /** @var Collection The journals to report on. */ | ||||
|     public $journals; | ||||
|     /** @var int The ID of the user. */ | ||||
|     public $userId; | ||||
|  | ||||
|     /** | ||||
|      * Create a new event instance. | ||||
|      * | ||||
|      * @param int        $userId | ||||
|      * @param Collection $journals | ||||
|      */ | ||||
|     public function __construct(int $userId, Collection $journals) | ||||
|     { | ||||
|         Log::debug('In event RequestedReportOnJournals.'); | ||||
|         $this->userId   = $userId; | ||||
|         $this->journals = $journals; | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      * Get the channels the event should broadcast on. | ||||
|      * | ||||
|      * @return \Illuminate\Broadcasting\Channel|array | ||||
|      */ | ||||
|     public function broadcastOn() | ||||
|     { | ||||
|         return new PrivateChannel('channel-name'); | ||||
|     } | ||||
| } | ||||
| @@ -1,8 +1,8 @@ | ||||
| <?php | ||||
| declare(strict_types=1); | ||||
|  | ||||
| /** | ||||
|  * RequestedVersionCheckStatus.php | ||||
|  * Copyright (c) 2017 thegrumpydictator@gmail.com | ||||
|  * Copyright (c) 2018 thegrumpydictator@gmail.com | ||||
|  * | ||||
|  * This file is part of Firefly III. | ||||
|  * | ||||
| @@ -20,6 +20,7 @@ declare(strict_types=1); | ||||
|  * along with Firefly III. If not, see <http://www.gnu.org/licenses/>. | ||||
|  */ | ||||
|  | ||||
| declare(strict_types=1); | ||||
|  | ||||
| namespace FireflyIII\Events; | ||||
|  | ||||
| @@ -34,9 +35,7 @@ class RequestedVersionCheckStatus extends Event | ||||
| { | ||||
|     use SerializesModels; | ||||
|  | ||||
|     /** | ||||
|      * @var User | ||||
|      */ | ||||
|     /** @var User The user */ | ||||
|     public $user; | ||||
|  | ||||
|     /** | ||||
|   | ||||
| @@ -1,8 +1,8 @@ | ||||
| <?php | ||||
| declare(strict_types=1); | ||||
|  | ||||
| /** | ||||
|  * StoredTransactionJournal.php | ||||
|  * Copyright (c) 2017 thegrumpydictator@gmail.com | ||||
|  * Copyright (c) 2018 thegrumpydictator@gmail.com | ||||
|  * | ||||
|  * This file is part of Firefly III. | ||||
|  * | ||||
| @@ -20,22 +20,25 @@ declare(strict_types=1); | ||||
|  * along with Firefly III. If not, see <http://www.gnu.org/licenses/>. | ||||
|  */ | ||||
|  | ||||
| declare(strict_types=1); | ||||
|  | ||||
| namespace FireflyIII\Events; | ||||
|  | ||||
| use FireflyIII\Models\TransactionJournal; | ||||
| use Illuminate\Queue\SerializesModels; | ||||
|  | ||||
| /** | ||||
|  * @codeCoverageIgnore | ||||
|  * Class StoredTransactionJournal. | ||||
|  * | ||||
|  * @codeCoverageIgnore | ||||
|  */ | ||||
| class StoredTransactionJournal extends Event | ||||
| { | ||||
|     use SerializesModels; | ||||
|  | ||||
|     /** @var TransactionJournal */ | ||||
|     /** @var TransactionJournal The journal that was stored. */ | ||||
|     public $journal; | ||||
|     /** @var int */ | ||||
|     /** @var int The piggy bank ID. */ | ||||
|     public $piggyBankId; | ||||
|  | ||||
|     /** | ||||
|   | ||||
| @@ -1,8 +1,8 @@ | ||||
| <?php | ||||
| declare(strict_types=1); | ||||
|  | ||||
| /** | ||||
|  * UpdatedTransactionJournal.php | ||||
|  * Copyright (c) 2017 thegrumpydictator@gmail.com | ||||
|  * Copyright (c) 2018 thegrumpydictator@gmail.com | ||||
|  * | ||||
|  * This file is part of Firefly III. | ||||
|  * | ||||
| @@ -20,6 +20,8 @@ declare(strict_types=1); | ||||
|  * along with Firefly III. If not, see <http://www.gnu.org/licenses/>. | ||||
|  */ | ||||
|  | ||||
| declare(strict_types=1); | ||||
|  | ||||
| namespace FireflyIII\Events; | ||||
|  | ||||
| use FireflyIII\Models\TransactionJournal; | ||||
| @@ -35,7 +37,7 @@ class UpdatedTransactionJournal extends Event | ||||
| { | ||||
|     use SerializesModels; | ||||
|  | ||||
|     /** @var TransactionJournal */ | ||||
|     /** @var TransactionJournal The journal. */ | ||||
|     public $journal; | ||||
|  | ||||
|     /** | ||||
|   | ||||
| @@ -1,8 +1,8 @@ | ||||
| <?php | ||||
| declare(strict_types=1); | ||||
|  | ||||
| /** | ||||
|  * UserChangedEmail.php | ||||
|  * Copyright (c) 2017 thegrumpydictator@gmail.com | ||||
|  * Copyright (c) 2018 thegrumpydictator@gmail.com | ||||
|  * | ||||
|  * This file is part of Firefly III. | ||||
|  * | ||||
| @@ -20,6 +20,8 @@ declare(strict_types=1); | ||||
|  * along with Firefly III. If not, see <http://www.gnu.org/licenses/>. | ||||
|  */ | ||||
|  | ||||
| declare(strict_types=1); | ||||
|  | ||||
| namespace FireflyIII\Events; | ||||
|  | ||||
| use FireflyIII\User; | ||||
| @@ -32,13 +34,13 @@ class UserChangedEmail extends Event | ||||
| { | ||||
|     use SerializesModels; | ||||
|  | ||||
|     /** @var string */ | ||||
|     /** @var string The user's IP address */ | ||||
|     public $ipAddress; | ||||
|     /** @var string */ | ||||
|     /** @var string The user's new email address */ | ||||
|     public $newEmail; | ||||
|     /** @var string */ | ||||
|     /** @var string The user's old email address */ | ||||
|     public $oldEmail; | ||||
|     /** @var User */ | ||||
|     /** @var User The user itself */ | ||||
|     public $user; | ||||
|  | ||||
|     /** | ||||
|   | ||||
| @@ -1,8 +1,8 @@ | ||||
| <?php | ||||
| declare(strict_types=1); | ||||
|  | ||||
| /** | ||||
|  * FireflyException.php | ||||
|  * Copyright (c) 2017 thegrumpydictator@gmail.com | ||||
|  * Copyright (c) 2018 thegrumpydictator@gmail.com | ||||
|  * | ||||
|  * This file is part of Firefly III. | ||||
|  * | ||||
| @@ -20,6 +20,8 @@ declare(strict_types=1); | ||||
|  * along with Firefly III. If not, see <http://www.gnu.org/licenses/>. | ||||
|  */ | ||||
|  | ||||
| declare(strict_types=1); | ||||
|  | ||||
| namespace FireflyIII\Exceptions; | ||||
|  | ||||
| use Exception; | ||||
|   | ||||
| @@ -1,8 +1,8 @@ | ||||
| <?php | ||||
| declare(strict_types=1); | ||||
|  | ||||
| /** | ||||
|  * Handler.php | ||||
|  * Copyright (c) 2017 thegrumpydictator@gmail.com | ||||
|  * Copyright (c) 2018 thegrumpydictator@gmail.com | ||||
|  * | ||||
|  * This file is part of Firefly III. | ||||
|  * | ||||
| @@ -20,6 +20,10 @@ declare(strict_types=1); | ||||
|  * along with Firefly III. If not, see <http://www.gnu.org/licenses/>. | ||||
|  */ | ||||
|  | ||||
| /** @noinspection MultipleReturnStatementsInspection */ | ||||
|  | ||||
| declare(strict_types=1); | ||||
|  | ||||
| namespace FireflyIII\Exceptions; | ||||
|  | ||||
| use ErrorException; | ||||
| @@ -27,7 +31,8 @@ use Exception; | ||||
| use FireflyIII\Jobs\MailError; | ||||
| use Illuminate\Auth\AuthenticationException; | ||||
| use Illuminate\Foundation\Exceptions\Handler as ExceptionHandler; | ||||
| use Illuminate\Validation\ValidationException; | ||||
| use Illuminate\Validation\ValidationException as LaravelValidationException; | ||||
| use League\OAuth2\Server\Exception\OAuthServerException; | ||||
| use Request; | ||||
| use Symfony\Component\HttpKernel\Exception\NotFoundHttpException; | ||||
|  | ||||
| @@ -36,36 +41,20 @@ use Symfony\Component\HttpKernel\Exception\NotFoundHttpException; | ||||
|  */ | ||||
| class Handler extends ExceptionHandler | ||||
| { | ||||
|     /** | ||||
|      * A list of the inputs that are never flashed for validation exceptions. | ||||
|      * | ||||
|      * @var array | ||||
|      */ | ||||
|     protected $dontFlash | ||||
|         = [ | ||||
|             'password', | ||||
|             'password_confirmation', | ||||
|         ]; | ||||
|     /** | ||||
|      * A list of the exception types that are not reported. | ||||
|      * | ||||
|      * @var array | ||||
|      */ | ||||
|     protected $dontReport | ||||
|         = [ | ||||
|         ]; | ||||
|  | ||||
|     /** | ||||
|      * Render an exception into an HTTP response. | ||||
|      * | ||||
|      * @param \Illuminate\Http\Request $request | ||||
|      * @param \Exception               $exception | ||||
|      * @param Request   $request | ||||
|      * @param Exception $exception | ||||
|      * @SuppressWarnings(PHPMD.CyclomaticComplexity) | ||||
|      * @SuppressWarnings(PHPMD.NPathComplexity) | ||||
|      * @SuppressWarnings(PHPMD.ExcessiveMethodLength) | ||||
|      * | ||||
|      * @return \Illuminate\Http\Response | ||||
|      * @return mixed | ||||
|      */ | ||||
|     public function render($request, Exception $exception) | ||||
|     { | ||||
|         if ($exception instanceof ValidationException && $request->expectsJson()) { | ||||
|         if ($exception instanceof LaravelValidationException && $request->expectsJson()) { | ||||
|             // ignore it: controller will handle it. | ||||
|             return parent::render($request, $exception); | ||||
|         } | ||||
| @@ -79,6 +68,11 @@ class Handler extends ExceptionHandler | ||||
|             return response()->json(['message' => 'Unauthenticated', 'exception' => 'AuthenticationException'], 401); | ||||
|         } | ||||
|  | ||||
|         if ($exception instanceof OAuthServerException && $request->expectsJson()) { | ||||
|             // somehow Laravel handler does not catch this: | ||||
|             return response()->json(['message' => $exception->getMessage(), 'exception' => 'OAuthServerException'], 401); | ||||
|         } | ||||
|  | ||||
|         if ($request->expectsJson()) { | ||||
|             $isDebug = config('app.debug', false); | ||||
|             if ($isDebug) { | ||||
| @@ -96,7 +90,7 @@ class Handler extends ExceptionHandler | ||||
|             return response()->json(['message' => 'Internal Firefly III Exception. See log files.', 'exception' => \get_class($exception)], 500); | ||||
|         } | ||||
|  | ||||
|         if ($exception instanceof FireflyException || $exception instanceof ErrorException) { | ||||
|         if ($exception instanceof FireflyException || $exception instanceof ErrorException || $exception instanceof OAuthServerException) { | ||||
|             $isDebug = env('APP_DEBUG', false); | ||||
|  | ||||
|             return response()->view('errors.FireflyException', ['exception' => $exception, 'debug' => $isDebug], 500); | ||||
| @@ -120,8 +114,12 @@ class Handler extends ExceptionHandler | ||||
|      */ | ||||
|     public function report(Exception $exception) | ||||
|     { | ||||
|  | ||||
|         $doMailError = env('SEND_ERROR_MESSAGE', true); | ||||
|         if (($exception instanceof FireflyException || $exception instanceof ErrorException) && $doMailError) { | ||||
|         // if the user wants us to mail: | ||||
|         if (true === $doMailError | ||||
|             // and if is one of these error instances | ||||
|             && ($exception instanceof FireflyException || $exception instanceof ErrorException || $exception instanceof OAuthServerException)) { | ||||
|             $userData = [ | ||||
|                 'id'    => 0, | ||||
|                 'email' => 'unknown@example.com', | ||||
| @@ -139,6 +137,9 @@ class Handler extends ExceptionHandler | ||||
|                 'line'         => $exception->getLine(), | ||||
|                 'code'         => $exception->getCode(), | ||||
|                 'version'      => config('firefly.version'), | ||||
|                 'url'          => Request::fullUrl(), | ||||
|                 'userAgent'    => Request::userAgent(), | ||||
|                 'json'         => Request::acceptsJson(), | ||||
|             ]; | ||||
|  | ||||
|             // create job that will mail. | ||||
|   | ||||
| @@ -1,8 +1,8 @@ | ||||
| <?php | ||||
| declare(strict_types=1); | ||||
|  | ||||
| /** | ||||
|  * NotImplementedException.php | ||||
|  * Copyright (c) 2017 thegrumpydictator@gmail.com | ||||
|  * Copyright (c) 2018 thegrumpydictator@gmail.com | ||||
|  * | ||||
|  * This file is part of Firefly III. | ||||
|  * | ||||
| @@ -20,6 +20,8 @@ declare(strict_types=1); | ||||
|  * along with Firefly III. If not, see <http://www.gnu.org/licenses/>. | ||||
|  */ | ||||
|  | ||||
| declare(strict_types=1); | ||||
|  | ||||
| namespace FireflyIII\Exceptions; | ||||
|  | ||||
| /** | ||||
|   | ||||
| @@ -1,8 +1,8 @@ | ||||
| <?php | ||||
| declare(strict_types=1); | ||||
|  | ||||
| /** | ||||
|  * ValidationException.php | ||||
|  * Copyright (c) 2017 thegrumpydictator@gmail.com | ||||
|  * Copyright (c) 2018 thegrumpydictator@gmail.com | ||||
|  * | ||||
|  * This file is part of Firefly III. | ||||
|  * | ||||
| @@ -20,6 +20,8 @@ declare(strict_types=1); | ||||
|  * along with Firefly III. If not, see <http://www.gnu.org/licenses/>. | ||||
|  */ | ||||
|  | ||||
| declare(strict_types=1); | ||||
|  | ||||
| namespace FireflyIII\Exceptions; | ||||
|  | ||||
| /** | ||||
|   | ||||
| @@ -1,8 +1,7 @@ | ||||
| <?php | ||||
| declare(strict_types=1); | ||||
| /** | ||||
|  * AttachmentCollector.php | ||||
|  * Copyright (c) 2017 thegrumpydictator@gmail.com | ||||
|  * Copyright (c) 2018 thegrumpydictator@gmail.com | ||||
|  * | ||||
|  * This file is part of Firefly III. | ||||
|  * | ||||
| @@ -20,6 +19,8 @@ declare(strict_types=1); | ||||
|  * along with Firefly III. If not, see <http://www.gnu.org/licenses/>. | ||||
|  */ | ||||
|  | ||||
| declare(strict_types=1); | ||||
|  | ||||
| namespace FireflyIII\Export\Collector; | ||||
|  | ||||
| use Carbon\Carbon; | ||||
| @@ -27,6 +28,7 @@ use Crypt; | ||||
| use FireflyIII\Models\Attachment; | ||||
| use FireflyIII\Repositories\Attachment\AttachmentRepositoryInterface; | ||||
| use Illuminate\Contracts\Encryption\DecryptException; | ||||
| use Illuminate\Contracts\Filesystem\FileNotFoundException; | ||||
| use Illuminate\Support\Collection; | ||||
| use Log; | ||||
| use Storage; | ||||
| @@ -36,15 +38,15 @@ use Storage; | ||||
|  */ | ||||
| class AttachmentCollector extends BasicCollector implements CollectorInterface | ||||
| { | ||||
|     /** @var Carbon */ | ||||
|     /** @var Carbon The end date of the range. */ | ||||
|     private $end; | ||||
|     /** @var \Illuminate\Contracts\Filesystem\Filesystem */ | ||||
|     /** @var \Illuminate\Contracts\Filesystem\Filesystem File system */ | ||||
|     private $exportDisk; | ||||
|     /** @var AttachmentRepositoryInterface */ | ||||
|     /** @var AttachmentRepositoryInterface Attachment repository */ | ||||
|     private $repository; | ||||
|     /** @var Carbon */ | ||||
|     /** @var Carbon Start date of range */ | ||||
|     private $start; | ||||
|     /** @var \Illuminate\Contracts\Filesystem\Filesystem */ | ||||
|     /** @var \Illuminate\Contracts\Filesystem\Filesystem Disk with uploads on it */ | ||||
|     private $uploadDisk; | ||||
|  | ||||
|     /** | ||||
| @@ -62,6 +64,8 @@ class AttachmentCollector extends BasicCollector implements CollectorInterface | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      * Run the routine. | ||||
|      * | ||||
|      * @return bool | ||||
|      */ | ||||
|     public function run(): bool | ||||
| @@ -78,6 +82,8 @@ class AttachmentCollector extends BasicCollector implements CollectorInterface | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      * Set the start and end date. | ||||
|      * | ||||
|      * @param Carbon $start | ||||
|      * @param Carbon $end | ||||
|      */ | ||||
| @@ -87,23 +93,30 @@ class AttachmentCollector extends BasicCollector implements CollectorInterface | ||||
|         $this->end   = $end; | ||||
|     } | ||||
|  | ||||
|     /** @noinspection MultipleReturnStatementsInspection */ | ||||
|     /** | ||||
|      * Export attachments. | ||||
|      * | ||||
|      * @param Attachment $attachment | ||||
|      * | ||||
|      * @return bool | ||||
|      */ | ||||
|     private function exportAttachment(Attachment $attachment): bool | ||||
|     { | ||||
|         $file = $attachment->fileName(); | ||||
|         $file      = $attachment->fileName(); | ||||
|         $decrypted = false; | ||||
|         if ($this->uploadDisk->exists($file)) { | ||||
|             try { | ||||
|                 $decrypted = Crypt::decrypt($this->uploadDisk->get($file)); | ||||
|             } catch (DecryptException $e) { | ||||
|             } catch (FileNotFoundException|DecryptException $e) { | ||||
|                 Log::error('Catchable error: could not decrypt attachment #' . $attachment->id . ' because: ' . $e->getMessage()); | ||||
|  | ||||
|                 return false; | ||||
|             } | ||||
|         } | ||||
|         if (false === $decrypted) { | ||||
|             return false; | ||||
|         } | ||||
|         $exportFile = $this->exportFileName($attachment); | ||||
|         $this->exportDisk->put($exportFile, $decrypted); | ||||
|         $this->getEntries()->push($exportFile); | ||||
| @@ -124,6 +137,8 @@ class AttachmentCollector extends BasicCollector implements CollectorInterface | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      * Get the attachments. | ||||
|      * | ||||
|      * @return Collection | ||||
|      */ | ||||
|     private function getAttachments(): Collection | ||||
|   | ||||
| @@ -1,8 +1,8 @@ | ||||
| <?php | ||||
| declare(strict_types=1); | ||||
|  | ||||
| /** | ||||
|  * BasicCollector.php | ||||
|  * Copyright (c) 2017 thegrumpydictator@gmail.com | ||||
|  * Copyright (c) 2018 thegrumpydictator@gmail.com | ||||
|  * | ||||
|  * This file is part of Firefly III. | ||||
|  * | ||||
| @@ -20,6 +20,8 @@ declare(strict_types=1); | ||||
|  * along with Firefly III. If not, see <http://www.gnu.org/licenses/>. | ||||
|  */ | ||||
|  | ||||
| declare(strict_types=1); | ||||
|  | ||||
| namespace FireflyIII\Export\Collector; | ||||
|  | ||||
| use FireflyIII\Models\ExportJob; | ||||
| @@ -31,11 +33,11 @@ use Illuminate\Support\Collection; | ||||
|  */ | ||||
| class BasicCollector | ||||
| { | ||||
|     /** @var ExportJob */ | ||||
|     /** @var ExportJob The job to export. */ | ||||
|     protected $job; | ||||
|     /** @var User */ | ||||
|     /** @var User The user */ | ||||
|     protected $user; | ||||
|     /** @var Collection */ | ||||
|     /** @var Collection All the entries. */ | ||||
|     private $entries; | ||||
|  | ||||
|     /** | ||||
| @@ -47,6 +49,8 @@ class BasicCollector | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      * Get all entries. | ||||
|      * | ||||
|      * @return Collection | ||||
|      */ | ||||
|     public function getEntries(): Collection | ||||
| @@ -55,26 +59,32 @@ class BasicCollector | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      * Set entries. | ||||
|      * | ||||
|      * @param Collection $entries | ||||
|      */ | ||||
|     public function setEntries(Collection $entries) | ||||
|     public function setEntries(Collection $entries): void | ||||
|     { | ||||
|         $this->entries = $entries; | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      * Set export job. | ||||
|      * | ||||
|      * @param ExportJob $job | ||||
|      */ | ||||
|     public function setJob(ExportJob $job) | ||||
|     public function setJob(ExportJob $job): void | ||||
|     { | ||||
|         $this->job  = $job; | ||||
|         $this->user = $job->user; | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      * Set user. | ||||
|      * | ||||
|      * @param User $user | ||||
|      */ | ||||
|     public function setUser(User $user) | ||||
|     public function setUser(User $user): void | ||||
|     { | ||||
|         $this->user = $user; | ||||
|     } | ||||
|   | ||||
| @@ -1,8 +1,8 @@ | ||||
| <?php | ||||
| declare(strict_types=1); | ||||
|  | ||||
| /** | ||||
|  * CollectorInterface.php | ||||
|  * Copyright (c) 2017 thegrumpydictator@gmail.com | ||||
|  * Copyright (c) 2018 thegrumpydictator@gmail.com | ||||
|  * | ||||
|  * This file is part of Firefly III. | ||||
|  * | ||||
| @@ -20,6 +20,8 @@ declare(strict_types=1); | ||||
|  * along with Firefly III. If not, see <http://www.gnu.org/licenses/>. | ||||
|  */ | ||||
|  | ||||
| declare(strict_types=1); | ||||
|  | ||||
| namespace FireflyIII\Export\Collector; | ||||
|  | ||||
| use FireflyIII\Models\ExportJob; | ||||
| @@ -31,21 +33,29 @@ use Illuminate\Support\Collection; | ||||
| interface CollectorInterface | ||||
| { | ||||
|     /** | ||||
|      * Get entries. | ||||
|      * | ||||
|      * @return Collection | ||||
|      */ | ||||
|     public function getEntries(): Collection; | ||||
|  | ||||
|     /** | ||||
|      * Run the collector. | ||||
|      * | ||||
|      * @return bool | ||||
|      */ | ||||
|     public function run(): bool; | ||||
|  | ||||
|     /** | ||||
|      * Set entries. | ||||
|      * | ||||
|      * @param Collection $entries | ||||
|      */ | ||||
|     public function setEntries(Collection $entries); | ||||
|  | ||||
|     /** | ||||
|      * Set export job. | ||||
|      * | ||||
|      * @param ExportJob $job | ||||
|      * | ||||
|      * @return mixed | ||||
|   | ||||
| @@ -1,8 +1,7 @@ | ||||
| <?php | ||||
| declare(strict_types=1); | ||||
| /** | ||||
|  * UploadCollector.php | ||||
|  * Copyright (c) 2017 thegrumpydictator@gmail.com | ||||
|  * Copyright (c) 2018 thegrumpydictator@gmail.com | ||||
|  * | ||||
|  * This file is part of Firefly III. | ||||
|  * | ||||
| @@ -20,6 +19,8 @@ declare(strict_types=1); | ||||
|  * along with Firefly III. If not, see <http://www.gnu.org/licenses/>. | ||||
|  */ | ||||
|  | ||||
| declare(strict_types=1); | ||||
|  | ||||
| namespace FireflyIII\Export\Collector; | ||||
|  | ||||
| use Crypt; | ||||
| @@ -82,7 +83,10 @@ class UploadCollector extends BasicCollector implements CollectorInterface | ||||
|         return true; | ||||
|     } | ||||
|  | ||||
|     /** @noinspection MultipleReturnStatementsInspection */ | ||||
|     /** | ||||
|      * Process new file uploads. | ||||
|      * | ||||
|      * @param string $key | ||||
|      * | ||||
|      * @return bool | ||||
|   | ||||
| @@ -1,8 +1,8 @@ | ||||
| <?php | ||||
| declare(strict_types=1); | ||||
|  | ||||
| /** | ||||
|  * Entry.php | ||||
|  * Copyright (c) 2017 thegrumpydictator@gmail.com | ||||
|  * Copyright (c) 2018 thegrumpydictator@gmail.com | ||||
|  * | ||||
|  * This file is part of Firefly III. | ||||
|  * | ||||
| @@ -20,6 +20,8 @@ declare(strict_types=1); | ||||
|  * along with Firefly III. If not, see <http://www.gnu.org/licenses/>. | ||||
|  */ | ||||
|  | ||||
| declare(strict_types=1); | ||||
|  | ||||
| namespace FireflyIII\Export\Entry; | ||||
|  | ||||
| use FireflyIII\Models\Transaction; | ||||
| @@ -44,137 +46,65 @@ use FireflyIII\Models\Transaction; | ||||
|  */ | ||||
| final class Entry | ||||
| { | ||||
|     // @formatter:off | ||||
|     /** | ||||
|      * @var int | ||||
|      */ | ||||
|     /** @var int ID of the journal */ | ||||
|     public $journal_id; | ||||
|     /** | ||||
|      * @var int | ||||
|      */ | ||||
|     /** @var int ID of the transaction */ | ||||
|     public $transaction_id = 0; | ||||
|  | ||||
|     /** | ||||
|      * @var string | ||||
|      */ | ||||
|     /** @var string The date. */ | ||||
|     public $date; | ||||
|     /** | ||||
|      * @var string | ||||
|      */ | ||||
|     /** @var string The description */ | ||||
|     public $description; | ||||
|  | ||||
|     /** | ||||
|      * @var string | ||||
|      */ | ||||
|     /** @var string The currency code. */ | ||||
|     public $currency_code; | ||||
|     /** | ||||
|      * @var string | ||||
|      */ | ||||
|     /** @var string The amount. */ | ||||
|     public $amount; | ||||
|     /** | ||||
|      * @var string | ||||
|      */ | ||||
|     /** @var string The foreign currency code */ | ||||
|     public $foreign_currency_code = ''; | ||||
|     /** | ||||
|      * @var string | ||||
|      */ | ||||
|     /** @var string Foreign amount */ | ||||
|     public $foreign_amount = '0'; | ||||
|  | ||||
|     /** | ||||
|      * @var string | ||||
|      */ | ||||
|     /** @var string Transaction type */ | ||||
|     public $transaction_type; | ||||
|  | ||||
|     /** | ||||
|      * @var string | ||||
|      */ | ||||
|     /** @var string Asset account ID */ | ||||
|     public $asset_account_id; | ||||
|     /** | ||||
|      * @var string | ||||
|      */ | ||||
|     /** @var string Asset account name */ | ||||
|     public $asset_account_name; | ||||
|     /** | ||||
|      * @var string | ||||
|      */ | ||||
|     /** @var string Asset account IBAN */ | ||||
|     public $asset_account_iban; | ||||
|     /** | ||||
|      * @var string | ||||
|      */ | ||||
|     /** @var string Asset account BIC */ | ||||
|     public $asset_account_bic; | ||||
|     /** | ||||
|      * @var string | ||||
|      */ | ||||
|     /** @var string Asset account number */ | ||||
|     public $asset_account_number; | ||||
|     /** | ||||
|      * @var string | ||||
|      */ | ||||
|     /** @var string Asset account currency code */ | ||||
|     public $asset_currency_code; | ||||
|  | ||||
|     /** | ||||
|      * @var string | ||||
|      */ | ||||
|     /** @var string Opposing account ID */ | ||||
|     public $opposing_account_id; | ||||
|     /** | ||||
|      * @var string | ||||
|      */ | ||||
|     /** @var string Opposing account name */ | ||||
|     public $opposing_account_name; | ||||
|     /** | ||||
|      * @var string | ||||
|      */ | ||||
|     /** @var string Opposing account IBAN */ | ||||
|     public $opposing_account_iban; | ||||
|     /** | ||||
|      * @var string | ||||
|      */ | ||||
|     /** @var string Opposing account BIC */ | ||||
|     public $opposing_account_bic; | ||||
|     /** | ||||
|      * @var string | ||||
|      */ | ||||
|     /** @var string Opposing account number */ | ||||
|     public $opposing_account_number; | ||||
|     /** | ||||
|      * @var string | ||||
|      */ | ||||
|     /** @var string Opposing account code */ | ||||
|     public $opposing_currency_code; | ||||
|  | ||||
|     /** | ||||
|      * @var string | ||||
|      */ | ||||
|     /** @var string Budget ID */ | ||||
|     public $budget_id; | ||||
|     /** | ||||
|      * @var string | ||||
|      */ | ||||
|     /** @var string Budget name */ | ||||
|     public $budget_name; | ||||
|  | ||||
|     /** | ||||
|      * @var string | ||||
|      */ | ||||
|     /** @var string Category ID */ | ||||
|     public $category_id; | ||||
|     /** | ||||
|      * @var string | ||||
|      */ | ||||
|     /** @var string Category name */ | ||||
|     public $category_name; | ||||
|  | ||||
|     /** | ||||
|      * @var string | ||||
|      */ | ||||
|     /** @var string Bill ID */ | ||||
|     public $bill_id; | ||||
|     /** | ||||
|      * @var string | ||||
|      */ | ||||
|     /** @var string Bill name */ | ||||
|     public $bill_name; | ||||
|  | ||||
|     /** | ||||
|      * @var string | ||||
|      */ | ||||
|     /** @var string Notes */ | ||||
|     public $notes; | ||||
|  | ||||
|     /** | ||||
|      * @var string | ||||
|      */ | ||||
|     /** @var string Tags */ | ||||
|     public $tags; | ||||
|  | ||||
|  | ||||
|     // @formatter:on | ||||
|  | ||||
|     /** | ||||
|      * Entry constructor. | ||||
|      */ | ||||
|   | ||||
| @@ -1,8 +1,7 @@ | ||||
| <?php | ||||
| declare(strict_types=1); | ||||
| /** | ||||
|  * ExpandedProcessor.php | ||||
|  * Copyright (c) 2017 thegrumpydictator@gmail.com | ||||
|  * Copyright (c) 2018 thegrumpydictator@gmail.com | ||||
|  * | ||||
|  * This file is part of Firefly III. | ||||
|  * | ||||
| @@ -20,6 +19,10 @@ declare(strict_types=1); | ||||
|  * along with Firefly III. If not, see <http://www.gnu.org/licenses/>. | ||||
|  */ | ||||
|  | ||||
| /** @noinspection PhpDynamicAsStaticMethodCallInspection */ | ||||
|  | ||||
| declare(strict_types=1); | ||||
|  | ||||
| namespace FireflyIII\Export; | ||||
|  | ||||
| use Crypt; | ||||
| @@ -28,18 +31,19 @@ use FireflyIII\Exceptions\FireflyException; | ||||
| use FireflyIII\Export\Collector\AttachmentCollector; | ||||
| use FireflyIII\Export\Collector\UploadCollector; | ||||
| use FireflyIII\Export\Entry\Entry; | ||||
| use FireflyIII\Export\Exporter\ExporterInterface; | ||||
| use FireflyIII\Helpers\Collector\JournalCollectorInterface; | ||||
| use FireflyIII\Helpers\Filter\InternalTransferFilter; | ||||
| use FireflyIII\Models\AccountMeta; | ||||
| use FireflyIII\Models\ExportJob; | ||||
| use FireflyIII\Models\Note; | ||||
| use FireflyIII\Models\Transaction; | ||||
| use FireflyIII\Models\TransactionJournal; | ||||
| use FireflyIII\Repositories\Currency\CurrencyRepositoryInterface; | ||||
| use Illuminate\Support\Collection; | ||||
| use Log; | ||||
| use Storage; | ||||
| use ZipArchive; | ||||
| use FireflyIII\Models\TransactionJournal; | ||||
|  | ||||
| /** | ||||
|  * Class ExpandedProcessor. | ||||
| @@ -48,23 +52,23 @@ use FireflyIII\Models\TransactionJournal; | ||||
|  */ | ||||
| class ExpandedProcessor implements ProcessorInterface | ||||
| { | ||||
|     /** @var Collection */ | ||||
|     /** @var Collection All accounts */ | ||||
|     public $accounts; | ||||
|     /** @var string */ | ||||
|     /** @var string The export format*/ | ||||
|     public $exportFormat; | ||||
|     /** @var bool */ | ||||
|     /** @var bool Should include attachments */ | ||||
|     public $includeAttachments; | ||||
|     /** @var bool */ | ||||
|     /** @var bool Should include old uploads */ | ||||
|     public $includeOldUploads; | ||||
|     /** @var ExportJob */ | ||||
|     /** @var ExportJob The export job itself */ | ||||
|     public $job; | ||||
|     /** @var array */ | ||||
|     /** @var array The settings*/ | ||||
|     public $settings; | ||||
|     /** @var Collection */ | ||||
|     /** @var Collection The entries to export. */ | ||||
|     private $exportEntries; | ||||
|     /** @var Collection */ | ||||
|     /** @var Collection The files to export */ | ||||
|     private $files; | ||||
|     /** @var Collection */ | ||||
|     /** @var Collection The journals. */ | ||||
|     private $journals; | ||||
|  | ||||
|     /** | ||||
| @@ -78,6 +82,8 @@ class ExpandedProcessor implements ProcessorInterface | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      * Collect all attachments | ||||
|      * | ||||
|      * @return bool | ||||
|      */ | ||||
|     public function collectAttachments(): bool | ||||
| @@ -141,6 +147,8 @@ class ExpandedProcessor implements ProcessorInterface | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      * Get old oploads. | ||||
|      * | ||||
|      * @return bool | ||||
|      */ | ||||
|     public function collectOldUploads(): bool | ||||
| @@ -156,6 +164,8 @@ class ExpandedProcessor implements ProcessorInterface | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      * Convert journals to export objects. | ||||
|      * | ||||
|      * @return bool | ||||
|      */ | ||||
|     public function convertJournals(): bool | ||||
| @@ -171,6 +181,8 @@ class ExpandedProcessor implements ProcessorInterface | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      * Create a ZIP file. | ||||
|      * | ||||
|      * @return bool | ||||
|      * | ||||
|      * @throws FireflyException | ||||
| @@ -202,11 +214,14 @@ class ExpandedProcessor implements ProcessorInterface | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      * Export the journals. | ||||
|      * | ||||
|      * @return bool | ||||
|      */ | ||||
|     public function exportJournals(): bool | ||||
|     { | ||||
|         $exporterClass = config('firefly.export_formats.' . $this->exportFormat); | ||||
|         /** @var ExporterInterface $exporter */ | ||||
|         $exporter      = app($exporterClass); | ||||
|         $exporter->setJob($this->job); | ||||
|         $exporter->setEntries($this->exportEntries); | ||||
| @@ -217,6 +232,8 @@ class ExpandedProcessor implements ProcessorInterface | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      * Get files. | ||||
|      * | ||||
|      * @return Collection | ||||
|      */ | ||||
|     public function getFiles(): Collection | ||||
| @@ -229,7 +246,7 @@ class ExpandedProcessor implements ProcessorInterface | ||||
|      * | ||||
|      * @param array $settings | ||||
|      */ | ||||
|     public function setSettings(array $settings) | ||||
|     public function setSettings(array $settings): void | ||||
|     { | ||||
|         // save settings | ||||
|         $this->settings           = $settings; | ||||
| @@ -241,9 +258,9 @@ class ExpandedProcessor implements ProcessorInterface | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      * | ||||
|      * Delete files. | ||||
|      */ | ||||
|     private function deleteFiles() | ||||
|     private function deleteFiles():void | ||||
|     { | ||||
|         $disk = Storage::disk('export'); | ||||
|         foreach ($this->getFiles() as $file) { | ||||
| @@ -252,6 +269,8 @@ class ExpandedProcessor implements ProcessorInterface | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      * Get currencies. | ||||
|      * | ||||
|      * @param array $array | ||||
|      * | ||||
|      * @return array | ||||
|   | ||||
| @@ -1,8 +1,8 @@ | ||||
| <?php | ||||
| declare(strict_types=1); | ||||
|  | ||||
| /** | ||||
|  * BasicExporter.php | ||||
|  * Copyright (c) 2017 thegrumpydictator@gmail.com | ||||
|  * Copyright (c) 2018 thegrumpydictator@gmail.com | ||||
|  * | ||||
|  * This file is part of Firefly III. | ||||
|  * | ||||
| @@ -20,6 +20,8 @@ declare(strict_types=1); | ||||
|  * along with Firefly III. If not, see <http://www.gnu.org/licenses/>. | ||||
|  */ | ||||
|  | ||||
| declare(strict_types=1); | ||||
|  | ||||
| namespace FireflyIII\Export\Exporter; | ||||
|  | ||||
| use FireflyIII\Models\ExportJob; | ||||
| @@ -30,9 +32,9 @@ use Illuminate\Support\Collection; | ||||
|  */ | ||||
| class BasicExporter | ||||
| { | ||||
|     /** @var ExportJob */ | ||||
|     /** @var ExportJob The export job */ | ||||
|     protected $job; | ||||
|     /** @var Collection */ | ||||
|     /** @var Collection The entries */ | ||||
|     private $entries; | ||||
|  | ||||
|     /** | ||||
| @@ -44,6 +46,8 @@ class BasicExporter | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      * Get all entries. | ||||
|      * | ||||
|      * @return Collection | ||||
|      */ | ||||
|     public function getEntries(): Collection | ||||
| @@ -52,17 +56,21 @@ class BasicExporter | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      * Set all entries. | ||||
|      * | ||||
|      * @param Collection $entries | ||||
|      */ | ||||
|     public function setEntries(Collection $entries) | ||||
|     public function setEntries(Collection $entries): void | ||||
|     { | ||||
|         $this->entries = $entries; | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      * Set the job. | ||||
|      * | ||||
|      * @param ExportJob $job | ||||
|      */ | ||||
|     public function setJob(ExportJob $job) | ||||
|     public function setJob(ExportJob $job): void | ||||
|     { | ||||
|         $this->job = $job; | ||||
|     } | ||||
|   | ||||
| @@ -1,8 +1,8 @@ | ||||
| <?php | ||||
| declare(strict_types=1); | ||||
|  | ||||
| /** | ||||
|  * CsvExporter.php | ||||
|  * Copyright (c) 2017 thegrumpydictator@gmail.com | ||||
|  * Copyright (c) 2018 thegrumpydictator@gmail.com | ||||
|  * | ||||
|  * This file is part of Firefly III. | ||||
|  * | ||||
| @@ -20,6 +20,8 @@ declare(strict_types=1); | ||||
|  * along with Firefly III. If not, see <http://www.gnu.org/licenses/>. | ||||
|  */ | ||||
|  | ||||
| declare(strict_types=1); | ||||
|  | ||||
| namespace FireflyIII\Export\Exporter; | ||||
|  | ||||
| use FireflyIII\Export\Entry\Entry; | ||||
| @@ -31,10 +33,12 @@ use Storage; | ||||
|  */ | ||||
| class CsvExporter extends BasicExporter implements ExporterInterface | ||||
| { | ||||
|     /** @var string */ | ||||
|     /** @var string Filename */ | ||||
|     private $fileName; | ||||
|  | ||||
|     /** | ||||
|      * Get file name. | ||||
|      * | ||||
|      * @return string | ||||
|      */ | ||||
|     public function getFileName(): string | ||||
| @@ -43,6 +47,8 @@ class CsvExporter extends BasicExporter implements ExporterInterface | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      * Run collector. | ||||
|      * | ||||
|      * @return bool | ||||
|      * | ||||
|      */ | ||||
| @@ -81,6 +87,9 @@ class CsvExporter extends BasicExporter implements ExporterInterface | ||||
|         return true; | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      * Make a temp file. | ||||
|      */ | ||||
|     private function tempFile() | ||||
|     { | ||||
|         $this->fileName = $this->job->key . '-records.csv'; | ||||
|   | ||||
| @@ -1,8 +1,8 @@ | ||||
| <?php | ||||
| declare(strict_types=1); | ||||
|  | ||||
| /** | ||||
|  * ExporterInterface.php | ||||
|  * Copyright (c) 2017 thegrumpydictator@gmail.com | ||||
|  * Copyright (c) 2018 thegrumpydictator@gmail.com | ||||
|  * | ||||
|  * This file is part of Firefly III. | ||||
|  * | ||||
| @@ -20,6 +20,8 @@ declare(strict_types=1); | ||||
|  * along with Firefly III. If not, see <http://www.gnu.org/licenses/>. | ||||
|  */ | ||||
|  | ||||
| declare(strict_types=1); | ||||
|  | ||||
| namespace FireflyIII\Export\Exporter; | ||||
|  | ||||
| use FireflyIII\Models\ExportJob; | ||||
| @@ -31,26 +33,36 @@ use Illuminate\Support\Collection; | ||||
| interface ExporterInterface | ||||
| { | ||||
|     /** | ||||
|      * Get entries. | ||||
|      * | ||||
|      * @return Collection | ||||
|      */ | ||||
|     public function getEntries(): Collection; | ||||
|  | ||||
|     /** | ||||
|      * Get file name. | ||||
|      * | ||||
|      * @return string | ||||
|      */ | ||||
|     public function getFileName(): string; | ||||
|  | ||||
|     /** | ||||
|      * Run exporter. | ||||
|      * | ||||
|      * @return bool | ||||
|      */ | ||||
|     public function run(): bool; | ||||
|  | ||||
|     /** | ||||
|      * Set entries. | ||||
|      * | ||||
|      * @param Collection $entries | ||||
|      */ | ||||
|     public function setEntries(Collection $entries); | ||||
|  | ||||
|     /** | ||||
|      * Set job. | ||||
|      * | ||||
|      * @param ExportJob $job | ||||
|      */ | ||||
|     public function setJob(ExportJob $job); | ||||
|   | ||||
| @@ -1,8 +1,8 @@ | ||||
| <?php | ||||
| declare(strict_types=1); | ||||
|  | ||||
| /** | ||||
|  * ProcessorInterface.php | ||||
|  * Copyright (c) 2017 thegrumpydictator@gmail.com | ||||
|  * Copyright (c) 2018 thegrumpydictator@gmail.com | ||||
|  * | ||||
|  * This file is part of Firefly III. | ||||
|  * | ||||
| @@ -20,6 +20,8 @@ declare(strict_types=1); | ||||
|  * along with Firefly III. If not, see <http://www.gnu.org/licenses/>. | ||||
|  */ | ||||
|  | ||||
| declare(strict_types=1); | ||||
|  | ||||
| namespace FireflyIII\Export; | ||||
|  | ||||
| use Illuminate\Support\Collection; | ||||
| @@ -35,41 +37,57 @@ interface ProcessorInterface | ||||
|     public function __construct(); | ||||
|  | ||||
|     /** | ||||
|      * Collect all attachments. | ||||
|      * | ||||
|      * @return bool | ||||
|      */ | ||||
|     public function collectAttachments(): bool; | ||||
|  | ||||
|     /** | ||||
|      * Collect all journals. | ||||
|      * | ||||
|      * @return bool | ||||
|      */ | ||||
|     public function collectJournals(): bool; | ||||
|  | ||||
|     /** | ||||
|      * Collect old uploads. | ||||
|      * | ||||
|      * @return bool | ||||
|      */ | ||||
|     public function collectOldUploads(): bool; | ||||
|  | ||||
|     /** | ||||
|      * Convert all journals. | ||||
|      * | ||||
|      * @return bool | ||||
|      */ | ||||
|     public function convertJournals(): bool; | ||||
|  | ||||
|     /** | ||||
|      * Create a zip file. | ||||
|      * | ||||
|      * @return bool | ||||
|      */ | ||||
|     public function createZipFile(): bool; | ||||
|  | ||||
|     /** | ||||
|      * Export journals. | ||||
|      * | ||||
|      * @return bool | ||||
|      */ | ||||
|     public function exportJournals(): bool; | ||||
|  | ||||
|     /** | ||||
|      * Get all files. | ||||
|      * | ||||
|      * @return Collection | ||||
|      */ | ||||
|     public function getFiles(): Collection; | ||||
|  | ||||
|     /** | ||||
|      * Set the settings. | ||||
|      * | ||||
|      * @param array $settings | ||||
|      */ | ||||
|     public function setSettings(array $settings); | ||||
|   | ||||
| @@ -1,5 +1,5 @@ | ||||
| <?php | ||||
| declare(strict_types=1); | ||||
|  | ||||
| /** | ||||
|  * AccountFactory.php | ||||
|  * Copyright (c) 2018 thegrumpydictator@gmail.com | ||||
| @@ -20,9 +20,14 @@ declare(strict_types=1); | ||||
|  * along with Firefly III. If not, see <http://www.gnu.org/licenses/>. | ||||
|  */ | ||||
|  | ||||
| /** @noinspection PhpDynamicAsStaticMethodCallInspection */ | ||||
| /** @noinspection PhpUndefinedMethodInspection */ | ||||
|  | ||||
| declare(strict_types=1); | ||||
|  | ||||
| namespace FireflyIII\Factory; | ||||
|  | ||||
| use FireflyIII\Exceptions\FireflyException; | ||||
| use FireflyIII\Models\Account; | ||||
| use FireflyIII\Models\AccountType; | ||||
| use FireflyIII\Services\Internal\Support\AccountServiceTrait; | ||||
| @@ -43,56 +48,63 @@ class AccountFactory | ||||
|      * @param array $data | ||||
|      * | ||||
|      * @return Account | ||||
|      * @throws FireflyException | ||||
|      * @SuppressWarnings(PHPMD.CyclomaticComplexity) | ||||
|      * @SuppressWarnings(PHPMD.ExcessiveMethodLength) | ||||
|      */ | ||||
|     public function create(array $data): Account | ||||
|     { | ||||
|         $type         = $this->getAccountType($data['account_type_id'], $data['accountType']); | ||||
|         $type = $this->getAccountType($data['account_type_id'], $data['accountType']); | ||||
|  | ||||
|         if (null === $type) { | ||||
|             throw new FireflyException( | ||||
|                 sprintf('AccountFactory::create() was unable to find account type #%d ("%s").', $data['account_type_id'], $data['accountType']) | ||||
|             ); | ||||
|         } | ||||
|  | ||||
|         $data['iban'] = $this->filterIban($data['iban']); | ||||
|  | ||||
|  | ||||
|         // account may exist already: | ||||
|         $existingAccount = $this->find($data['name'], $type->type); | ||||
|         if (null !== $existingAccount) { | ||||
|             return $existingAccount; | ||||
|         $return = $this->find($data['name'], $type->type); | ||||
|  | ||||
|  | ||||
|         if (null === $return) { | ||||
|             // create it: | ||||
|             $databaseData | ||||
|                 = [ | ||||
|                 'user_id'         => $this->user->id, | ||||
|                 'account_type_id' => $type->id, | ||||
|                 'name'            => $data['name'], | ||||
|                 'virtual_balance' => $data['virtualBalance'] ?? '0', | ||||
|                 'active'          => true === $data['active'], | ||||
|                 'iban'            => $data['iban'], | ||||
|             ]; | ||||
|  | ||||
|             // remove virtual balance when not an asset account: | ||||
|             if ($type->type !== AccountType::ASSET) { | ||||
|                 $databaseData['virtual_balance'] = '0'; | ||||
|             } | ||||
|  | ||||
|             // fix virtual balance when it's empty | ||||
|             if ('' === $databaseData['virtual_balance']) { | ||||
|                 $databaseData['virtual_balance'] = '0'; | ||||
|             } | ||||
|  | ||||
|             $return = Account::create($databaseData); | ||||
|             $this->updateMetaData($return, $data); | ||||
|  | ||||
|             if ($type->type === AccountType::ASSET) { | ||||
|                 if ($this->validIBData($data)) { | ||||
|                     $this->updateIB($return, $data); | ||||
|                 } | ||||
|                 if (!$this->validIBData($data)) { | ||||
|                     $this->deleteIB($return); | ||||
|                 } | ||||
|             } | ||||
|             $this->updateNote($return, $data['notes'] ?? ''); | ||||
|         } | ||||
|  | ||||
|  | ||||
|         // create it: | ||||
|         $databaseData | ||||
|             = [ | ||||
|             'user_id'         => $this->user->id, | ||||
|             'account_type_id' => $type->id, | ||||
|             'name'            => $data['name'], | ||||
|             'virtual_balance' => $data['virtualBalance'] ?? '0', | ||||
|             'active'          => true === $data['active'], | ||||
|             'iban'            => $data['iban'], | ||||
|         ]; | ||||
|  | ||||
|         // remove virtual balance when not an asset account: | ||||
|         if ($type->type !== AccountType::ASSET) { | ||||
|             $databaseData['virtual_balance'] = '0'; | ||||
|         } | ||||
|  | ||||
|         // fix virtual balance when it's empty | ||||
|         if ($databaseData['virtual_balance'] === '') { | ||||
|             $databaseData['virtual_balance'] = '0'; | ||||
|         } | ||||
|  | ||||
|         $newAccount = Account::create($databaseData); | ||||
|         $this->updateMetaData($newAccount, $data); | ||||
|  | ||||
|         if ($this->validIBData($data) && $type->type === AccountType::ASSET) { | ||||
|             $this->updateIB($newAccount, $data); | ||||
|         } | ||||
|         if (!$this->validIBData($data) && $type->type === AccountType::ASSET) { | ||||
|             $this->deleteIB($newAccount); | ||||
|         } | ||||
|         // update note: | ||||
|         if (isset($data['notes'])) { | ||||
|             $this->updateNote($newAccount, $data['notes']); | ||||
|         } | ||||
|  | ||||
|         return $newAccount; | ||||
|         return $return; | ||||
|     } | ||||
|  | ||||
|     /** | ||||
| @@ -105,15 +117,16 @@ class AccountFactory | ||||
|     { | ||||
|         $type     = AccountType::whereType($accountType)->first(); | ||||
|         $accounts = $this->user->accounts()->where('account_type_id', $type->id)->get(['accounts.*']); | ||||
|  | ||||
|         $return   = null; | ||||
|         /** @var Account $object */ | ||||
|         foreach ($accounts as $object) { | ||||
|             if ($object->name === $accountName) { | ||||
|                 return $object; | ||||
|                 $return = $object; | ||||
|                 break; | ||||
|             } | ||||
|         } | ||||
|  | ||||
|         return null; | ||||
|         return $return; | ||||
|     } | ||||
|  | ||||
|     /** | ||||
| @@ -121,30 +134,35 @@ class AccountFactory | ||||
|      * @param string $accountType | ||||
|      * | ||||
|      * @return Account | ||||
|      * @throws FireflyException | ||||
|      */ | ||||
|     public function findOrCreate(string $accountName, string $accountType): Account | ||||
|     { | ||||
|         $type     = AccountType::whereType($accountType)->first(); | ||||
|         $accounts = $this->user->accounts()->where('account_type_id', $type->id)->get(['accounts.*']); | ||||
|  | ||||
|         $return   = null; | ||||
|         /** @var Account $object */ | ||||
|         foreach ($accounts as $object) { | ||||
|             if ($object->name === $accountName) { | ||||
|                 return $object; | ||||
|                 $return = $object; | ||||
|                 break; | ||||
|             } | ||||
|         } | ||||
|         if (null === $return) { | ||||
|             $return = $this->create( | ||||
|                 [ | ||||
|                     'user_id'         => $this->user->id, | ||||
|                     'name'            => $accountName, | ||||
|                     'account_type_id' => $type->id, | ||||
|                     'accountType'     => null, | ||||
|                     'virtualBalance'  => '0', | ||||
|                     'iban'            => null, | ||||
|                     'active'          => true, | ||||
|                 ] | ||||
|             ); | ||||
|         } | ||||
|  | ||||
|         return $this->create( | ||||
|             [ | ||||
|                 'user_id'         => $this->user->id, | ||||
|                 'name'            => $accountName, | ||||
|                 'account_type_id' => $type->id, | ||||
|                 'accountType'     => null, | ||||
|                 'virtualBalance'  => '0', | ||||
|                 'iban'            => null, | ||||
|                 'active'          => true, | ||||
|             ] | ||||
|         ); | ||||
|         return $return; | ||||
|     } | ||||
|  | ||||
|     /** | ||||
| @@ -160,18 +178,23 @@ class AccountFactory | ||||
|      * @param null|string $accountType | ||||
|      * | ||||
|      * @return AccountType|null | ||||
|      * @SuppressWarnings(PHPMD.CyclomaticComplexity) | ||||
|      */ | ||||
|     protected function getAccountType(?int $accountTypeId, ?string $accountType): ?AccountType | ||||
|     { | ||||
|         $accountTypeId = (int)$accountTypeId; | ||||
|         $result        = null; | ||||
|         if ($accountTypeId > 0) { | ||||
|             return AccountType::find($accountTypeId); | ||||
|             $result = AccountType::find($accountTypeId); | ||||
|         } | ||||
|         $type   = config('firefly.accountTypeByIdentifier.' . (string)$accountType); | ||||
|         $result = AccountType::whereType($type)->first(); | ||||
|         if (null === $result && null !== $accountType) { | ||||
|             // try as full name: | ||||
|             $result = AccountType::whereType($accountType)->first(); | ||||
|         if (null === $result) { | ||||
|             /** @var string $type */ | ||||
|             $type   = (string)config('firefly.accountTypeByIdentifier.' . $accountType); | ||||
|             $result = AccountType::whereType($type)->first(); | ||||
|             if (null === $result && null !== $accountType) { | ||||
|                 // try as full name: | ||||
|                 $result = AccountType::whereType($accountType)->first(); | ||||
|             } | ||||
|         } | ||||
|  | ||||
|         return $result; | ||||
|   | ||||
| @@ -1,5 +1,5 @@ | ||||
| <?php | ||||
| declare(strict_types=1); | ||||
|  | ||||
| /** | ||||
|  * AccountMetaFactory.php | ||||
|  * Copyright (c) 2018 thegrumpydictator@gmail.com | ||||
| @@ -20,16 +20,21 @@ declare(strict_types=1); | ||||
|  * along with Firefly III. If not, see <http://www.gnu.org/licenses/>. | ||||
|  */ | ||||
|  | ||||
| declare(strict_types=1); | ||||
|  | ||||
| namespace FireflyIII\Factory; | ||||
|  | ||||
| use Exception; | ||||
| use FireflyIII\Models\Account; | ||||
| use FireflyIII\Models\AccountMeta; | ||||
| use Log; | ||||
|  | ||||
| /** | ||||
|  * Class AccountMetaFactory | ||||
|  */ | ||||
| class AccountMetaFactory | ||||
| { | ||||
|  | ||||
|     /** | ||||
|      * @param array $data | ||||
|      * | ||||
| @@ -40,4 +45,45 @@ class AccountMetaFactory | ||||
|         return AccountMeta::create($data); | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      * Create update or delete meta data. | ||||
|      * | ||||
|      * @param Account $account | ||||
|      * @param string  $field | ||||
|      * @param string  $value | ||||
|      * | ||||
|      * @return AccountMeta|null | ||||
|      */ | ||||
|     public function crud(Account $account, string $field, string $value): ?AccountMeta | ||||
|     { | ||||
|         /** @var AccountMeta $entry */ | ||||
|         $entry = $account->accountMeta()->where('name', $field)->first(); | ||||
|  | ||||
|         // must not be an empty string: | ||||
|         if ('' !== $value) { | ||||
|  | ||||
|             // if $data has field and $entry is null, create new one: | ||||
|             if (null === $entry) { | ||||
|                 Log::debug(sprintf('Created meta-field "%s":"%s" for account #%d ("%s") ', $field, $value, $account->id, $account->name)); | ||||
|                 $this->create(['account_id' => $account->id, 'name' => $field, 'data' => $value]); | ||||
|             } | ||||
|  | ||||
|             // if $data has field and $entry is not null, update $entry: | ||||
|             if (null !== $entry) { | ||||
|                 $entry->data = $value; | ||||
|                 $entry->save(); | ||||
|                 Log::debug(sprintf('Updated meta-field "%s":"%s" for #%d ("%s") ', $field, $value, $account->id, $account->name)); | ||||
|             } | ||||
|         } | ||||
|         if ('' === $value && null !== $entry && isset($data[$field])) { | ||||
|             try { | ||||
|                 $entry->delete(); | ||||
|             } catch (Exception $e) { | ||||
|                 Log::debug(sprintf('Could not delete entry: %s', $e->getMessage())); | ||||
|             } | ||||
|         } | ||||
|  | ||||
|         return $entry; | ||||
|     } | ||||
|  | ||||
| } | ||||
|   | ||||
							
								
								
									
										79
									
								
								app/Factory/AttachmentFactory.php
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										79
									
								
								app/Factory/AttachmentFactory.php
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,79 @@ | ||||
| <?php | ||||
| /** | ||||
|  * AttachmentFactory.php | ||||
|  * Copyright (c) 2018 thegrumpydictator@gmail.com | ||||
|  * | ||||
|  * This file is part of Firefly III. | ||||
|  * | ||||
|  * Firefly III is free software: you can redistribute it and/or modify | ||||
|  * it under the terms of the GNU General Public License as published by | ||||
|  * the Free Software Foundation, either version 3 of the License, or | ||||
|  * (at your option) any later version. | ||||
|  * | ||||
|  * Firefly III is distributed in the hope that it will be useful, | ||||
|  * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||||
|  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the | ||||
|  * GNU General Public License for more details. | ||||
|  * | ||||
|  * You should have received a copy of the GNU General Public License | ||||
|  * along with Firefly III. If not, see <http://www.gnu.org/licenses/>. | ||||
|  */ | ||||
|  | ||||
| declare(strict_types=1); | ||||
|  | ||||
| namespace FireflyIII\Factory; | ||||
|  | ||||
| use FireflyIII\Models\Attachment; | ||||
| use FireflyIII\Models\Note; | ||||
| use FireflyIII\User; | ||||
|  | ||||
| /** | ||||
|  * Class AttachmentFactory | ||||
|  */ | ||||
| class AttachmentFactory | ||||
| { | ||||
|     /** @var User */ | ||||
|     private $user; | ||||
|  | ||||
|     /** | ||||
|      * @param array $data | ||||
|      * | ||||
|      * @return Attachment|null | ||||
|      */ | ||||
|     public function create(array $data): ?Attachment | ||||
|     { | ||||
|         // create attachment: | ||||
|         $attachment = Attachment::create( | ||||
|             [ | ||||
|                 'user_id'         => $this->user->id, | ||||
|                 'attachable_id'   => $data['model_id'], | ||||
|                 'attachable_type' => $data['model'], | ||||
|                 'md5'             => '', | ||||
|                 'filename'        => $data['filename'], | ||||
|                 'title'           => '' === $data['title'] ? null : $data['title'], | ||||
|                 'description'     => null, | ||||
|                 'mime'            => '', | ||||
|                 'size'            => 0, | ||||
|                 'uploaded'        => 0, | ||||
|             ] | ||||
|         ); | ||||
|         $notes      = (string)($data['notes'] ?? ''); | ||||
|         if ('' !== $notes) { | ||||
|             $note = new Note; | ||||
|             $note->noteable()->associate($attachment); | ||||
|             $note->text = $notes; | ||||
|             $note->save(); | ||||
|         } | ||||
|  | ||||
|         return $attachment; | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      * @param User $user | ||||
|      */ | ||||
|     public function setUser(User $user): void | ||||
|     { | ||||
|         $this->user = $user; | ||||
|     } | ||||
|  | ||||
| } | ||||
Some files were not shown because too many files have changed in this diff Show More
		Reference in New Issue
	
	Block a user