Compare commits

..

132 Commits

Author SHA1 Message Date
James Cole
5a47391a64 Merge branch 'release/4.0.1' 2016-10-04 20:13:50 +02:00
James Cole
a31ac79173 New version. 2016-10-04 20:13:40 +02:00
James Cole
0d0a604254 Changelog for 4.0.1 [skip ci] 2016-10-04 20:13:09 +02:00
James Cole
724d25f2c2 Merge branch 'develop'
* develop:
  Fixed some rare bugs.
  Extra clear button to reapply rules #307
  Fix trim when null [skip ci]
  Fixed a bug where incoming transactions would not be properly filtered in several reports.
  Removed for #334
  Fix #337 [skip ci]
  Fix #335
  Remove account extra text #336 [skip ci]
  Fixes bug #338
  Refer to correct page [skip ci]
  Catch unset row.
2016-10-04 20:08:35 +02:00
James Cole
8ed22d452d Merge pull request #342 from tomwerf/master
ING Import
2016-10-04 20:02:34 +02:00
Tom van der Werf
d7fef45a56 added some comments 2016-10-04 17:50:01 +00:00
Tom van der Werf
dc22802dec removed some debug commands 2016-10-04 17:30:49 +00:00
Tom van der Werf
ce5af7b1d9 Better descriptions for ING accounts 2016-10-03 17:08:24 +00:00
James Cole
0a147e5c9c Fixed some rare bugs. 2016-10-02 15:09:43 +02:00
James Cole
7d21255f7f Extra clear button to reapply rules #307 2016-10-02 08:14:11 +02:00
James Cole
13f952f182 Fix trim when null [skip ci] 2016-10-01 09:41:16 +02:00
James Cole
b494be228b Fixed a bug where incoming transactions would not be properly filtered in several reports. 2016-10-01 09:37:18 +02:00
James Cole
0fdaac53d0 Removed for #334 2016-10-01 08:49:33 +02:00
James Cole
e1b3a08878 Fix #337 [skip ci] 2016-10-01 08:49:02 +02:00
James Cole
dc893588b0 Fix #335 2016-10-01 08:48:13 +02:00
James Cole
b9fcc443ec Remove account extra text #336 [skip ci] 2016-10-01 08:45:14 +02:00
James Cole
d8586c8043 Fixes bug #338 2016-09-29 19:17:24 +02:00
James Cole
4252a3e53b Refer to correct page [skip ci] 2016-09-29 07:04:58 +02:00
James Cole
dbb5cdb9cf Catch unset row. 2016-09-29 07:02:47 +02:00
James Cole
9bdfecbfdc Merge branch 'release/4.0.0' 2016-09-26 18:37:33 +02:00
James Cole
3ec8a8c375 Merge branch 'release/4.0.0' into develop 2016-09-26 18:37:33 +02:00
James Cole
f85e4a24e5 New license information. 2016-09-26 18:37:20 +02:00
James Cole
0dda87c78e New license. 2016-09-26 18:34:31 +02:00
James Cole
2fc09ff9d7 Fix empty pop-ups in report. 2016-09-25 14:47:55 +02:00
James Cole
e4e0e21293 Smaller method. 2016-09-25 08:59:27 +02:00
James Cole
15089f0d7e Some issues fixed for scrutiniser. 2016-09-25 08:50:12 +02:00
James Cole
7232c1d7bb partial fix for #307 2016-09-25 08:46:57 +02:00
James Cole
9a53d8c21c Some array_keys fixes. 2016-09-25 08:46:42 +02:00
James Cole
0d198193db Some issues fixed for scrutiniser. 2016-09-25 08:36:35 +02:00
James Cole
45bc23b8af Some issues fixed for scrutiniser. 2016-09-25 08:32:53 +02:00
James Cole
3323c31765 Some issues fixed for scrutiniser. 2016-09-25 08:24:03 +02:00
James Cole
bb7c26b77c Some issues fixed for scrutiniser. 2016-09-25 08:20:17 +02:00
James Cole
9101d6a2c0 Add lines to configuration on wiki. [skip ci] 2016-09-24 19:32:00 +02:00
James Cole
ad2b254be0 Fix for issue #328. Turns out the import routine converts accounts back and forth instead of creating new entries. 2016-09-24 18:59:31 +02:00
James Cole
abc4f856ce Fix nullable fields. 2016-09-24 17:22:42 +02:00
James Cole
b3b66a8f92 Merge pull request #329 from niekvanderkooy/develop
Fix assignment of array variables
2016-09-24 17:04:32 +02:00
Niek van der Kooy
2f7cf9b916 Fix assignment of array variables 2016-09-24 17:01:41 +02:00
James Cole
b822e0c6e7 Upgrade stuff for 4.0.0 2016-09-24 15:30:08 +02:00
James Cole
6fef9ee72b #315 2016-09-24 10:58:48 +02:00
James Cole
ab6dd0a1ec #314 2016-09-24 10:55:13 +02:00
James Cole
9deef5ac92 #325 2016-09-24 10:53:39 +02:00
James Cole
577187babe Fix #324 [skip ci] 2016-09-24 10:52:13 +02:00
James Cole
577290e813 add strtolower [skip ci] 2016-09-24 09:14:47 +02:00
James Cole
f3b9798216 Fix some rule things. 2016-09-24 09:12:17 +02:00
James Cole
4dcaa96d16 Fix group error. I hope. 2016-09-24 08:59:29 +02:00
James Cole
0dcbf451d6 Add verify command to composer.json 2016-09-24 08:59:14 +02:00
James Cole
e87f6ca40e Fix some possible NULL values. 2016-09-24 08:55:01 +02:00
James Cole
1f34e33d8c Update composer, improve verify routine. 2016-09-23 22:31:01 +02:00
James Cole
258e87e127 Merge pull request #323 from Mortalife/master
Adding GBP to Seed
2016-09-22 07:58:21 +02:00
Matthew Peck
3ec8efcfc1 Adding GBP to Seed 2016-09-21 20:45:36 +01:00
James Cole
70ea227bd0 Add logging to processor #322 2016-09-21 21:01:10 +02:00
James Cole
27c832ed58 Logging for rule triggers #322 2016-09-21 20:58:12 +02:00
James Cole
a31b4ccf01 Basic logging for willMatchEverything #322 2016-09-21 20:30:09 +02:00
James Cole
d221ea68d0 Gave all rule actions some logging. #322 2016-09-21 20:12:04 +02:00
James Cole
dc9fe58536 Fix tags input width. 2016-09-21 19:23:50 +02:00
James Cole
f871e29bdb Quick fix for broken attachments. 2016-09-21 19:16:47 +02:00
James Cole
1357352276 Merge pull request #320 from Mortalife/master
Decimal place fix on import
2016-09-20 20:21:02 +02:00
James Cole
e169754693 Fix display bug for attachments 2016-09-20 17:23:12 +02:00
James Cole
1cfe4f40ba Fix display bug for attachments 2016-09-20 17:22:07 +02:00
James Cole
5545d1c1ba Fix display bug for attachments 2016-09-20 17:21:26 +02:00
James Cole
e5f7228fa9 Fix future query problems (current users not affected either way) [skip ci] 2016-09-20 09:32:58 +02:00
James Cole
11385494eb Fix for income entry. 2016-09-20 08:57:08 +02:00
James Cole
ae328de469 Fix bug in year report. 2016-09-20 08:26:42 +02:00
James Cole
0574a706c8 Error in decrypt error (yes) 2016-09-20 07:57:04 +02:00
Matthew Peck
70bb85a75b Cleanup 2016-09-20 00:00:11 +01:00
Matthew Peck
8cd901b57b Added support for multiple decimal places 2016-09-19 23:53:51 +01:00
James Cole
8b9818c48e This will fix #316 2016-09-18 20:00:13 +02:00
James Cole
a95099fa46 Update FF configuration. 2016-09-18 19:57:21 +02:00
James Cole
221e4b7fc0 Fix some migrations [skip ci] 2016-09-18 18:14:07 +02:00
James Cole
6cff3eb61e Fix some migrations [skip ci] 2016-09-18 17:52:31 +02:00
James Cole
e4fd97ae77 Some code fixes. [skip ci] 2016-09-17 09:52:28 +02:00
James Cole
5ca9099654 Some code fixes. 2016-09-17 09:50:40 +02:00
James Cole
6e33e26ddf Update copyright notices, update German language. 2016-09-17 07:57:32 +02:00
James Cole
04461a4ab8 Updated composer.lock [skip ci] 2016-09-17 07:22:39 +02:00
James Cole
a4b9bbff54 Update AdminLTE template. 2016-09-17 07:19:09 +02:00
James Cole
4ad4252a77 Extend exclude path. Trigger a new inspection. 2016-09-17 07:10:29 +02:00
James Cole
aac0c9ab98 Various layout updates and tiny upgrade fixes [skip ci] 2016-09-16 13:29:56 +02:00
James Cole
c123e1044a Expand config so people won't get errors here [skip ci] 2016-09-16 12:19:29 +02:00
James Cole
d25d0454fc Code clean up 2016-09-16 12:15:58 +02:00
James Cole
f38984398d Code clean up [skip ci] 2016-09-16 12:07:45 +02:00
James Cole
a07799cfa4 MySQL 5.7 compatible query fixing. [skip ci] 2016-09-16 11:16:31 +02:00
James Cole
7c52f297ee MySQL 5.7 compatible query fixing. [skip ci] 2016-09-16 11:06:21 +02:00
James Cole
50a3279b30 MySQL 5.7 compatible query fixing. [skip ci] 2016-09-16 11:04:24 +02:00
James Cole
0ea14eb987 MySQL 5.7 compatible grouping. [skip ci] 2016-09-16 11:01:35 +02:00
James Cole
cf1b98e569 MySQL 5.7 compatible grouping. 2016-09-16 10:55:26 +02:00
James Cole
63fb435002 Expand code. 2016-09-16 10:50:19 +02:00
James Cole
2f8263f53a Possible fix for reports [skip ci] 2016-09-16 09:36:08 +02:00
James Cole
fb649779d6 Do not need to sort. Fix MySQL 5.7 compatibility. 2016-09-16 09:31:40 +02:00
James Cole
bb58f605f7 Some new login / logout routes 2016-09-16 09:21:36 +02:00
James Cole
fccdf56c5d Fixed some query things. 2016-09-16 09:09:54 +02:00
James Cole
bd53410c71 Some changes in login routes for 5.3 2016-09-16 09:02:35 +02:00
James Cole
7d63f124c4 Fixing some login routes 2016-09-16 07:22:57 +02:00
James Cole
9ffc5d857c Fixed some db bugs. These will only pop up when developing. 2016-09-16 07:16:09 +02:00
James Cole
2f93784acd More code for 5.3 2016-09-16 07:05:34 +02:00
James Cole
d00fbe4eb3 More code for 5.3 2016-09-16 06:48:38 +02:00
James Cole
51d9f041ae Changes for login routes. 2016-09-16 06:43:13 +02:00
James Cole
b872ab8b86 New code and new routes for 5.3 2016-09-16 06:40:45 +02:00
James Cole
3d25fd79ca First set of upgrade to 5.3 stuff. 2016-09-16 06:19:40 +02:00
James Cole
3aad78e6ef Lots of updated libraries.
Signed-off-by: James Cole <thegrumpydictator@gmail.com>
2016-09-15 19:14:55 +02:00
James Cole
7d5bb72b0c Fix for #312
Signed-off-by: James Cole <thegrumpydictator@gmail.com>
2016-09-15 19:14:22 +02:00
James Cole
46e5aae8bb Fix changelog. [skip ci]
Signed-off-by: James Cole <thegrumpydictator@gmail.com>
2016-09-15 19:00:22 +02:00
James Cole
b9e2ee7af3 Merge branch 'release/3.10.4' 2016-09-14 20:40:52 +02:00
James Cole
c1a2892788 New changelog.
Signed-off-by: James Cole <thegrumpydictator@gmail.com>
2016-09-14 20:40:12 +02:00
James Cole
2078183e0d Update version and composer file. 2016-09-14 20:37:12 +02:00
James Cole
fab1d53714 Simplified upgrade instructions. 2016-09-14 20:35:45 +02:00
James Cole
3fe831c7d8 Bit of code cleanup courtesy of PHPStorm. 2016-09-13 19:20:09 +02:00
James Cole
6958f71cfd @fuf discovered a bug where FF3 will fall back to the hard-coded system default currency and not the set default currency. See #307 2016-09-13 19:19:58 +02:00
James Cole
a7351f348d Fixed a bug mentioned by @vissert and added some logging for @sandermulders
Signed-off-by: James Cole <thegrumpydictator@gmail.com>
2016-09-12 18:43:10 +02:00
James Cole
5379e03447 Merge pull request #311 from sandermulders/fix/nullable-values
add migration that correctly sets nullable for description fields on rules and rule_groups
2016-09-12 16:52:14 +02:00
Sander Mulders
539058e32d Fix for #310: add migration that correctly sets nullable for description fields on rules and rule_groups 2016-09-12 14:24:01 +02:00
James Cole
11b6b5a63c Merge branch 'release/3.10.3' into develop 2016-09-11 08:17:42 +02:00
James Cole
1155096226 Merge branch 'release/3.10.3' 2016-09-11 08:17:41 +02:00
James Cole
2920dd356e Updated translations.
Signed-off-by: James Cole <thegrumpydictator@gmail.com>
2016-09-11 08:17:35 +02:00
James Cole
9c3dac8170 Config for new version.
Signed-off-by: James Cole <thegrumpydictator@gmail.com>
2016-09-11 08:13:22 +02:00
James Cole
49f9909b15 New changelog.
Signed-off-by: James Cole <thegrumpydictator@gmail.com>
2016-09-11 08:13:14 +02:00
James Cole
e4fef6dfc3 Fixed an import bug where a new transaction validation rule would break storing of the transaction, while the import would not notice this error happening. The importer will now also correctly set a date on the "import tag" and will not tag an incomplete journal as already imported.
Signed-off-by: James Cole <thegrumpydictator@gmail.com>
2016-09-11 08:08:01 +02:00
James Cole
2da087401e Extend audit report
Signed-off-by: James Cole <thegrumpydictator@gmail.com>
2016-09-10 18:37:16 +02:00
James Cole
629baf9de5 Added invoice date
Signed-off-by: James Cole <thegrumpydictator@gmail.com>
2016-09-10 18:36:52 +02:00
James Cole
29a930dae5 Updated translations.
Signed-off-by: James Cole <thegrumpydictator@gmail.com>
2016-09-09 11:36:19 +02:00
James Cole
d920537dd2 Updated translations.
Signed-off-by: James Cole <thegrumpydictator@gmail.com>
2016-09-09 11:29:19 +02:00
James Cole
106b04a5da Update composer.lock [skip ci]
Signed-off-by: James Cole <thegrumpydictator@gmail.com>
2016-09-09 11:19:50 +02:00
James Cole
176752e219 Code for optional fields #301
Signed-off-by: James Cole <thegrumpydictator@gmail.com>
2016-09-09 11:19:40 +02:00
James Cole
8d19f60091 Various translation updates.
Signed-off-by: James Cole <thegrumpydictator@gmail.com>
2016-09-09 11:19:19 +02:00
James Cole
e937aa2f74 Fix a bug in piggy bank display [skip ci]
Signed-off-by: James Cole <thegrumpydictator@gmail.com>
2016-09-09 06:17:50 +02:00
James Cole
c3ccc4ccdf This should fix #308
Signed-off-by: James Cole <thegrumpydictator@gmail.com>
2016-09-08 21:10:24 +02:00
James Cole
6c5cd705c0 Some code for new optional fields, see #301
Signed-off-by: James Cole <thegrumpydictator@gmail.com>
2016-09-04 16:21:51 +02:00
James Cole
ce003f217b Removed unused "budget maximum" preference 2016-09-03 21:13:08 +02:00
James Cole
8c7ef49eb6 New code by @vissert that allows category edit (see #282)
Signed-off-by: James Cole <thegrumpydictator@gmail.com>
2016-09-03 05:01:48 +02:00
James Cole
29af4bd1b9 This fixes #303 2016-09-03 04:54:57 +02:00
James Cole
2ce5142b06 Small fix for #303
Signed-off-by: James Cole <thegrumpydictator@gmail.com>
2016-09-01 19:01:08 +02:00
James Cole
f3a8a25872 Fixed #303
Signed-off-by: James Cole <thegrumpydictator@gmail.com>
2016-09-01 18:31:39 +02:00
James Cole
598e97d028 Forgot to escape things, which causes havoc in the Dutch translation.
Signed-off-by: James Cole <thegrumpydictator@gmail.com>
2016-08-31 18:50:46 +02:00
338 changed files with 7533 additions and 3295 deletions

View File

@@ -3,14 +3,17 @@ APP_DEBUG=false
APP_FORCE_SSL=false
APP_FORCE_ROOT=
APP_KEY=SomeRandomStringOf32CharsExactly
LOG_LEVEL=warning
APP_LOG_LEVEL=warning
APP_URL=http://localhost
DB_CONNECTION=mysql
DB_HOST=localhost
DB_HOST=127.0.0.1
DB_PORT=3306
DB_DATABASE=homestead
DB_USERNAME=homestead
DB_PASSWORD=secret
BROADCAST_DRIVER=log
CACHE_DRIVER=file
SESSION_DRIVER=file
QUEUE_DRIVER=sync
@@ -19,17 +22,14 @@ COOKIE_PATH="/"
COOKIE_DOMAIN=
COOKIE_SECURE=false
DEFAULT_CURRENCY=EUR
DEFAULT_LANGUAGE=en_US
REDIS_HOST=localhost
REDIS_HOST=127.0.0.1
REDIS_PASSWORD=null
REDIS_PORT=6379
MAIL_DRIVER=smtp
MAIL_HOST=mailtrap.io
MAIL_PORT=2525
MAIL_FROM=enter_your_email_here
MAIL_FROM=changeme@example.com
MAIL_USERNAME=null
MAIL_PASSWORD=null
MAIL_ENCRYPTION=null
@@ -38,7 +38,10 @@ SEND_REGISTRATION_MAIL=true
MUST_CONFIRM_ACCOUNT=false
SHOW_INCOMPLETE_TRANSLATIONS=false
SHOW_DEMO_WARNING=false
ANALYTICS_ID=
SITE_OWNER=mail@example.com
PUSHER_KEY=
PUSHER_SECRET=
PUSHER_APP_ID=

View File

@@ -1,38 +0,0 @@
APP_ENV=testing
APP_DEBUG=true
APP_FORCE_SSL=false
APP_KEY=SomeRandomStringOf32CharsExactly
LOG_LEVEL=debug
DB_CONNECTION=sqlite
DB_HOST=localhost
DB_DATABASE=homestead
DB_USERNAME=homestead
DB_PASSWORD=secret
CACHE_DRIVER=array
SESSION_DRIVER=array
QUEUE_DRIVER=array
DEFAULT_CURRENCY=EUR
DEFAULT_LANGUAGE=en_US
REDIS_HOST=localhost
REDIS_PASSWORD=null
REDIS_PORT=6379
MAIL_DRIVER=log
MAIL_HOST=mailtrap.io
MAIL_PORT=2525
MAIL_FROM=your_address_here@example.com
MAIL_USERNAME=null
MAIL_PASSWORD=null
MAIL_ENCRYPTION=null
SHOW_INCOMPLETE_TRANSLATIONS=false
ANALYTICS_ID=abcde
RUNCLEANUP=false
SITE_OWNER=your_address_here@example.com
BLOCKED_DOMAINS=

2
.gitattributes vendored
View File

@@ -1,3 +1,3 @@
* text=auto
*.css linguist-vendored
*.less linguist-vendored
*.scss linguist-vendored

6
.gitignore vendored Normal file → Executable file
View File

@@ -1,5 +1,9 @@
/vendor
/node_modules
/public/storage
/vendor
/.idea
Homestead.json
Homestead.yaml
.env
_development
.env.local

View File

@@ -5,3 +5,4 @@ filter:
excluded_paths:
- app/Support/Migration/*
- app/database/migrations/*
- database/migrations/*

View File

@@ -2,8 +2,77 @@
All notable changes to this project will be documented in this file.
This project adheres to [Semantic Versioning](http://semver.org/).
## [Unreleased]
- No unreleased changes yet.
## [4.0.1] - 2016-10-04
### Added
- New ING import specific by @tomwerf
- New Presidents Choice specific to fix #307
- Added some trimming (#335)
### Changed
- Initial release.
### Deprecated
- Initial release.
### Removed
- Initial release.
### Fixed
- Fixed a bug where incoming transactions would not be properly filtered in several reports.
- #334 by @cyberkov
- #337
- #336
- #338 found by @roberthorlings
### Security
- Initial release.
## [4.0.0] - 2015-09-26
### Added
- Upgraded to Laravel 5.3, most other libraries upgraded as well.
- Added GBP as currency, thanks to @Mortalife
### Changed
- Jump to version 4.0.0.
- Firefly III is now subject to a [Creative Commons Attribution-ShareAlike 4.0 International License](https://creativecommons.org/licenses/by-sa/4.0/) license. Previous versions of this software are still MIT licensed.
### Fixed
- Support for specific decimal places, thanks to @Mortalife
- Various CSS fixes
- Various bugs, thanks to @fuf, @sandermulders and @vissert
- Various queries optimized for MySQL 5.7
## [3.10.4] - 2015-09-14
### Fixed
- Migration fix by @sandermulders
- Tricky import bug fix thanks to @vissert
- Currency preference will be correctly pulled from user settings, thanks to @fuf
- Simplified code for upgrade instructions.
## [3.10.3] - 2016-08-29
### Added
- More fields for mass-edit, thanks to @Vissert (#282)
- First start of German translation
### Changed
- More optional fields for transactions and the ability to filter them.
### Removed
- Preference for budget maximum.
### Fixed
- A bug in the translation routine broke the import.
- It was possible to destroy your Firefly installation by removing all currencies. Thanks @mondjef
- Translation bugs.
- Import bug.
### Security
- Firefly will not accept registrations beyond the first one, by default.
## [3.10.2] - 2016-08-29
### Added
@@ -53,13 +122,6 @@ This project adheres to [Semantic Versioning](http://semver.org/).
- The date picker now supports more ranges and periods.
- Rewrote all migrations. #272
### Deprecated
- Initial release.
### Removed
- Initial release.
### Fixed
- Issue #264
- Issue #265
@@ -74,10 +136,6 @@ This project adheres to [Semantic Versioning](http://semver.org/).
- Bulk update problems, #280, thanks @stickgrinder
- Fixed various problems with amount reporting of split transactions.
### Security
- Initial release.
[3.9.1]
### Fixed
- Fixed a bug where removing money from a piggy bank would not work. See issue #265 and #269

View File

@@ -1,7 +1,7 @@
Copyright (C) 2016 thegrumpydictator@gmail.com
Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
This work is licensed under a Creative Commons Attribution-ShareAlike 4.0 International License.
The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
https://creativecommons.org/licenses/by-sa/4.0/
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.

View File

@@ -22,24 +22,40 @@ use Illuminate\Log\Writer;
*/
class ConfigureLogging extends IlluminateConfigureLogging
{
/**
* @param Application $app
* @param Writer $log
* Configure the Monolog handlers for the application.
*
* @param \Illuminate\Contracts\Foundation\Application $app
* @param \Illuminate\Log\Writer $log
*
* @return void
*/
protected function configureDailyHandler(Application $app, Writer $log)
{
$config = $app->make('config');
$maxFiles = $config->get('app.log_max_files');
$log->useDailyFiles(
$app->storagePath() . '/logs/firefly-iii.log',
$app->make('config')->get('app.log_max_files', 5)
$app->storagePath() . '/logs/firefly-iii.log', is_null($maxFiles) ? 5 : $maxFiles,
$config->get('app.log_level', 'debug')
);
}
/**
* @param Application $app
* @param Writer $log
* Configure the Monolog handlers for the application.
*
* @param \Illuminate\Contracts\Foundation\Application $app
* @param \Illuminate\Log\Writer $log
*
* @return void
*/
protected function configureSingleHandler(Application $app, Writer $log)
{
$log->useFiles($app->storagePath() . '/logs/firefly-iii.log');
$log->useFiles(
$app->storagePath() . '/logs/firefly-iii.log',
$app->make('config')->get('app.log_level', 'debug')
);
}
}

View File

@@ -0,0 +1,99 @@
<?php
/**
* ScanAttachments.php
* Copyright (C) 2016 thegrumpydictator@gmail.com
*
* This software may be modified and distributed under the terms
* of the MIT license. See the LICENSE file for details.
*/
declare(strict_types = 1);
namespace FireflyIII\Console\Commands;
use Crypt;
use FireflyIII\Models\Attachment;
use Illuminate\Console\Command;
use Illuminate\Contracts\Encryption\DecryptException;
use Illuminate\Contracts\Filesystem\FileNotFoundException;
use Storage;
/**
* Class ScanAttachments
*
* @package FireflyIII\Console\Commands
*/
class ScanAttachments extends Command
{
/**
* The console command description.
*
* @var string
*/
protected $description = 'Rescan all attachments and re-set the MD5 hash and mime.';
/**
* The name and signature of the console command.
*
* @var string
*/
protected $signature = 'firefly:scan-attachments';
/**
* Create a new command instance.
*
*/
public function __construct()
{
parent::__construct();
}
/**
* Execute the console command.
*/
public function handle()
{
$attachments = Attachment::get();
$disk = Storage::disk('upload');
/** @var Attachment $attachment */
foreach ($attachments as $attachment) {
$fileName = $attachment->fileName();
// try to grab file content:
try {
$content = $disk->get($fileName);
} catch (FileNotFoundException $e) {
$this->error(sprintf('Could not find data for attachment #%d', $attachment->id));
continue;
}
// try to decrypt content.
try {
$decrypted = Crypt::decrypt($content);
} catch (DecryptException $e) {
$this->error(sprintf('Could not decrypt data of attachment #%d', $attachment->id));
continue;
}
// make temp file:
$tmpfname = tempnam(sys_get_temp_dir(), 'FireflyIII');
// store content in temp file:
file_put_contents($tmpfname, $decrypted);
// get md5 and mime
$md5 = md5_file($tmpfname);
$mime = mime_content_type($tmpfname);
// update attachment:
$attachment->md5 = $md5;
$attachment->mime = $mime;
$attachment->save();
$this->line(sprintf('Fixed attachment #%d', $attachment->id));
// find file:
}
}
}

View File

@@ -51,15 +51,22 @@ class UpgradeFireflyInstructions extends Command
/** @var string $version */
$version = config('firefly.version');
$config = config('upgrade.text');
$text = $config[$version] ?? null;
$text = null;
foreach (array_keys($config) as $compare) {
// if string starts with:
$len = strlen($compare);
if (substr($version, 0, $len) === $compare) {
$text = $config[$compare];
}
}
$this->line('+------------------------------------------------------------------------------+');
$this->line('');
if (is_null($text)) {
$this->line('Thank you for installing Firefly III, v' . $version);
$this->line('If you are upgrading from a previous version,');
$this->info('there are no extra upgrade instructions.');
$this->info('There are no extra upgrade instructions.');
$this->line('Firefly III should be ready for use.');
} else {
$this->line('Thank you for installing Firefly III, v' . $version);

View File

@@ -12,13 +12,13 @@ declare(strict_types = 1);
namespace FireflyIII\Console\Commands;
use Crypt;
use DB;
use FireflyIII\Models\Account;
use FireflyIII\Models\Budget;
use FireflyIII\Models\Category;
use FireflyIII\Models\Tag;
use FireflyIII\Models\Transaction;
use FireflyIII\Models\TransactionJournal;
use FireflyIII\Models\TransactionType;
use FireflyIII\Repositories\User\UserRepositoryInterface;
use FireflyIII\User;
use Illuminate\Console\Command;
@@ -79,6 +79,9 @@ class VerifyDatabase extends Command
// report on journals with no transactions at all.
$this->reportNoTransactions();
// transfers with budgets.
$this->reportTransfersBudgets();
}
/**
@@ -89,11 +92,10 @@ class VerifyDatabase extends Command
$set = Account
::leftJoin('transactions', 'transactions.account_id', '=', 'accounts.id')
->leftJoin('users', 'accounts.user_id', '=', 'users.id')
->groupBy('accounts.id')
->having('transaction_count', '=', 0)
->groupBy(['accounts.id', 'accounts.encrypted', 'accounts.name', 'accounts.user_id', 'users.email'])
->whereNull('transactions.account_id')
->get(
['accounts.id', 'accounts.encrypted', 'accounts.name', 'accounts.user_id', 'users.email',
DB::raw('COUNT(`transactions`.`id`) AS `transaction_count`')]
['accounts.id', 'accounts.encrypted', 'accounts.name', 'accounts.user_id', 'users.email']
);
/** @var stdClass $entry */
@@ -113,9 +115,9 @@ class VerifyDatabase extends Command
$set = Budget
::leftJoin('budget_limits', 'budget_limits.budget_id', '=', 'budgets.id')
->leftJoin('users', 'budgets.user_id', '=', 'users.id')
->groupBy('budgets.id')
->having('budget_limit_count', '=', 0)
->get(['budgets.id', 'budgets.name', 'budgets.user_id', 'users.email', DB::raw('COUNT(`budget_limits`.`id`) AS `budget_limit_count`')]);
->groupBy(['budgets.id', 'budgets.name', 'budgets.user_id', 'users.email'])
->whereNull('budget_limits.id')
->get(['budgets.id', 'budgets.name', 'budgets.user_id', 'users.email']);
/** @var stdClass $entry */
foreach ($set as $entry) {
@@ -225,19 +227,16 @@ class VerifyDatabase extends Command
}
}
/**
*
*/
private function reportNoTransactions()
{
/*
* select transaction_journals.id, count(transactions.id) as transaction_count from transaction_journals
left join transactions ON transaction_journals.id = transactions.transaction_journal_id
group by transaction_journals.id
having transaction_count = 0
*/
$set = TransactionJournal
::leftJoin('transactions', 'transactions.transaction_journal_id', '=', 'transaction_journals.id')
->groupBy('transaction_journals.id')
->having('transaction_count', '=', 0)
->get(['transaction_journals.id', DB::raw('COUNT(`transactions`.`id`) as `transaction_count`')]);
->whereNull('transactions.transaction_journal_id')
->get(['transaction_journals.id']);
foreach ($set as $entry) {
$this->error(
@@ -306,4 +305,29 @@ having transaction_count = 0
);
}
}
/**
*
*/
private function reportTransfersBudgets()
{
$set = TransactionJournal
::distinct()
->leftJoin('transaction_types', 'transaction_types.id', '=', 'transaction_journals.transaction_type_id')
->leftJoin('budget_transaction_journal', 'transaction_journals.id', '=', 'budget_transaction_journal.transaction_journal_id')
->where('transaction_types.type', TransactionType::TRANSFER)
->whereNotNull('budget_transaction_journal.budget_id')->get(['transaction_journals.id']);
/** @var TransactionJournal $entry */
foreach ($set as $entry) {
$this->error(
sprintf(
'Error: Transaction journal #%d is a transfer, but has a budget. Edit it without changing anything, so the budget will be removed.',
$entry->id
)
);
}
}
}

28
app/Console/Kernel.php Normal file → Executable file
View File

@@ -13,8 +13,10 @@ namespace FireflyIII\Console;
use FireflyIII\Console\Commands\EncryptFile;
use FireflyIII\Console\Commands\Import;
use FireflyIII\Console\Commands\ScanAttachments;
use FireflyIII\Console\Commands\UpgradeFireflyInstructions;
use FireflyIII\Console\Commands\VerifyDatabase;
use Illuminate\Console\Scheduling\Schedule;
use Illuminate\Foundation\Console\Kernel as ConsoleKernel;
/**
@@ -24,11 +26,10 @@ use Illuminate\Foundation\Console\Kernel as ConsoleKernel;
*/
class Kernel extends ConsoleKernel
{
/**
* The bootstrap classes for the application.
*
* This needs to be for with the next upgrade.
* Next upgrade verify these are the same.
*
* @var array
*/
@@ -55,5 +56,28 @@ class Kernel extends ConsoleKernel
VerifyDatabase::class,
Import::class,
EncryptFile::class,
ScanAttachments::class,
];
/**
* Register the Closure based commands for the application.
*
* @return void
*/
protected function commands()
{
require base_path('routes/console.php');
}
/**
* Define the application's command schedule.
*
* @param \Illuminate\Console\Scheduling\Schedule $schedule
*
* @return void
*/
protected function schedule(Schedule $schedule)
{
}
}

View File

@@ -148,16 +148,20 @@ class AccountCrud implements AccountCrudInterface
if (count($types) > 0) {
$query->leftJoin('account_types', 'accounts.account_type_id', '=', 'account_types.id');
$query->whereIn('account_types.type', $types);
}
Log::debug(sprintf('Searching for account named %s of the following type(s)', $name), ['types' => $types]);
$accounts = $query->get(['accounts.*']);
/** @var Account $account */
foreach ($accounts as $account) {
if ($account->name === $name) {
Log::debug(sprintf('Found #%d (%s) with type id %d', $account->id, $account->name, $account->account_type_id));
return $account;
}
}
Log::debug('Found nothing.');
return new Account;
}
@@ -217,6 +221,33 @@ class AccountCrud implements AccountCrudInterface
return $result;
}
/**
* @param array $types
*
* @return Collection
*/
public function getActiveAccountsByType(array $types): Collection
{
/** @var Collection $result */
$query = $this->user->accounts()->with(
['accountmeta' => function (HasMany $query) {
$query->where('name', 'accountRole');
}]
);
if (count($types) > 0) {
$query->accountTypeIn($types);
}
$query->where('active', 1);
$result = $query->get(['accounts.*']);
$result = $result->sortBy(
function (Account $account) {
return strtolower($account->name);
}
);
return $result;
}
/**
* @param array $data
*

View File

@@ -75,6 +75,13 @@ interface AccountCrudInterface
*/
public function getAccountsByType(array $types): Collection;
/**
* @param array $types
*
* @return Collection
*/
public function getActiveAccountsByType(array $types): Collection;
/**
* @param array $data
*

33
app/Exceptions/Handler.php Normal file → Executable file
View File

@@ -10,14 +10,15 @@
declare(strict_types = 1);
namespace FireflyIII\Exceptions;
use Auth;
use ErrorException;
use Exception;
use FireflyIII\Jobs\MailError;
use Illuminate\Auth\Access\AuthorizationException;
use Illuminate\Auth\AuthenticationException;
use Illuminate\Database\Eloquent\ModelNotFoundException;
use Illuminate\Foundation\Exceptions\Handler as ExceptionHandler;
use Request;
use Illuminate\Session\TokenMismatchException;
use Illuminate\Validation\ValidationException as ValException;
use Symfony\Component\HttpKernel\Exception\HttpException;
/**
@@ -34,9 +35,12 @@ class Handler extends ExceptionHandler
*/
protected $dontReport
= [
AuthenticationException::class,
AuthorizationException::class,
HttpException::class,
ModelNotFoundException::class,
TokenMismatchException::class,
ValException::class,
];
/**
@@ -71,15 +75,14 @@ class Handler extends ExceptionHandler
*/
public function report(Exception $exception)
{
if ($exception instanceof FireflyException || $exception instanceof ErrorException) {
$userData = [
'id' => 0,
'email' => 'unknown@example.com',
];
if (Auth::check()) {
$userData['id'] = Auth::user()->id;
$userData['email'] = Auth::user()->email;
if (auth()->check()) {
$userData['id'] = auth()->user()->id;
$userData['email'] = auth()->user()->email;
}
$data = [
'class' => get_class($exception),
@@ -92,10 +95,26 @@ class Handler extends ExceptionHandler
];
// create job that will mail.
$job = new MailError($userData, env('SITE_OWNER'), Request::ip(), $data);
$ip = $_SERVER['REMOTE_ADDR'] ?? '0.0.0.0';
$job = new MailError($userData, env('SITE_OWNER', ''), $ip, $data);
dispatch($job);
}
parent::report($exception);
}
/**
* Convert an authentication exception into an unauthenticated response.
*
* @param \Illuminate\Http\Request $request
* @return \Illuminate\Http\Response
*/
protected function unauthenticated($request)
{
if ($request->expectsJson()) {
return response()->json(['error' => 'Unauthenticated.'], 401);
}
return redirect()->guest('login');
}
}

View File

@@ -11,7 +11,6 @@ declare(strict_types = 1);
namespace FireflyIII\Export\Collector;
use Auth;
use Crypt;
use FireflyIII\Models\ExportJob;
use Illuminate\Contracts\Encryption\DecryptException;
@@ -50,7 +49,7 @@ class UploadCollector extends BasicCollector implements CollectorInterface
$this->exportDisk = Storage::disk('export');
// file names associated with the old import routine.
$this->expected = 'csv-upload-' . Auth::user()->id . '-';
$this->expected = 'csv-upload-' . auth()->user()->id . '-';
// for the new import routine:
$this->getImportKeys();
@@ -76,7 +75,7 @@ class UploadCollector extends BasicCollector implements CollectorInterface
*/
private function getImportKeys()
{
$set = Auth::user()->importJobs()->where('status', 'import_complete')->get(['import_jobs.*']);
$set = auth()->user()->importJobs()->where('status', 'import_complete')->get(['import_jobs.*']);
if ($set->count() > 0) {
$keys = $set->pluck('key')->toArray();
$this->importKeys = $keys;
@@ -158,7 +157,7 @@ class UploadCollector extends BasicCollector implements CollectorInterface
{
// find job associated with import file:
$name = str_replace('.upload', '', $entry);
$job = Auth::user()->importJobs()->where('key', $name)->first();
$job = auth()->user()->importJobs()->where('key', $name)->first();
$content = '';
try {
$content = Crypt::decrypt($this->uploadDisk->get($entry));

View File

@@ -11,7 +11,6 @@ declare(strict_types = 1);
namespace FireflyIII\Handlers\Events;
use Auth;
use FireflyIII\Events\TransactionJournalStored;
use FireflyIII\Models\PiggyBank;
use FireflyIII\Models\PiggyBankEvent;
@@ -39,7 +38,7 @@ class ConnectJournalToPiggyBank
$piggyBankId = $event->piggyBankId;
/** @var PiggyBank $piggyBank */
$piggyBank = Auth::user()->piggyBanks()->where('piggy_banks.id', $piggyBankId)->first(['piggy_banks.*']);
$piggyBank = auth()->user()->piggyBanks()->where('piggy_banks.id', $piggyBankId)->first(['piggy_banks.*']);
if (is_null($piggyBank)) {
return true;

View File

@@ -17,7 +17,6 @@ use FireflyIII\Models\Rule;
use FireflyIII\Models\RuleGroup;
use FireflyIII\Rules\Processor;
use FireflyIII\User;
use Illuminate\Support\Facades\Auth;
/**
* Class FireRulesForStore
@@ -38,7 +37,7 @@ class FireRulesForStore
{
// get all the user's rule groups, with the rules, order by 'order'.
/** @var User $user */
$user = Auth::user();
$user = auth()->user();
$groups = $user->ruleGroups()->where('rule_groups.active', 1)->orderBy('order', 'ASC')->get();
//
/** @var RuleGroup $group */

View File

@@ -11,7 +11,6 @@ declare(strict_types = 1);
namespace FireflyIII\Handlers\Events;
use Auth;
use FireflyIII\Events\TransactionJournalUpdated;
use FireflyIII\Models\Rule;
use FireflyIII\Models\RuleGroup;
@@ -36,7 +35,7 @@ class FireRulesForUpdate
{
// get all the user's rule groups, with the rules, order by 'order'.
/** @var User $user */
$user = Auth::user();
$user = auth()->user();
$groups = $user->ruleGroups()->where('rule_groups.active', 1)->orderBy('order', 'ASC')->get();
//
/** @var RuleGroup $group */

View File

@@ -10,7 +10,6 @@
declare(strict_types = 1);
namespace FireflyIII\Helpers\Attachments;
use Auth;
use Crypt;
use FireflyIII\Models\Attachment;
use Illuminate\Database\Eloquent\Model;
@@ -60,7 +59,7 @@ class AttachmentHelper implements AttachmentHelperInterface
*/
public function getAttachmentLocation(Attachment $attachment): string
{
$path = storage_path('upload') . DIRECTORY_SEPARATOR . 'at-' . $attachment->id . '.data';
$path = sprintf('%s%sat-%d.data', storage_path('upload'), DIRECTORY_SEPARATOR, intval($attachment->id));
return $path;
}
@@ -112,7 +111,7 @@ class AttachmentHelper implements AttachmentHelperInterface
$md5 = md5_file($file->getRealPath());
$name = $file->getClientOriginalName();
$class = get_class($model);
$count = Auth::user()->attachments()->where('md5', $md5)->where('attachable_id', $model->id)->where('attachable_type', $class)->count();
$count = auth()->user()->attachments()->where('md5', $md5)->where('attachable_id', $model->id)->where('attachable_type', $class)->count();
if ($count > 0) {
$msg = (string)trans('validation.file_already_attached', ['name' => $name]);
@@ -139,7 +138,7 @@ class AttachmentHelper implements AttachmentHelperInterface
}
$attachment = new Attachment; // create Attachment object.
$attachment->user()->associate(Auth::user());
$attachment->user()->associate(auth()->user());
$attachment->attachable()->associate($model);
$attachment->md5 = md5_file($file->getRealPath());
$attachment->filename = $file->getClientOriginalName();

View File

@@ -11,7 +11,6 @@ declare(strict_types = 1);
namespace FireflyIII\Helpers\Report;
use Auth;
use Carbon\Carbon;
use DB;
use FireflyIII\Helpers\Collection\Balance;
@@ -102,34 +101,34 @@ class BalanceReportHelper implements BalanceReportHelperInterface
private function allCoveredByBalancingActs(Collection $accounts, Carbon $start, Carbon $end): Collection
{
$ids = $accounts->pluck('id')->toArray();
$set = Auth::user()->tags()
->leftJoin('tag_transaction_journal', 'tag_transaction_journal.tag_id', '=', 'tags.id')
->leftJoin('transaction_journals', 'tag_transaction_journal.transaction_journal_id', '=', 'transaction_journals.id')
->leftJoin('transaction_types', 'transaction_journals.transaction_type_id', '=', 'transaction_types.id')
->leftJoin(
'transactions AS t_source', function (JoinClause $join) {
$join->on('transaction_journals.id', '=', 't_source.transaction_journal_id')->where('t_source.amount', '<', 0);
}
)
->leftJoin(
'transactions AS t_destination', function (JoinClause $join) {
$join->on('transaction_journals.id', '=', 't_destination.transaction_journal_id')->where('t_destination.amount', '>', 0);
}
)
->where('tags.tagMode', 'balancingAct')
->where('transaction_types.type', TransactionType::TRANSFER)
->where('transaction_journals.date', '>=', $start->format('Y-m-d'))
->where('transaction_journals.date', '<=', $end->format('Y-m-d'))
->whereNull('transaction_journals.deleted_at')
->whereIn('t_source.account_id', $ids)
->whereIn('t_destination.account_id', $ids)
->groupBy('t_destination.account_id')
->get(
[
't_destination.account_id',
DB::raw('SUM(`t_destination`.`amount`) as `sum`'),
]
);
$set = auth()->user()->tags()
->leftJoin('tag_transaction_journal', 'tag_transaction_journal.tag_id', '=', 'tags.id')
->leftJoin('transaction_journals', 'tag_transaction_journal.transaction_journal_id', '=', 'transaction_journals.id')
->leftJoin('transaction_types', 'transaction_journals.transaction_type_id', '=', 'transaction_types.id')
->leftJoin(
'transactions AS t_source', function (JoinClause $join) {
$join->on('transaction_journals.id', '=', 't_source.transaction_journal_id')->where('t_source.amount', '<', 0);
}
)
->leftJoin(
'transactions AS t_destination', function (JoinClause $join) {
$join->on('transaction_journals.id', '=', 't_destination.transaction_journal_id')->where('t_destination.amount', '>', 0);
}
)
->where('tags.tagMode', 'balancingAct')
->where('transaction_types.type', TransactionType::TRANSFER)
->where('transaction_journals.date', '>=', $start->format('Y-m-d'))
->where('transaction_journals.date', '<=', $end->format('Y-m-d'))
->whereNull('transaction_journals.deleted_at')
->whereIn('t_source.account_id', $ids)
->whereIn('t_destination.account_id', $ids)
->groupBy('t_destination.account_id')
->get(
[
't_destination.account_id',
DB::raw('SUM(`t_destination`.`amount`) as `sum`'),
]
);
return $set;
}

View File

@@ -11,7 +11,6 @@ declare(strict_types = 1);
namespace FireflyIII\Http\Controllers;
use Auth;
use Carbon\Carbon;
use ExpandedForm;
use FireflyIII\Crud\Account\AccountCrudInterface;
@@ -173,9 +172,9 @@ class AccountController extends Controller
$types = config('firefly.accountTypesByIdentifier.' . $what);
$accounts = $crud->getAccountsByType($types);
/** @var Carbon $start */
$start = clone session('start', Carbon::now()->startOfMonth());
$start = clone session('start', Carbon::now()->startOfMonth());
/** @var Carbon $end */
$end = clone session('end', Carbon::now()->endOfMonth());
$end = clone session('end', Carbon::now()->endOfMonth());
$start->subDay();
$ids = $accounts->pluck('id')->toArray();
@@ -207,16 +206,16 @@ class AccountController extends Controller
$subTitle = $account->name;
$range = Preferences::get('viewRange', '1M')->data;
/** @var Carbon $start */
$start = session('start', Navigation::startOfPeriod(new Carbon, $range));
$start = session('start', Navigation::startOfPeriod(new Carbon, $range));
/** @var Carbon $end */
$end = session('end', Navigation::endOfPeriod(new Carbon, $range));
$page = intval(Input::get('page'));
$pageSize = Preferences::get('transactionPageSize', 50)->data;
$offset = ($page - 1) * $pageSize;
$set = $repository->journalsInPeriod(new Collection([$account]), [], $start, $end);
$count = $set->count();
$subSet = $set->splice($offset, $pageSize);
$journals = new LengthAwarePaginator($subSet, $count, $pageSize, $page);
$end = session('end', Navigation::endOfPeriod(new Carbon, $range));
$page = intval(Input::get('page'));
$pageSize = Preferences::get('transactionPageSize', 50)->data;
$offset = ($page - 1) * $pageSize;
$set = $repository->journalsInPeriod(new Collection([$account]), [], $start, $end);
$count = $set->count();
$subSet = $set->splice($offset, $pageSize);
$journals = new LengthAwarePaginator($subSet, $count, $pageSize, $page);
$journals->setPath('accounts/show/' . $account->id);
// grouped other months thing:
@@ -296,14 +295,14 @@ class AccountController extends Controller
public function store(AccountFormRequest $request, AccountCrudInterface $crud)
{
$accountData = [
'name' => $request->input('name'),
'name' => trim($request->input('name')),
'accountType' => $request->input('what'),
'virtualBalance' => round($request->input('virtualBalance'), 2),
'virtualBalanceCurrency' => intval($request->input('amount_currency_id_virtualBalance')),
'active' => true,
'user' => Auth::user()->id,
'iban' => $request->input('iban'),
'accountNumber' => $request->input('accountNumber'),
'user' => auth()->user()->id,
'iban' => trim($request->input('iban')),
'accountNumber' => trim($request->input('accountNumber')),
'accountRole' => $request->input('accountRole'),
'openingBalance' => round($request->input('openingBalance'), 2),
'openingBalanceDate' => new Carbon((string)$request->input('openingBalanceDate')),
@@ -347,7 +346,7 @@ class AccountController extends Controller
$accountData = [
'name' => $request->input('name'),
'active' => $request->input('active'),
'user' => Auth::user()->id,
'user' => auth()->user()->id,
'iban' => $request->input('iban'),
'accountNumber' => $request->input('accountNumber'),
'accountRole' => $request->input('accountRole'),

View File

@@ -12,7 +12,13 @@ declare(strict_types = 1);
namespace FireflyIII\Http\Controllers\Admin;
use Config;
use FireflyIII\Http\Controllers\Controller;
use FireflyIII\Http\Requests\ConfigurationRequest;
use FireflyIII\Support\Facades\FireflyConfig;
use Preferences;
use Redirect;
use Session;
use View;
/**
@@ -42,8 +48,30 @@ class ConfigurationController extends Controller
$subTitle = strval(trans('firefly.instance_configuration'));
$subTitleIcon = 'fa-wrench';
return view('admin.configuration.index', compact('subTitle', 'subTitleIcon'));
// all available configuration and their default value in case
// they don't exist yet.
$singleUserMode = FireflyConfig::get('single_user_mode', Config::get('firefly.configuration.single_user_mode'))->data;
return view('admin.configuration.index', compact('subTitle', 'subTitleIcon', 'singleUserMode'));
}
/**
* @param ConfigurationRequest $request
*/
public function store(ConfigurationRequest $request)
{
// get config values:
$singleUserMode = intval($request->get('single_user_mode')) === 1 ? true : false;
// store config values
FireflyConfig::set('single_user_mode', $singleUserMode);
// flash message
Session::flash('success', strval(trans('firefly.configuration_updated')));
Preferences::mark();
return Redirect::route('admin.configuration.index');
}
}

View File

@@ -58,7 +58,7 @@ class DomainController extends Controller
return redirect(route('admin.users.domains'));
}
$domain = $request->get('domain');
$domain = strtolower($request->get('domain'));
$blocked = FireflyConfig::get('blocked-domains', [])->data;
if (in_array($domain, $blocked)) {

View File

@@ -1,313 +0,0 @@
<?php
/**
* AuthController.php
* Copyright (C) 2016 thegrumpydictator@gmail.com
*
* This software may be modified and distributed under the terms
* of the MIT license. See the LICENSE file for details.
*/
declare(strict_types = 1);
namespace FireflyIII\Http\Controllers\Auth;
use Auth;
use FireflyIII\Events\UserRegistration;
use FireflyIII\Exceptions\FireflyException;
use FireflyIII\Http\Controllers\Controller;
use FireflyIII\Support\Facades\FireflyConfig;
use FireflyIII\User;
use Illuminate\Foundation\Auth\AuthenticatesAndRegistersUsers;
use Illuminate\Foundation\Auth\ThrottlesLogins;
use Illuminate\Http\Request;
use Illuminate\Mail\Message;
use Illuminate\Support\Facades\Lang;
use Log;
use Mail;
use Session;
use Swift_TransportException;
use Validator;
/**
* Class AuthController
*
* @package FireflyIII\Http\Controllers\Auth
*/
class AuthController extends Controller
{
use AuthenticatesAndRegistersUsers, ThrottlesLogins;
/**
* Where to redirect users after login / registration.
*
* @var string
*/
protected $redirectTo = '/home';
/**
* Create a new authentication controller instance.
*
*/
public function __construct()
{
$this->middleware('guest', ['except' => 'logout']);
parent::__construct();
}
/**
* Handle a login request to the application.
*
* @param \Illuminate\Http\Request $request
*
* @return \Illuminate\Http\Response
*/
public function login(Request $request)
{
$this->validate($request, [$this->loginUsername() => 'required', 'password' => 'required',]);
$throttles = $this->isUsingThrottlesLoginsTrait();
if ($throttles && $this->hasTooManyLoginAttempts($request)) {
return $this->sendLockoutResponse($request);
}
$credentials = $this->getCredentials($request);
$credentials['blocked'] = 0; // most not be blocked.
if (Auth::guard($this->getGuard())->attempt($credentials, $request->has('remember'))) {
return $this->handleUserWasAuthenticated($request, $throttles);
}
// check if user is blocked:
$errorMessage = '';
/** @var User $foundUser */
$foundUser = User::where('email', $credentials['email'])->where('blocked', 1)->first();
if (!is_null($foundUser)) {
// if it exists, show message:
$code = strlen(strval($foundUser->blocked_code)) > 0 ? $foundUser->blocked_code : 'general_blocked';
$errorMessage = strval(trans('firefly.' . $code . '_error', ['email' => $credentials['email']]));
$this->reportBlockedUserLoginAttempt($foundUser, $code, $request->ip());
}
if ($throttles) {
$this->incrementLoginAttempts($request);
}
return $this->sendFailedLoginResponse($request, $errorMessage);
}
/**
* Handle a registration request for the application.
*
* @param \Illuminate\Http\Request $request
*
* @return \Illuminate\Http\Response
* @throws FireflyException
* @throws \Illuminate\Foundation\Validation\ValidationException
*/
public function register(Request $request)
{
$validator = $this->validator($request->all());
if ($validator->fails()) {
$this->throwValidationException(
$request, $validator
);
}
$data = $request->all();
$data['password'] = bcrypt($data['password']);
// is user email domain blocked?
if ($this->isBlockedDomain($data['email'])) {
$validator->getMessageBag()->add('email', (string)trans('validation.invalid_domain'));
$this->reportBlockedDomainRegistrationAttempt($data['email'], $request->ip());
$this->throwValidationException(
$request, $validator
);
}
$user = $this->create($request->all());
// trigger user registration event:
event(new UserRegistration($user, $request->ip()));
Auth::login($user);
Session::flash('success', strval(trans('firefly.registered')));
Session::flash('gaEventCategory', 'user');
Session::flash('gaEventAction', 'new-registration');
return redirect($this->redirectPath());
}
/**
* Show the application registration form.
*
* @return \Illuminate\Http\Response
*/
public function showRegistrationForm()
{
$showDemoWarning = env('SHOW_DEMO_WARNING', false);
return view('auth.register', compact('showDemoWarning'));
}
/**
* Create a new user instance after a valid registration.
*
* @param array $data
*
* @return User
*/
protected function create(array $data)
{
return User::create(
[
'email' => $data['email'],
'password' => bcrypt($data['password']),
]
);
}
/**
* @return array
*/
protected function getBlockedDomains()
{
return FireflyConfig::get('blocked-domains', [])->data;
}
/**
* Get the failed login message.
*
* @param string $message
*
* @return string
*/
protected function getFailedLoginMessage(string $message)
{
if (strlen($message) > 0) {
return $message;
}
return Lang::has('auth.failed')
? Lang::get('auth.failed')
: 'These credentials do not match our records.';
}
/**
* @param string $email
*
* @return bool
*/
protected function isBlockedDomain(string $email)
{
$parts = explode('@', $email);
$blocked = $this->getBlockedDomains();
if (isset($parts[1]) && in_array($parts[1], $blocked)) {
return true;
}
return false;
}
/**
* Get the failed login response instance.
*
* @param \Illuminate\Http\Request $request
* @param string $message
*
* @return \Illuminate\Http\RedirectResponse
*/
protected function sendFailedLoginResponse(Request $request, string $message)
{
return redirect()->back()
->withInput($request->only($this->loginUsername(), 'remember'))
->withErrors(
[
$this->loginUsername() => $this->getFailedLoginMessage($message),
]
);
}
/**
* Get a validator for an incoming registration request.
*
* @param array $data
*
* @return \Illuminate\Contracts\Validation\Validator
*/
protected function validator(array $data)
{
return Validator::make(
$data, [
'email' => 'required|email|max:255|unique:users',
'password' => 'required|confirmed|min:6',
]
);
}
/**
* Send a message home about a blocked domain and the address attempted to register.
*
* @param string $registrationMail
* @param string $ipAddress
*/
private function reportBlockedDomainRegistrationAttempt(string $registrationMail, string $ipAddress)
{
try {
$email = env('SITE_OWNER', false);
$parts = explode('@', $registrationMail);
$domain = $parts[1];
$fields = [
'email_address' => $registrationMail,
'blocked_domain' => $domain,
'ip' => $ipAddress,
];
Mail::send(
['emails.blocked-registration-html', 'emails.blocked-registration'], $fields, function (Message $message) use ($email, $domain) {
$message->to($email, $email)->subject('Blocked a registration attempt with domain ' . $domain . '.');
}
);
} catch (Swift_TransportException $e) {
Log::error($e->getMessage());
}
}
/**
* Send a message home about the blocked attempt to login.
* Perhaps in a later stage, simply log these messages.
*
* @param User $user
* @param string $code
* @param string $ipAddress
*/
private function reportBlockedUserLoginAttempt(User $user, string $code, string $ipAddress)
{
try {
$email = env('SITE_OWNER', false);
$fields = [
'user_id' => $user->id,
'user_address' => $user->email,
'code' => $code,
'ip' => $ipAddress,
];
Mail::send(
['emails.blocked-login-html', 'emails.blocked-login'], $fields, function (Message $message) use ($email, $user) {
$message->to($email, $email)->subject('Blocked a login attempt from ' . trim($user->email) . '.');
}
);
} catch (Swift_TransportException $e) {
Log::error($e->getMessage());
}
}
}

View File

@@ -11,7 +11,6 @@ declare(strict_types = 1);
namespace FireflyIII\Http\Controllers\Auth;
use Auth;
use FireflyIII\Events\ResendConfirmation;
use FireflyIII\Events\UserIsConfirmed;
use FireflyIII\Exceptions\FireflyException;
@@ -55,10 +54,10 @@ class ConfirmationController extends Controller
if ($database === $code && ($now - $time <= $maxDiff)) {
// trigger user registration event:
event(new UserIsConfirmed(Auth::user(), $request->ip()));
event(new UserIsConfirmed(auth()->user(), $request->ip()));
Preferences::setForUser(Auth::user(), 'user_confirmed', true);
Preferences::setForUser(Auth::user(), 'user_confirmed_confirmed', time());
Preferences::setForUser(auth()->user(), 'user_confirmed', true);
Preferences::setForUser(auth()->user(), 'user_confirmed_confirmed', time());
Session::flash('success', strval(trans('firefly.account_is_confirmed')));
return redirect(route('home'));
@@ -79,7 +78,7 @@ class ConfirmationController extends Controller
$owner = env('SITE_OWNER', 'mail@example.com');
$view = 'auth.confirmation.no-resent';
if ($now - $time > $maxDiff) {
event(new ResendConfirmation(Auth::user(), $request->ip()));
event(new ResendConfirmation(auth()->user(), $request->ip()));
$view = 'auth.confirmation.resent';
}

View File

@@ -0,0 +1,34 @@
<?php
/**
* ForgotPasswordController.php
* Copyright (C) 2016 thegrumpydictator@gmail.com
*
* This software may be modified and distributed under the terms
* of the MIT license. See the LICENSE file for details.
*/
declare(strict_types = 1);
namespace FireflyIII\Http\Controllers\Auth;
use FireflyIII\Http\Controllers\Controller;
use Illuminate\Foundation\Auth\SendsPasswordResetEmails;
/**
* Class ForgotPasswordController
*
* @package FireflyIII\Http\Controllers\Auth
*/
class ForgotPasswordController extends Controller
{
use SendsPasswordResetEmails;
/**
* Create a new controller instance.
*
*/
public function __construct()
{
parent::__construct();
$this->middleware('guest');
}
}

View File

@@ -0,0 +1,195 @@
<?php
/**
* LoginController.php
* Copyright (C) 2016 thegrumpydictator@gmail.com
*
* This software may be modified and distributed under the terms
* of the MIT license. See the LICENSE file for details.
*/
declare(strict_types = 1);
namespace FireflyIII\Http\Controllers\Auth;
use Config;
use FireflyConfig;
use FireflyIII\Http\Controllers\Controller;
use FireflyIII\User;
use Illuminate\Foundation\Auth\AuthenticatesUsers;
use Illuminate\Http\Request;
use Illuminate\Mail\Message;
use Lang;
use Log;
use Mail;
use Swift_TransportException;
/**
* Class LoginController
*
* @package FireflyIII\Http\Controllers\Auth
*/
class LoginController extends Controller
{
/*
|--------------------------------------------------------------------------
| Login Controller
|--------------------------------------------------------------------------
|
| This controller handles authenticating users for the application and
| redirecting them to your home screen. The controller uses a trait
| to conveniently provide its functionality to your applications.
|
*/
use AuthenticatesUsers;
/**
* Where to redirect users after login / registration.
*
* @var string
*/
protected $redirectTo = '/home';
/**
* Create a new controller instance.
*
*/
public function __construct()
{
parent::__construct();
$this->middleware('guest', ['except' => 'logout']);
}
/**
* Handle a login request to the application.
*
* @param \Illuminate\Http\Request $request
*
* @return \Illuminate\Http\Response
*/
public function login(Request $request)
{
$this->validateLogin($request);
// If the class is using the ThrottlesLogins trait, we can automatically throttle
// the login attempts for this application. We'll key this by the username and
// the IP address of the client making these requests into this application.
if ($lockedOut = $this->hasTooManyLoginAttempts($request)) {
$this->fireLockoutEvent($request);
return $this->sendLockoutResponse($request);
}
$credentials = $this->credentials($request);
$credentials['blocked'] = 0; // most not be blocked.
if ($this->guard()->attempt($credentials, $request->has('remember'))) {
return $this->sendLoginResponse($request);
}
// check if user is blocked:
$errorMessage = '';
/** @var User $foundUser */
$foundUser = User::where('email', $credentials['email'])->where('blocked', 1)->first();
if (!is_null($foundUser)) {
// if it exists, show message:
$code = strlen(strval($foundUser->blocked_code)) > 0 ? $foundUser->blocked_code : 'general_blocked';
$errorMessage = strval(trans('firefly.' . $code . '_error', ['email' => $credentials['email']]));
$this->reportBlockedUserLoginAttempt($foundUser, $code, $request->ip());
}
// If the login attempt was unsuccessful we will increment the number of attempts
// to login and redirect the user back to the login form. Of course, when this
// user surpasses their maximum number of attempts they will get locked out.
if (!$lockedOut) {
$this->incrementLoginAttempts($request);
}
return $this->sendFailedLoginResponse($request, $errorMessage);
}
/**
* Show the application login form.
*
* @return \Illuminate\Http\Response
*/
public function showLoginForm(Request $request)
{
// is allowed to?
$singleUserMode = FireflyConfig::get('single_user_mode', Config::get('firefly.configuration.single_user_mode'))->data;
$userCount = User::count();
$allowRegistration = true;
if ($singleUserMode === true && $userCount > 0) {
$allowRegistration = false;
}
$email = $request->old('email');
$remember = $request->old('remember');
return view('auth.login', compact('allowRegistration', 'email', 'remember'));
}
/**
* Get the failed login message.
*
* @param string $message
*
* @return string
*/
protected function getFailedLoginMessage(string $message)
{
if (strlen($message) > 0) {
return $message;
}
return Lang::has('auth.failed') ? Lang::get('auth.failed') : 'These credentials do not match our records.';
}
/**
* Get the failed login response instance.
*
* @param \Illuminate\Http\Request $request
* @param string $message
*
* @return \Illuminate\Http\RedirectResponse
*/
protected function sendFailedLoginResponse(Request $request, string $message)
{
return redirect()->back()
->withInput($request->only($this->username(), 'remember'))
->withErrors(
[
$this->username() => $this->getFailedLoginMessage($message),
]
);
}
/**
* Send a message home about the blocked attempt to login.
* Perhaps in a later stage, simply log these messages.
*
* @param User $user
* @param string $code
* @param string $ipAddress
*/
private function reportBlockedUserLoginAttempt(User $user, string $code, string $ipAddress)
{
try {
$email = env('SITE_OWNER', false);
$fields = [
'user_id' => $user->id,
'user_address' => $user->email,
'code' => $code,
'ip' => $ipAddress,
];
Mail::send(
['emails.blocked-login-html', 'emails.blocked-login'], $fields, function (Message $message) use ($email, $user) {
$message->to($email, $email)->subject('Blocked a login attempt from ' . trim($user->email) . '.');
}
);
} catch (Swift_TransportException $e) {
Log::error($e->getMessage());
}
}
}

View File

@@ -23,6 +23,7 @@ use Illuminate\Support\Facades\Password;
* Class PasswordController
*
* @package FireflyIII\Http\Controllers\Auth
* @method getEmailSubject
*/
class PasswordController extends Controller
{

View File

@@ -0,0 +1,224 @@
<?php
/**
* RegisterController.php
* Copyright (C) 2016 thegrumpydictator@gmail.com
*
* This software may be modified and distributed under the terms
* of the MIT license. See the LICENSE file for details.
*/
declare(strict_types = 1);
namespace FireflyIII\Http\Controllers\Auth;
use Auth;
use Config;
use FireflyIII\Events\UserRegistration;
use FireflyIII\Http\Controllers\Controller;
use FireflyIII\Support\Facades\FireflyConfig;
use FireflyIII\User;
use Illuminate\Foundation\Auth\RegistersUsers;
use Illuminate\Http\Request;
use Illuminate\Mail\Message;
use Log;
use Mail;
use Session;
use Swift_TransportException;
use Validator;
/**
* Class RegisterController
*
* @package FireflyIII\Http\Controllers\Auth
*/
class RegisterController extends Controller
{
/*
|--------------------------------------------------------------------------
| Register Controller
|--------------------------------------------------------------------------
|
| This controller handles the registration of new users as well as their
| validation and creation. By default this controller uses a trait to
| provide this functionality without requiring any additional code.
|
*/
use RegistersUsers;
/**
* Where to redirect users after login / registration.
*
* @var string
*/
protected $redirectTo = '/home';
/**
* Create a new controller instance.
*/
public function __construct()
{
parent::__construct();
$this->middleware('guest');
}
/**
* @param Request $request
*
* @return \Illuminate\Contracts\View\Factory|\Illuminate\Http\RedirectResponse|\Illuminate\Routing\Redirector|\Illuminate\View\View
*/
public function register(Request $request)
{
// is allowed to?
$singleUserMode = FireflyConfig::get('single_user_mode', Config::get('firefly.configuration.single_user_mode'))->data;
$userCount = User::count();
if ($singleUserMode === true && $userCount > 0) {
$message = 'Registration is currently not available.';
return view('error', compact('message'));
}
$validator = $this->validator($request->all());
if ($validator->fails()) {
$this->throwValidationException($request, $validator);
}
$data = $request->all();
$data['password'] = bcrypt($data['password']);
// is user email domain blocked?
if ($this->isBlockedDomain($data['email'])) {
$validator->getMessageBag()->add('email', (string)trans('validation.invalid_domain'));
$this->reportBlockedDomainRegistrationAttempt($data['email'], $request->ip());
$this->throwValidationException($request, $validator);
}
$user = $this->create($request->all());
// trigger user registration event:
event(new UserRegistration($user, $request->ip()));
Auth::login($user);
Session::flash('success', strval(trans('firefly.registered')));
Session::flash('gaEventCategory', 'user');
Session::flash('gaEventAction', 'new-registration');
return redirect($this->redirectPath());
}
/**
* OLD
* Show the application registration form.
*
* @return \Illuminate\Http\Response
*/
public function showRegistrationForm(Request $request)
{
$showDemoWarning = config('firefly.show-demo-warning', false);
// is allowed to?
$singleUserMode = FireflyConfig::get('single_user_mode', Config::get('firefly.configuration.single_user_mode'))->data;
$userCount = User::count();
if ($singleUserMode === true && $userCount > 0) {
$message = 'Registration is currently not available.';
return view('error', compact('message'));
}
$email = $request->old('email');
return view('auth.register', compact('showDemoWarning', 'email'));
}
/**
* Create a new user instance after a valid registration.
*
* @param array $data
*
* @return User
*/
protected function create(array $data)
{
return User::create(
[
'email' => $data['email'],
'password' => bcrypt($data['password']),
]
);
}
/**
* Get a validator for an incoming registration request.
*
* @param array $data
*
* @return \Illuminate\Contracts\Validation\Validator
*/
protected function validator(array $data)
{
return Validator::make(
$data, [
'email' => 'required|email|max:255|unique:users',
'password' => 'required|min:6|confirmed',
]
);
}
/**
* @return array
*/
private function getBlockedDomains()
{
return FireflyConfig::get('blocked-domains', [])->data;
}
/**
* @param string $email
*
* @return bool
*/
private function isBlockedDomain(string $email)
{
$parts = explode('@', $email);
$blocked = $this->getBlockedDomains();
if (isset($parts[1]) && in_array($parts[1], $blocked)) {
return true;
}
return false;
}
/**
* Send a message home about a blocked domain and the address attempted to register.
*
* @param string $registrationMail
* @param string $ipAddress
*/
private function reportBlockedDomainRegistrationAttempt(string $registrationMail, string $ipAddress)
{
try {
$email = env('SITE_OWNER', false);
$parts = explode('@', $registrationMail);
$domain = $parts[1];
$fields = [
'email_address' => $registrationMail,
'blocked_domain' => $domain,
'ip' => $ipAddress,
];
Mail::send(
['emails.blocked-registration-html', 'emails.blocked-registration'], $fields, function (Message $message) use ($email, $domain) {
$message->to($email, $email)->subject('Blocked a registration attempt with domain ' . $domain . '.');
}
);
} catch (Swift_TransportException $e) {
Log::error($e->getMessage());
}
}
}

View File

@@ -0,0 +1,44 @@
<?php
/**
* ResetPasswordController.php
* Copyright (C) 2016 thegrumpydictator@gmail.com
*
* This software may be modified and distributed under the terms
* of the MIT license. See the LICENSE file for details.
*/
declare(strict_types = 1);
namespace FireflyIII\Http\Controllers\Auth;
use FireflyIII\Http\Controllers\Controller;
use Illuminate\Foundation\Auth\ResetsPasswords;
/**
* Class ResetPasswordController
*
* @package FireflyIII\Http\Controllers\Auth
*/
class ResetPasswordController extends Controller
{
/*
|--------------------------------------------------------------------------
| Password Reset Controller
|--------------------------------------------------------------------------
|
| This controller is responsible for handling password reset requests
| and uses a simple trait to include this behavior. You're free to
| explore this trait and override any methods you wish to tweak.
|
*/
use ResetsPasswords;
/**
* Create a new controller instance.
*
*/
public function __construct()
{
$this->middleware('guest');
}
}

View File

@@ -11,7 +11,6 @@ declare(strict_types = 1);
namespace FireflyIII\Http\Controllers\Auth;
use Auth;
use Carbon\Carbon;
use FireflyIII\Exceptions\FireflyException;
use FireflyIII\Http\Controllers\Controller;
@@ -34,7 +33,7 @@ class TwoFactorController extends Controller
*/
public function index()
{
$user = Auth::user();
$user = auth()->user();
// to make sure the validator in the next step gets the secret, we push it in session
$secret = Preferences::get('twoFactorAuthSecret', '')->data;
@@ -54,7 +53,7 @@ class TwoFactorController extends Controller
*/
public function lostTwoFactor()
{
$user = Auth::user();
$user = auth()->user();
$siteOwner = env('SITE_OWNER', '');
$title = strval(trans('firefly.two_factor_forgot_title'));

View File

@@ -130,7 +130,7 @@ class BillController extends Controller
/** @var Carbon $start */
$start = session('start');
/** @var Carbon $end */
$end = session('end');
$end = session('end');
$bills = $repository->getBills();
$bills->each(

View File

@@ -12,7 +12,6 @@ declare(strict_types = 1);
namespace FireflyIII\Http\Controllers;
use Amount;
use Auth;
use Carbon\Carbon;
use Config;
use FireflyIII\Crud\Account\AccountCrudInterface;
@@ -221,12 +220,11 @@ class BudgetController extends Controller
}
$budgetMaximum = Preferences::get('budgetMaximum', 1000)->data;
$defaultCurrency = Amount::getDefaultCurrency();
return view(
'budgets.index', compact(
'budgetMaximum', 'periodStart', 'periodEnd',
'periodStart', 'periodEnd',
'period', 'range', 'budgetIncomeTotal',
'defaultCurrency', 'inactive', 'budgets',
'spent', 'budgeted'
@@ -360,7 +358,7 @@ class BudgetController extends Controller
{
$budgetData = [
'name' => $request->input('name'),
'user' => Auth::user()->id,
'user' => auth()->user()->id,
];
$budget = $repository->store($budgetData);

View File

@@ -11,7 +11,6 @@ declare(strict_types = 1);
namespace FireflyIII\Http\Controllers;
use Auth;
use Carbon\Carbon;
use FireflyIII\Crud\Account\AccountCrudInterface;
use FireflyIII\Http\Requests\CategoryFormRequest;
@@ -166,9 +165,9 @@ class CategoryController extends Controller
*/
public function show(CRI $repository, AccountCrudInterface $crud, Category $category)
{
$range = Preferences::get('viewRange', '1M')->data;
$range = Preferences::get('viewRange', '1M')->data;
/** @var Carbon $start */
$start = session('start', Navigation::startOfPeriod(new Carbon, $range));
$start = session('start', Navigation::startOfPeriod(new Carbon, $range));
/** @var Carbon $end */
$end = session('end', Navigation::endOfPeriod(new Carbon, $range));
$hideCategory = true; // used in list.
@@ -184,7 +183,7 @@ class CategoryController extends Controller
$journals->setPath('categories/show/' . $category->id);
// oldest transaction in category:
$start = $repository->firstUseDate($category, new Collection);
$start = $repository->firstUseDate($category);
if ($start->year == 1900) {
$start = new Carbon;
}
@@ -264,8 +263,8 @@ class CategoryController extends Controller
public function store(CategoryFormRequest $request, CRI $repository)
{
$categoryData = [
'name' => $request->input('name'),
'user' => Auth::user()->id,
'name' => trim($request->input('name')),
'user' => auth()->user()->id,
];
$category = $repository->store($categoryData);

View File

@@ -20,6 +20,7 @@ use FireflyIII\Models\TransactionJournal;
use FireflyIII\Repositories\Budget\BudgetRepositoryInterface;
use FireflyIII\Support\CacheProperties;
use Illuminate\Support\Collection;
use Log;
use Navigation;
use Preferences;
use Response;
@@ -35,19 +36,14 @@ class BudgetController extends Controller
/** @var BudgetChartGeneratorInterface */
protected $generator;
/** @var BudgetRepositoryInterface */
protected $repository;
/**
*
* BudgetController constructor.
*/
public function __construct()
{
parent::__construct();
// create chart generator:
$this->generator = app(BudgetChartGeneratorInterface::class);
$this->repository = app(BudgetRepositoryInterface::class);
}
/**
@@ -143,8 +139,9 @@ class BudgetController extends Controller
*
* @return \Symfony\Component\HttpFoundation\Response
*/
public function frontpage()
public function frontpage(BudgetRepositoryInterface $repository)
{
Log::debug('Hello');
$start = session('start', Carbon::now()->startOfMonth());
$end = session('end', Carbon::now()->endOfMonth());
// chart properties for cache:
@@ -156,8 +153,8 @@ class BudgetController extends Controller
if ($cache->has()) {
return Response::json($cache->get());
}
$budgets = $this->repository->getActiveBudgets();
$repetitions = $this->repository->getAllBudgetLimitRepetitions($start, $end);
$budgets = $repository->getActiveBudgets();
$repetitions = $repository->getAllBudgetLimitRepetitions($start, $end);
$allEntries = new Collection;
/** @var Budget $budget */
@@ -166,15 +163,15 @@ class BudgetController extends Controller
$reps = $this->filterRepetitions($repetitions, $budget, $start, $end);
if ($reps->count() === 0) {
$collection = $this->spentInPeriodSingle($budget, $start, $end);
$collection = $this->spentInPeriodSingle($repository, $budget, $start, $end);
$allEntries = $allEntries->merge($collection);
continue;
}
$collection = $this->spentInPeriodMulti($budget, $reps);
$collection = $this->spentInPeriodMulti($repository, $budget, $reps);
$allEntries = $allEntries->merge($collection);
}
$entry = $this->spentInPeriodWithout($start, $end);
$entry = $this->spentInPeriodWithout($repository, $start, $end);
$allEntries->push($entry);
$data = $this->generator->frontpage($allEntries);
$cache->store($data);
@@ -216,6 +213,7 @@ class BudgetController extends Controller
if (in_array(strval($repetition->budget_id), $budgetIds)) {
return true;
}
return false;
}
);
@@ -292,6 +290,7 @@ class BudgetController extends Controller
if ($repetition->budget_id === $budget->id && $repetition->startdate == $currentStart) {
return true;
}
return false;
}
);
@@ -329,25 +328,27 @@ class BudgetController extends Controller
if ($repetition->startdate < $end && $repetition->enddate > $start && $repetition->budget_id === $budget->id) {
return true;
}
return false;
}
);
}
/**
* @param Budget $budget
* @param Collection $repetitions
* @param BudgetRepositoryInterface $repository
* @param Budget $budget
* @param Collection $repetitions
*
* @return Collection
*/
private function spentInPeriodMulti(Budget $budget, Collection $repetitions): Collection
private function spentInPeriodMulti(BudgetRepositoryInterface $repository, Budget $budget, Collection $repetitions): Collection
{
$format = strval(trans('config.month_and_day'));
$collection = new Collection;
$name = $budget->name;
/** @var LimitRepetition $repetition */
foreach ($repetitions as $repetition) {
$expenses = $this->repository->spentInPeriod(new Collection([$budget]), new Collection, $repetition->startdate, $repetition->enddate);
$expenses = $repository->spentInPeriod(new Collection([$budget]), new Collection, $repetition->startdate, $repetition->enddate);
if ($repetitions->count() > 1) {
$name = $budget->name . ' ' . trans(
@@ -367,18 +368,19 @@ class BudgetController extends Controller
}
/**
* @param Budget $budget
* @param Carbon $start
* @param Carbon $end
* @param BudgetRepositoryInterface $repository
* @param Budget $budget
* @param Carbon $start
* @param Carbon $end
*
* @return Collection
*/
private function spentInPeriodSingle(Budget $budget, Carbon $start, Carbon $end): Collection
private function spentInPeriodSingle(BudgetRepositoryInterface $repository, Budget $budget, Carbon $start, Carbon $end): Collection
{
$collection = new Collection;
$amount = '0';
$left = '0';
$spent = $this->repository->spentInPeriod(new Collection([$budget]), new Collection, $start, $end);
$spent = $repository->spentInPeriod(new Collection([$budget]), new Collection, $start, $end);
$overspent = '0';
$array = [$budget->name, $left, $spent, $overspent, $amount, $spent];
$collection->push($array);
@@ -387,14 +389,15 @@ class BudgetController extends Controller
}
/**
* @param Carbon $start
* @param Carbon $end
* @param BudgetRepositoryInterface $repository
* @param Carbon $start
* @param Carbon $end
*
* @return array
*/
private function spentInPeriodWithout(Carbon $start, Carbon $end):array
private function spentInPeriodWithout(BudgetRepositoryInterface $repository, Carbon $start, Carbon $end):array
{
$list = $this->repository->journalsInPeriodWithoutBudget(new Collection, $start, $end);
$list = $repository->journalsInPeriodWithoutBudget(new Collection, $start, $end);
$sum = '0';
/** @var TransactionJournal $entry */
foreach ($list as $entry) {

View File

@@ -58,7 +58,7 @@ class CategoryController extends Controller
*/
public function all(CRI $repository, AccountCrudInterface $crud, Category $category)
{
$start = $repository->firstUseDate($category, new Collection);
$start = $repository->firstUseDate($category);
$range = Preferences::get('viewRange', '1M')->data;
$start = Navigation::startOfPeriod($start, $range);
$categoryCollection = new Collection([$category]);
@@ -108,13 +108,12 @@ class CategoryController extends Controller
}
/**
* Show this month's category overview.
* @param CRI $repository
* @param AccountCrudInterface $crud
*
* @param CRI $repository
*
* @return \Symfony\Component\HttpFoundation\Response
* @return \Illuminate\Http\JsonResponse
*/
public function frontpage(CRI $repository)
public function frontpage(CRI $repository, AccountCrudInterface $crud)
{
$start = session('start', Carbon::now()->startOfMonth());
$end = session('end', Carbon::now()->endOfMonth());
@@ -128,10 +127,11 @@ class CategoryController extends Controller
return Response::json($cache->get());
}
$categories = $repository->getCategories();
$accounts = $crud->getAccountsByType([AccountType::ASSET, AccountType::DEFAULT]);
$set = new Collection;
/** @var Category $category */
foreach ($categories as $category) {
$spent = $repository->spentInPeriod(new Collection([$category]), new Collection, $start, $end);
$spent = $repository->spentInPeriod(new Collection([$category]), $accounts, $start, $end);
if (bccomp($spent, '0') === -1) {
$category->spent = $spent;
$set->push($category);

38
app/Http/Controllers/Controller.php Normal file → Executable file
View File

@@ -11,15 +11,11 @@ declare(strict_types = 1);
namespace FireflyIII\Http\Controllers;
use App;
use Auth;
use Carbon\Carbon;
use Illuminate\Foundation\Auth\Access\AuthorizesRequests;
use Illuminate\Foundation\Bus\DispatchesJobs;
use Illuminate\Foundation\Validation\ValidatesRequests;
use Illuminate\Routing\Controller as BaseController;
use NumberFormatter;
use Preferences;
use View;
/**
@@ -48,36 +44,11 @@ class Controller extends BaseController
View::share('hideBills', false);
View::share('hideTags', false);
if (Auth::check()) {
$pref = Preferences::get('language', env('DEFAULT_LANGUAGE', 'en_US'));
$lang = $pref->data;
// save some formats:
$this->monthFormat = (string)trans('config.month');
$this->monthAndDayFormat = (string)trans('config.month_and_day');
$this->dateTimeFormat = (string)trans('config.date_time');
App::setLocale($lang);
Carbon::setLocale(substr($lang, 0, 2));
$locale = explode(',', trans('config.locale'));
$locale = array_map('trim', $locale);
setlocale(LC_TIME, $locale);
setlocale(LC_MONETARY, $locale);
// save some formats:
$this->monthFormat = (string)trans('config.month');
$this->monthAndDayFormat = (string)trans('config.month_and_day');
$this->dateTimeFormat = (string)trans('config.date_time');
// change localeconv to a new array:
$numberFormatter = numfmt_create($lang, NumberFormatter::CURRENCY);
$localeconv = [
'mon_decimal_point' => $numberFormatter->getSymbol($numberFormatter->getAttribute(NumberFormatter::DECIMAL_SEPARATOR_SYMBOL)),
'mon_thousands_sep' => $numberFormatter->getSymbol($numberFormatter->getAttribute(NumberFormatter::MONETARY_GROUPING_SEPARATOR_SYMBOL)),
'frac_digits' => $numberFormatter->getAttribute(NumberFormatter::MAX_FRACTION_DIGITS),
];
View::share('monthFormat', $this->monthFormat);
View::share('monthAndDayFormat', $this->monthAndDayFormat);
View::share('dateTimeFormat', $this->dateTimeFormat);
View::share('language', $lang);
View::share('localeconv', $localeconv);
}
}
/**
@@ -107,5 +78,4 @@ class Controller extends BaseController
return $sum;
}
}

View File

@@ -11,7 +11,6 @@ declare(strict_types = 1);
namespace FireflyIII\Http\Controllers;
use Auth;
use Cache;
use FireflyIII\Http\Requests\CurrencyFormRequest;
use FireflyIII\Models\TransactionCurrency;
@@ -81,20 +80,19 @@ class CurrencyController extends Controller
}
/**
* @param CurrencyRepositoryInterface $repository
* @param TransactionCurrency $currency
* @param TransactionCurrency $currency
*
* @return \Illuminate\Http\RedirectResponse|View
*/
public function delete(CurrencyRepositoryInterface $repository, TransactionCurrency $currency)
public function delete(TransactionCurrency $currency)
{
if ($repository->countJournals($currency) > 0) {
if (!$this->canDeleteCurrency($currency)) {
Session::flash('error', trans('firefly.cannot_delete_currency', ['name' => $currency->name]));
return redirect(route('currency.index'));
}
// put previous url in session
Session::put('currency.delete.url', URL::previous());
Session::flash('gaEventCategory', 'currency');
@@ -106,22 +104,21 @@ class CurrencyController extends Controller
}
/**
* @param CurrencyRepositoryInterface $repository
* @param TransactionCurrency $currency
* @param TransactionCurrency $currency
*
* @return \Illuminate\Http\RedirectResponse
* @throws \Exception
*/
public function destroy(CurrencyRepositoryInterface $repository, TransactionCurrency $currency)
public function destroy(TransactionCurrency $currency)
{
if ($repository->countJournals($currency) > 0) {
if (!$this->canDeleteCurrency($currency)) {
Session::flash('error', trans('firefly.cannot_delete_currency', ['name' => $currency->name]));
return redirect(route('currency.index'));
}
Session::flash('success', trans('firefly.deleted_currency', ['name' => $currency->name]));
if (Auth::user()->hasRole('owner')) {
if (auth()->user()->hasRole('owner')) {
$currency->delete();
}
@@ -136,7 +133,7 @@ class CurrencyController extends Controller
public function edit(TransactionCurrency $currency)
{
$subTitleIcon = 'fa-pencil';
$subTitle = trans('firefly.edit_currency', ['name' => $currency->name]);
$subTitle = trans('breadcrumbs.edit_currency', ['name' => $currency->name]);
$currency->symbol = htmlentities($currency->symbol);
// put previous url in session if not redirect from store (not "return_to_edit").
@@ -159,10 +156,10 @@ class CurrencyController extends Controller
public function index(CurrencyRepositoryInterface $repository)
{
$currencies = $repository->get();
$defaultCurrency = $repository->getCurrencyByPreference(Preferences::get('currencyPreference', env('DEFAULT_CURRENCY', 'EUR')));
$defaultCurrency = $repository->getCurrencyByPreference(Preferences::get('currencyPreference', config('firefly.default_currency', 'EUR')));
if (!Auth::user()->hasRole('owner')) {
if (!auth()->user()->hasRole('owner')) {
Session::flash('warning', trans('firefly.ask_site_owner', ['owner' => env('SITE_OWNER')]));
}
@@ -179,8 +176,8 @@ class CurrencyController extends Controller
*/
public function store(CurrencyFormRequest $request, CurrencyRepositoryInterface $repository)
{
if (!Auth::user()->hasRole('owner')) {
Log::error('User ' . Auth::user()->id . ' is not admin, but tried to store a currency.');
if (!auth()->user()->hasRole('owner')) {
Log::error('User ' . auth()->user()->id . ' is not admin, but tried to store a currency.');
return redirect(session('currency.create.url'));
}
@@ -211,7 +208,7 @@ class CurrencyController extends Controller
public function update(CurrencyFormRequest $request, CurrencyRepositoryInterface $repository, TransactionCurrency $currency)
{
$data = $request->getCurrencyData();
if (Auth::user()->hasRole('owner')) {
if (auth()->user()->hasRole('owner')) {
$currency = $repository->update($currency, $data);
}
Session::flash('success', trans('firefly.updated_currency', ['name' => $currency->name]));
@@ -229,4 +226,39 @@ class CurrencyController extends Controller
}
/**
* @param TransactionCurrency $currency
*
* @return bool
*/
private function canDeleteCurrency(TransactionCurrency $currency): bool
{
$repository = app(CurrencyRepositoryInterface::class);
// has transactions still
if ($repository->countJournals($currency) > 0) {
return false;
}
// is the only currency left
if ($repository->get()->count() === 1) {
return false;
}
// is the default currency for the user or the system
$defaultCode = Preferences::get('currencyPreference', config('firefly.default_currency', 'EUR'))->data;
if ($currency->code === $defaultCode) {
return false;
}
// is the default currency for the system
$defaultSystemCode = config('firefly.default_currency', 'EUR');
if ($currency->code === $defaultSystemCode) {
return false;
}
// can be deleted
return true;
}
}

View File

@@ -39,7 +39,7 @@ class HelpController extends Controller
*/
public function show(HelpInterface $help, string $route)
{
$language = Preferences::get('language', env('DEFAULT_LANGUAGE', 'en_US'))->data;
$language = Preferences::get('language', config('firefly.default_language', 'en_US'))->data;
$content = [
'text' => '<p>' . strval(trans('firefly.route_has_no_help')) . '</p>',
'title' => 'Help',

View File

@@ -222,4 +222,5 @@ class HomeController extends Controller
return false;
}
}

View File

@@ -6,6 +6,7 @@
* This software may be modified and distributed under the terms
* of the MIT license. See the LICENSE file for details.
*/
declare(strict_types = 1);
namespace FireflyIII\Http\Controllers;
@@ -306,7 +307,7 @@ class ImportController extends Controller
public function start(ImportJob $job)
{
set_time_limit(0);
if ($job->status == "settings_complete") {
if ($job->status == 'settings_complete') {
ImportProcedure::runImport($job);
}
}
@@ -415,16 +416,25 @@ class ImportController extends Controller
* @param ImportJob $job
*
* @return SetupInterface
* @throws FireflyException
*/
private function makeImporter(ImportJob $job): SetupInterface
{
// create proper importer (depends on job)
$type = $job->file_type;
/** @var SetupInterface $importer */
$importer = app('FireflyIII\Import\Setup\\' . ucfirst($type) . 'Setup');
$importer->setJob($job);
$type = strtolower($job->file_type);
return $importer;
// validate type:
$validTypes = array_keys(config('firefly.import_formats'));
if (in_array($type, $validTypes)) {
/** @var SetupInterface $importer */
$importer = app('FireflyIII\Import\Setup\\' . ucfirst($type) . 'Setup');
$importer->setJob($job);
return $importer;
}
throw new FireflyException(sprintf('"%s" is not a valid file type', $type));
}
@@ -450,8 +460,7 @@ class ImportController extends Controller
Log::debug('Will redirect to complete()');
return redirect(route('import.complete', [$job->key]));
case
'import_complete':
case 'import_complete':
Log::debug('Will redirect to finished()');
return redirect(route('import.finished', [$job->key]));

View File

@@ -10,7 +10,6 @@
declare(strict_types = 1);
namespace FireflyIII\Http\Controllers;
use Auth;
use Carbon\Carbon;
use FireflyIII\Crud\Account\AccountCrudInterface;
use FireflyIII\Http\Requests\NewUserFormRequest;
@@ -43,7 +42,7 @@ class NewUserController extends Controller
public function index(ARI $repository)
{
View::share('title', 'Welcome to Firefly!');
View::share('title', trans('firefly.welcome'));
View::share('mainTitleIcon', 'fa-fire');
@@ -107,7 +106,7 @@ class NewUserController extends Controller
'accountType' => 'asset',
'virtualBalance' => 0,
'active' => true,
'user' => Auth::user()->id,
'user' => auth()->user()->id,
'accountRole' => 'defaultAsset',
'openingBalance' => round($request->input('bank_balance'), 2),
'openingBalanceDate' => new Carbon,
@@ -133,7 +132,7 @@ class NewUserController extends Controller
'accountType' => 'asset',
'virtualBalance' => 0,
'active' => true,
'user' => Auth::user()->id,
'user' => auth()->user()->id,
'accountRole' => 'savingAsset',
'openingBalance' => round($request->input('savings_balance'), 2),
'openingBalanceDate' => new Carbon,
@@ -158,7 +157,7 @@ class NewUserController extends Controller
'accountType' => 'asset',
'virtualBalance' => round($request->get('credit_card_limit'), 2),
'active' => true,
'user' => Auth::user()->id,
'user' => auth()->user()->id,
'accountRole' => 'ccAsset',
'openingBalance' => null,
'openingBalanceDate' => null,

View File

@@ -253,7 +253,7 @@ class PiggyBankController extends Controller
*/
public function postAdd(PiggyBankRepositoryInterface $repository, ARI $accounts, PiggyBank $piggyBank)
{
$amount = strval(round(Input::get('amount'), 2));
$amount = strval(round(Input::get('amount'), 2));
/** @var Carbon $date */
$date = session('end', Carbon::now()->endOfMonth());
$leftOnAccount = $accounts->leftOnAccount($piggyBank->account, $date);

View File

@@ -13,6 +13,7 @@ namespace FireflyIII\Http\Controllers\Popup;
use Carbon\Carbon;
use FireflyIII\Crud\Account\AccountCrudInterface;
use FireflyIII\Exceptions\FireflyException;
use FireflyIII\Helpers\Collection\BalanceLine;
use FireflyIII\Http\Controllers\Controller;
@@ -112,6 +113,7 @@ class ReportController extends Controller
if ($tags === 0) {
return true;
}
return false;
}
);
@@ -183,7 +185,7 @@ class ReportController extends Controller
{
/** @var AccountRepositoryInterface $repository */
$repository = app(AccountRepositoryInterface::class);
$crud = app('FireflyIII\Crud\Account\AccountCrudInterface');
$crud = app(AccountCrudInterface::class);
$account = $crud->find(intval($attributes['accountId']));
$types = [TransactionType::WITHDRAWAL, TransactionType::TRANSFER];
$journals = $repository->journalsInPeriod($attributes['accounts'], $types, $attributes['startDate'], $attributes['endDate']);
@@ -191,9 +193,11 @@ class ReportController extends Controller
// filter for transfers and withdrawals TO the given $account
$journals = $journals->filter(
function (TransactionJournal $journal) use ($account) {
if ($journal->destination_account_id === $account->id) {
$destinations = TransactionJournal::destinationAccountList($journal)->pluck('id')->toArray();
if (in_array($account->id, $destinations)) {
return true;
}
return false;
}
);
@@ -221,14 +225,18 @@ class ReportController extends Controller
$journals = $repository->journalsInPeriod(new Collection([$account]), $types, $attributes['startDate'], $attributes['endDate']);
$destinations = $attributes['accounts']->pluck('id')->toArray();
// filter for transfers and withdrawals FROM the given $account
$journals = $journals->filter(
function (TransactionJournal $journal) use ($account, $destinations) {
$currentSources = TransactionJournal::sourceAccountList($journal)->pluck('id')->toArray();
$currentDest = TransactionJournal::destinationAccountList($journal)->pluck('id')->toArray();
if (
$journal->source_account_id === $account->id
&& in_array($journal->destination_account_id, $destinations)
!empty(array_intersect([$account->id], $currentSources))
&& !empty(array_intersect($destinations, $currentDest))
) {
return true;
}
return false;
}
);

View File

@@ -10,11 +10,10 @@
declare(strict_types = 1);
namespace FireflyIII\Http\Controllers;
use Auth;
use FireflyIII\Crud\Account\AccountCrudInterface;
use FireflyIII\Http\Requests\TokenFormRequest;
use FireflyIII\Models\AccountType;
use Input;
use Illuminate\Http\Request;
use PragmaRX\Google2FA\Contracts\Google2FA;
use Preferences;
use Session;
@@ -47,7 +46,7 @@ class PreferencesController extends Controller
{
$domain = $this->getDomain();
/** @noinspection PhpMethodParametersCountMismatchInspection */
$secret = $google2fa->generateSecretKey(16, Auth::user()->id);
$secret = $google2fa->generateSecretKey(16, auth()->user()->id);
Session::flash('two-factor-secret', $secret);
$image = $google2fa->getQRCodeInline('Firefly III at ' . $domain, null, $secret, 150);
@@ -79,13 +78,12 @@ class PreferencesController extends Controller
$viewRangePref = Preferences::get('viewRange', '1M');
$viewRange = $viewRangePref->data;
$frontPageAccounts = Preferences::get('frontPageAccounts', []);
$budgetMax = Preferences::get('budgetMaximum', 1000);
$language = Preferences::get('language', env('DEFAULT_LANGUAGE', 'en_US'))->data;
$budgetMaximum = $budgetMax->data;
$language = Preferences::get('language', config('firefly.default_language', 'en_US'))->data;
$transactionPageSize = Preferences::get('transactionPageSize', 50)->data;
$customFiscalYear = Preferences::get('customFiscalYear', 0)->data;
$fiscalYearStartStr = Preferences::get('fiscalYearStart', '01-01')->data;
$fiscalYearStart = date('Y') . '-' . $fiscalYearStartStr;
$tjOptionalFields = Preferences::get('transaction_journal_optional_fields', [])->data;
$is2faEnabled = Preferences::get('twoFactorAuthEnabled', 0)->data; // twoFactorAuthEnabled
$has2faSecret = !is_null(Preferences::get('twoFactorAuthSecret')); // hasTwoFactorAuthSecret
$showIncomplete = env('SHOW_INCOMPLETE_TRANSLATIONS', false) === true;
@@ -93,7 +91,7 @@ class PreferencesController extends Controller
return view(
'preferences.index',
compact(
'budgetMaximum', 'language', 'accounts', 'frontPageAccounts',
'language', 'accounts', 'frontPageAccounts', 'tjOptionalFields',
'viewRange', 'customFiscalYear', 'transactionPageSize', 'fiscalYearStart', 'is2faEnabled',
'has2faSecret', 'showIncomplete'
)
@@ -117,38 +115,36 @@ class PreferencesController extends Controller
}
/**
* @return \Illuminate\Http\RedirectResponse
* @param Request $request
*
* @return \Illuminate\Http\RedirectResponse|\Illuminate\Routing\Redirector
*/
public function postIndex()
public function postIndex(Request $request)
{
// front page accounts
$frontPageAccounts = [];
if (is_array(Input::get('frontPageAccounts'))) {
foreach (Input::get('frontPageAccounts') as $id) {
if (is_array($request->get('frontPageAccounts'))) {
foreach ($request->get('frontPageAccounts') as $id) {
$frontPageAccounts[] = intval($id);
}
Preferences::set('frontPageAccounts', $frontPageAccounts);
}
// view range:
Preferences::set('viewRange', Input::get('viewRange'));
Preferences::set('viewRange', $request->get('viewRange'));
// forget session values:
Session::forget('start');
Session::forget('end');
Session::forget('range');
// budget maximum:
$budgetMaximum = intval(Input::get('budgetMaximum'));
Preferences::set('budgetMaximum', $budgetMaximum);
// custom fiscal year
$customFiscalYear = intval(Input::get('customFiscalYear')) === 1;
$fiscalYearStart = date('m-d', strtotime(Input::get('fiscalYearStart')));
$customFiscalYear = intval($request->get('customFiscalYear')) === 1;
$fiscalYearStart = date('m-d', strtotime($request->get('fiscalYearStart')));
Preferences::set('customFiscalYear', $customFiscalYear);
Preferences::set('fiscalYearStart', $fiscalYearStart);
// save page size:
$transactionPageSize = intval(Input::get('transactionPageSize'));
$transactionPageSize = intval($request->get('transactionPageSize'));
if ($transactionPageSize > 0 && $transactionPageSize < 1337) {
Preferences::set('transactionPageSize', $transactionPageSize);
} else {
@@ -156,7 +152,7 @@ class PreferencesController extends Controller
}
// two factor auth
$twoFactorAuthEnabled = intval(Input::get('twoFactorAuthEnabled'));
$twoFactorAuthEnabled = intval($request->get('twoFactorAuthEnabled'));
$hasTwoFactorAuthSecret = !is_null(Preferences::get('twoFactorAuthSecret'));
// If we already have a secret, just set the two factor auth enabled to 1, and let the user continue with the existing secret.
@@ -165,11 +161,26 @@ class PreferencesController extends Controller
}
// language:
$lang = Input::get('language');
$lang = $request->get('language');
if (in_array($lang, array_keys(config('firefly.languages')))) {
Preferences::set('language', $lang);
}
// optional fields for transactions:
$setOptions = $request->get('tj');
$optionalTj = [
'interest_date' => isset($setOptions['interest_date']),
'book_date' => isset($setOptions['book_date']),
'process_date' => isset($setOptions['process_date']),
'due_date' => isset($setOptions['due_date']),
'payment_date' => isset($setOptions['payment_date']),
'invoice_date' => isset($setOptions['invoice_date']),
'internal_reference' => isset($setOptions['internal_reference']),
'notes' => isset($setOptions['notes']),
'attachments' => isset($setOptions['attachments']),
];
Preferences::set('transaction_journal_optional_fields', $optionalTj);
Session::flash('success', strval(trans('firefly.saved_preferences')));
Preferences::mark();

View File

@@ -11,7 +11,6 @@ declare(strict_types = 1);
namespace FireflyIII\Http\Controllers;
use Auth;
use FireflyIII\Events\UserIsDeleted;
use FireflyIII\Http\Requests\DeleteAccountFormRequest;
use FireflyIII\Http\Requests\ProfileFormRequest;
@@ -41,7 +40,7 @@ class ProfileController extends Controller
*/
public function changePassword()
{
return view('profile.change-password')->with('title', Auth::user()->email)->with('subTitle', trans('firefly.change_your_password'))->with(
return view('profile.change-password')->with('title', auth()->user()->email)->with('subTitle', trans('firefly.change_your_password'))->with(
'mainTitleIcon', 'fa-user'
);
}
@@ -51,7 +50,7 @@ class ProfileController extends Controller
*/
public function deleteAccount()
{
return view('profile.delete-account')->with('title', Auth::user()->email)->with('subTitle', trans('firefly.delete_account'))->with(
return view('profile.delete-account')->with('title', auth()->user()->email)->with('subTitle', trans('firefly.delete_account'))->with(
'mainTitleIcon', 'fa-user'
);
}
@@ -62,7 +61,7 @@ class ProfileController extends Controller
*/
public function index()
{
return view('profile.index')->with('title', trans('firefly.profile'))->with('subTitle', Auth::user()->email)->with('mainTitleIcon', 'fa-user');
return view('profile.index')->with('title', trans('firefly.profile'))->with('subTitle', auth()->user()->email)->with('mainTitleIcon', 'fa-user');
}
/**
@@ -73,7 +72,7 @@ class ProfileController extends Controller
public function postChangePassword(ProfileFormRequest $request)
{
// old, new1, new2
if (!Hash::check($request->get('current_password'), Auth::user()->password)) {
if (!Hash::check($request->get('current_password'), auth()->user()->password)) {
Session::flash('error', strval(trans('firefly.invalid_current_password')));
return redirect(route('profile.change-password'));
@@ -86,8 +85,8 @@ class ProfileController extends Controller
}
// update the user with the new password.
Auth::user()->password = bcrypt($request->get('new_password'));
Auth::user()->save();
auth()->user()->password = bcrypt($request->get('new_password'));
auth()->user()->save();
Session::flash('success', strval(trans('firefly.password_changed')));
@@ -103,22 +102,22 @@ class ProfileController extends Controller
public function postDeleteAccount(DeleteAccountFormRequest $request)
{
// old, new1, new2
if (!Hash::check($request->get('password'), Auth::user()->password)) {
if (!Hash::check($request->get('password'), auth()->user()->password)) {
Session::flash('error', strval(trans('firefly.invalid_password')));
return redirect(route('profile.delete-account'));
}
// respond to deletion:
event(new UserIsDeleted(Auth::user(), $request->ip()));
event(new UserIsDeleted(auth()->user(), $request->ip()));
// store some stuff for the future:
$registration = Preferences::get('registration_ip_address')->data;
$confirmation = Preferences::get('confirmation_ip_address')->data;
// DELETE!
$email = Auth::user()->email;
Auth::user()->delete();
$email = auth()->user()->email;
auth()->user()->delete();
Session::flush();
Session::flash('gaEventCategory', 'user');
Session::flash('gaEventAction', 'delete-account');

View File

@@ -50,18 +50,11 @@ class ReportController extends Controller
/**
*
*
* @param ReportHelperInterface $helper
*/
public function __construct(ReportHelperInterface $helper)
public function __construct()
{
parent::__construct();
$this->helper = $helper;
$this->accountHelper = app(AccountReportHelperInterface::class);
$this->budgetHelper = app(BudgetReportHelperInterface::class);
$this->balanceHelper = app(BalanceReportHelperInterface::class);
View::share('title', trans('firefly.reports'));
View::share('mainTitleIcon', 'fa-line-chart');
@@ -74,6 +67,7 @@ class ReportController extends Controller
*/
public function index(AccountCrudInterface $crud)
{
$this->createRepositories();
/** @var Carbon $start */
$start = clone session('first');
$months = $this->helper->listOfMonths($start);
@@ -104,6 +98,7 @@ class ReportController extends Controller
*/
public function report(string $reportType, Carbon $start, Carbon $end, Collection $accounts)
{
$this->createRepositories();
// throw an error if necessary.
if ($end < $start) {
throw new FireflyException('End date cannot be before start date, silly!');
@@ -192,8 +187,9 @@ class ReportController extends Controller
$transactionAmount = $journal->source_amount;
// get currently relevant transaction:
if (intval($journal->destination_account_id) === $account->id) {
$transactionAmount = $journal->destination_amount;
$destinations = TransactionJournal::destinationAccountList($journal)->pluck('id')->toArray();
if (in_array($account->id, $destinations)) {
$transactionAmount = TransactionJournal::amountPositive($journal);
}
$newBalance = bcadd($startBalance, $transactionAmount);
$journal->after = $newBalance;
@@ -215,14 +211,32 @@ class ReportController extends Controller
$reportType = 'audit';
$accountIds = join(',', $accounts->pluck('id')->toArray());
$hideable = ['buttons', 'icon', 'description', 'balance_before', 'amount', 'balance_after', 'date', 'book_date', 'process_date', 'interest_date',
'from', 'to', 'budget', 'category', 'bill', 'create_date', 'update_date',
$hideable = ['buttons', 'icon', 'description', 'balance_before', 'amount', 'balance_after', 'date',
'interest_date', 'book_date', 'process_date',
// three new optional fields.
'due_date', 'payment_date', 'invoice_date',
'from', 'to', 'budget', 'category', 'bill',
// more new optional fields
'internal_reference', 'notes',
'create_date', 'update_date',
];
$defaultShow = ['icon', 'description', 'balance_before', 'amount', 'balance_after', 'date', 'to'];
return view('reports.audit.report', compact('start', 'end', 'reportType', 'accountIds', 'accounts', 'auditData', 'hideable', 'defaultShow'));
}
/**
*
*/
private function createRepositories()
{
$this->helper = app(ReportHelperInterface::class);
$this->accountHelper = app(AccountReportHelperInterface::class);
$this->budgetHelper = app(BudgetReportHelperInterface::class);
$this->balanceHelper = app(BalanceReportHelperInterface::class);
}
/**
* @param $reportType
* @param Carbon $start

View File

@@ -11,7 +11,6 @@ declare(strict_types = 1);
namespace FireflyIII\Http\Controllers;
use Auth;
use FireflyIII\Http\Requests\RuleFormRequest;
use FireflyIII\Http\Requests\TestRuleFormRequest;
use FireflyIII\Models\Rule;
@@ -189,7 +188,7 @@ class RuleController extends Controller
{
$this->createDefaultRuleGroup();
$this->createDefaultRule();
$ruleGroups = $repository->getRuleGroupsWithRules(Auth::user());
$ruleGroups = $repository->getRuleGroupsWithRules(auth()->user());
return view('rules.index', compact('ruleGroups'));
}
@@ -243,7 +242,7 @@ class RuleController extends Controller
$data = [
'rule_group_id' => $ruleGroup->id,
'title' => $request->get('title'),
'user_id' => Auth::user()->id,
'user_id' => auth()->user()->id,
'trigger' => $request->get('trigger'),
'description' => $request->get('description'),
'rule-triggers' => $request->get('rule-trigger'),
@@ -380,7 +379,7 @@ class RuleController extends Controller
$data = [
'rule_group_id' => $repository->getFirstRuleGroup()->id,
'stop_processing' => 0,
'user_id' => Auth::user()->id,
'user_id' => auth()->user()->id,
'title' => trans('firefly.default_rule_name'),
'description' => trans('firefly.default_rule_description'),
'trigger' => 'store-journal',
@@ -413,7 +412,7 @@ class RuleController extends Controller
if ($repository->count() === 0) {
$data = [
'user_id' => Auth::user()->id,
'user_id' => auth()->user()->id,
'title' => trans('firefly.default_rule_group_name'),
'description' => trans('firefly.default_rule_group_description'),
];

View File

@@ -11,7 +11,6 @@ declare(strict_types = 1);
namespace FireflyIII\Http\Controllers;
use Auth;
use Carbon\Carbon;
use ExpandedForm;
use FireflyIII\Crud\Account\AccountCrudInterface;
@@ -96,7 +95,7 @@ class RuleGroupController extends Controller
{
$title = $ruleGroup->title;
$moveTo = Auth::user()->ruleGroups()->find(intval(Input::get('move_rules_before_delete')));
$moveTo = auth()->user()->ruleGroups()->find(intval(Input::get('move_rules_before_delete')));
$repository->destroy($ruleGroup, $moveTo);
@@ -163,7 +162,7 @@ class RuleGroupController extends Controller
$job = new ExecuteRuleGroupOnExistingTransactions($ruleGroup);
// Apply parameters to the job
$job->setUser(Auth::user());
$job->setUser(auth()->user());
$job->setAccounts($accounts);
$job->setStartDate($startDate);
$job->setEndDate($endDate);
@@ -207,7 +206,7 @@ class RuleGroupController extends Controller
$data = [
'title' => $request->input('title'),
'description' => $request->input('description'),
'user_id' => Auth::user()->id,
'user_id' => auth()->user()->id,
];
$ruleGroup = $repository->store($data);

View File

@@ -11,7 +11,6 @@ declare(strict_types = 1);
namespace FireflyIII\Http\Controllers;
use Auth;
use FireflyIII\Http\Requests\TagFormRequest;
use FireflyIII\Models\Preference;
use FireflyIII\Models\Tag;
@@ -194,7 +193,7 @@ class TagController extends Controller
foreach ($types as $type) {
/** @var Collection $tags */
$tags = Auth::user()->tags()->where('tagMode', $type)->orderBy('date', 'ASC')->get();
$tags = auth()->user()->tags()->where('tagMode', $type)->orderBy('date', 'ASC')->get();
$tags = $tags->sortBy(
function (Tag $tag) {
$date = !is_null($tag->date) ? $tag->date->format('Ymd') : '000000';
@@ -218,18 +217,17 @@ class TagController extends Controller
}
/**
* @param Tag $tag
* @param Tag $tag
* @param TagRepositoryInterface $repository
*
* @return View
*/
public function show(Tag $tag)
public function show(Tag $tag, TagRepositoryInterface $repository)
{
$subTitle = $tag->tag;
$subTitleIcon = 'fa-tag';
/** @var Collection $journals */
$journals = $tag->transactionJournals()->sortCorrectly()->expanded()->get(TransactionJournal::queryFields());
$sum = $journals->sum(
$journals = $repository->getJournals($tag);
$sum = $journals->sum(
function (TransactionJournal $journal) {
return TransactionJournal::amount($journal);
}

View File

@@ -11,7 +11,6 @@ declare(strict_types = 1);
namespace FireflyIII\Http\Controllers\Transaction;
use Auth;
use Carbon\Carbon;
use ExpandedForm;
use FireflyIII\Http\Controllers\Controller;
@@ -192,7 +191,7 @@ class MassController extends Controller
$destAccountName = $request->get('destination_account_name')[$journal->id] ?? '';
$budgetId = $journal->budgets->first() ? $journal->budgets->first()->id : 0;
$category = $journal->categories->first() ? $journal->categories->first()->name : '';
$category = $request->get('category')[$journal->id];
$tags = $journal->tags->pluck('tag')->toArray();
// build data array
@@ -201,11 +200,11 @@ class MassController extends Controller
'what' => $what,
'description' => $request->get('description')[$journal->id],
'source_account_id' => intval($sourceAccountId),
'source_account_name' => intval($destAccountId),
'destination_account_id' => $sourceAccountName,
'source_account_name' => $sourceAccountName,
'destination_account_id' => intval($destAccountId),
'destination_account_name' => $destAccountName,
'amount' => round($request->get('amount')[$journal->id], 4),
'user' => Auth::user()->id,
'user' => auth()->user()->id,
'amount_currency_id_amount' => intval($request->get('amount_currency_id_amount_' . $journal->id)),
'date' => new Carbon($request->get('date')[$journal->id]),
'interest_date' => $journal->interest_date,

View File

@@ -67,6 +67,7 @@ class SplitController extends Controller
$budgets = ExpandedForm::makeSelectListWithEmpty($budgetRepository->getActiveBudgets());
$piggyBanks = ExpandedForm::makeSelectListWithEmpty($piggyRepository->getPiggyBanksWithAmount());
$subTitle = trans('form.add_new_' . $sessionData['what']);
$optionalFields = Preferences::get('transaction_journal_optional_fields', [])->data;
$subTitleIcon = 'fa-plus';
$preFilled = [
'what' => $sessionData['what'] ?? 'withdrawal',
@@ -83,7 +84,7 @@ class SplitController extends Controller
return view(
'split.journals.create',
compact('journal', 'piggyBanks', 'subTitle', 'subTitleIcon', 'preFilled', 'assetAccounts', 'currencies', 'budgets', 'uploadSize')
compact('journal', 'piggyBanks', 'subTitle', 'optionalFields', 'subTitleIcon', 'preFilled', 'assetAccounts', 'currencies', 'budgets', 'uploadSize')
);
}
@@ -101,6 +102,7 @@ class SplitController extends Controller
$uploadSize = min(Steam::phpBytes(ini_get('upload_max_filesize')), Steam::phpBytes(ini_get('post_max_size')));
$currencies = ExpandedForm::makeSelectList($currencyRepository->get());
$assetAccounts = ExpandedForm::makeSelectList($crud->getAccountsByType(['Default account', 'Asset account']));
$optionalFields = Preferences::get('transaction_journal_optional_fields', [])->data;
$budgets = ExpandedForm::makeSelectListWithEmpty($budgetRepository->getActiveBudgets());
$preFilled = $this->arrayFromJournal($request, $journal);
$subTitle = trans('breadcrumbs.edit_journal', ['description' => $journal->description]);
@@ -118,7 +120,8 @@ class SplitController extends Controller
return view(
'split.journals.edit',
compact(
'subTitleIcon', 'currencies', 'preFilled', 'subTitle', 'amount', 'sourceAccounts', 'uploadSize', 'destinationAccounts', 'assetAccounts',
'subTitleIcon', 'currencies', 'optionalFields',
'preFilled', 'subTitle', 'amount', 'sourceAccounts', 'uploadSize', 'destinationAccounts', 'assetAccounts',
'budgets', 'journal'
)
);

View File

@@ -13,6 +13,7 @@ namespace FireflyIII\Http\Controllers;
use Carbon\Carbon;
use ExpandedForm;
use FireflyIII\Crud\Account\AccountCrudInterface;
use FireflyIII\Events\TransactionJournalStored;
use FireflyIII\Events\TransactionJournalUpdated;
use FireflyIII\Helpers\Attachments\AttachmentHelperInterface;
@@ -44,6 +45,12 @@ class TransactionController extends Controller
parent::__construct();
View::share('title', trans('firefly.transactions'));
View::share('mainTitleIcon', 'fa-repeat');
$maxFileSize = Steam::phpBytes(ini_get('upload_max_filesize'));
$maxPostSize = Steam::phpBytes(ini_get('post_max_size'));
$uploadSize = min($maxFileSize, $maxPostSize);
View::share('uploadSize', $uploadSize);
}
/**
@@ -53,18 +60,19 @@ class TransactionController extends Controller
*/
public function create(string $what = TransactionType::DEPOSIT)
{
$crud = app('FireflyIII\Crud\Account\AccountCrudInterface');
$crud = app(AccountCrudInterface::class);
$budgetRepository = app('FireflyIII\Repositories\Budget\BudgetRepositoryInterface');
$piggyRepository = app('FireflyIII\Repositories\PiggyBank\PiggyBankRepositoryInterface');
$what = strtolower($what);
$uploadSize = min(Steam::phpBytes(ini_get('upload_max_filesize')), Steam::phpBytes(ini_get('post_max_size')));
$assetAccounts = ExpandedForm::makeSelectList($crud->getAccountsByType(['Default account', 'Asset account']));
$assetAccounts = ExpandedForm::makeSelectList($crud->getActiveAccountsByType(['Default account', 'Asset account']));
$budgets = ExpandedForm::makeSelectListWithEmpty($budgetRepository->getActiveBudgets());
$piggyBanks = $piggyRepository->getPiggyBanksWithAmount();
$piggies = ExpandedForm::makeSelectListWithEmpty($piggyBanks);
$preFilled = Session::has('preFilled') ? session('preFilled') : [];
$subTitle = trans('form.add_new_' . $what);
$subTitleIcon = 'fa-plus';
$optionalFields = Preferences::get('transaction_journal_optional_fields', [])->data;
Session::put('preFilled', $preFilled);
@@ -80,7 +88,7 @@ class TransactionController extends Controller
asort($piggies);
return view('transactions.create', compact('assetAccounts', 'subTitleIcon', 'uploadSize', 'budgets', 'what', 'piggies', 'subTitle'));
return view('transactions.create', compact('assetAccounts', 'subTitleIcon', 'uploadSize', 'budgets', 'what', 'piggies', 'subTitle', 'optionalFields'));
}
/**
@@ -135,19 +143,23 @@ class TransactionController extends Controller
if ($count > 2) {
return redirect(route('split.journal.edit', [$journal->id]));
}
$budgetRepository = app('FireflyIII\Repositories\Budget\BudgetRepositoryInterface');
$piggyRepository = app('FireflyIII\Repositories\PiggyBank\PiggyBankRepositoryInterface');
$crud = app('FireflyIII\Crud\Account\AccountCrudInterface');
$assetAccounts = ExpandedForm::makeSelectList($crud->getAccountsByType(['Default account', 'Asset account']));
$budgetList = ExpandedForm::makeSelectListWithEmpty($budgetRepository->getActiveBudgets());
$piggyBankList = ExpandedForm::makeSelectListWithEmpty($piggyRepository->getPiggyBanks());
$maxFileSize = Steam::phpBytes(ini_get('upload_max_filesize'));
$maxPostSize = Steam::phpBytes(ini_get('post_max_size'));
$uploadSize = min($maxFileSize, $maxPostSize);
$what = strtolower(TransactionJournal::transactionTypeStr($journal));
$subTitle = trans('breadcrumbs.edit_journal', ['description' => $journal->description]);
// code to get list data:
$budgetRepository = app('FireflyIII\Repositories\Budget\BudgetRepositoryInterface');
$piggyRepository = app('FireflyIII\Repositories\PiggyBank\PiggyBankRepositoryInterface');
$crud = app('FireflyIII\Crud\Account\AccountCrudInterface');
$assetAccounts = ExpandedForm::makeSelectList($crud->getAccountsByType(['Default account', 'Asset account']));
$budgetList = ExpandedForm::makeSelectListWithEmpty($budgetRepository->getActiveBudgets());
$piggyBankList = ExpandedForm::makeSelectListWithEmpty($piggyRepository->getPiggyBanks());
// view related code
$subTitle = trans('breadcrumbs.edit_journal', ['description' => $journal->description]);
$what = strtolower(TransactionJournal::transactionTypeStr($journal));
// journal related code
$sourceAccounts = TransactionJournal::sourceAccountList($journal);
$destinationAccounts = TransactionJournal::destinationAccountList($journal);
$optionalFields = Preferences::get('transaction_journal_optional_fields', [])->data;
$preFilled = [
'date' => TransactionJournal::dateAsString($journal),
'interest_date' => TransactionJournal::dateAsString($journal, 'interest_date'),
@@ -162,6 +174,13 @@ class TransactionController extends Controller
'destination_account_id' => $destinationAccounts->first()->id,
'destination_account_name' => $destinationAccounts->first()->name,
'amount' => TransactionJournal::amountPositive($journal),
// new custom fields:
'due_date' => TransactionJournal::dateAsString($journal, 'due_date'),
'payment_date' => TransactionJournal::dateAsString($journal, 'payment_date'),
'invoice_date' => TransactionJournal::dateAsString($journal, 'invoice_date'),
'interal_reference' => $journal->getMeta('internal_reference'),
'notes' => $journal->getMeta('notes'),
];
if ($journal->isWithdrawal() && $destinationAccounts->first()->accountType->type == AccountType::CASH) {
@@ -183,9 +202,10 @@ class TransactionController extends Controller
}
Session::forget('transactions.edit.fromUpdate');
return view('transactions.edit', compact('journal', 'uploadSize', 'assetAccounts', 'what', 'budgetList', 'piggyBankList', 'subTitle'))->with(
'data', $preFilled
);
return view(
'transactions.edit',
compact('journal', 'optionalFields', 'assetAccounts', 'what', 'budgetList', 'piggyBankList', 'subTitle')
)->with('data', $preFilled);
}
/**

18
app/Http/Kernel.php Normal file → Executable file
View File

@@ -6,7 +6,6 @@
* This software may be modified and distributed under the terms
* of the MIT license. See the LICENSE file for details.
*/
declare(strict_types = 1);
namespace FireflyIII\Http;
@@ -23,9 +22,11 @@ use FireflyIII\Http\Middleware\RedirectIfAuthenticated;
use FireflyIII\Http\Middleware\RedirectIfTwoFactorAuthenticated;
use FireflyIII\Http\Middleware\VerifyCsrfToken;
use Illuminate\Auth\Middleware\AuthenticateWithBasicAuth;
use Illuminate\Auth\Middleware\Authorize;
use Illuminate\Cookie\Middleware\AddQueuedCookiesToResponse;
use Illuminate\Foundation\Http\Kernel as HttpKernel;
use Illuminate\Foundation\Http\Middleware\CheckForMaintenanceMode;
use Illuminate\Routing\Middleware\SubstituteBindings;
use Illuminate\Routing\Middleware\ThrottleRequests;
use Illuminate\Session\Middleware\StartSession;
use Illuminate\View\Middleware\ShareErrorsFromSession;
@@ -37,10 +38,11 @@ use Illuminate\View\Middleware\ShareErrorsFromSession;
*/
class Kernel extends HttpKernel
{
/**
* The bootstrap classes for the application.
*
* Next upgrade should verify these are all here.
* Next upgrade verify these are the same.
*
* @var array
*/
@@ -83,6 +85,7 @@ class Kernel extends HttpKernel
StartSession::class,
ShareErrorsFromSession::class,
VerifyCsrfToken::class,
SubstituteBindings::class,
],
// MUST NOT be logged in. Does not care about 2FA or confirmation.
'user-not-logged-in' => [
@@ -91,9 +94,9 @@ class Kernel extends HttpKernel
StartSession::class,
ShareErrorsFromSession::class,
VerifyCsrfToken::class,
SubstituteBindings::class,
RedirectIfAuthenticated::class,
],
// MUST be logged in.
// MUST NOT have 2FA
// don't care about confirmation:
@@ -103,6 +106,7 @@ class Kernel extends HttpKernel
StartSession::class,
ShareErrorsFromSession::class,
VerifyCsrfToken::class,
SubstituteBindings::class,
Authenticate::class,
RedirectIfTwoFactorAuthenticated::class,
],
@@ -115,6 +119,7 @@ class Kernel extends HttpKernel
StartSession::class,
ShareErrorsFromSession::class,
VerifyCsrfToken::class,
SubstituteBindings::class,
Authenticate::class,
AuthenticateTwoFactor::class,
IsNotConfirmed::class,
@@ -129,6 +134,7 @@ class Kernel extends HttpKernel
StartSession::class,
ShareErrorsFromSession::class,
VerifyCsrfToken::class,
SubstituteBindings::class,
Authenticate::class,
],
@@ -142,6 +148,7 @@ class Kernel extends HttpKernel
StartSession::class,
ShareErrorsFromSession::class,
VerifyCsrfToken::class,
SubstituteBindings::class,
Authenticate::class,
AuthenticateTwoFactor::class,
IsConfirmed::class,
@@ -159,6 +166,7 @@ class Kernel extends HttpKernel
StartSession::class,
ShareErrorsFromSession::class,
VerifyCsrfToken::class,
SubstituteBindings::class,
Authenticate::class,
AuthenticateTwoFactor::class,
IsConfirmed::class,
@@ -168,8 +176,10 @@ class Kernel extends HttpKernel
],
'api' => [
'throttle:60,1',
'bindings',
],
];
@@ -184,6 +194,8 @@ class Kernel extends HttpKernel
= [
'auth' => Authenticate::class,
'auth.basic' => AuthenticateWithBasicAuth::class,
'bindings' => SubstituteBindings::class,
'can' => Authorize::class,
'guest' => RedirectIfAuthenticated::class,
'throttle' => ThrottleRequests::class,
'range' => Range::class,

View File

@@ -41,7 +41,7 @@ class Authenticate
return redirect()->guest('login');
}
if (intval(Auth::user()->blocked) === 1) {
if (intval(auth()->user()->blocked) === 1) {
Auth::guard($guard)->logout();
Session::flash('logoutMessage', trans('firefly.block_account_logout'));

View File

@@ -45,7 +45,7 @@ class AuthenticateTwoFactor
return redirect()->guest('login');
}
if (intval(Auth::user()->blocked) === 1) {
if (intval(auth()->user()->blocked) === 1) {
Auth::guard($guard)->logout();
Session::flash('logoutMessage', trans('firefly.block_account_logout'));

1
app/Http/Middleware/EncryptCookies.php Normal file → Executable file
View File

@@ -6,7 +6,6 @@
* This software may be modified and distributed under the terms
* of the MIT license. See the LICENSE file for details.
*/
declare(strict_types = 1);
namespace FireflyIII\Http\Middleware;

View File

@@ -43,7 +43,7 @@ class IsAdmin
return redirect()->guest('login');
}
/** @var User $user */
$user = Auth::user();
$user = auth()->user();
if (!$user->hasRole('owner')) {
return redirect(route('home'));
}

View File

@@ -11,6 +11,7 @@ declare(strict_types = 1);
namespace FireflyIII\Http\Middleware;
use App;
use Carbon\Carbon;
use Closure;
use FireflyIII\Exceptions\FireflyException;
@@ -19,6 +20,7 @@ use Illuminate\Contracts\Auth\Guard;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\Auth;
use Navigation;
use NumberFormatter;
use Preferences;
use Session;
use View;
@@ -62,36 +64,56 @@ class Range
public function handle(Request $request, Closure $theNext, $guard = null)
{
if (!Auth::guard($guard)->guest()) {
// ignore preference. set the range to be the current month:
if (!Session::has('start') && !Session::has('end')) {
$viewRange = Preferences::get('viewRange', '1M')->data;
$start = new Carbon;
$start = Navigation::updateStartDate($viewRange, $start);
$end = Navigation::updateEndDate($viewRange, $start);
// set start, end and finish:
$this->setRange();
Session::put('start', $start);
Session::put('end', $end);
}
if (!Session::has('first')) {
/** @var JournalRepositoryInterface $repository */
$repository = app(JournalRepositoryInterface::class);
$journal = $repository->first();
$first = Carbon::now()->startOfYear();
if (!is_null($journal->id)) {
$first = $journal->date;
}
Session::put('first', $first);
}
// get variables for date range:
$this->datePicker();
// set view variables.
$this->configureView();
}
$this->datePicker();
return $theNext($request);
}
private function configureView()
{
$pref = Preferences::get('language', config('firefly.default_language', 'en_US'));
$lang = $pref->data;
App::setLocale($lang);
Carbon::setLocale(substr($lang, 0, 2));
$locale = explode(',', trans('config.locale'));
$locale = array_map('trim', $locale);
setlocale(LC_TIME, $locale);
setlocale(LC_MONETARY, $locale);
// save some formats:
$monthFormat = (string)trans('config.month');
$monthAndDayFormat = (string)trans('config.month_and_day');
$dateTimeFormat = (string)trans('config.date_time');
// change localeconv to a new array:
$numberFormatter = numfmt_create($lang, NumberFormatter::CURRENCY);
$localeconv = [
'mon_decimal_point' => $numberFormatter->getSymbol($numberFormatter->getAttribute(NumberFormatter::DECIMAL_SEPARATOR_SYMBOL)),
'mon_thousands_sep' => $numberFormatter->getSymbol($numberFormatter->getAttribute(NumberFormatter::MONETARY_GROUPING_SEPARATOR_SYMBOL)),
'frac_digits' => $numberFormatter->getAttribute(NumberFormatter::MAX_FRACTION_DIGITS),
];
View::share('monthFormat', $monthFormat);
View::share('monthAndDayFormat', $monthAndDayFormat);
View::share('dateTimeFormat', $dateTimeFormat);
View::share('language', $lang);
View::share('localeconv', $localeconv);
}
/**
* @throws FireflyException
*/
private function datePicker()
{
$viewRange = Preferences::get('viewRange', '1M')->data;
@@ -141,4 +163,33 @@ class Range
View::share('dpRanges', $ranges);
}
/**
*
*/
private function setRange()
{
// ignore preference. set the range to be the current month:
if (!Session::has('start') && !Session::has('end')) {
$viewRange = Preferences::get('viewRange', '1M')->data;
$start = new Carbon;
$start = Navigation::updateStartDate($viewRange, $start);
$end = Navigation::updateEndDate($viewRange, $start);
Session::put('start', $start);
Session::put('end', $end);
}
if (!Session::has('first')) {
/** @var JournalRepositoryInterface $repository */
$repository = app(JournalRepositoryInterface::class);
$journal = $repository->first();
$first = Carbon::now()->startOfYear();
if (!is_null($journal->id)) {
$first = $journal->date;
}
Session::put('first', $first);
}
}
}

2
app/Http/Middleware/RedirectIfAuthenticated.php Normal file → Executable file
View File

@@ -6,7 +6,6 @@
* This software may be modified and distributed under the terms
* of the MIT license. See the LICENSE file for details.
*/
declare(strict_types = 1);
namespace FireflyIII\Http\Middleware;
@@ -33,7 +32,6 @@ class RedirectIfAuthenticated
public function handle($request, Closure $next, $guard = null)
{
if (Auth::guard($guard)->check()) {
return redirect('/');
}

2
app/Http/Middleware/VerifyCsrfToken.php Normal file → Executable file
View File

@@ -6,8 +6,8 @@
* This software may be modified and distributed under the terms
* of the MIT license. See the LICENSE file for details.
*/
declare(strict_types = 1);
namespace FireflyIII\Http\Middleware;
use Illuminate\Foundation\Http\Middleware\VerifyCsrfToken as BaseVerifier;

View File

@@ -11,7 +11,6 @@ declare(strict_types = 1);
namespace FireflyIII\Http\Requests;
use Auth;
use FireflyIII\Models\Account;
use Input;
@@ -29,7 +28,7 @@ class AccountFormRequest extends Request
public function authorize()
{
// Only allow logged in users
return Auth::check();
return auth()->check();
}
/**

View File

@@ -11,8 +11,6 @@ declare(strict_types = 1);
namespace FireflyIII\Http\Requests;
use Auth;
/**
* Class AttachmentFormRequest
*
@@ -27,7 +25,7 @@ class AttachmentFormRequest extends Request
public function authorize()
{
// Only allow logged in users
return Auth::check();
return auth()->check();
}
/**

View File

@@ -11,7 +11,6 @@ declare(strict_types = 1);
namespace FireflyIII\Http\Requests;
use Auth;
use Carbon\Carbon;
use Input;
@@ -29,7 +28,7 @@ class BillFormRequest extends Request
public function authorize()
{
// Only allow logged in users
return Auth::check();
return auth()->check();
}
/**
@@ -45,7 +44,7 @@ class BillFormRequest extends Request
'amount_currency_id_amount_max' => intval($this->get('amount_currency_id_amount_max')),
'amount_max' => round($this->get('amount_max'), 2),
'date' => new Carbon($this->get('date')),
'user' => Auth::user()->id,
'user' => auth()->user()->id,
'repeat_freq' => $this->get('repeat_freq'),
'skip' => intval($this->get('skip')),
'automatch' => intval($this->get('automatch')) === 1,

View File

@@ -11,7 +11,6 @@ declare(strict_types = 1);
namespace FireflyIII\Http\Requests;
use Auth;
use FireflyIII\Models\Budget;
use Input;
@@ -29,7 +28,7 @@ class BudgetFormRequest extends Request
public function authorize()
{
// Only allow logged in users
return Auth::check();
return auth()->check();
}
/**

View File

@@ -11,7 +11,6 @@ declare(strict_types = 1);
namespace FireflyIII\Http\Requests;
use Auth;
use FireflyIII\Models\Category;
use Input;
@@ -29,7 +28,7 @@ class CategoryFormRequest extends Request
public function authorize()
{
// Only allow logged in users
return Auth::check();
return auth()->check();
}
/**

View File

@@ -0,0 +1,42 @@
<?php
/**
* ConfigurationRequest.php
* Copyright (C) 2016 thegrumpydictator@gmail.com
*
* This software may be modified and distributed under the terms
* of the MIT license. See the LICENSE file for details.
*/
declare(strict_types = 1);
namespace FireflyIII\Http\Requests;
/**
* Class ConfigurationRequest
*
*
* @package FireflyIII\Http\Requests
*/
class ConfigurationRequest extends Request
{
/**
* @return bool
*/
public function authorize()
{
// Only allow logged in users and admins
return auth()->check() && auth()->user()->hasRole('owner');
}
/**
* @return array
*/
public function rules()
{
$rules = [
'single_user_mode' => 'between:0,1|numeric',
];
return $rules;
}
}

View File

@@ -11,7 +11,6 @@ declare(strict_types = 1);
namespace FireflyIII\Http\Requests;
use Auth;
use Input;
/**
@@ -28,7 +27,7 @@ class CurrencyFormRequest extends Request
public function authorize()
{
// Only allow logged in users
return Auth::check();
return auth()->check();
}
/**

View File

@@ -11,8 +11,6 @@ declare(strict_types = 1);
namespace FireflyIII\Http\Requests;
use Auth;
/**
* Class DeleteAccountFormRequest
*
@@ -27,7 +25,7 @@ class DeleteAccountFormRequest extends Request
public function authorize()
{
// Only allow logged in users
return Auth::check();
return auth()->check();
}
/**

View File

@@ -11,7 +11,6 @@ declare(strict_types = 1);
namespace FireflyIII\Http\Requests;
use Auth;
use Carbon\Carbon;
/**
@@ -28,7 +27,7 @@ class ExportFormRequest extends Request
public function authorize()
{
// Only allow logged in users
return Auth::check();
return auth()->check();
}
/**

View File

@@ -11,8 +11,6 @@ declare(strict_types = 1);
namespace FireflyIII\Http\Requests;
use Auth;
/**
* Class ImportUploadRequest
*
@@ -27,7 +25,7 @@ class ImportUploadRequest extends Request
public function authorize()
{
// Only allow logged in users
return Auth::check();
return auth()->check();
}
/**

View File

@@ -11,7 +11,6 @@ declare(strict_types = 1);
namespace FireflyIII\Http\Requests;
use Auth;
use Carbon\Carbon;
use Exception;
use FireflyIII\Exceptions\FireflyException;
@@ -32,7 +31,7 @@ class JournalFormRequest extends Request
public function authorize()
{
// Only allow logged in users
return Auth::check();
return auth()->check();
}
/**
@@ -40,26 +39,34 @@ class JournalFormRequest extends Request
*/
public function getJournalData()
{
$tags = $this->get('tags') ?? '';
$tags = $this->getFieldOrEmptyString('tags');
return [
'what' => $this->get('what'),
'description' => $this->get('description'),
'description' => trim($this->get('description')),
'source_account_id' => intval($this->get('source_account_id')),
'source_account_name' => $this->get('source_account_name') ?? '',
'source_account_name' => trim($this->getFieldOrEmptyString('source_account_name')),
'destination_account_id' => intval($this->get('destination_account_id')),
'destination_account_name' => $this->get('destination_account_name') ?? '',
'destination_account_name' => trim($this->getFieldOrEmptyString('destination_account_name')),
'amount' => round($this->get('amount'), 2),
'user' => Auth::user()->id,
'user' => auth()->user()->id,
'amount_currency_id_amount' => intval($this->get('amount_currency_id_amount')),
'date' => new Carbon($this->get('date')),
'interest_date' => $this->get('interest_date') ? new Carbon($this->get('interest_date')) : null,
'book_date' => $this->get('book_date') ? new Carbon($this->get('book_date')) : null,
'process_date' => $this->get('process_date') ? new Carbon($this->get('process_date')) : null,
'interest_date' => $this->getDateOrNull('interest_date'),
'book_date' => $this->getDateOrNull('book_date'),
'process_date' => $this->getDateOrNull('process_date'),
'budget_id' => intval($this->get('budget_id')),
'category' => $this->get('category') ?? '',
'category' => trim($this->getFieldOrEmptyString('category')),
'tags' => explode(',', $tags),
'piggy_bank_id' => $this->get('piggy_bank_id') ? intval($this->get('piggy_bank_id')) : 0,
'piggy_bank_id' => intval($this->get('piggy_bank_id')),
// new custom fields here:
'due_date' => $this->getDateOrNull('due_date'),
'payment_date' => $this->getDateOrNull('payment_date'),
'invoice_date' => $this->getDateOrNull('invoice_date'),
'internal_reference' => trim(strval($this->get('internal_reference'))),
'notes' => trim(strval($this->get('notes'))),
];
}
@@ -81,6 +88,12 @@ class JournalFormRequest extends Request
'category' => 'between:1,255',
'amount_currency_id_amount' => 'required|exists:transaction_currencies,id',
'piggy_bank_id' => 'numeric',
// new custom fields here:
'due_date' => 'date',
'payment_date' => 'date',
'internal_reference' => 'min:1,max:255',
'notes' => 'min:1,max:65536',
];
switch ($what) {
@@ -106,4 +119,24 @@ class JournalFormRequest extends Request
return $rules;
}
/**
* @param string $field
*
* @return Carbon|null
*/
private function getDateOrNull(string $field)
{
return $this->get($field) ? new Carbon($this->get($field)) : null;
}
/**
* @param string $field
*
* @return string
*/
private function getFieldOrEmptyString(string $field): string
{
return $this->get($field) ?? '';
}
}

View File

@@ -11,8 +11,6 @@ declare(strict_types = 1);
namespace FireflyIII\Http\Requests;
use Auth;
/**
* Class MassDeleteJournalRequest
*
@@ -27,7 +25,7 @@ class MassDeleteJournalRequest extends Request
public function authorize()
{
// Only allow logged in users
return Auth::check();
return auth()->check();
}
/**

View File

@@ -11,8 +11,6 @@ declare(strict_types = 1);
namespace FireflyIII\Http\Requests;
use Auth;
/**
* Class MassEditJournalRequest
*
@@ -27,7 +25,7 @@ class MassEditJournalRequest extends Request
public function authorize()
{
// Only allow logged in users
return Auth::check();
return auth()->check();
}
/**

View File

@@ -11,8 +11,6 @@ declare(strict_types = 1);
namespace FireflyIII\Http\Requests;
use Auth;
/**
* Class NewUserFormRequest
*
@@ -27,7 +25,7 @@ class NewUserFormRequest extends Request
public function authorize()
{
// Only allow logged in users
return Auth::check();
return auth()->check();
}
/**

View File

@@ -11,7 +11,6 @@ declare(strict_types = 1);
namespace FireflyIII\Http\Requests;
use Auth;
use Input;
/**
@@ -28,7 +27,7 @@ class PiggyBankFormRequest extends Request
public function authorize()
{
// Only allow logged in users
return Auth::check();
return auth()->check();
}
/**

View File

@@ -11,8 +11,6 @@ declare(strict_types = 1);
namespace FireflyIII\Http\Requests;
use Auth;
/**
* Class ProfileFormRequest
*
@@ -27,7 +25,7 @@ class ProfileFormRequest extends Request
public function authorize()
{
// Only allow logged in users
return Auth::check();
return auth()->check();
}
/**

View File

@@ -11,7 +11,6 @@ declare(strict_types = 1);
namespace FireflyIII\Http\Requests;
use Auth;
use FireflyIII\Models\RuleGroup;
use Input;
@@ -29,7 +28,7 @@ class RuleFormRequest extends Request
public function authorize()
{
// Only allow logged in users
return Auth::check();
return auth()->check();
}
/**

View File

@@ -18,7 +18,6 @@ declare(strict_types = 1);
namespace FireflyIII\Http\Requests;
use Auth;
use FireflyIII\Models\RuleGroup;
use Input;
@@ -36,7 +35,7 @@ class RuleGroupFormRequest extends Request
public function authorize()
{
// Only allow logged in users
return Auth::check();
return auth()->check();
}
/**

View File

@@ -11,7 +11,6 @@ declare(strict_types = 1);
namespace FireflyIII\Http\Requests;
use Auth;
use Carbon\Carbon;
/**
@@ -28,7 +27,7 @@ class SelectTransactionsRequest extends Request
public function authorize()
{
// Only allow logged in users
return Auth::check();
return auth()->check();
}
/**

View File

@@ -11,7 +11,6 @@ declare(strict_types = 1);
namespace FireflyIII\Http\Requests;
use Auth;
use Carbon\Carbon;
@@ -28,7 +27,7 @@ class SplitJournalFormRequest extends Request
public function authorize(): bool
{
// Only allow logged in users
return Auth::check();
return auth()->check();
}
/**

View File

@@ -10,7 +10,6 @@
declare(strict_types = 1);
namespace FireflyIII\Http\Requests;
use Auth;
use Carbon\Carbon;
use FireflyIII\Models\Tag;
use Input;
@@ -29,7 +28,7 @@ class TagFormRequest extends Request
public function authorize()
{
// Only allow logged in users
return Auth::check();
return auth()->check();
}
/**

View File

@@ -11,8 +11,6 @@ declare(strict_types = 1);
namespace FireflyIII\Http\Requests;
use Auth;
/**
* Class RuleFormRequest
*
@@ -27,7 +25,7 @@ class TestRuleFormRequest extends Request
public function authorize()
{
// Only allow logged in users
return Auth::check();
return auth()->check();
}
/**

View File

@@ -11,8 +11,6 @@ declare(strict_types = 1);
namespace FireflyIII\Http\Requests;
use Auth;
/**
* Class TokenFormRequest
*
@@ -27,7 +25,7 @@ class TokenFormRequest extends Request
public function authorize()
{
// Only allow logged in users
return Auth::check();
return auth()->check();
}
/**

View File

@@ -23,6 +23,7 @@ class Amount extends BasicConverter implements ConverterInterface
* Some people, when confronted with a problem, think "I know, I'll use regular expressions." Now they have two problems.
* - Jamie Zawinski
*
*
* @param $value
*
* @return float
@@ -33,12 +34,12 @@ class Amount extends BasicConverter implements ConverterInterface
$decimalPosition = $len - 3;
$decimal = null;
if ($len > 2 && $value{$decimalPosition} == '.') {
if (($len > 2 && $value{$decimalPosition} == '.') || ($len > 2 && strpos($value, '.') > $decimalPosition)) {
$decimal = '.';
}
if ($len > 2 && $value{$decimalPosition} == ',') {
$decimal = ',';
}
}
// if decimal is dot, replace all comma's and spaces with nothing. then parse as float (round to 4 pos)
if ($decimal === '.') {

View File

@@ -11,6 +11,7 @@ declare(strict_types = 1);
namespace FireflyIII\Import;
use Carbon\Carbon;
use FireflyIII\Exceptions\FireflyException;
use FireflyIII\Models\ImportJob;
use FireflyIII\Models\Rule;
@@ -112,7 +113,11 @@ class ImportStorage
$meta = TransactionJournalMeta::where('name', 'originalImportHash')->where('data', json_encode($hash))->first(['journal_meta.*']);
if (!is_null($meta)) {
return $meta->transactionjournal;
/** @var TransactionJournal $journal */
$journal = $meta->transactionjournal;
if (intval($journal->completed) === 1) {
return $journal;
}
}
return new TransactionJournal;
@@ -151,7 +156,7 @@ class ImportStorage
$repository = app(TagRepositoryInterface::class, [$this->user]);
$data = [
'tag' => trans('firefly.import_with_key', ['key' => $this->job->key]),
'date' => null,
'date' => new Carbon,
'description' => null,
'latitude' => null,
'longitude' => null,
@@ -288,7 +293,7 @@ class ImportStorage
private function storeJournal($entry): TransactionJournal
{
$billId = is_null($entry->fields['bill']) ? null : $entry->fields['bill']->id;
$billId = is_null($entry->fields['bill']) || intval($entry->fields['bill']->id) === 0 ? null : intval($entry->fields['bill']->id);
$journalData = [
'user_id' => $entry->user->id,
'transaction_type_id' => $entry->fields['transaction-type']->id,
@@ -305,7 +310,7 @@ class ImportStorage
$journal = TransactionJournal::create($journalData);
foreach ($journal->getErrors()->all() as $err) {
Log::error($err);
Log::error('Error when storing journal: ' . $err);
}
Log::debug('Created journal', ['id' => $journal->id]);
@@ -376,8 +381,31 @@ class ImportStorage
'amount' => $amount,
];
$one = Transaction::create($sourceData);
$two = Transaction::create($destinationData);
$one = Transaction::create($sourceData);
$two = Transaction::create($destinationData);
$error = false;
if (is_null($one->id)) {
Log::error('Could not create transaction 1.', $one->getErrors()->all());
$error = true;
}
if (is_null($two->id)) {
Log::error('Could not create transaction 1.', $two->getErrors()->all());
$error = true;
}
// respond to error
if ($error === true) {
$errorText = sprintf('Cannot import row %d, because an error occured when storing data.', $index);
Log::error($errorText);
$extendedStatus = $this->job->extended_status;
$extendedStatus['errors'][] = $errorText;
$this->job->extended_status = $extendedStatus;
$this->job->save();
return new TransactionJournal;
}
Log::debug('Created transaction 1', ['id' => $one->id, 'account' => $one->account_id, 'account_name' => $accounts['source']->name]);
Log::debug('Created transaction 2', ['id' => $two->id, 'account' => $two->account_id, 'account_name' => $accounts['destination']->name]);

View File

@@ -21,6 +21,7 @@ use FireflyIII\Repositories\Currency\CurrencyRepositoryInterface;
use FireflyIII\User;
use Illuminate\Support\Collection;
use Log;
use Preferences;
/**
* Class ImportValidator
@@ -177,10 +178,25 @@ class ImportValidator
$result = $repository->findByName($account->name, [$type]);
if (is_null($result->id)) {
// can convert account:
Log::debug(sprintf('No account named %s of type %s, will convert.', $account->name, $type));
$result = $repository->updateAccountType($account, $type);
Log::debug(sprintf('No account named %s of type %s, create new account.', $account->name, $type));
$result = $repository->store(
[
'user' => $this->user->id,
'accountType' => config('firefly.shortNamesByFullName.' . $type),
'name' => $account->name,
'virtualBalance' => 0,
'active' => true,
'iban' => null,
'openingBalance' => 0,
]
);
}
Log::debug(
sprintf(
'Using another account named %s (#%d) of type %s, will use that one instead of %s (#%d)', $account->name, $result->id, $type, $account->name,
$account->id
)
);
return $result;
@@ -246,6 +262,7 @@ class ImportValidator
$entry->valid = false;
Log::warning('Cannot import entry. Asset account is NULL and import account is also NULL.');
return $entry;
}
Log::debug('Asset account is OK.', ['id' => $entry->fields['asset-account']->id, 'name' => $entry->fields['asset-account']->name]);
@@ -357,13 +374,16 @@ class ImportValidator
{
if (is_null($entry->fields['currency'])) {
/** @var CurrencyRepositoryInterface $repository */
$repository = app(CurrencyRepositoryInterface::class);
$entry->fields['currency'] = $repository->findByCode(env('DEFAULT_CURRENCY', 'EUR'));
Log::debug('Set currency to EUR');
$repository = app(CurrencyRepositoryInterface::class, [$this->user]);
// is the default currency for the user or the system
$defaultCode = Preferences::getForUser($this->user, 'currencyPreference', config('firefly.default_currency', 'EUR'))->data;
$entry->fields['currency'] = $repository->findByCode($defaultCode);
Log::debug(sprintf('Set currency to %s', $defaultCode));
return $entry;
}
Log::debug('Currency is OK');
Log::debug(sprintf('Currency is OK: %s', $entry->fields['currency']->code));
return $entry;
}

View File

@@ -11,6 +11,7 @@ declare(strict_types = 1);
namespace FireflyIII\Import\Importer;
use FireflyIII\Exceptions\FireflyException;
use FireflyIII\Import\Converter\ConverterInterface;
use FireflyIII\Import\ImportEntry;
use FireflyIII\Import\Specifics\SpecificInterface;
@@ -31,12 +32,15 @@ class CsvImporter implements ImporterInterface
/** @var ImportJob */
public $job;
public $validSpecifics = [];
/**
* CsvImporter constructor.
*/
public function __construct()
{
$this->collection = new Collection;
$this->collection = new Collection;
$this->validSpecifics = array_keys(config('csv.import_specifics'));
}
/**
@@ -111,6 +115,11 @@ class CsvImporter implements ImporterInterface
// and this is the point where the specifix go to work.
foreach ($config['specifics'] as $name => $enabled) {
if (!in_array($name, $this->validSpecifics)) {
throw new FireflyException(sprintf('"%s" is not a valid class name', $name));
}
/** @var SpecificInterface $specific */
$specific = app('FireflyIII\Import\Specifics\\' . $name);
@@ -120,12 +129,19 @@ class CsvImporter implements ImporterInterface
foreach ($row as $rowIndex => $value) {
// find the role for this column:
$role = $config['column-roles'][$rowIndex] ?? '_ignore';
$doMap = $config['column-do-mapping'][$rowIndex] ?? false;
$role = $config['column-roles'][$rowIndex] ?? '_ignore';
$doMap = $config['column-do-mapping'][$rowIndex] ?? false;
$validConverters = array_keys(config('csv.import_roles'));
// throw error when not a valid converter.
if (!in_array($role, $validConverters)) {
throw new FireflyException(sprintf('"%s" is not a valid role.', $role));
}
$converterClass = config('csv.import_roles.' . $role . '.converter');
$mapping = $config['column-mapping-config'][$rowIndex] ?? [];
$className = sprintf('FireflyIII\\Import\\Converter\\%s', $converterClass);
/** @var ConverterInterface $converter */
$converter = app('FireflyIII\\Import\\Converter\\' . $converterClass);
$converter = app($className);
// set some useful values for the converter:
$converter->setMapping($mapping);
$converter->setDoMap($doMap);

View File

@@ -13,7 +13,6 @@ namespace FireflyIII\Import\Logging;
use Illuminate\Console\Command;
use Monolog\Handler\AbstractProcessingHandler;
use Monolog\Logger;
/**
* Class CommandHandler
@@ -55,31 +54,9 @@ class CommandHandler extends AbstractProcessingHandler
*/
private function changeLevel(string $level)
{
switch ($level) {
case 'debug':
$this->setLevel(Logger::DEBUG);
break;
case 'info':
$this->setLevel(Logger::INFO);
break;
case 'notice':
$this->setLevel(Logger::NOTICE);
break;
case 'warning':
$this->setLevel(Logger::WARNING);
break;
case 'error':
$this->setLevel(Logger::ERROR);
break;
case 'critical':
$this->setLevel(Logger::CRITICAL);
break;
case 'alert':
$this->setLevel(Logger::ALERT);
break;
case 'emergency':
$this->setLevel(Logger::EMERGENCY);
break;
$level = strtoupper($level);
if (defined(sprintf('Logger::%s', $level))) {
$this->setLevel(constant(sprintf('Logger::%s', $level)));
}
}
}

View File

@@ -14,6 +14,7 @@ namespace FireflyIII\Import\Setup;
use ExpandedForm;
use FireflyIII\Crud\Account\AccountCrud;
use FireflyIII\Exceptions\FireflyException;
use FireflyIII\Import\Mapper\MapperInterface;
use FireflyIII\Import\MapperPreProcess\PreProcessorInterface;
use FireflyIII\Import\Specifics\SpecificInterface;
@@ -32,7 +33,6 @@ use Symfony\Component\HttpFoundation\FileBag;
*/
class CsvSetup implements SetupInterface
{
const EXAMPLE_ROWS = 5;
/** @var Account */
public $defaultImportAccount;
/** @var ImportJob */
@@ -49,29 +49,13 @@ class CsvSetup implements SetupInterface
/**
* Create initial (empty) configuration array.
*
*
*
* @return bool
*/
public function configure(): bool
{
if (is_null($this->job->configuration) || (is_array($this->job->configuration) && count($this->job->configuration) === 0)) {
Log::debug('No config detected, will create empty one.');
$config = [
'has-headers' => false, // assume
'date-format' => 'Ymd', // assume
'delimiter' => ',', // assume
'import-account' => 0, // none,
'specifics' => [], // none
'column-count' => 0, // unknown
'column-roles' => [], // unknown
'column-do-mapping' => [], // not yet set which columns must be mapped
'column-roles-complete' => false, // not yet configured roles for columns
'column-mapping-config' => [], // no mapping made yet.
'column-mapping-complete' => false, // so mapping is not complete.
];
$this->job->configuration = $config;
$this->job->configuration = config('csv.default_config');
$this->job->save();
return true;
@@ -148,6 +132,7 @@ class CsvSetup implements SetupInterface
* the import job.
*
* @return string
* @throws FireflyException
*/
public function getViewForSettings(): string
{
@@ -158,9 +143,7 @@ class CsvSetup implements SetupInterface
if ($this->doColumnMapping()) {
return 'import.csv.map';
}
echo 'no view for settings';
exit;
throw new FireflyException('There is no view for the current CSV import step.');
}
/**
@@ -171,8 +154,8 @@ class CsvSetup implements SetupInterface
*/
public function requireUserSettings(): bool
{
Log::debug('doColumnMapping is ' . ($this->doColumnMapping() ? 'true' : 'false'));
Log::debug('doColumnRoles is ' . ($this->doColumnRoles() ? 'true' : 'false'));
Log::debug(sprintf('doColumnMapping is %s', $this->doColumnMapping()));
Log::debug(sprintf('doColumnRoles is %s', $this->doColumnRoles()));
if ($this->doColumnMapping() || $this->doColumnRoles()) {
Log::debug('Return true');
@@ -216,7 +199,11 @@ class CsvSetup implements SetupInterface
// loop specifics.
if (isset($data['specifics']) && is_array($data['specifics'])) {
foreach ($data['specifics'] as $name => $enabled) {
$config['specifics'][$name] = 1;
// verify their content.
$className = sprintf('FireflyIII\Import\Specifics\%s', $name);
if (class_exists($className)) {
$config['specifics'][$name] = 1;
}
}
}
$this->job->configuration = $config;
@@ -322,6 +309,7 @@ class CsvSetup implements SetupInterface
/**
* @return array
* @throws FireflyException
*/
private function getDataForColumnMapping(): array
{
@@ -331,11 +319,19 @@ class CsvSetup implements SetupInterface
foreach ($config['column-do-mapping'] as $index => $mustBeMapped) {
if ($mustBeMapped) {
$column = $config['column-roles'][$index] ?? '_ignore';
$column = $config['column-roles'][$index] ?? '_ignore';
// is valid column?
$validColumns = array_keys(config('csv.import_roles'));
if (!in_array($column, $validColumns)) {
throw new FireflyException(sprintf('"%s" is not a valid column.', $column));
}
$canBeMapped = config('csv.import_roles.' . $column . '.mappable');
$preProcessMap = config('csv.import_roles.' . $column . '.pre-process-map');
if ($canBeMapped) {
$mapperName = '\FireflyIII\Import\Mapper\\' . config('csv.import_roles.' . $column . '.mapper');
$mapperClass = config('csv.import_roles.' . $column . '.mapper');
$mapperName = sprintf('\\FireflyIII\\Import\Mapper\\%s', $mapperClass);
/** @var MapperInterface $mapper */
$mapper = new $mapperName;
$indexes[] = $index;
@@ -348,8 +344,11 @@ class CsvSetup implements SetupInterface
'values' => [],
];
if ($preProcessMap) {
$data[$index]['preProcessMap'] = '\FireflyIII\Import\MapperPreProcess\\' .
config('csv.import_roles.' . $column . '.pre-process-mapper');
$preClass = sprintf(
'\\FireflyIII\\Import\\MapperPreProcess\\%s',
config('csv.import_roles.' . $column . '.pre-process-mapper')
);
$data[$index]['preProcessMap'] = $preClass;
}
}
@@ -361,15 +360,21 @@ class CsvSetup implements SetupInterface
/** @var Reader $reader */
$reader = Reader::createFromString($content);
$reader->setDelimiter($config['delimiter']);
$results = $reader->fetch();
$results = $reader->fetch();
$validSpecifics = array_keys(config('csv.import_specifics'));
foreach ($results as $rowIndex => $row) {
// run specifics here:
// and this is the point where the specifix go to work.
foreach ($config['specifics'] as $name => $enabled) {
if (!in_array($name, $validSpecifics)) {
throw new FireflyException(sprintf('"%s" is not a valid class name', $name));
}
$class = config('csv.import_specifics.' . $name);
/** @var SpecificInterface $specific */
$specific = app('FireflyIII\Import\Specifics\\' . $name);
$specific = app($class);
// it returns the row, possibly modified:
$row = $specific->run($row);
@@ -425,7 +430,7 @@ class CsvSetup implements SetupInterface
$reader = Reader::createFromString($content);
$reader->setDelimiter($config['delimiter']);
$start = $config['has-headers'] ? 1 : 0;
$end = $start + self::EXAMPLE_ROWS; // first X rows
$end = $start + config('csv.example_rows');
// collect example data in $data['columns']
while ($start < $end) {

View File

@@ -50,9 +50,15 @@ class AbnAmroDescription implements SpecificInterface
public function run(array $row): array
{
$this->row = $row;
if (!isset($row[7])) {
return $row;
}
// Try to parse the description in known formats.
$parsed = $this->parseSepaDescription() || $this->parseTRTPDescription() || $this->parseGEABEADescription() || $this->parseABNAMRODescription();
// If the description could not be parsed, specify an unknown opposing
// account, as an opposing account is required
if (!$parsed) {

View File

@@ -0,0 +1,112 @@
<?php
/**
* IngDescription.php
* Copyright (C) 2016 thegrumpydictator@gmail.com
*
* This software may be modified and distributed under the terms
* of the MIT license. See the LICENSE file for details.
*/
declare(strict_types = 1);
namespace FireflyIII\Import\Specifics;
/**
* Class IngDescription
*
* Parses the description from CSV files for Ing bank accounts.
*
* With Mutation 'InternetBankieren', 'Overschrijving', 'Verzamelbetaling' and 'Incasso' the
* Name of Opposing account the Opposing IBAN number are in the Description
* This class will remove them
* Add Name in description by 'Betaalautomaat' so those are easily recognizable
*
* @package FireflyIII\Import\Specifics
*/
class IngDescription implements SpecificInterface
{
/** @var array */
public $row;
/**
* @return string
*/
public static function getDescription(): string
{
return 'Create better descriptions in ING import files.';
}
/**
* @return string
*/
public static function getName(): string
{
return 'ING description';
}
/**
* @param array $row
*
* @return array
*/
public function run(array $row): array
{
$this->row = $row;
if (count($this->row) >= 8) { // check if the array is correct
switch ($this->row[4]) { // Get value for the mutation type
case 'GT': // InternetBanieren
case 'OV': // Overschrijving
case 'VZ': // Verzamelbetaling
case 'IC': // Incasso
$this->removeIBANIngDescription();
$this->removeNameIngDescription();
break;
case 'BA' : // Betaalautomaat
$this->addNameIngDescription();
break;
}
}
return $this->row;
}
/**
* Remove IBAN number out of the description
* Default description of Description is: Naam: <OPPOS NAME> Omschrijving: <DESCRIPTION> IBAN: <OPPOS IBAN NR>
*
* @return bool true
*/
protected function removeIBANIngDescription()
{
// Try replace the iban number with nothing. The IBAN nr is found in the third row
$this->row[8] = preg_replace('/\sIBAN:\s'.$this->row[3].'/', '', $this->row[8]);
return true;
}
/**
* Remove name from the description (Remove everything before the description incl the word 'Omschrijving' )
*
* @return bool true
*/
protected function removeNameIngDescription()
{
// Try remove everything bevore the 'Omschrijving'
$this->row[8] = preg_replace('/.+Omschrijving: /', '', $this->row[8]);
return true;
}
/**
* Add the Opposing name from cell 1 in the description for Betaalautomaten
* Otherwise the description is only: 'Pasvolgnr:<nr> <date> Transactie:<NR> Term:<nr>'
*
* @return bool true
*/
protected function addNameIngDescription()
{
$this->row[8] = $this->row[1]. " " . $this->row[8];
return true;
}
}

View File

@@ -0,0 +1,59 @@
<?php
/**
* PresidentsChoice.php
* Copyright (C) 2016 thegrumpydictator@gmail.com
*
* This software may be modified and distributed under the terms
* of the MIT license. See the LICENSE file for details.
*/
declare(strict_types = 1);
namespace FireflyIII\Import\Specifics;
/**
* Class PresidentsChoice
*
* @package FireflyIII\Import\Specifics
*/
class PresidentsChoice implements SpecificInterface
{
/**
* @return string
*/
public static function getDescription(): string
{
return 'Fixes problems with files from Presidents Choice Financial.';
}
/**
* @return string
*/
public static function getName(): string
{
return 'Presidents "Choice"';
}
/**
* @param array $row
*
* @return array
*/
public function run(array $row): array
{
// first, if column 2 is empty and 3 is not, do nothing.
// if column 3 is empty and column 2 is not, move amount to column 3, *-1
if (isset($row[3]) && strlen($row[3]) === 0) {
$row[3] = bcmul($row[2], '-1');
}
if (isset($row[1])) {
// copy description into column 2, which is now usable.
$row[2] = $row[1];
}
return $row;
}
}

View File

@@ -11,7 +11,6 @@ declare(strict_types = 1);
namespace FireflyIII\Models;
use Auth;
use Crypt;
use FireflyIII\Exceptions\FireflyException;
use Illuminate\Contracts\Encryption\DecryptException;
@@ -153,8 +152,8 @@ class Account extends Model
public static function routeBinder(Account $value)
{
if (Auth::check()) {
if ($value->user_id == Auth::user()->id) {
if (auth()->check()) {
if ($value->user_id == auth()->user()->id) {
return $value;
}
}

View File

@@ -11,7 +11,6 @@ declare(strict_types = 1);
namespace FireflyIII\Models;
use Auth;
use Crypt;
use Illuminate\Database\Eloquent\Model;
use Illuminate\Database\Eloquent\Relations\BelongsTo;
@@ -69,9 +68,9 @@ class Attachment extends Model
*/
public static function routeBinder(Attachment $value)
{
if (Auth::check()) {
if (auth()->check()) {
if ($value->user_id == Auth::user()->id) {
if ($value->user_id == auth()->user()->id) {
return $value;
}
}
@@ -105,7 +104,7 @@ class Attachment extends Model
*/
public function getDescriptionAttribute($value)
{
if (is_null($value)) {
if (is_null($value) || strlen($value) === 0) {
return null;
}
@@ -119,7 +118,7 @@ class Attachment extends Model
*/
public function getFilenameAttribute($value)
{
if (is_null($value)) {
if (is_null($value) || strlen($value) === 0) {
return null;
}
@@ -133,7 +132,7 @@ class Attachment extends Model
*/
public function getMimeAttribute($value)
{
if (is_null($value)) {
if (is_null($value) || strlen($value) === 0) {
return null;
}
@@ -148,7 +147,7 @@ class Attachment extends Model
*/
public function getNotesAttribute($value)
{
if (is_null($value)) {
if (is_null($value) || strlen($value) === 0) {
return null;
}
@@ -163,7 +162,7 @@ class Attachment extends Model
*/
public function getTitleAttribute($value)
{
if (is_null($value)) {
if (is_null($value) || strlen($value) === 0) {
return null;
}

View File

@@ -11,7 +11,6 @@ declare(strict_types = 1);
namespace FireflyIII\Models;
use Auth;
use Crypt;
use Illuminate\Database\Eloquent\Model;
use Illuminate\Database\Eloquent\Relations\BelongsTo;
@@ -81,8 +80,8 @@ class Bill extends Model
*/
public static function routeBinder(Bill $value)
{
if (Auth::check()) {
if ($value->user_id == Auth::user()->id) {
if (auth()->check()) {
if ($value->user_id == auth()->user()->id) {
return $value;
}
}

View File

@@ -11,7 +11,6 @@ declare(strict_types = 1);
namespace FireflyIII\Models;
use Auth;
use Crypt;
use Illuminate\Database\Eloquent\Model;
use Illuminate\Database\Eloquent\Relations\BelongsTo;
@@ -94,8 +93,8 @@ class Budget extends Model
*/
public static function routeBinder(Budget $value)
{
if (Auth::check()) {
if ($value->user_id == Auth::user()->id) {
if (auth()->check()) {
if ($value->user_id == auth()->user()->id) {
return $value;
}
}

View File

@@ -11,7 +11,6 @@ declare(strict_types = 1);
namespace FireflyIII\Models;
use Auth;
use Crypt;
use Illuminate\Database\Eloquent\Model;
use Illuminate\Database\Eloquent\Relations\BelongsTo;
@@ -89,8 +88,8 @@ class Category extends Model
*/
public static function routeBinder(Category $value)
{
if (Auth::check()) {
if ($value->user_id == Auth::user()->id) {
if (auth()->check()) {
if ($value->user_id == auth()->user()->id) {
return $value;
}
}

View File

@@ -11,7 +11,6 @@ declare(strict_types = 1);
namespace FireflyIII\Models;
use Auth;
use Illuminate\Database\Eloquent\Model;
use Symfony\Component\HttpKernel\Exception\NotFoundHttpException;
@@ -44,8 +43,8 @@ class ExportJob extends Model
*/
public static function routeBinder($value)
{
if (Auth::check()) {
$model = self::where('key', $value)->where('user_id', Auth::user()->id)->first();
if (auth()->check()) {
$model = self::where('key', $value)->where('user_id', auth()->user()->id)->first();
if (!is_null($model)) {
return $model;
}

Some files were not shown because too many files have changed in this diff Show More