Merge branch 'release/4.7.3'

This commit is contained in:
James Cole
2018-04-28 16:27:55 +02:00
623 changed files with 8226 additions and 3797 deletions

View File

@@ -1,12 +1,14 @@
#!/bin/bash
# make sure we own the volumes:
chown -R www-data:www-data $FIREFLY_PATH/storage/export $FIREFLY_PATH/storage/upload
chmod -R 775 $FIREFLY_PATH/storage/export $FIREFLY_PATH/storage/upload
chown -R www-data:www-data -R $FIREFLY_PATH/storage/export $FIREFLY_PATH/storage/upload $FIREFLY_PATH/storage/logs $FIREFLY_PATH/storage/cache
chmod -R 775 $FIREFLY_PATH/storage/export $FIREFLY_PATH/storage/upload $FIREFLY_PATH/storage/upload $FIREFLY_PATH/storage/logs $FIREFLY_PATH/storage/cache
# remove any lingering files that may break upgrades:
rm -f $FIREFLY_PATH/storage/logs/laravel.log
cat .env.docker | envsubst > .env && cat .env
composer dump-autoload
php artisan optimize
php artisan package:discover
php artisan firefly:instructions install
exec apache2-foreground

View File

@@ -22,7 +22,7 @@ LOG_CHANNEL=${LOG_CHANNEL}
# Database credentials. Make sure the database exists. I recommend a dedicated user for Firefly III
# If you use SQLite, set connection to `sqlite` and remove the database, username and password settings.
DB_CONNECTION=mysql
DB_CONNECTION=${FF_DB_CONNECTION}
DB_HOST=${FF_DB_HOST}
DB_PORT=${FF_DB_PORT}
DB_DATABASE=${FF_DB_NAME}

View File

@@ -54,7 +54,7 @@ COOKIE_DOMAIN=
COOKIE_SECURE=false
# If you want Firefly III to mail you, update these settings
MAIL_DRIVER=smtp
MAIL_DRIVER=log
MAIL_HOST=smtp.mailtrap.io
MAIL_PORT=2525
MAIL_FROM=changeme@example.com

View File

@@ -54,7 +54,7 @@ COOKIE_DOMAIN=
COOKIE_SECURE=false
# If you want Firefly III to mail you, update these settings
MAIL_DRIVER=smtp
MAIL_DRIVER=log
MAIL_HOST=smtp.mailtrap.io
MAIL_PORT=2525
MAIL_FROM=changeme@example.com

View File

@@ -54,7 +54,7 @@ COOKIE_DOMAIN=
COOKIE_SECURE=false
# If you want Firefly III to mail you, update these settings
MAIL_DRIVER=smtp
MAIL_DRIVER=log
MAIL_HOST=smtp.mailtrap.io
MAIL_PORT=2525
MAIL_FROM=changeme@example.com

55
.github/stale.yml vendored Normal file
View File

@@ -0,0 +1,55 @@
# Configuration for probot-stale - https://github.com/probot/stale
# Number of days of inactivity before an Issue or Pull Request becomes stale
daysUntilStale: 30
# Number of days of inactivity before a stale Issue or Pull Request is closed.
# Set to false to disable. If disabled, issues still need to be closed manually, but will remain marked as stale.
daysUntilClose: 7
# Issues or Pull Requests with these labels will never be considered stale. Set to `[]` to disable
# - "[Status] Maybe Later"
exemptLabels:
- enhancement
- feature
# Set to true to ignore issues in a project (defaults to false)
exemptProjects: false
# Set to true to ignore issues in a milestone (defaults to false)
exemptMilestones: false
# Label to use when marking as stale
staleLabel: stale
# Comment to post when marking as stale. Set to `false` to disable
markComment: >
This issue has been automatically marked as stale because it has not had
recent activity. It will be closed if no further activity occurs. Thank you
for your contributions.
# Comment to post when removing the stale label.
# unmarkComment: >
# Your comment here.
# Comment to post when closing a stale Issue or Pull Request.
# closeComment: >
# Your comment here.
# Limit the number of actions per hour, from 1-30. Default is 30
limitPerRun: 30
# Limit to only `issues` or `pulls`
# only: issues
# Optionally, specify configuration settings that are specific to just 'issues' or 'pulls':
# pulls:
# daysUntilStale: 30
# markComment: >
# This pull request has been automatically marked as stale because it has not had
# recent activity. It will be closed if no further activity occurs. Thank you
# for your contributions.
# issues:
# exemptLabels:
# - confirmed

View File

@@ -1,3 +1,42 @@
# 4.7.3
- Currency added to API
- Firfely III will also generate a cash wallet for new users.
- Can now reset Spectre and bunq settings
- Docker file has a time zone
- Allow database connection to be configured in Docker file
- Can now view and edit attachments in edit-screen
- User can visit hidden `/attachments` page
- [Issue 1356](https://github.com/firefly-iii/firefly-iii/issues/1356): Budgets will show the remaining amount per day
- [Issue 1367](https://github.com/firefly-iii/firefly-iii/issues/1367): Rules now come in strict and non-strict mode.
- Added a security.txt
- More support for trusted proxies
- Improved edit routine for split transactions.
- Upgrade routine can handle `proc_close` being disabled.
- Bills now use rules to match transactions, making it more flexible.
- [Issue 1328](https://github.com/firefly-iii/firefly-iii/issues/1328): piggy banks no have a more useful chart.
- Spectre API upgraded to v4
- Move to MariaDB ([issue 1366](https://github.com/firefly-iii/firefly-iii/issues/1366))
- Piggy banks take currency from parent account ([issue 1334](https://github.com/firefly-iii/firefly-iii/issues/1334))
- [Issue 1341](https://github.com/firefly-iii/firefly-iii/issues/1341): Removed depricated command from dockerfile
- Several issues with docker image ([issue 1320](https://github.com/firefly-iii/firefly-iii/issues/1320), [issue 1382](https://github.com/firefly-iii/firefly-iii/issues/1382)).
- Fix giant tags and division by zero ([issue 1325](https://github.com/firefly-iii/firefly-iii/issues/1325) and others)
- Several issues with bunq import ([issue 1352](https://github.com/firefly-iii/firefly-iii/issues/1352), [issue 1330](https://github.com/firefly-iii/firefly-iii/issues/1330), [issue 1378](https://github.com/firefly-iii/firefly-iii/issues/1378), [issue 1380](https://github.com/firefly-iii/firefly-iii/issues/1380))
- [Issue 1246](https://github.com/firefly-iii/firefly-iii/issues/1246): date picker is internationalised
- [Issue 1327](https://github.com/firefly-iii/firefly-iii/issues/1327): fix formattting issues in piggy banks
- [Issue 1348](https://github.com/firefly-iii/firefly-iii/issues/1348): 500 error in API
- [Issue 1349](https://github.com/firefly-iii/firefly-iii/issues/1349): Errors in import routine
- Several fixes for (multi-currency) reconciliation ([issue 1336](https://github.com/firefly-iii/firefly-iii/issues/1336), [issue 1363](https://github.com/firefly-iii/firefly-iii/issues/1363))
- [Issue 1353](https://github.com/firefly-iii/firefly-iii/issues/1353): return NULL values in range-indicator
- Bug in split transaction edit routine
- Piggy bank percentage was very specific.
- Logging in Slack is easier to config.
- [Issue 1312](https://github.com/firefly-iii/firefly-iii/issues/1312) Import broken for ING accounts
- [Issue 1313](https://github.com/firefly-iii/firefly-iii/issues/1313) Error when creating new asset account
- [Issue 1317](https://github.com/firefly-iii/firefly-iii/issues/1317) Forgot an include :(
- Null pointer exception in transaction overview.
- Installations running in subdirs were incapable of creating OAuth tokens.
- OAuth keys were not created in all cases.
# 4.7.2
- [Issue 1123](https://github.com/firefly-iii/firefly-iii/issues/1123) First browser based update routine.
- Add support for Italian.
@@ -40,8 +79,6 @@
- [Issue 1297](https://github.com/firefly-iii/firefly-iii/issues/1297) Could not convert to withdrawal
- [Issue 1226](https://github.com/firefly-iii/firefly-iii/issues/1226) Category overview in default report shows no income.
- Various other bugs and problems ([issue 1198](https://github.com/firefly-iii/firefly-iii/issues/1198), [issue 1213](https://github.com/firefly-iii/firefly-iii/issues/1213), [issue 1237](https://github.com/firefly-iii/firefly-iii/issues/1237), [issue 1238](https://github.com/firefly-iii/firefly-iii/issues/1238), [issue 1199](https://github.com/firefly-iii/firefly-iii/issues/1199), [issue 1200](https://github.com/firefly-iii/firefly-iii/issues/1200))
### Security
- Fixed an issue with token validation on the command line.
# 4.7.1

View File

@@ -202,7 +202,6 @@ lib/x86_64-linux-gnu/libz.so.1.2.8
lib64/ld-linux-x86-64.so.2
opt/app/.codeclimate.yml
opt/app/.env
opt/app/.env.current
opt/app/.env.docker
opt/app/.env.example
opt/app/.env.heroku
@@ -341,12 +340,14 @@ opt/app/app/Helpers/Collection/Category.php
opt/app/app/Helpers/Collector/JournalCollector.php
opt/app/app/Helpers/Collector/JournalCollectorInterface.php
opt/app/app/Helpers/Filter/AmountFilter.php
opt/app/app/Helpers/Filter/CountAttachmentsFilter.php
opt/app/app/Helpers/Filter/EmptyFilter.php
opt/app/app/Helpers/Filter/FilterInterface.php
opt/app/app/Helpers/Filter/InternalTransferFilter.php
opt/app/app/Helpers/Filter/NegativeAmountFilter.php
opt/app/app/Helpers/Filter/OpposingAccountFilter.php
opt/app/app/Helpers/Filter/PositiveAmountFilter.php
opt/app/app/Helpers/Filter/SplitIndicatorFilter.php
opt/app/app/Helpers/Filter/TransferFilter.php
opt/app/app/Helpers/FiscalHelper.php
opt/app/app/Helpers/FiscalHelperInterface.php
@@ -418,6 +419,7 @@ opt/app/app/Http/Controllers/ReportController.php
opt/app/app/Http/Controllers/RuleController.php
opt/app/app/Http/Controllers/RuleGroupController.php
opt/app/app/Http/Controllers/SearchController.php
opt/app/app/Http/Controllers/System/InstallController.php
opt/app/app/Http/Controllers/TagController.php
opt/app/app/Http/Controllers/Transaction/BulkController.php
opt/app/app/Http/Controllers/Transaction/ConvertController.php
@@ -431,6 +433,7 @@ opt/app/app/Http/Middleware/Authenticate.php
opt/app/app/Http/Middleware/AuthenticateTwoFactor.php
opt/app/app/Http/Middleware/Binder.php
opt/app/app/Http/Middleware/EncryptCookies.php
opt/app/app/Http/Middleware/Installer.php
opt/app/app/Http/Middleware/IsAdmin.php
opt/app/app/Http/Middleware/IsDemoUser.php
opt/app/app/Http/Middleware/IsSandStormUser.php
@@ -475,6 +478,7 @@ opt/app/app/Http/Requests/TestRuleFormRequest.php
opt/app/app/Http/Requests/TokenFormRequest.php
opt/app/app/Http/Requests/UserFormRequest.php
opt/app/app/Http/Requests/UserRegistrationRequest.php
opt/app/app/Import/Configuration/BunqConfigurator.php
opt/app/app/Import/Configuration/ConfiguratorInterface.php
opt/app/app/Import/Configuration/FileConfigurator.php
opt/app/app/Import/Configuration/SpectreConfigurator.php
@@ -510,6 +514,7 @@ opt/app/app/Import/Prerequisites/BunqPrerequisites.php
opt/app/app/Import/Prerequisites/FilePrerequisites.php
opt/app/app/Import/Prerequisites/PrerequisitesInterface.php
opt/app/app/Import/Prerequisites/SpectrePrerequisites.php
opt/app/app/Import/Routine/BunqRoutine.php
opt/app/app/Import/Routine/FileRoutine.php
opt/app/app/Import/Routine/RoutineInterface.php
opt/app/app/Import/Routine/SpectreRoutine.php
@@ -605,8 +610,6 @@ opt/app/app/Repositories/ImportJob/ImportJobRepository.php
opt/app/app/Repositories/ImportJob/ImportJobRepositoryInterface.php
opt/app/app/Repositories/Journal/JournalRepository.php
opt/app/app/Repositories/Journal/JournalRepositoryInterface.php
opt/app/app/Repositories/Journal/JournalTasker.php
opt/app/app/Repositories/Journal/JournalTaskerInterface.php
opt/app/app/Repositories/LinkType/LinkTypeRepository.php
opt/app/app/Repositories/LinkType/LinkTypeRepositoryInterface.php
opt/app/app/Repositories/PiggyBank/PiggyBankRepository.php
@@ -633,10 +636,14 @@ opt/app/app/Services/Bunq/Object/Amount.php
opt/app/app/Services/Bunq/Object/Avatar.php
opt/app/app/Services/Bunq/Object/BunqObject.php
opt/app/app/Services/Bunq/Object/DeviceServer.php
opt/app/app/Services/Bunq/Object/Image.php
opt/app/app/Services/Bunq/Object/LabelMonetaryAccount.php
opt/app/app/Services/Bunq/Object/LabelUser.php
opt/app/app/Services/Bunq/Object/MonetaryAccountBank.php
opt/app/app/Services/Bunq/Object/MonetaryAccountProfile.php
opt/app/app/Services/Bunq/Object/MonetaryAccountSetting.php
opt/app/app/Services/Bunq/Object/NotificationFilter.php
opt/app/app/Services/Bunq/Object/Payment.php
opt/app/app/Services/Bunq/Object/ServerPublicKey.php
opt/app/app/Services/Bunq/Object/UserCompany.php
opt/app/app/Services/Bunq/Object/UserLight.php
@@ -648,28 +655,36 @@ opt/app/app/Services/Bunq/Request/DeviceSessionRequest.php
opt/app/app/Services/Bunq/Request/InstallationTokenRequest.php
opt/app/app/Services/Bunq/Request/ListDeviceServerRequest.php
opt/app/app/Services/Bunq/Request/ListMonetaryAccountRequest.php
opt/app/app/Services/Bunq/Request/ListPaymentRequest.php
opt/app/app/Services/Bunq/Request/ListUserRequest.php
opt/app/app/Services/Bunq/Token/BunqToken.php
opt/app/app/Services/Bunq/Token/InstallationToken.php
opt/app/app/Services/Bunq/Token/SessionToken.php
opt/app/app/Services/Currency/ExchangeRateInterface.php
opt/app/app/Services/Currency/FixerIO.php
opt/app/app/Services/Currency/FixerIOv2.php
opt/app/app/Services/Github/Object/GithubObject.php
opt/app/app/Services/Github/Object/Release.php
opt/app/app/Services/Github/Request/GithubRequest.php
opt/app/app/Services/Github/Request/UpdateRequest.php
opt/app/app/Services/Internal/Destroy/AccountDestroyService.php
opt/app/app/Services/Internal/Destroy/BillDestroyService.php
opt/app/app/Services/Internal/Destroy/CategoryDestroyService.php
opt/app/app/Services/Internal/Destroy/CurrencyDestroyService.php
opt/app/app/Services/Internal/Destroy/JournalDestroyService.php
opt/app/app/Services/Internal/File/EncryptService.php
opt/app/app/Services/Internal/Support/AccountServiceTrait.php
opt/app/app/Services/Internal/Support/BillServiceTrait.php
opt/app/app/Services/Internal/Support/JournalServiceTrait.php
opt/app/app/Services/Internal/Support/TransactionServiceTrait.php
opt/app/app/Services/Internal/Update/AccountUpdateService.php
opt/app/app/Services/Internal/Update/BillUpdateService.php
opt/app/app/Services/Internal/Update/CategoryUpdateService.php
opt/app/app/Services/Internal/Update/CurrencyUpdateService.php
opt/app/app/Services/Internal/Update/JournalUpdateService.php
opt/app/app/Services/Internal/Update/TransactionUpdateService.php
opt/app/app/Services/Password/PwndVerifier.php
opt/app/app/Services/Password/PwndVerifierV2.php
opt/app/app/Services/Password/Verifier.php
opt/app/app/Services/Spectre/Exception/DuplicatedCustomerException.php
opt/app/app/Services/Spectre/Exception/SpectreException.php
@@ -711,6 +726,7 @@ opt/app/app/Support/Facades/Navigation.php
opt/app/app/Support/Facades/Preferences.php
opt/app/app/Support/Facades/Steam.php
opt/app/app/Support/FireflyConfig.php
opt/app/app/Support/Import/Configuration/Bunq/HaveAccounts.php
opt/app/app/Support/Import/Configuration/ConfigurationInterface.php
opt/app/app/Support/Import/Configuration/File/Initial.php
opt/app/app/Support/Import/Configuration/File/Map.php
@@ -824,8 +840,10 @@ opt/app/config/database.php
opt/app/config/filesystems.php
opt/app/config/firefly.php
opt/app/config/google2fa.php
opt/app/config/hashing.php
opt/app/config/import.php
opt/app/config/intro.php
opt/app/config/logging.php
opt/app/config/mail.php
opt/app/config/queue.php
opt/app/config/services.php
@@ -834,6 +852,7 @@ opt/app/config/twigbridge.php
opt/app/config/upgrade.php
opt/app/config/view.php
opt/app/database/factories/ModelFactory.php
opt/app/database/migrations
opt/app/database/migrations/2016_06_16_000000_create_support_tables.php
opt/app/database/migrations/2016_06_16_000001_create_users_table.php
opt/app/database/migrations/2016_06_16_000002_create_main_tables.php
@@ -853,7 +872,9 @@ opt/app/database/migrations/2018_01_01_000002_create_oauth_access_tokens_table.p
opt/app/database/migrations/2018_01_01_000003_create_oauth_refresh_tokens_table.php
opt/app/database/migrations/2018_01_01_000004_create_oauth_clients_table.php
opt/app/database/migrations/2018_01_01_000005_create_oauth_personal_access_clients_table.php
opt/app/database/migrations/2018_03_19_141348_changes_for_v472.php
opt/app/database/seeds/AccountTypeSeeder.php
opt/app/database/seeds/ConfigSeeder.php
opt/app/database/seeds/DatabaseSeeder.php
opt/app/database/seeds/LinkTypeSeeder.php
opt/app/database/seeds/PermissionSeeder.php
@@ -1046,6 +1067,7 @@ opt/app/public/js/ff/guest.js
opt/app/public/js/ff/help.js
opt/app/public/js/ff/import/status.js
opt/app/public/js/ff/index.js
opt/app/public/js/ff/install/index.js
opt/app/public/js/ff/intro/intro.js
opt/app/public/js/ff/piggy-banks/create.js
opt/app/public/js/ff/piggy-banks/edit.js
@@ -1085,6 +1107,7 @@ opt/app/public/js/lib/bootstrap-sortable.js
opt/app/public/js/lib/bootstrap-tagsinput.min.js
opt/app/public/js/lib/bootstrap-tagsinput.min.js.map
opt/app/public/js/lib/bootstrap3-typeahead.min.js
opt/app/public/js/lib/chartjs-plugin-annotation.min.js
opt/app/public/js/lib/daterangepicker.js
opt/app/public/js/lib/html5shiv.min.js
opt/app/public/js/lib/jquery-ui.min.js
@@ -1115,7 +1138,6 @@ opt/app/public/lib/leaflet/leaflet.js.map
opt/app/public/manifest.json
opt/app/public/mix-manifest.json
opt/app/public/mstile-150x150.png
opt/app/public/report.html
opt/app/public/robots.txt
opt/app/public/safari-pinned-tab.svg
opt/app/public/web.config
@@ -1128,7 +1150,6 @@ opt/app/resources/assets/js/components/passport/AuthorizedClients.vue
opt/app/resources/assets/js/components/passport/Clients.vue
opt/app/resources/assets/js/components/passport/PersonalAccessTokens.vue
opt/app/resources/assets/js/lang.js
opt/app/resources/assets/js/messages.js
opt/app/resources/assets/sass/_variables.scss
opt/app/resources/assets/sass/app.scss
opt/app/resources/lang/de_DE/auth.php
@@ -1208,6 +1229,21 @@ opt/app/resources/lang/id_ID/list.php
opt/app/resources/lang/id_ID/pagination.php
opt/app/resources/lang/id_ID/passwords.php
opt/app/resources/lang/id_ID/validation.php
opt/app/resources/lang/it_IT/auth.php
opt/app/resources/lang/it_IT/bank.php
opt/app/resources/lang/it_IT/breadcrumbs.php
opt/app/resources/lang/it_IT/components.php
opt/app/resources/lang/it_IT/config.php
opt/app/resources/lang/it_IT/csv.php
opt/app/resources/lang/it_IT/demo.php
opt/app/resources/lang/it_IT/firefly.php
opt/app/resources/lang/it_IT/form.php
opt/app/resources/lang/it_IT/import.php
opt/app/resources/lang/it_IT/intro.php
opt/app/resources/lang/it_IT/list.php
opt/app/resources/lang/it_IT/pagination.php
opt/app/resources/lang/it_IT/passwords.php
opt/app/resources/lang/it_IT/validation.php
opt/app/resources/lang/nl_NL/auth.php
opt/app/resources/lang/nl_NL/bank.php
opt/app/resources/lang/nl_NL/breadcrumbs.php
@@ -1289,7 +1325,6 @@ opt/app/resources/stubs/binary.bin
opt/app/resources/stubs/csv.csv
opt/app/resources/stubs/demo-configuration.json
opt/app/resources/stubs/demo-import.csv
opt/app/resources/tests/blns.base64.json
opt/app/resources/views/accounts/create.twig
opt/app/resources/views/accounts/delete.twig
opt/app/resources/views/accounts/edit.twig
@@ -1400,6 +1435,7 @@ opt/app/resources/views/form/tags.twig
opt/app/resources/views/form/text.twig
opt/app/resources/views/form/textarea.twig
opt/app/resources/views/import/bank/form.twig
opt/app/resources/views/import/bunq/accounts.twig
opt/app/resources/views/import/bunq/prerequisites.twig
opt/app/resources/views/import/file/initial.twig
opt/app/resources/views/import/file/map.twig
@@ -1411,6 +1447,7 @@ opt/app/resources/views/import/spectre/prerequisites.twig
opt/app/resources/views/import/spectre/redirect.twig
opt/app/resources/views/import/status.twig
opt/app/resources/views/index.twig
opt/app/resources/views/install/index.twig
opt/app/resources/views/javascript/accounts.twig
opt/app/resources/views/javascript/currencies.twig
opt/app/resources/views/javascript/variables.twig
@@ -1418,6 +1455,7 @@ opt/app/resources/views/json/piggy-banks.twig
opt/app/resources/views/layout/default.twig
opt/app/resources/views/layout/empty.twig
opt/app/resources/views/layout/guest.twig
opt/app/resources/views/layout/install.twig
opt/app/resources/views/list/accounts.twig
opt/app/resources/views/list/bills.twig
opt/app/resources/views/list/categories.twig
@@ -1451,10 +1489,10 @@ opt/app/resources/views/popup/report/budget-spent-amount.twig
opt/app/resources/views/popup/report/category-entry.twig
opt/app/resources/views/popup/report/expense-entry.twig
opt/app/resources/views/popup/report/income-entry.twig
opt/app/resources/views/preferences/code.twig
opt/app/resources/views/preferences/index.twig
opt/app/resources/views/profile/change-email.twig
opt/app/resources/views/profile/change-password.twig
opt/app/resources/views/profile/code.twig
opt/app/resources/views/profile/delete-account.twig
opt/app/resources/views/profile/index.twig
opt/app/resources/views/reports/account/report.twig
@@ -1523,6 +1561,7 @@ opt/app/routes/breadcrumbs.php
opt/app/routes/channels.php
opt/app/routes/console.php
opt/app/routes/web.php
opt/app/security.txt
opt/app/server.php
opt/app/storage
opt/app/vendor/autoload.php
@@ -1801,6 +1840,7 @@ opt/app/vendor/doctrine/dbal/lib/Doctrine/DBAL/Cache/ArrayStatement.php
opt/app/vendor/doctrine/dbal/lib/Doctrine/DBAL/Cache/CacheException.php
opt/app/vendor/doctrine/dbal/lib/Doctrine/DBAL/Cache/QueryCacheProfile.php
opt/app/vendor/doctrine/dbal/lib/Doctrine/DBAL/Cache/ResultCacheStatement.php
opt/app/vendor/doctrine/dbal/lib/Doctrine/DBAL/ColumnCase.php
opt/app/vendor/doctrine/dbal/lib/Doctrine/DBAL/Configuration.php
opt/app/vendor/doctrine/dbal/lib/Doctrine/DBAL/Connection.php
opt/app/vendor/doctrine/dbal/lib/Doctrine/DBAL/ConnectionException.php
@@ -1856,6 +1896,7 @@ opt/app/vendor/doctrine/dbal/lib/Doctrine/DBAL/Driver/SQLSrv/SQLSrvException.php
opt/app/vendor/doctrine/dbal/lib/Doctrine/DBAL/Driver/SQLSrv/SQLSrvStatement.php
opt/app/vendor/doctrine/dbal/lib/Doctrine/DBAL/Driver/ServerInfoAwareConnection.php
opt/app/vendor/doctrine/dbal/lib/Doctrine/DBAL/Driver/Statement.php
opt/app/vendor/doctrine/dbal/lib/Doctrine/DBAL/Driver/StatementIterator.php
opt/app/vendor/doctrine/dbal/lib/Doctrine/DBAL/DriverManager.php
opt/app/vendor/doctrine/dbal/lib/Doctrine/DBAL/Event/ConnectionEventArgs.php
opt/app/vendor/doctrine/dbal/lib/Doctrine/DBAL/Event/Listeners/MysqlSessionInit.php
@@ -1892,6 +1933,7 @@ opt/app/vendor/doctrine/dbal/lib/Doctrine/DBAL/Exception/SyntaxErrorException.ph
opt/app/vendor/doctrine/dbal/lib/Doctrine/DBAL/Exception/TableExistsException.php
opt/app/vendor/doctrine/dbal/lib/Doctrine/DBAL/Exception/TableNotFoundException.php
opt/app/vendor/doctrine/dbal/lib/Doctrine/DBAL/Exception/UniqueConstraintViolationException.php
opt/app/vendor/doctrine/dbal/lib/Doctrine/DBAL/FetchMode.php
opt/app/vendor/doctrine/dbal/lib/Doctrine/DBAL/Id/TableGenerator.php
opt/app/vendor/doctrine/dbal/lib/Doctrine/DBAL/Id/TableGeneratorSchemaVisitor.php
opt/app/vendor/doctrine/dbal/lib/Doctrine/DBAL/LockMode.php
@@ -1899,16 +1941,20 @@ opt/app/vendor/doctrine/dbal/lib/Doctrine/DBAL/Logging/DebugStack.php
opt/app/vendor/doctrine/dbal/lib/Doctrine/DBAL/Logging/EchoSQLLogger.php
opt/app/vendor/doctrine/dbal/lib/Doctrine/DBAL/Logging/LoggerChain.php
opt/app/vendor/doctrine/dbal/lib/Doctrine/DBAL/Logging/SQLLogger.php
opt/app/vendor/doctrine/dbal/lib/Doctrine/DBAL/ParameterType.php
opt/app/vendor/doctrine/dbal/lib/Doctrine/DBAL/Platforms/AbstractPlatform.php
opt/app/vendor/doctrine/dbal/lib/Doctrine/DBAL/Platforms/DB2Platform.php
opt/app/vendor/doctrine/dbal/lib/Doctrine/DBAL/Platforms/DateIntervalUnit.php
opt/app/vendor/doctrine/dbal/lib/Doctrine/DBAL/Platforms/DrizzlePlatform.php
opt/app/vendor/doctrine/dbal/lib/Doctrine/DBAL/Platforms/Keywords/DB2Keywords.php
opt/app/vendor/doctrine/dbal/lib/Doctrine/DBAL/Platforms/Keywords/DrizzleKeywords.php
opt/app/vendor/doctrine/dbal/lib/Doctrine/DBAL/Platforms/Keywords/KeywordList.php
opt/app/vendor/doctrine/dbal/lib/Doctrine/DBAL/Platforms/Keywords/MariaDb102Keywords.php
opt/app/vendor/doctrine/dbal/lib/Doctrine/DBAL/Platforms/Keywords/MsSQLKeywords.php
opt/app/vendor/doctrine/dbal/lib/Doctrine/DBAL/Platforms/Keywords/MySQL57Keywords.php
opt/app/vendor/doctrine/dbal/lib/Doctrine/DBAL/Platforms/Keywords/MySQLKeywords.php
opt/app/vendor/doctrine/dbal/lib/Doctrine/DBAL/Platforms/Keywords/OracleKeywords.php
opt/app/vendor/doctrine/dbal/lib/Doctrine/DBAL/Platforms/Keywords/PostgreSQL100Keywords.php
opt/app/vendor/doctrine/dbal/lib/Doctrine/DBAL/Platforms/Keywords/PostgreSQL91Keywords.php
opt/app/vendor/doctrine/dbal/lib/Doctrine/DBAL/Platforms/Keywords/PostgreSQL92Keywords.php
opt/app/vendor/doctrine/dbal/lib/Doctrine/DBAL/Platforms/Keywords/PostgreSQL94Keywords.php
@@ -1923,9 +1969,11 @@ opt/app/vendor/doctrine/dbal/lib/Doctrine/DBAL/Platforms/Keywords/SQLServer2008K
opt/app/vendor/doctrine/dbal/lib/Doctrine/DBAL/Platforms/Keywords/SQLServer2012Keywords.php
opt/app/vendor/doctrine/dbal/lib/Doctrine/DBAL/Platforms/Keywords/SQLServerKeywords.php
opt/app/vendor/doctrine/dbal/lib/Doctrine/DBAL/Platforms/Keywords/SQLiteKeywords.php
opt/app/vendor/doctrine/dbal/lib/Doctrine/DBAL/Platforms/MariaDb1027Platform.php
opt/app/vendor/doctrine/dbal/lib/Doctrine/DBAL/Platforms/MySQL57Platform.php
opt/app/vendor/doctrine/dbal/lib/Doctrine/DBAL/Platforms/MySqlPlatform.php
opt/app/vendor/doctrine/dbal/lib/Doctrine/DBAL/Platforms/OraclePlatform.php
opt/app/vendor/doctrine/dbal/lib/Doctrine/DBAL/Platforms/PostgreSQL100Platform.php
opt/app/vendor/doctrine/dbal/lib/Doctrine/DBAL/Platforms/PostgreSQL91Platform.php
opt/app/vendor/doctrine/dbal/lib/Doctrine/DBAL/Platforms/PostgreSQL92Platform.php
opt/app/vendor/doctrine/dbal/lib/Doctrine/DBAL/Platforms/PostgreSQL94Platform.php
@@ -1940,6 +1988,7 @@ opt/app/vendor/doctrine/dbal/lib/Doctrine/DBAL/Platforms/SQLServer2008Platform.p
opt/app/vendor/doctrine/dbal/lib/Doctrine/DBAL/Platforms/SQLServer2012Platform.php
opt/app/vendor/doctrine/dbal/lib/Doctrine/DBAL/Platforms/SQLServerPlatform.php
opt/app/vendor/doctrine/dbal/lib/Doctrine/DBAL/Platforms/SqlitePlatform.php
opt/app/vendor/doctrine/dbal/lib/Doctrine/DBAL/Platforms/TrimMode.php
opt/app/vendor/doctrine/dbal/lib/Doctrine/DBAL/Portability/Connection.php
opt/app/vendor/doctrine/dbal/lib/Doctrine/DBAL/Portability/Statement.php
opt/app/vendor/doctrine/dbal/lib/Doctrine/DBAL/Query/Expression/CompositeExpression.php
@@ -2000,6 +2049,7 @@ opt/app/vendor/doctrine/dbal/lib/Doctrine/DBAL/Tools/Console/Command/ReservedWor
opt/app/vendor/doctrine/dbal/lib/Doctrine/DBAL/Tools/Console/Command/RunSqlCommand.php
opt/app/vendor/doctrine/dbal/lib/Doctrine/DBAL/Tools/Console/ConsoleRunner.php
opt/app/vendor/doctrine/dbal/lib/Doctrine/DBAL/Tools/Console/Helper/ConnectionHelper.php
opt/app/vendor/doctrine/dbal/lib/Doctrine/DBAL/TransactionIsolationLevel.php
opt/app/vendor/doctrine/dbal/lib/Doctrine/DBAL/Types/ArrayType.php
opt/app/vendor/doctrine/dbal/lib/Doctrine/DBAL/Types/BigIntType.php
opt/app/vendor/doctrine/dbal/lib/Doctrine/DBAL/Types/BinaryType.php
@@ -2020,6 +2070,8 @@ opt/app/vendor/doctrine/dbal/lib/Doctrine/DBAL/Types/IntegerType.php
opt/app/vendor/doctrine/dbal/lib/Doctrine/DBAL/Types/JsonArrayType.php
opt/app/vendor/doctrine/dbal/lib/Doctrine/DBAL/Types/JsonType.php
opt/app/vendor/doctrine/dbal/lib/Doctrine/DBAL/Types/ObjectType.php
opt/app/vendor/doctrine/dbal/lib/Doctrine/DBAL/Types/PhpDateTimeMappingType.php
opt/app/vendor/doctrine/dbal/lib/Doctrine/DBAL/Types/PhpIntegerMappingType.php
opt/app/vendor/doctrine/dbal/lib/Doctrine/DBAL/Types/SimpleArrayType.php
opt/app/vendor/doctrine/dbal/lib/Doctrine/DBAL/Types/SmallIntType.php
opt/app/vendor/doctrine/dbal/lib/Doctrine/DBAL/Types/StringType.php
@@ -2039,6 +2091,28 @@ opt/app/vendor/doctrine/lexer/LICENSE
opt/app/vendor/doctrine/lexer/README.md
opt/app/vendor/doctrine/lexer/composer.json
opt/app/vendor/doctrine/lexer/lib/Doctrine/Common/Lexer/AbstractLexer.php
opt/app/vendor/dragonmantank/cron-expression/.editorconfig
opt/app/vendor/dragonmantank/cron-expression/CHANGELOG.md
opt/app/vendor/dragonmantank/cron-expression/LICENSE
opt/app/vendor/dragonmantank/cron-expression/README.md
opt/app/vendor/dragonmantank/cron-expression/composer.json
opt/app/vendor/dragonmantank/cron-expression/src/Cron/AbstractField.php
opt/app/vendor/dragonmantank/cron-expression/src/Cron/CronExpression.php
opt/app/vendor/dragonmantank/cron-expression/src/Cron/DayOfMonthField.php
opt/app/vendor/dragonmantank/cron-expression/src/Cron/DayOfWeekField.php
opt/app/vendor/dragonmantank/cron-expression/src/Cron/FieldFactory.php
opt/app/vendor/dragonmantank/cron-expression/src/Cron/FieldInterface.php
opt/app/vendor/dragonmantank/cron-expression/src/Cron/HoursField.php
opt/app/vendor/dragonmantank/cron-expression/src/Cron/MinutesField.php
opt/app/vendor/dragonmantank/cron-expression/src/Cron/MonthField.php
opt/app/vendor/dragonmantank/cron-expression/tests/Cron/AbstractFieldTest.php
opt/app/vendor/dragonmantank/cron-expression/tests/Cron/CronExpressionTest.php
opt/app/vendor/dragonmantank/cron-expression/tests/Cron/DayOfMonthFieldTest.php
opt/app/vendor/dragonmantank/cron-expression/tests/Cron/DayOfWeekFieldTest.php
opt/app/vendor/dragonmantank/cron-expression/tests/Cron/FieldFactoryTest.php
opt/app/vendor/dragonmantank/cron-expression/tests/Cron/HoursFieldTest.php
opt/app/vendor/dragonmantank/cron-expression/tests/Cron/MinutesFieldTest.php
opt/app/vendor/dragonmantank/cron-expression/tests/Cron/MonthFieldTest.php
opt/app/vendor/egulias/email-validator/EmailValidator/EmailLexer.php
opt/app/vendor/egulias/email-validator/EmailValidator/EmailParser.php
opt/app/vendor/egulias/email-validator/EmailValidator/EmailValidator.php
@@ -2323,15 +2397,17 @@ opt/app/vendor/laravel/framework/src/Illuminate/Console/Events/CommandStarting.p
opt/app/vendor/laravel/framework/src/Illuminate/Console/GeneratorCommand.php
opt/app/vendor/laravel/framework/src/Illuminate/Console/OutputStyle.php
opt/app/vendor/laravel/framework/src/Illuminate/Console/Parser.php
opt/app/vendor/laravel/framework/src/Illuminate/Console/Scheduling/CacheMutex.php
opt/app/vendor/laravel/framework/src/Illuminate/Console/Scheduling/CacheEventMutex.php
opt/app/vendor/laravel/framework/src/Illuminate/Console/Scheduling/CacheSchedulingMutex.php
opt/app/vendor/laravel/framework/src/Illuminate/Console/Scheduling/CallbackEvent.php
opt/app/vendor/laravel/framework/src/Illuminate/Console/Scheduling/CommandBuilder.php
opt/app/vendor/laravel/framework/src/Illuminate/Console/Scheduling/Event.php
opt/app/vendor/laravel/framework/src/Illuminate/Console/Scheduling/EventMutex.php
opt/app/vendor/laravel/framework/src/Illuminate/Console/Scheduling/ManagesFrequencies.php
opt/app/vendor/laravel/framework/src/Illuminate/Console/Scheduling/Mutex.php
opt/app/vendor/laravel/framework/src/Illuminate/Console/Scheduling/Schedule.php
opt/app/vendor/laravel/framework/src/Illuminate/Console/Scheduling/ScheduleFinishCommand.php
opt/app/vendor/laravel/framework/src/Illuminate/Console/Scheduling/ScheduleRunCommand.php
opt/app/vendor/laravel/framework/src/Illuminate/Console/Scheduling/SchedulingMutex.php
opt/app/vendor/laravel/framework/src/Illuminate/Console/composer.json
opt/app/vendor/laravel/framework/src/Illuminate/Container/BoundMethod.php
opt/app/vendor/laravel/framework/src/Illuminate/Container/Container.php
@@ -2382,7 +2458,6 @@ opt/app/vendor/laravel/framework/src/Illuminate/Contracts/Filesystem/Filesystem.
opt/app/vendor/laravel/framework/src/Illuminate/Contracts/Foundation/Application.php
opt/app/vendor/laravel/framework/src/Illuminate/Contracts/Hashing/Hasher.php
opt/app/vendor/laravel/framework/src/Illuminate/Contracts/Http/Kernel.php
opt/app/vendor/laravel/framework/src/Illuminate/Contracts/Logging/Log.php
opt/app/vendor/laravel/framework/src/Illuminate/Contracts/Mail/MailQueue.php
opt/app/vendor/laravel/framework/src/Illuminate/Contracts/Mail/Mailable.php
opt/app/vendor/laravel/framework/src/Illuminate/Contracts/Mail/Mailer.php
@@ -2589,6 +2664,7 @@ opt/app/vendor/laravel/framework/src/Illuminate/Foundation/Bus/PendingChain.php
opt/app/vendor/laravel/framework/src/Illuminate/Foundation/Bus/PendingDispatch.php
opt/app/vendor/laravel/framework/src/Illuminate/Foundation/ComposerScripts.php
opt/app/vendor/laravel/framework/src/Illuminate/Foundation/Console/AppNameCommand.php
opt/app/vendor/laravel/framework/src/Illuminate/Foundation/Console/ChannelMakeCommand.php
opt/app/vendor/laravel/framework/src/Illuminate/Foundation/Console/ClearCompiledCommand.php
opt/app/vendor/laravel/framework/src/Illuminate/Foundation/Console/ClosureCommand.php
opt/app/vendor/laravel/framework/src/Illuminate/Foundation/Console/ConfigCacheCommand.php
@@ -2606,7 +2682,6 @@ opt/app/vendor/laravel/framework/src/Illuminate/Foundation/Console/ListenerMakeC
opt/app/vendor/laravel/framework/src/Illuminate/Foundation/Console/MailMakeCommand.php
opt/app/vendor/laravel/framework/src/Illuminate/Foundation/Console/ModelMakeCommand.php
opt/app/vendor/laravel/framework/src/Illuminate/Foundation/Console/NotificationMakeCommand.php
opt/app/vendor/laravel/framework/src/Illuminate/Foundation/Console/OptimizeCommand.php
opt/app/vendor/laravel/framework/src/Illuminate/Foundation/Console/PackageDiscoverCommand.php
opt/app/vendor/laravel/framework/src/Illuminate/Foundation/Console/PolicyMakeCommand.php
opt/app/vendor/laravel/framework/src/Illuminate/Foundation/Console/PresetCommand.php
@@ -2635,7 +2710,9 @@ opt/app/vendor/laravel/framework/src/Illuminate/Foundation/Console/StorageLinkCo
opt/app/vendor/laravel/framework/src/Illuminate/Foundation/Console/TestMakeCommand.php
opt/app/vendor/laravel/framework/src/Illuminate/Foundation/Console/UpCommand.php
opt/app/vendor/laravel/framework/src/Illuminate/Foundation/Console/VendorPublishCommand.php
opt/app/vendor/laravel/framework/src/Illuminate/Foundation/Console/ViewCacheCommand.php
opt/app/vendor/laravel/framework/src/Illuminate/Foundation/Console/ViewClearCommand.php
opt/app/vendor/laravel/framework/src/Illuminate/Foundation/Console/stubs/channel.stub
opt/app/vendor/laravel/framework/src/Illuminate/Foundation/Console/stubs/console.stub
opt/app/vendor/laravel/framework/src/Illuminate/Foundation/Console/stubs/event-handler-queued.stub
opt/app/vendor/laravel/framework/src/Illuminate/Foundation/Console/stubs/event-handler.stub
@@ -2671,6 +2748,7 @@ opt/app/vendor/laravel/framework/src/Illuminate/Foundation/EnvironmentDetector.p
opt/app/vendor/laravel/framework/src/Illuminate/Foundation/Events/Dispatchable.php
opt/app/vendor/laravel/framework/src/Illuminate/Foundation/Events/LocaleUpdated.php
opt/app/vendor/laravel/framework/src/Illuminate/Foundation/Exceptions/Handler.php
opt/app/vendor/laravel/framework/src/Illuminate/Foundation/Exceptions/WhoopsHandler.php
opt/app/vendor/laravel/framework/src/Illuminate/Foundation/Exceptions/views/404.blade.php
opt/app/vendor/laravel/framework/src/Illuminate/Foundation/Exceptions/views/419.blade.php
opt/app/vendor/laravel/framework/src/Illuminate/Foundation/Exceptions/views/429.blade.php
@@ -2708,6 +2786,7 @@ opt/app/vendor/laravel/framework/src/Illuminate/Foundation/Testing/Concerns/Inte
opt/app/vendor/laravel/framework/src/Illuminate/Foundation/Testing/Concerns/MakesHttpRequests.php
opt/app/vendor/laravel/framework/src/Illuminate/Foundation/Testing/Concerns/MocksApplicationServices.php
opt/app/vendor/laravel/framework/src/Illuminate/Foundation/Testing/Constraints/HasInDatabase.php
opt/app/vendor/laravel/framework/src/Illuminate/Foundation/Testing/Constraints/SeeInOrder.php
opt/app/vendor/laravel/framework/src/Illuminate/Foundation/Testing/Constraints/SoftDeletedInDatabase.php
opt/app/vendor/laravel/framework/src/Illuminate/Foundation/Testing/DatabaseMigrations.php
opt/app/vendor/laravel/framework/src/Illuminate/Foundation/Testing/DatabaseTransactions.php
@@ -2722,7 +2801,9 @@ opt/app/vendor/laravel/framework/src/Illuminate/Foundation/Testing/WithoutMiddle
opt/app/vendor/laravel/framework/src/Illuminate/Foundation/Validation/ValidatesRequests.php
opt/app/vendor/laravel/framework/src/Illuminate/Foundation/helpers.php
opt/app/vendor/laravel/framework/src/Illuminate/Foundation/stubs/facade.stub
opt/app/vendor/laravel/framework/src/Illuminate/Hashing/ArgonHasher.php
opt/app/vendor/laravel/framework/src/Illuminate/Hashing/BcryptHasher.php
opt/app/vendor/laravel/framework/src/Illuminate/Hashing/HashManager.php
opt/app/vendor/laravel/framework/src/Illuminate/Hashing/HashServiceProvider.php
opt/app/vendor/laravel/framework/src/Illuminate/Hashing/composer.json
opt/app/vendor/laravel/framework/src/Illuminate/Http/Concerns/InteractsWithContentTypes.php
@@ -2730,17 +2811,20 @@ opt/app/vendor/laravel/framework/src/Illuminate/Http/Concerns/InteractsWithFlash
opt/app/vendor/laravel/framework/src/Illuminate/Http/Concerns/InteractsWithInput.php
opt/app/vendor/laravel/framework/src/Illuminate/Http/Exceptions/HttpResponseException.php
opt/app/vendor/laravel/framework/src/Illuminate/Http/Exceptions/PostTooLargeException.php
opt/app/vendor/laravel/framework/src/Illuminate/Http/Exceptions/ThrottleRequestsException.php
opt/app/vendor/laravel/framework/src/Illuminate/Http/File.php
opt/app/vendor/laravel/framework/src/Illuminate/Http/FileHelpers.php
opt/app/vendor/laravel/framework/src/Illuminate/Http/JsonResponse.php
opt/app/vendor/laravel/framework/src/Illuminate/Http/Middleware/CheckResponseForModifications.php
opt/app/vendor/laravel/framework/src/Illuminate/Http/Middleware/FrameGuard.php
opt/app/vendor/laravel/framework/src/Illuminate/Http/Middleware/SetCacheHeaders.php
opt/app/vendor/laravel/framework/src/Illuminate/Http/RedirectResponse.php
opt/app/vendor/laravel/framework/src/Illuminate/Http/Request.php
opt/app/vendor/laravel/framework/src/Illuminate/Http/Resources/CollectsResources.php
opt/app/vendor/laravel/framework/src/Illuminate/Http/Resources/ConditionallyLoadsAttributes.php
opt/app/vendor/laravel/framework/src/Illuminate/Http/Resources/DelegatesToResource.php
opt/app/vendor/laravel/framework/src/Illuminate/Http/Resources/Json/AnonymousResourceCollection.php
opt/app/vendor/laravel/framework/src/Illuminate/Http/Resources/Json/JsonResource.php
opt/app/vendor/laravel/framework/src/Illuminate/Http/Resources/Json/PaginatedResourceResponse.php
opt/app/vendor/laravel/framework/src/Illuminate/Http/Resources/Json/Resource.php
opt/app/vendor/laravel/framework/src/Illuminate/Http/Resources/Json/ResourceCollection.php
@@ -2756,8 +2840,9 @@ opt/app/vendor/laravel/framework/src/Illuminate/Http/Testing/MimeType.php
opt/app/vendor/laravel/framework/src/Illuminate/Http/UploadedFile.php
opt/app/vendor/laravel/framework/src/Illuminate/Http/composer.json
opt/app/vendor/laravel/framework/src/Illuminate/Log/Events/MessageLogged.php
opt/app/vendor/laravel/framework/src/Illuminate/Log/LogManager.php
opt/app/vendor/laravel/framework/src/Illuminate/Log/LogServiceProvider.php
opt/app/vendor/laravel/framework/src/Illuminate/Log/Writer.php
opt/app/vendor/laravel/framework/src/Illuminate/Log/Logger.php
opt/app/vendor/laravel/framework/src/Illuminate/Log/composer.json
opt/app/vendor/laravel/framework/src/Illuminate/Mail/Events/MessageSending.php
opt/app/vendor/laravel/framework/src/Illuminate/Mail/Events/MessageSent.php
@@ -2922,7 +3007,10 @@ opt/app/vendor/laravel/framework/src/Illuminate/Redis/RedisServiceProvider.php
opt/app/vendor/laravel/framework/src/Illuminate/Redis/composer.json
opt/app/vendor/laravel/framework/src/Illuminate/Routing/Console/ControllerMakeCommand.php
opt/app/vendor/laravel/framework/src/Illuminate/Routing/Console/MiddlewareMakeCommand.php
opt/app/vendor/laravel/framework/src/Illuminate/Routing/Console/stubs/controller.api.stub
opt/app/vendor/laravel/framework/src/Illuminate/Routing/Console/stubs/controller.model.api.stub
opt/app/vendor/laravel/framework/src/Illuminate/Routing/Console/stubs/controller.model.stub
opt/app/vendor/laravel/framework/src/Illuminate/Routing/Console/stubs/controller.nested.api.stub
opt/app/vendor/laravel/framework/src/Illuminate/Routing/Console/stubs/controller.nested.stub
opt/app/vendor/laravel/framework/src/Illuminate/Routing/Console/stubs/controller.plain.stub
opt/app/vendor/laravel/framework/src/Illuminate/Routing/Console/stubs/controller.stub
@@ -2932,6 +3020,7 @@ opt/app/vendor/laravel/framework/src/Illuminate/Routing/Controller.php
opt/app/vendor/laravel/framework/src/Illuminate/Routing/ControllerDispatcher.php
opt/app/vendor/laravel/framework/src/Illuminate/Routing/ControllerMiddlewareOptions.php
opt/app/vendor/laravel/framework/src/Illuminate/Routing/Events/RouteMatched.php
opt/app/vendor/laravel/framework/src/Illuminate/Routing/Exceptions/InvalidSignatureException.php
opt/app/vendor/laravel/framework/src/Illuminate/Routing/Exceptions/UrlGenerationException.php
opt/app/vendor/laravel/framework/src/Illuminate/Routing/ImplicitRouteBinding.php
opt/app/vendor/laravel/framework/src/Illuminate/Routing/Matching/HostValidator.php
@@ -2942,6 +3031,7 @@ opt/app/vendor/laravel/framework/src/Illuminate/Routing/Matching/ValidatorInterf
opt/app/vendor/laravel/framework/src/Illuminate/Routing/Middleware/SubstituteBindings.php
opt/app/vendor/laravel/framework/src/Illuminate/Routing/Middleware/ThrottleRequests.php
opt/app/vendor/laravel/framework/src/Illuminate/Routing/Middleware/ThrottleRequestsWithRedis.php
opt/app/vendor/laravel/framework/src/Illuminate/Routing/Middleware/ValidateSignature.php
opt/app/vendor/laravel/framework/src/Illuminate/Routing/MiddlewareNameResolver.php
opt/app/vendor/laravel/framework/src/Illuminate/Routing/PendingResourceRegistration.php
opt/app/vendor/laravel/framework/src/Illuminate/Routing/Pipeline.php
@@ -3043,6 +3133,7 @@ opt/app/vendor/laravel/framework/src/Illuminate/Support/Testing/Fakes/Notificati
opt/app/vendor/laravel/framework/src/Illuminate/Support/Testing/Fakes/PendingMailFake.php
opt/app/vendor/laravel/framework/src/Illuminate/Support/Testing/Fakes/QueueFake.php
opt/app/vendor/laravel/framework/src/Illuminate/Support/Traits/CapsuleManagerTrait.php
opt/app/vendor/laravel/framework/src/Illuminate/Support/Traits/Localizable.php
opt/app/vendor/laravel/framework/src/Illuminate/Support/Traits/Macroable.php
opt/app/vendor/laravel/framework/src/Illuminate/Support/ViewErrorBag.php
opt/app/vendor/laravel/framework/src/Illuminate/Support/composer.json
@@ -3083,6 +3174,7 @@ opt/app/vendor/laravel/framework/src/Illuminate/View/Compilers/Concerns/Compiles
opt/app/vendor/laravel/framework/src/Illuminate/View/Compilers/Concerns/CompilesComponents.php
opt/app/vendor/laravel/framework/src/Illuminate/View/Compilers/Concerns/CompilesConditionals.php
opt/app/vendor/laravel/framework/src/Illuminate/View/Compilers/Concerns/CompilesEchos.php
opt/app/vendor/laravel/framework/src/Illuminate/View/Compilers/Concerns/CompilesHelpers.php
opt/app/vendor/laravel/framework/src/Illuminate/View/Compilers/Concerns/CompilesIncludes.php
opt/app/vendor/laravel/framework/src/Illuminate/View/Compilers/Concerns/CompilesInjections.php
opt/app/vendor/laravel/framework/src/Illuminate/View/Compilers/Concerns/CompilesJson.php
@@ -3265,7 +3357,7 @@ opt/app/vendor/lcobucci/jwt/test/unit/TokenTest.php
opt/app/vendor/lcobucci/jwt/test/unit/ValidationDataTest.php
opt/app/vendor/league/commonmark/.styleci.yml
opt/app/vendor/league/commonmark/CHANGELOG.md
opt/app/vendor/league/commonmark/CONDUCT.md
opt/app/vendor/league/commonmark/CODE_OF_CONDUCT.md
opt/app/vendor/league/commonmark/CONTRIBUTING.md
opt/app/vendor/league/commonmark/LICENSE
opt/app/vendor/league/commonmark/README.md
@@ -3378,6 +3470,7 @@ opt/app/vendor/league/commonmark/src/Util/LinkParserHelper.php
opt/app/vendor/league/commonmark/src/Util/RegexHelper.php
opt/app/vendor/league/commonmark/src/Util/UrlEncoder.php
opt/app/vendor/league/commonmark/src/Util/Xml.php
opt/app/vendor/league/csv/CHANGELOG.md
opt/app/vendor/league/csv/LICENSE
opt/app/vendor/league/csv/autoload.php
opt/app/vendor/league/csv/composer.json
@@ -3721,32 +3814,9 @@ opt/app/vendor/monolog/monolog/tests/Monolog/Processor/WebProcessorTest.php
opt/app/vendor/monolog/monolog/tests/Monolog/PsrLogCompatTest.php
opt/app/vendor/monolog/monolog/tests/Monolog/RegistryTest.php
opt/app/vendor/monolog/monolog/tests/Monolog/TestCase.php
opt/app/vendor/mtdowling/cron-expression/.editorconfig
opt/app/vendor/mtdowling/cron-expression/CHANGELOG.md
opt/app/vendor/mtdowling/cron-expression/LICENSE
opt/app/vendor/mtdowling/cron-expression/README.md
opt/app/vendor/mtdowling/cron-expression/composer.json
opt/app/vendor/mtdowling/cron-expression/src/Cron/AbstractField.php
opt/app/vendor/mtdowling/cron-expression/src/Cron/CronExpression.php
opt/app/vendor/mtdowling/cron-expression/src/Cron/DayOfMonthField.php
opt/app/vendor/mtdowling/cron-expression/src/Cron/DayOfWeekField.php
opt/app/vendor/mtdowling/cron-expression/src/Cron/FieldFactory.php
opt/app/vendor/mtdowling/cron-expression/src/Cron/FieldInterface.php
opt/app/vendor/mtdowling/cron-expression/src/Cron/HoursField.php
opt/app/vendor/mtdowling/cron-expression/src/Cron/MinutesField.php
opt/app/vendor/mtdowling/cron-expression/src/Cron/MonthField.php
opt/app/vendor/mtdowling/cron-expression/src/Cron/YearField.php
opt/app/vendor/mtdowling/cron-expression/tests/Cron/AbstractFieldTest.php
opt/app/vendor/mtdowling/cron-expression/tests/Cron/CronExpressionTest.php
opt/app/vendor/mtdowling/cron-expression/tests/Cron/DayOfMonthFieldTest.php
opt/app/vendor/mtdowling/cron-expression/tests/Cron/DayOfWeekFieldTest.php
opt/app/vendor/mtdowling/cron-expression/tests/Cron/FieldFactoryTest.php
opt/app/vendor/mtdowling/cron-expression/tests/Cron/HoursFieldTest.php
opt/app/vendor/mtdowling/cron-expression/tests/Cron/MinutesFieldTest.php
opt/app/vendor/mtdowling/cron-expression/tests/Cron/MonthFieldTest.php
opt/app/vendor/mtdowling/cron-expression/tests/Cron/YearFieldTest.php
opt/app/vendor/nesbot/carbon/.php_cs.dist
opt/app/vendor/nesbot/carbon/LICENSE
opt/app/vendor/nesbot/carbon/build.php
opt/app/vendor/nesbot/carbon/composer.json
opt/app/vendor/nesbot/carbon/readme.md
opt/app/vendor/nesbot/carbon/src/Carbon/Carbon.php
@@ -3774,6 +3844,7 @@ opt/app/vendor/nesbot/carbon/src/Carbon/Lang/fi.php
opt/app/vendor/nesbot/carbon/src/Carbon/Lang/fo.php
opt/app/vendor/nesbot/carbon/src/Carbon/Lang/fr.php
opt/app/vendor/nesbot/carbon/src/Carbon/Lang/gl.php
opt/app/vendor/nesbot/carbon/src/Carbon/Lang/gu.php
opt/app/vendor/nesbot/carbon/src/Carbon/Lang/he.php
opt/app/vendor/nesbot/carbon/src/Carbon/Lang/hr.php
opt/app/vendor/nesbot/carbon/src/Carbon/Lang/hu.php
@@ -3815,7 +3886,7 @@ opt/app/vendor/nesbot/carbon/src/Carbon/Lang/uz.php
opt/app/vendor/nesbot/carbon/src/Carbon/Lang/vi.php
opt/app/vendor/nesbot/carbon/src/Carbon/Lang/zh.php
opt/app/vendor/nesbot/carbon/src/Carbon/Lang/zh_TW.php
opt/app/vendor/nesbot/carbon/trigger
opt/app/vendor/nesbot/carbon/src/Carbon/Translator.php
opt/app/vendor/paragonie/constant_time_encoding/LICENSE.txt
opt/app/vendor/paragonie/constant_time_encoding/README.md
opt/app/vendor/paragonie/constant_time_encoding/composer.json
@@ -3889,16 +3960,23 @@ opt/app/vendor/phpseclib/phpseclib/phpseclib/System/SSH/Agent.php
opt/app/vendor/phpseclib/phpseclib/phpseclib/System/SSH/Agent/Identity.php
opt/app/vendor/phpseclib/phpseclib/phpseclib/bootstrap.php
opt/app/vendor/phpseclib/phpseclib/phpseclib/openssl.cnf
opt/app/vendor/pragmarx/google2fa-laravel/CHANGELOG.md
opt/app/vendor/pragmarx/google2fa-laravel/LICENSE
opt/app/vendor/pragmarx/google2fa-laravel/changelog.md
opt/app/vendor/pragmarx/google2fa-laravel/README.md
opt/app/vendor/pragmarx/google2fa-laravel/composer.json
opt/app/vendor/pragmarx/google2fa-laravel/docs/middleware.jpg
opt/app/vendor/pragmarx/google2fa-laravel/phpspec.yml
opt/app/vendor/pragmarx/google2fa-laravel/readme.md
opt/app/vendor/pragmarx/google2fa-laravel/src/Events/EmptyOneTimePasswordReceived.php
opt/app/vendor/pragmarx/google2fa-laravel/src/Events/LoggedOut.php
opt/app/vendor/pragmarx/google2fa-laravel/src/Events/LoginFailed.php
opt/app/vendor/pragmarx/google2fa-laravel/src/Events/LoginSucceeded.php
opt/app/vendor/pragmarx/google2fa-laravel/src/Events/OneTimePasswordExpired.php
opt/app/vendor/pragmarx/google2fa-laravel/src/Events/OneTimePasswordRequested.php
opt/app/vendor/pragmarx/google2fa-laravel/src/Events/OneTimePasswordRequested53.php
opt/app/vendor/pragmarx/google2fa-laravel/src/Exceptions/InvalidOneTimePassword.php
opt/app/vendor/pragmarx/google2fa-laravel/src/Exceptions/InvalidSecretKey.php
opt/app/vendor/pragmarx/google2fa-laravel/src/Facade.php
opt/app/vendor/pragmarx/google2fa-laravel/src/Google2FA.php
opt/app/vendor/pragmarx/google2fa-laravel/src/Middleware.php
opt/app/vendor/pragmarx/google2fa-laravel/src/ServiceProvider.php
opt/app/vendor/pragmarx/google2fa-laravel/src/Support/Auth.php
@@ -3911,14 +3989,21 @@ opt/app/vendor/pragmarx/google2fa-laravel/src/Support/Request.php
opt/app/vendor/pragmarx/google2fa-laravel/src/Support/Response.php
opt/app/vendor/pragmarx/google2fa-laravel/src/Support/Session.php
opt/app/vendor/pragmarx/google2fa-laravel/src/config/config.php
opt/app/vendor/pragmarx/google2fa-laravel/tests/spec/Support/AuthenticatorSpec.php
opt/app/vendor/pragmarx/google2fa-laravel/tests/Google2FaLaravelTest.php
opt/app/vendor/pragmarx/google2fa-laravel/tests/Support/User.php
opt/app/vendor/pragmarx/google2fa-laravel/tests/TestCase.php
opt/app/vendor/pragmarx/google2fa-laravel/tests/bootstrap.php
opt/app/vendor/pragmarx/google2fa-laravel/tests/views/google2fa/index.blade.php
opt/app/vendor/pragmarx/google2fa-laravel/upgrading.md
opt/app/vendor/pragmarx/google2fa/LICENSE
opt/app/vendor/pragmarx/google2fa/LICENSE.md
opt/app/vendor/pragmarx/google2fa/README.md
opt/app/vendor/pragmarx/google2fa/RELICENSED.md
opt/app/vendor/pragmarx/google2fa/changelog.md
opt/app/vendor/pragmarx/google2fa/composer.json
opt/app/vendor/pragmarx/google2fa/composer.lock
opt/app/vendor/pragmarx/google2fa/docs/playground.jpg
opt/app/vendor/pragmarx/google2fa/src/Exceptions/IncompatibleWithGoogleAuthenticatorException.php
opt/app/vendor/pragmarx/google2fa/src/Exceptions/InsecureCallException.php
opt/app/vendor/pragmarx/google2fa/src/Exceptions/InvalidCharactersException.php
opt/app/vendor/pragmarx/google2fa/src/Exceptions/SecretKeyTooShortException.php
opt/app/vendor/pragmarx/google2fa/src/Google2FA.php
@@ -4503,7 +4588,6 @@ opt/app/vendor/symfony/console/Descriptor/XmlDescriptor.php
opt/app/vendor/symfony/console/Event/ConsoleCommandEvent.php
opt/app/vendor/symfony/console/Event/ConsoleErrorEvent.php
opt/app/vendor/symfony/console/Event/ConsoleEvent.php
opt/app/vendor/symfony/console/Event/ConsoleExceptionEvent.php
opt/app/vendor/symfony/console/Event/ConsoleTerminateEvent.php
opt/app/vendor/symfony/console/EventListener/ErrorListener.php
opt/app/vendor/symfony/console/Exception/CommandNotFoundException.php
@@ -4877,7 +4961,6 @@ opt/app/vendor/symfony/debug/Debug.php
opt/app/vendor/symfony/debug/DebugClassLoader.php
opt/app/vendor/symfony/debug/ErrorHandler.php
opt/app/vendor/symfony/debug/Exception/ClassNotFoundException.php
opt/app/vendor/symfony/debug/Exception/ContextErrorException.php
opt/app/vendor/symfony/debug/Exception/FatalErrorException.php
opt/app/vendor/symfony/debug/Exception/FatalThrowableError.php
opt/app/vendor/symfony/debug/Exception/FlattenException.php
@@ -4892,15 +4975,6 @@ opt/app/vendor/symfony/debug/FatalErrorHandler/UndefinedFunctionFatalErrorHandle
opt/app/vendor/symfony/debug/FatalErrorHandler/UndefinedMethodFatalErrorHandler.php
opt/app/vendor/symfony/debug/LICENSE
opt/app/vendor/symfony/debug/README.md
opt/app/vendor/symfony/debug/Resources/ext/README.md
opt/app/vendor/symfony/debug/Resources/ext/config.m4
opt/app/vendor/symfony/debug/Resources/ext/config.w32
opt/app/vendor/symfony/debug/Resources/ext/php_symfony_debug.h
opt/app/vendor/symfony/debug/Resources/ext/symfony_debug.c
opt/app/vendor/symfony/debug/Resources/ext/tests/001.phpt
opt/app/vendor/symfony/debug/Resources/ext/tests/002.phpt
opt/app/vendor/symfony/debug/Resources/ext/tests/002_1.phpt
opt/app/vendor/symfony/debug/Resources/ext/tests/003.phpt
opt/app/vendor/symfony/debug/Tests/DebugClassLoaderTest.php
opt/app/vendor/symfony/debug/Tests/ErrorHandlerTest.php
opt/app/vendor/symfony/debug/Tests/Exception/FlattenExceptionTest.php
@@ -4963,7 +5037,6 @@ opt/app/vendor/symfony/finder/Comparator/Comparator.php
opt/app/vendor/symfony/finder/Comparator/DateComparator.php
opt/app/vendor/symfony/finder/Comparator/NumberComparator.php
opt/app/vendor/symfony/finder/Exception/AccessDeniedException.php
opt/app/vendor/symfony/finder/Exception/ExceptionInterface.php
opt/app/vendor/symfony/finder/Finder.php
opt/app/vendor/symfony/finder/Glob.php
opt/app/vendor/symfony/finder/Iterator/CustomFilterIterator.php
@@ -4973,7 +5046,6 @@ opt/app/vendor/symfony/finder/Iterator/ExcludeDirectoryFilterIterator.php
opt/app/vendor/symfony/finder/Iterator/FileTypeFilterIterator.php
opt/app/vendor/symfony/finder/Iterator/FilecontentFilterIterator.php
opt/app/vendor/symfony/finder/Iterator/FilenameFilterIterator.php
opt/app/vendor/symfony/finder/Iterator/FilterIterator.php
opt/app/vendor/symfony/finder/Iterator/MultiplePcreFilterIterator.php
opt/app/vendor/symfony/finder/Iterator/PathFilterIterator.php
opt/app/vendor/symfony/finder/Iterator/RecursiveDirectoryIterator.php
@@ -5012,7 +5084,6 @@ opt/app/vendor/symfony/finder/Tests/Iterator/ExcludeDirectoryFilterIteratorTest.
opt/app/vendor/symfony/finder/Tests/Iterator/FileTypeFilterIteratorTest.php
opt/app/vendor/symfony/finder/Tests/Iterator/FilecontentFilterIteratorTest.php
opt/app/vendor/symfony/finder/Tests/Iterator/FilenameFilterIteratorTest.php
opt/app/vendor/symfony/finder/Tests/Iterator/FilterIteratorTest.php
opt/app/vendor/symfony/finder/Tests/Iterator/Iterator.php
opt/app/vendor/symfony/finder/Tests/Iterator/IteratorTestCase.php
opt/app/vendor/symfony/finder/Tests/Iterator/MockFileListIterator.php
@@ -5076,22 +5147,18 @@ opt/app/vendor/symfony/http-foundation/Session/SessionBagInterface.php
opt/app/vendor/symfony/http-foundation/Session/SessionBagProxy.php
opt/app/vendor/symfony/http-foundation/Session/SessionInterface.php
opt/app/vendor/symfony/http-foundation/Session/Storage/Handler/AbstractSessionHandler.php
opt/app/vendor/symfony/http-foundation/Session/Storage/Handler/MemcacheSessionHandler.php
opt/app/vendor/symfony/http-foundation/Session/Storage/Handler/MemcachedSessionHandler.php
opt/app/vendor/symfony/http-foundation/Session/Storage/Handler/MongoDbSessionHandler.php
opt/app/vendor/symfony/http-foundation/Session/Storage/Handler/NativeFileSessionHandler.php
opt/app/vendor/symfony/http-foundation/Session/Storage/Handler/NativeSessionHandler.php
opt/app/vendor/symfony/http-foundation/Session/Storage/Handler/NullSessionHandler.php
opt/app/vendor/symfony/http-foundation/Session/Storage/Handler/PdoSessionHandler.php
opt/app/vendor/symfony/http-foundation/Session/Storage/Handler/StrictSessionHandler.php
opt/app/vendor/symfony/http-foundation/Session/Storage/Handler/WriteCheckSessionHandler.php
opt/app/vendor/symfony/http-foundation/Session/Storage/MetadataBag.php
opt/app/vendor/symfony/http-foundation/Session/Storage/MockArraySessionStorage.php
opt/app/vendor/symfony/http-foundation/Session/Storage/MockFileSessionStorage.php
opt/app/vendor/symfony/http-foundation/Session/Storage/NativeSessionStorage.php
opt/app/vendor/symfony/http-foundation/Session/Storage/PhpBridgeSessionStorage.php
opt/app/vendor/symfony/http-foundation/Session/Storage/Proxy/AbstractProxy.php
opt/app/vendor/symfony/http-foundation/Session/Storage/Proxy/NativeProxy.php
opt/app/vendor/symfony/http-foundation/Session/Storage/Proxy/SessionHandlerProxy.php
opt/app/vendor/symfony/http-foundation/Session/Storage/SessionStorageInterface.php
opt/app/vendor/symfony/http-foundation/StreamedResponse.php
@@ -5142,22 +5209,18 @@ opt/app/vendor/symfony/http-foundation/Tests/Session/Storage/Handler/Fixtures/wi
opt/app/vendor/symfony/http-foundation/Tests/Session/Storage/Handler/Fixtures/with_cookie.php
opt/app/vendor/symfony/http-foundation/Tests/Session/Storage/Handler/Fixtures/with_cookie_and_session.expected
opt/app/vendor/symfony/http-foundation/Tests/Session/Storage/Handler/Fixtures/with_cookie_and_session.php
opt/app/vendor/symfony/http-foundation/Tests/Session/Storage/Handler/MemcacheSessionHandlerTest.php
opt/app/vendor/symfony/http-foundation/Tests/Session/Storage/Handler/MemcachedSessionHandlerTest.php
opt/app/vendor/symfony/http-foundation/Tests/Session/Storage/Handler/MongoDbSessionHandlerTest.php
opt/app/vendor/symfony/http-foundation/Tests/Session/Storage/Handler/NativeFileSessionHandlerTest.php
opt/app/vendor/symfony/http-foundation/Tests/Session/Storage/Handler/NativeSessionHandlerTest.php
opt/app/vendor/symfony/http-foundation/Tests/Session/Storage/Handler/NullSessionHandlerTest.php
opt/app/vendor/symfony/http-foundation/Tests/Session/Storage/Handler/PdoSessionHandlerTest.php
opt/app/vendor/symfony/http-foundation/Tests/Session/Storage/Handler/StrictSessionHandlerTest.php
opt/app/vendor/symfony/http-foundation/Tests/Session/Storage/Handler/WriteCheckSessionHandlerTest.php
opt/app/vendor/symfony/http-foundation/Tests/Session/Storage/MetadataBagTest.php
opt/app/vendor/symfony/http-foundation/Tests/Session/Storage/MockArraySessionStorageTest.php
opt/app/vendor/symfony/http-foundation/Tests/Session/Storage/MockFileSessionStorageTest.php
opt/app/vendor/symfony/http-foundation/Tests/Session/Storage/NativeSessionStorageTest.php
opt/app/vendor/symfony/http-foundation/Tests/Session/Storage/PhpBridgeSessionStorageTest.php
opt/app/vendor/symfony/http-foundation/Tests/Session/Storage/Proxy/AbstractProxyTest.php
opt/app/vendor/symfony/http-foundation/Tests/Session/Storage/Proxy/NativeProxyTest.php
opt/app/vendor/symfony/http-foundation/Tests/Session/Storage/Proxy/SessionHandlerProxyTest.php
opt/app/vendor/symfony/http-foundation/Tests/StreamedResponseTest.php
opt/app/vendor/symfony/http-foundation/Tests/schema/http-status-codes.rng
@@ -5175,7 +5238,6 @@ opt/app/vendor/symfony/http-kernel/CacheWarmer/CacheWarmerAggregate.php
opt/app/vendor/symfony/http-kernel/CacheWarmer/CacheWarmerInterface.php
opt/app/vendor/symfony/http-kernel/CacheWarmer/WarmableInterface.php
opt/app/vendor/symfony/http-kernel/Client.php
opt/app/vendor/symfony/http-kernel/Config/EnvParametersResource.php
opt/app/vendor/symfony/http-kernel/Config/FileLocator.php
opt/app/vendor/symfony/http-kernel/Controller/ArgumentResolver.php
opt/app/vendor/symfony/http-kernel/Controller/ArgumentResolver/DefaultValueResolver.php
@@ -5208,11 +5270,9 @@ opt/app/vendor/symfony/http-kernel/DataCollector/MemoryDataCollector.php
opt/app/vendor/symfony/http-kernel/DataCollector/RequestDataCollector.php
opt/app/vendor/symfony/http-kernel/DataCollector/RouterDataCollector.php
opt/app/vendor/symfony/http-kernel/DataCollector/TimeDataCollector.php
opt/app/vendor/symfony/http-kernel/DataCollector/Util/ValueExporter.php
opt/app/vendor/symfony/http-kernel/Debug/FileLinkFormatter.php
opt/app/vendor/symfony/http-kernel/Debug/TraceableEventDispatcher.php
opt/app/vendor/symfony/http-kernel/DependencyInjection/AddAnnotatedClassesToCachePass.php
opt/app/vendor/symfony/http-kernel/DependencyInjection/AddClassesToCachePass.php
opt/app/vendor/symfony/http-kernel/DependencyInjection/ConfigurableExtension.php
opt/app/vendor/symfony/http-kernel/DependencyInjection/ControllerArgumentValueResolverPass.php
opt/app/vendor/symfony/http-kernel/DependencyInjection/Extension.php
@@ -5307,7 +5367,6 @@ opt/app/vendor/symfony/http-kernel/Tests/CacheClearer/Psr6CacheClearerTest.php
opt/app/vendor/symfony/http-kernel/Tests/CacheWarmer/CacheWarmerAggregateTest.php
opt/app/vendor/symfony/http-kernel/Tests/CacheWarmer/CacheWarmerTest.php
opt/app/vendor/symfony/http-kernel/Tests/ClientTest.php
opt/app/vendor/symfony/http-kernel/Tests/Config/EnvParametersResourceTest.php
opt/app/vendor/symfony/http-kernel/Tests/Config/FileLocatorTest.php
opt/app/vendor/symfony/http-kernel/Tests/Controller/ArgumentResolver/ServiceValueResolverTest.php
opt/app/vendor/symfony/http-kernel/Tests/Controller/ArgumentResolverTest.php
@@ -5324,7 +5383,6 @@ opt/app/vendor/symfony/http-kernel/Tests/DataCollector/LoggerDataCollectorTest.p
opt/app/vendor/symfony/http-kernel/Tests/DataCollector/MemoryDataCollectorTest.php
opt/app/vendor/symfony/http-kernel/Tests/DataCollector/RequestDataCollectorTest.php
opt/app/vendor/symfony/http-kernel/Tests/DataCollector/TimeDataCollectorTest.php
opt/app/vendor/symfony/http-kernel/Tests/DataCollector/Util/ValueExporterTest.php
opt/app/vendor/symfony/http-kernel/Tests/Debug/FileLinkFormatterTest.php
opt/app/vendor/symfony/http-kernel/Tests/Debug/TraceableEventDispatcherTest.php
opt/app/vendor/symfony/http-kernel/Tests/DependencyInjection/AddAnnotatedClassesToCachePassTest.php
@@ -5442,18 +5500,11 @@ opt/app/vendor/symfony/polyfill-php56/Php56.php
opt/app/vendor/symfony/polyfill-php56/README.md
opt/app/vendor/symfony/polyfill-php56/bootstrap.php
opt/app/vendor/symfony/polyfill-php56/composer.json
opt/app/vendor/symfony/polyfill-php70/LICENSE
opt/app/vendor/symfony/polyfill-php70/Php70.php
opt/app/vendor/symfony/polyfill-php70/README.md
opt/app/vendor/symfony/polyfill-php70/Resources/stubs/ArithmeticError.php
opt/app/vendor/symfony/polyfill-php70/Resources/stubs/AssertionError.php
opt/app/vendor/symfony/polyfill-php70/Resources/stubs/DivisionByZeroError.php
opt/app/vendor/symfony/polyfill-php70/Resources/stubs/Error.php
opt/app/vendor/symfony/polyfill-php70/Resources/stubs/ParseError.php
opt/app/vendor/symfony/polyfill-php70/Resources/stubs/SessionUpdateTimestampHandlerInterface.php
opt/app/vendor/symfony/polyfill-php70/Resources/stubs/TypeError.php
opt/app/vendor/symfony/polyfill-php70/bootstrap.php
opt/app/vendor/symfony/polyfill-php70/composer.json
opt/app/vendor/symfony/polyfill-php72/LICENSE
opt/app/vendor/symfony/polyfill-php72/Php72.php
opt/app/vendor/symfony/polyfill-php72/README.md
opt/app/vendor/symfony/polyfill-php72/bootstrap.php
opt/app/vendor/symfony/polyfill-php72/composer.json
opt/app/vendor/symfony/polyfill-util/Binary.php
opt/app/vendor/symfony/polyfill-util/BinaryNoFuncOverload.php
opt/app/vendor/symfony/polyfill-util/BinaryOnFuncOverload.php
@@ -5480,7 +5531,6 @@ opt/app/vendor/symfony/process/Pipes/PipesInterface.php
opt/app/vendor/symfony/process/Pipes/UnixPipes.php
opt/app/vendor/symfony/process/Pipes/WindowsPipes.php
opt/app/vendor/symfony/process/Process.php
opt/app/vendor/symfony/process/ProcessBuilder.php
opt/app/vendor/symfony/process/ProcessUtils.php
opt/app/vendor/symfony/process/README.md
opt/app/vendor/symfony/process/Tests/ExecutableFinderTest.php
@@ -5488,10 +5538,8 @@ opt/app/vendor/symfony/process/Tests/NonStopableProcess.php
opt/app/vendor/symfony/process/Tests/PhpExecutableFinderTest.php
opt/app/vendor/symfony/process/Tests/PhpProcessTest.php
opt/app/vendor/symfony/process/Tests/PipeStdinInStdoutStdErrStreamSelect.php
opt/app/vendor/symfony/process/Tests/ProcessBuilderTest.php
opt/app/vendor/symfony/process/Tests/ProcessFailedExceptionTest.php
opt/app/vendor/symfony/process/Tests/ProcessTest.php
opt/app/vendor/symfony/process/Tests/ProcessUtilsTest.php
opt/app/vendor/symfony/process/Tests/SignalListener.php
opt/app/vendor/symfony/process/composer.json
opt/app/vendor/symfony/process/phpunit.xml.dist
@@ -5614,6 +5662,17 @@ opt/app/vendor/symfony/routing/Tests/Fixtures/empty.yml
opt/app/vendor/symfony/routing/Tests/Fixtures/file_resource.yml
opt/app/vendor/symfony/routing/Tests/Fixtures/foo.xml
opt/app/vendor/symfony/routing/Tests/Fixtures/foo1.xml
opt/app/vendor/symfony/routing/Tests/Fixtures/glob/bar.xml
opt/app/vendor/symfony/routing/Tests/Fixtures/glob/bar.yml
opt/app/vendor/symfony/routing/Tests/Fixtures/glob/baz.xml
opt/app/vendor/symfony/routing/Tests/Fixtures/glob/baz.yml
opt/app/vendor/symfony/routing/Tests/Fixtures/glob/import_multiple.xml
opt/app/vendor/symfony/routing/Tests/Fixtures/glob/import_multiple.yml
opt/app/vendor/symfony/routing/Tests/Fixtures/glob/import_single.xml
opt/app/vendor/symfony/routing/Tests/Fixtures/glob/import_single.yml
opt/app/vendor/symfony/routing/Tests/Fixtures/glob/php_dsl.php
opt/app/vendor/symfony/routing/Tests/Fixtures/glob/php_dsl_bar.php
opt/app/vendor/symfony/routing/Tests/Fixtures/glob/php_dsl_baz.php
opt/app/vendor/symfony/routing/Tests/Fixtures/incomplete.yml
opt/app/vendor/symfony/routing/Tests/Fixtures/list_defaults.xml
opt/app/vendor/symfony/routing/Tests/Fixtures/list_in_list_defaults.xml
@@ -5863,7 +5922,6 @@ opt/app/vendor/symfony/var-dumper/Caster/EnumStub.php
opt/app/vendor/symfony/var-dumper/Caster/ExceptionCaster.php
opt/app/vendor/symfony/var-dumper/Caster/FrameStub.php
opt/app/vendor/symfony/var-dumper/Caster/LinkStub.php
opt/app/vendor/symfony/var-dumper/Caster/MongoCaster.php
opt/app/vendor/symfony/var-dumper/Caster/PdoCaster.php
opt/app/vendor/symfony/var-dumper/Caster/PgSqlCaster.php
opt/app/vendor/symfony/var-dumper/Caster/RedisCaster.php
@@ -6538,6 +6596,7 @@ opt/app/vendor/twig/twig/test/Twig/Tests/Fixtures/macros/simple.test
opt/app/vendor/twig/twig/test/Twig/Tests/Fixtures/macros/varargs.test
opt/app/vendor/twig/twig/test/Twig/Tests/Fixtures/macros/varargs_argument.test
opt/app/vendor/twig/twig/test/Twig/Tests/Fixtures/macros/with_filters.test
opt/app/vendor/twig/twig/test/Twig/Tests/Fixtures/regression/block_names_unicity.test
opt/app/vendor/twig/twig/test/Twig/Tests/Fixtures/regression/combined_debug_info.test
opt/app/vendor/twig/twig/test/Twig/Tests/Fixtures/regression/empty_token.test
opt/app/vendor/twig/twig/test/Twig/Tests/Fixtures/regression/issue_1143.test
@@ -6776,16 +6835,6 @@ opt/app/vendor/vlucas/phpdotenv/src/Exception/InvalidPathException.php
opt/app/vendor/vlucas/phpdotenv/src/Exception/ValidationException.php
opt/app/vendor/vlucas/phpdotenv/src/Loader.php
opt/app/vendor/vlucas/phpdotenv/src/Validator.php
opt/app/vendor/watson/validating/LICENSE.txt
opt/app/vendor/watson/validating/README.md
opt/app/vendor/watson/validating/composer.json
opt/app/vendor/watson/validating/src/Injectors/UniqueInjector.php
opt/app/vendor/watson/validating/src/Injectors/UniqueWithInjector.php
opt/app/vendor/watson/validating/src/ValidatingInterface.php
opt/app/vendor/watson/validating/src/ValidatingModel.php
opt/app/vendor/watson/validating/src/ValidatingObserver.php
opt/app/vendor/watson/validating/src/ValidatingTrait.php
opt/app/vendor/watson/validating/src/ValidationException.php
opt/app/vendor/zendframework/zend-diactoros/.coveralls.yml
opt/app/vendor/zendframework/zend-diactoros/CHANGELOG.md
opt/app/vendor/zendframework/zend-diactoros/CONDUCT.md

View File

@@ -15,8 +15,8 @@ const pkgdef :Spk.PackageDefinition = (
manifest = (
appTitle = (defaultText = "Firefly III"),
appVersion = 10,
appMarketingVersion = (defaultText = "4.7.2"),
appVersion = 11,
appMarketingVersion = (defaultText = "4.7.3"),
actions = [
# Define your "new document" handlers here.

View File

@@ -1,6 +1,7 @@
language: php
php:
- 7.1
- 7.2
cache:
directories:

View File

@@ -28,7 +28,7 @@ RUN apt-get update -y && \
RUN docker-php-ext-install -j$(nproc) curl gd intl json readline tidy zip bcmath xml mbstring pdo_sqlite pdo_mysql bz2 pdo_pgsql
# Generate locales supported by Firefly III
RUN echo "de_DE.UTF-8 UTF-8\nen_US.UTF-8 UTF-8\nfr_FR.UTF-8 UTF-8\nid_ID.UTF-8 UTF-8\nnl_NL.UTF-8 UTF-8\npl_PL.UTF-8 UTF-8" > /etc/locale.gen && locale-gen
RUN echo "de_DE.UTF-8 UTF-8\nen_US.UTF-8 UTF-8\nes_ES.UTF-8 UTF-8\nfr_FR.UTF-8 UTF-8\nid_ID.UTF-8 UTF-8\nit_IT.UTF-8 UTF-8\nnl_NL.UTF-8 UTF-8\npl_PL.UTF-8 UTF-8pt_BR.UTF-8 UTF-8ru_RU.UTF-8 UTF-8\ntr_TR.UTF-8 UTF-8\n\n" > /etc/locale.gen && locale-gen
# copy Apache config to correct spot.
COPY ./.deploy/docker/apache2.conf /etc/apache2/apache2.conf

View File

@@ -27,6 +27,7 @@ use FireflyIII\Exceptions\FireflyException;
use FireflyIII\Models\Bill;
use FireflyIII\Repositories\Bill\BillRepositoryInterface;
use FireflyIII\Transformers\BillTransformer;
use Illuminate\Http\JsonResponse;
use Illuminate\Http\Request;
use Illuminate\Support\Collection;
use League\Fractal\Manager;
@@ -47,7 +48,7 @@ class BillController extends Controller
/**
* BillController constructor.
*
* @throws \FireflyIII\Exceptions\FireflyException
* @throws FireflyException
*/
public function __construct()
{
@@ -66,11 +67,11 @@ class BillController extends Controller
/**
* Remove the specified resource from storage.
*
* @param \FireflyIII\Models\Bill $bill
* @param Bill $bill
*
* @return \Illuminate\Http\Response
* @return JsonResponse
*/
public function delete(Bill $bill)
public function delete(Bill $bill): JsonResponse
{
$this->repository->destroy($bill);
@@ -82,9 +83,9 @@ class BillController extends Controller
*
* @param Request $request
*
* @return \Illuminate\Http\JsonResponse
* @return JsonResponse
*/
public function index(Request $request)
public function index(Request $request): JsonResponse
{
$pageSize = (int)Preferences::getForUser(auth()->user(), 'listPageSize', 50)->data;
$paginator = $this->repository->getPaginator($pageSize);
@@ -106,9 +107,9 @@ class BillController extends Controller
* @param Request $request
* @param Bill $bill
*
* @return \Illuminate\Http\JsonResponse
* @return JsonResponse
*/
public function show(Request $request, Bill $bill)
public function show(Request $request, Bill $bill): JsonResponse
{
$manager = new Manager();
// add include parameter:
@@ -126,22 +127,22 @@ class BillController extends Controller
/**
* @param BillRequest $request
*
* @return \Illuminate\Http\JsonResponse
* @return JsonResponse
* @throws FireflyException
*/
public function store(BillRequest $request)
public function store(BillRequest $request): JsonResponse
{
$bill = $this->repository->store($request->getAll());
if(null !== $bill) {
$manager = new Manager();
$baseUrl = $request->getSchemeAndHttpHost() . '/api/v1';
$manager->setSerializer(new JsonApiSerializer($baseUrl));
$bill = $this->repository->store($request->getAll());
if (null !== $bill) {
$manager = new Manager();
$baseUrl = $request->getSchemeAndHttpHost() . '/api/v1';
$manager->setSerializer(new JsonApiSerializer($baseUrl));
$resource = new Item($bill, new BillTransformer($this->parameters), 'bills');
$resource = new Item($bill, new BillTransformer($this->parameters), 'bills');
return response()->json($manager->createData($resource)->toArray())->header('Content-Type', 'application/vnd.api+json');
return response()->json($manager->createData($resource)->toArray())->header('Content-Type', 'application/vnd.api+json');
}
throw new FireflyException('Could not store new bill.');
throw new FireflyException('Could not store new bill.'); // @codeCoverageIgnore
}
@@ -150,9 +151,9 @@ class BillController extends Controller
* @param BillRequest $request
* @param Bill $bill
*
* @return \Illuminate\Http\JsonResponse
* @return JsonResponse
*/
public function update(BillRequest $request, Bill $bill)
public function update(BillRequest $request, Bill $bill): JsonResponse
{
$data = $request->getAll();
$bill = $this->repository->update($bill, $data);

View File

@@ -48,18 +48,9 @@ class Controller extends BaseController
/**
* Controller constructor.
*
* @throws FireflyException
*/
public function __construct()
{
// is site a demo site?
$isDemoSite = FireflyConfig::get('is_demo_site', config('firefly.configuration.is_demo_site'))->data;
// do not expose API on demo site:
if (true === $isDemoSite) {
throw new FireflyException('The API is not available on the demo site.');
}
// get global parameters
$this->parameters = $this->getParameters();
}
@@ -83,7 +74,7 @@ class Controller extends BaseController
}
}
$return .= http_build_query($params);
if (strlen($return) === 1) {
if (\strlen($return) === 1) {
return '';
}

View File

@@ -0,0 +1,208 @@
<?php
/**
* CurrencyController.php
* Copyright (c) 2018 thegrumpydictator@gmail.com
*
* This file is part of Firefly III.
*
* Firefly III is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* Firefly III is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with Firefly III. If not, see <http://www.gnu.org/licenses/>.
*/
declare(strict_types=1);
namespace FireflyIII\Api\V1\Controllers;
use FireflyIII\Api\V1\Requests\BillRequest;
use FireflyIII\Api\V1\Requests\CurrencyRequest;
use FireflyIII\Exceptions\FireflyException;
use FireflyIII\Models\TransactionCurrency;
use FireflyIII\Repositories\Currency\CurrencyRepositoryInterface;
use FireflyIII\Repositories\User\UserRepositoryInterface;
use FireflyIII\Transformers\CurrencyTransformer;
use Illuminate\Http\JsonResponse;
use Illuminate\Http\Request;
use Illuminate\Pagination\LengthAwarePaginator;
use League\Fractal\Manager;
use League\Fractal\Pagination\IlluminatePaginatorAdapter;
use League\Fractal\Resource\Collection as FractalCollection;
use League\Fractal\Resource\Item;
use League\Fractal\Serializer\JsonApiSerializer;
use Preferences;
/**
* Class CurrencyController
*/
class CurrencyController extends Controller
{
/** @var CurrencyRepositoryInterface */
private $repository;
/** @var UserRepositoryInterface */
private $userRepository;
/**
* CurrencyRepository constructor.
*
* @throws FireflyException
*/
public function __construct()
{
parent::__construct();
$this->middleware(
function ($request, $next) {
/** @var CurrencyRepositoryInterface repository */
$this->repository = app(CurrencyRepositoryInterface::class);
$this->userRepository = app(UserRepositoryInterface::class);
$this->repository->setUser(auth()->user());
return $next($request);
}
);
}
/**
* Remove the specified resource from storage.
*
* @param TransactionCurrency $currency
*
* @return JsonResponse
* @throws FireflyException
*/
public function delete(TransactionCurrency $currency): JsonResponse
{
if (!$this->userRepository->hasRole(auth()->user(), 'owner')) {
// access denied:
throw new FireflyException('No access to method, user is not owner.'); // @codeCoverageIgnore
}
if (!$this->repository->canDeleteCurrency($currency)) {
throw new FireflyException('No access to method, currency is in use.'); // @codeCoverageIgnore
}
$this->repository->destroy($currency);
return response()->json([], 204);
}
/**
* Display a listing of the resource.
*
* @param Request $request
*
* @return JsonResponse
*/
public function index(Request $request): JsonResponse
{
$pageSize = (int)Preferences::getForUser(auth()->user(), 'listPageSize', 50)->data;
$collection = $this->repository->get();
$count = $collection->count();
// slice them:
$currencies = $collection->slice(($this->parameters->get('page') - 1) * $pageSize, $pageSize);
$paginator = new LengthAwarePaginator($currencies, $count, $pageSize, $this->parameters->get('page'));
$paginator->setPath(route('api.v1.currencies.index') . $this->buildParams());
$manager = new Manager();
$baseUrl = $request->getSchemeAndHttpHost() . '/api/v1';
$manager->setSerializer(new JsonApiSerializer($baseUrl));
$defaultCurrency = app('amount')->getDefaultCurrencyByUser(auth()->user());
$this->parameters->set('defaultCurrency', $defaultCurrency);
$resource = new FractalCollection($currencies, new CurrencyTransformer($this->parameters), 'currencies');
$resource->setPaginator(new IlluminatePaginatorAdapter($paginator));
return response()->json($manager->createData($resource)->toArray())->header('Content-Type', 'application/vnd.api+json');
}
/**
* @param Request $request
* @param TransactionCurrency $currency
*
* @return JsonResponse
*/
public function show(Request $request, TransactionCurrency $currency): JsonResponse
{
$manager = new Manager();
// add include parameter:
$include = $request->get('include') ?? '';
$manager->parseIncludes($include);
$baseUrl = $request->getSchemeAndHttpHost() . '/api/v1';
$manager->setSerializer(new JsonApiSerializer($baseUrl));
$defaultCurrency = app('amount')->getDefaultCurrencyByUser(auth()->user());
$this->parameters->set('defaultCurrency', $defaultCurrency);
$resource = new Item($currency, new CurrencyTransformer($this->parameters), 'currencies');
return response()->json($manager->createData($resource)->toArray())->header('Content-Type', 'application/vnd.api+json');
}
/**
* @param CurrencyRequest $request
*
* @return JsonResponse
* @throws FireflyException
*/
public function store(CurrencyRequest $request): JsonResponse
{
$currency = $this->repository->store($request->getAll());
if ($request->boolean('default') === true) {
Preferences::set('currencyPreference', $currency->code);
Preferences::mark();
}
if (null !== $currency) {
$manager = new Manager();
$baseUrl = $request->getSchemeAndHttpHost() . '/api/v1';
$manager->setSerializer(new JsonApiSerializer($baseUrl));
$defaultCurrency = app('amount')->getDefaultCurrencyByUser(auth()->user());
$this->parameters->set('defaultCurrency', $defaultCurrency);
$resource = new Item($currency, new CurrencyTransformer($this->parameters), 'currencies');
return response()->json($manager->createData($resource)->toArray())->header('Content-Type', 'application/vnd.api+json');
}
throw new FireflyException('Could not store new currency.'); // @codeCoverageIgnore
}
/**
* @param CurrencyRequest $request
* @param TransactionCurrency $currency
*
* @return JsonResponse
*/
public function update(CurrencyRequest $request, TransactionCurrency $currency): JsonResponse
{
$data = $request->getAll();
$currency = $this->repository->update($currency, $data);
if ($request->boolean('default') === true) {
Preferences::set('currencyPreference', $currency->code);
Preferences::mark();
}
$manager = new Manager();
$baseUrl = $request->getSchemeAndHttpHost() . '/api/v1';
$manager->setSerializer(new JsonApiSerializer($baseUrl));
$defaultCurrency = app('amount')->getDefaultCurrencyByUser(auth()->user());
$this->parameters->set('defaultCurrency', $defaultCurrency);
$resource = new Item($currency, new CurrencyTransformer($this->parameters), 'currencies');
return response()->json($manager->createData($resource)->toArray())->header('Content-Type', 'application/vnd.api+json');
}
}

View File

@@ -111,7 +111,7 @@ class TransactionController extends Controller
$collector->setAllAssetAccounts();
// remove internal transfer filter:
if (in_array(TransactionType::TRANSFER, $types)) {
if (\in_array(TransactionType::TRANSFER, $types)) {
$collector->removeFilter(InternalTransferFilter::class);
}

View File

@@ -24,6 +24,7 @@ declare(strict_types=1);
namespace FireflyIII\Api\V1\Controllers;
use FireflyIII\Api\V1\Requests\UserRequest;
use FireflyIII\Exceptions\FireflyException;
use FireflyIII\Repositories\User\UserRepositoryInterface;
use FireflyIII\Transformers\UserTransformer;
use FireflyIII\User;
@@ -35,7 +36,7 @@ use League\Fractal\Resource\Collection as FractalCollection;
use League\Fractal\Resource\Item;
use League\Fractal\Serializer\JsonApiSerializer;
use Preferences;
use Symfony\Component\HttpFoundation\File\Exception\AccessDeniedException;
/**
* Class UserController
@@ -70,7 +71,7 @@ class UserController extends Controller
* @param \FireflyIII\User $user
*
* @return \Illuminate\Http\Response
* @throws \Symfony\Component\HttpFoundation\File\Exception\AccessDeniedException
* @throws FireflyException
*/
public function delete(User $user)
{
@@ -79,7 +80,7 @@ class UserController extends Controller
return response()->json([], 204);
}
throw new AccessDeniedException(''); // @codeCoverageIgnore
throw new FireflyException('No access to method.'); // @codeCoverageIgnore
}
/**

View File

@@ -46,18 +46,17 @@ class BillRequest extends Request
public function getAll(): array
{
$data = [
'name' => $this->string('name'),
'match' => $this->string('match'),
'amount_min' => $this->string('amount_min'),
'amount_max' => $this->string('amount_max'),
//'currency_id' => $this->integer('currency_id'),
//'currency_code' => $this->string('currency_code'),
'date' => $this->date('date'),
'repeat_freq' => $this->string('repeat_freq'),
'skip' => $this->integer('skip'),
'automatch' => $this->boolean('automatch'),
'active' => $this->boolean('active'),
'notes' => $this->string('notes'),
'name' => $this->string('name'),
'amount_min' => $this->string('amount_min'),
'amount_max' => $this->string('amount_max'),
'currency_id' => $this->integer('currency_id'),
'currency_code' => $this->string('currency_code'),
'date' => $this->date('date'),
'repeat_freq' => $this->string('repeat_freq'),
'skip' => $this->integer('skip'),
'automatch' => $this->boolean('automatch'),
'active' => $this->boolean('active'),
'notes' => $this->string('notes'),
];
return $data;
@@ -69,18 +68,17 @@ class BillRequest extends Request
public function rules(): array
{
$rules = [
'name' => 'required|between:1,255|uniqueObjectForUser:bills,name',
'match' => 'required|between:1,255|uniqueObjectForUser:bills,match',
'amount_min' => 'required|numeric|more:0',
'amount_max' => 'required|numeric|more:0',
//'currency_id' => 'numeric|exists:transaction_currencies,id|required_without:currency_code',
//'currency_code' => 'min:3|max:3|exists:transaction_currencies,code|required_without:currency_id',
'date' => 'required|date',
'repeat_freq' => 'required|in:weekly,monthly,quarterly,half-year,yearly',
'skip' => 'required|between:0,31',
'automatch' => 'required|boolean',
'active' => 'required|boolean',
'notes' => 'between:1,65536',
'name' => 'required|between:1,255|uniqueObjectForUser:bills,name',
'amount_min' => 'required|numeric|more:0',
'amount_max' => 'required|numeric|more:0',
'currency_id' => 'numeric|exists:transaction_currencies,id|required_without:currency_code',
'currency_code' => 'min:3|max:3|exists:transaction_currencies,code|required_without:currency_id',
'date' => 'required|date',
'repeat_freq' => 'required|in:weekly,monthly,quarterly,half-year,yearly',
'skip' => 'required|between:0,31',
'automatch' => 'required|boolean',
'active' => 'required|boolean',
'notes' => 'between:1,65536',
];
switch ($this->method()) {
default:
@@ -89,7 +87,6 @@ class BillRequest extends Request
case 'PATCH':
$bill = $this->route()->parameter('bill');
$rules['name'] .= ',' . $bill->id;
$rules['match'] .= ',' . $bill->id;
break;
}

View File

@@ -0,0 +1,83 @@
<?php
/**
* CurrencyRequest.php
* Copyright (c) 2018 thegrumpydictator@gmail.com
*
* This file is part of Firefly III.
*
* Firefly III is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* Firefly III is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with Firefly III. If not, see <http://www.gnu.org/licenses/>.
*/
declare(strict_types=1);
namespace FireflyIII\Api\V1\Requests;
/**
* Class CurrencyRequest
*/
class CurrencyRequest extends Request
{
/**
* @return bool
*/
public function authorize(): bool
{
// Only allow authenticated users
return auth()->check();
}
/**
* @return array
*/
public function getAll()
{
return [
'name' => $this->string('name'),
'code' => $this->string('code'),
'symbol' => $this->string('symbol'),
'decimal_places' => $this->integer('decimal_places'),
'default' => $this->boolean('default'),
];
}
/**
* @return array
*/
public function rules(): array
{
$rules = [
'name' => 'required|between:1,255|unique:transaction_currencies,name',
'code' => 'required|between:3,3|unique:transaction_currencies,code',
'symbol' => 'required|between:1,5|unique:transaction_currencies,symbol',
'decimal_places' => 'required|between:0,20|numeric|min:0|max:20',
'default' => 'in:true,false',
];
switch ($this->method()) {
default:
break;
case 'PUT':
case 'PATCH':
$currency = $this->route()->parameter('currency');
$rules['name'] = 'required|between:1,255|unique:transaction_currencies,name,' . $currency->id;
$rules['code'] = 'required|between:1,255|unique:transaction_currencies,code,' . $currency->id;
$rules['symbol'] = 'required|between:1,255|unique:transaction_currencies,symbol,' . $currency->id;
break;
}
return $rules;
}
}

View File

@@ -168,7 +168,6 @@ class TransactionRequest extends Request
* @param Validator $validator
*
* @return void
* @throws \FireflyIII\Exceptions\FireflyException
*/
public function withValidator(Validator $validator): void
{
@@ -202,7 +201,7 @@ class TransactionRequest extends Request
$accountId = (int)$accountId;
$accountName = (string)$accountName;
// both empty? hard exit.
if ($accountId < 1 && strlen($accountName) === 0) {
if ($accountId < 1 && \strlen($accountName) === 0) {
$validator->errors()->add($idField, trans('validation.filled', ['attribute' => $idField]));
return null;
@@ -225,7 +224,7 @@ class TransactionRequest extends Request
return $first;
}
$account = $repository->findByNameNull($accountName, [AccountType::ASSET]);
$account = $repository->findByName($accountName, [AccountType::ASSET]);
if (null === $account) {
$validator->errors()->add($nameField, trans('validation.belongs_user'));
@@ -245,7 +244,7 @@ class TransactionRequest extends Request
$data = $validator->getData();
$transactions = $data['transactions'] ?? [];
// need at least one transaction
if (count($transactions) === 0) {
if (\count($transactions) === 0) {
$validator->errors()->add('description', trans('validation.at_least_one_transaction'));
}
}
@@ -263,13 +262,13 @@ class TransactionRequest extends Request
$journalDescription = (string)($data['description'] ?? '');
$validDescriptions = 0;
foreach ($transactions as $index => $transaction) {
if (strlen((string)($transaction['description'] ?? '')) > 0) {
if (\strlen((string)($transaction['description'] ?? '')) > 0) {
$validDescriptions++;
}
}
// no valid descriptions and empty journal description? error.
if ($validDescriptions === 0 && strlen($journalDescription) === 0) {
if ($validDescriptions === 0 && \strlen($journalDescription) === 0) {
$validator->errors()->add('description', trans('validation.filled', ['attribute' => trans('validation.attributes.description')]));
}
@@ -288,7 +287,7 @@ class TransactionRequest extends Request
foreach ($transactions as $index => $transaction) {
$description = (string)($transaction['description'] ?? '');
// filled description is mandatory for split transactions.
if (count($transactions) > 1 && strlen($description) === 0) {
if (\count($transactions) > 1 && \strlen($description) === 0) {
$validator->errors()->add(
'transactions.' . $index . '.description',
trans('validation.filled', ['attribute' => trans('validation.attributes.transaction_description')])
@@ -355,7 +354,7 @@ class TransactionRequest extends Request
$accountId = (int)$accountId;
$accountName = (string)$accountName;
// both empty? done!
if ($accountId < 1 && strlen($accountName) === 0) {
if ($accountId < 1 && \strlen($accountName) === 0) {
return null;
}
if ($accountId !== 0) {
@@ -457,7 +456,7 @@ class TransactionRequest extends Request
protected function validateSplitAccounts(Validator $validator)
{
$data = $validator->getData();
$count = isset($data['transactions']) ? count($data['transactions']) : 0;
$count = isset($data['transactions']) ? \count($data['transactions']) : 0;
if ($count < 2) {
return;
}
@@ -487,17 +486,17 @@ class TransactionRequest extends Request
// switch on type:
switch ($data['type']) {
case 'withdrawal':
if (count($sources) > 1) {
if (\count($sources) > 1) {
$validator->errors()->add('transactions.0.source_id', trans('validation.all_accounts_equal'));
}
break;
case 'deposit':
if (count($destinations) > 1) {
if (\count($destinations) > 1) {
$validator->errors()->add('transactions.0.destination_id', trans('validation.all_accounts_equal'));
}
break;
case 'transfer':
if (count($sources) > 1 || count($destinations) > 1) {
if (\count($sources) > 1 || \count($destinations) > 1) {
$validator->errors()->add('transactions.0.source_id', trans('validation.all_accounts_equal'));
$validator->errors()->add('transactions.0.destination_id', trans('validation.all_accounts_equal'));
}

View File

@@ -89,9 +89,9 @@ class CreateExport extends Command
$accountRepository->setUser($user);
// first date
$firstJournal = $journalRepository->first();
$firstJournal = $journalRepository->firstNull();
$first = new Carbon;
if (null !== $firstJournal->id) {
if (null !== $firstJournal) {
$first = $firstJournal->date;
}

View File

@@ -100,6 +100,5 @@ class DecryptAttachment extends Command
}
$this->info(sprintf('%d bytes written. Exiting now..', $result));
return;
}
}

View File

@@ -93,7 +93,6 @@ class Import extends Command
sprintf('The import has finished. %d transactions have been imported out of %d records.', $routine->getJournals()->count(), $routine->getLines())
);
return;
}
/**

View File

@@ -28,13 +28,20 @@ use FireflyIII\Models\Account;
use FireflyIII\Models\AccountMeta;
use FireflyIII\Models\AccountType;
use FireflyIII\Models\Attachment;
use FireflyIII\Models\Bill;
use FireflyIII\Models\Note;
use FireflyIII\Models\Preference;
use FireflyIII\Models\Rule;
use FireflyIII\Models\RuleAction;
use FireflyIII\Models\RuleGroup;
use FireflyIII\Models\RuleTrigger;
use FireflyIII\Models\Transaction;
use FireflyIII\Models\TransactionCurrency;
use FireflyIII\Models\TransactionJournal;
use FireflyIII\Models\TransactionJournalMeta;
use FireflyIII\Models\TransactionType;
use FireflyIII\Repositories\Currency\CurrencyRepositoryInterface;
use FireflyIII\User;
use Illuminate\Console\Command;
use Illuminate\Database\QueryException;
use Illuminate\Support\Collection;
@@ -79,9 +86,128 @@ class UpgradeDatabase extends Command
$this->line('Done updating currency information..');
$this->migrateNotes();
$this->migrateAttachmentData();
$this->info('Firefly III database is up to date.');
$this->migrateBillsToRules();
return;
$this->info('Firefly III database is up to date.');
}
public function migrateBillsToRules()
{
foreach (User::get() as $user) {
/** @var Preference $lang */
$lang = Preferences::getForUser($user, 'language', 'en_US');
$groupName = (string)trans('firefly.rulegroup_for_bills_title', [], $lang->data);
$ruleGroup = $user->ruleGroups()->where('title', $groupName)->first();
$currencyPreference = Preferences::getForUser($user, 'currencyPreference', config('firefly.default_currency', 'EUR'));
$currency = TransactionCurrency::where('code', $currencyPreference->data)->first();
if (null === $currency) {
$currency = app('amount')->getDefaultCurrency();
}
if ($ruleGroup === null) {
$array = RuleGroup::get(['order'])->pluck('order')->toArray();
$order = \count($array) > 0 ? max($array) + 1 : 1;
$ruleGroup = RuleGroup::create(
[
'user_id' => $user->id,
'title' => (string)trans('firefly.rulegroup_for_bills_title', [], $lang->data),
'description' => (string)trans('firefly.rulegroup_for_bills_description', [], $lang->data),
'order' => $order,
'active' => 1,
]
);
}
// loop bills.
$order = 1;
/** @var Collection $collection */
$collection = $user->bills()->get();
/** @var Bill $bill */
foreach ($collection as $bill) {
if ($bill->match !== 'MIGRATED_TO_RULES') {
$rule = Rule::create(
[
'user_id' => $user->id,
'rule_group_id' => $ruleGroup->id,
'title' => (string)trans('firefly.rule_for_bill_title', ['name' => $bill->name], $lang->data),
'description' => (string)trans('firefly.rule_for_bill_description', ['name' => $bill->name], $lang->data),
'order' => $order,
'active' => $bill->active,
'stop_processing' => 1,
]
);
// add default trigger
RuleTrigger::create(
[
'rule_id' => $rule->id,
'trigger_type' => 'user_action',
'trigger_value' => 'store-journal',
'active' => 1,
'stop_processing' => 0,
'order' => 1,
]
);
// add trigger for description
$match = implode(' ', explode(',', $bill->match));
RuleTrigger::create(
[
'rule_id' => $rule->id,
'trigger_type' => 'description_contains',
'trigger_value' => $match,
'active' => 1,
'stop_processing' => 0,
'order' => 2,
]
);
// add triggers for amounts:
RuleTrigger::create(
[
'rule_id' => $rule->id,
'trigger_type' => 'amount_less',
'trigger_value' => round($bill->amount_max, $currency->decimal_places),
'active' => 1,
'stop_processing' => 0,
'order' => 3,
]
);
RuleTrigger::create(
[
'rule_id' => $rule->id,
'trigger_type' => 'amount_more',
'trigger_value' => round($bill->amount_min, $currency->decimal_places),
'active' => 1,
'stop_processing' => 0,
'order' => 4,
]
);
// create action
RuleAction::create(
[
'rule_id' => $rule->id,
'action_type' => 'link_to_bill',
'action_value' => $bill->name,
'order' => 1,
'active' => 1,
'stop_processing' => 0,
]
);
$order++;
$bill->match = 'MIGRATED_TO_RULES';
$bill->save();
$this->line(sprintf('Updated bill #%d ("%s") so it will use rules.', $bill->id, $bill->name));
}
// give bills a currency when they dont have one.
if (null === $bill->transaction_currency_id) {
$this->line(sprintf('Gave bill #%d ("%s") a currency (%s).', $bill->id, $bill->name, $currency->name));
$bill->transactionCurrency()->associate($currency);
$bill->save();
}
}
}
}
/**
@@ -114,7 +240,6 @@ class UpgradeDatabase extends Command
$this->updateJournalidentifiers((int)$journalId);
}
return;
}
/**
@@ -168,7 +293,6 @@ class UpgradeDatabase extends Command
}
);
return;
}
/**
@@ -226,7 +350,6 @@ class UpgradeDatabase extends Command
}
);
return;
}
/**
@@ -287,7 +410,7 @@ class UpgradeDatabase extends Command
// move description:
$description = (string)$att->description;
if (strlen($description) > 0) {
if (\strlen($description) > 0) {
// find or create note:
$note = $att->notes()->first();
if (null === $note) {
@@ -358,7 +481,6 @@ class UpgradeDatabase extends Command
$journal->save();
}
return;
}
/**
@@ -404,7 +526,6 @@ class UpgradeDatabase extends Command
++$identifier;
}
return;
}
/**
@@ -425,7 +546,13 @@ class UpgradeDatabase extends Command
{
/** @var CurrencyRepositoryInterface $repository */
$repository = app(CurrencyRepositoryInterface::class);
$currency = $repository->find((int)$transaction->account->getMeta('currency_id'));
$currency = $repository->findNull((int)$transaction->account->getMeta('currency_id'));
if (null === $currency) {
Log::error(sprintf('Account #%d ("%s") must have currency preference but has none.', $transaction->account->id, $transaction->account->name));
return;
}
// has no currency ID? Must have, so fill in using account preference:
if (null === $transaction->transaction_currency_id) {
@@ -455,9 +582,9 @@ class UpgradeDatabase extends Command
$journal = $transaction->transactionJournal;
/** @var Transaction $opposing */
$opposing = $journal->transactions()->where('amount', '>', 0)->where('identifier', $transaction->identifier)->first();
$opposingCurrency = $repository->find((int)$opposing->account->getMeta('currency_id'));
$opposingCurrency = $repository->findNull((int)$opposing->account->getMeta('currency_id'));
if (null === $opposingCurrency->id) {
if (null === $opposingCurrency) {
Log::error(sprintf('Account #%d ("%s") must have currency preference but has none.', $opposing->account->id, $opposing->account->name));
return;
@@ -473,7 +600,12 @@ class UpgradeDatabase extends Command
$opposing->transaction_currency_id = $currency->id;
$transaction->save();
$opposing->save();
Log::debug(sprintf('Cleaned up transaction #%d and #%d', $transaction->id, $opposing->id));
Log::debug(sprintf('Currency for account "%s" is %s, and currency for account "%s" is also
%s, so %s #%d (#%d and #%d) has been verified to be to %s exclusively.',
$opposing->account->name, $opposingCurrency->code,
$transaction->account->name, $transaction->transactionCurrency->code,
$journal->transactionType->type, $journal->id,
$transaction->id, $opposing->id, $currency->code));
return;
}
@@ -526,7 +658,6 @@ class UpgradeDatabase extends Command
$opposing->save();
}
return;
}
}

View File

@@ -92,7 +92,7 @@ class UpgradeFireflyInstructions extends Command
$text = '';
foreach (array_keys($config) as $compare) {
// if string starts with:
$len = strlen($compare);
$len = \strlen($compare);
if (substr($version, 0, $len) === $compare) {
$text = $config[$compare];
}
@@ -139,7 +139,7 @@ class UpgradeFireflyInstructions extends Command
$text = '';
foreach (array_keys($config) as $compare) {
// if string starts with:
$len = strlen($compare);
$len = \strlen($compare);
if (substr($version, 0, $len) === $compare) {
$text = $config[$compare];
}

View File

@@ -87,12 +87,13 @@ class VerifyDatabase extends Command
$this->createLinkTypes();
$this->createAccessTokens();
$this->fixDoubleAmounts();
$this->fixBadMeta();
}
/**
* Create user access tokens, if not present already.
*/
private function createAccessTokens()
private function createAccessTokens(): void
{
$count = 0;
$users = User::get();
@@ -114,7 +115,7 @@ class VerifyDatabase extends Command
/**
* Create default link types if necessary.
*/
private function createLinkTypes()
private function createLinkTypes(): void
{
$count = 0;
$set = [
@@ -140,7 +141,69 @@ class VerifyDatabase extends Command
}
}
private function fixDoubleAmounts()
/**
* Fix the situation where the matching transactions
* of a journal somehow have non-matching categories
* or budgets
*/
private function fixBadMeta(): void
{
// categories
$set = Transaction
::leftJoin('category_transaction', 'category_transaction.transaction_id', '=', 'transactions.id')
->whereNull('transactions.deleted_at')
->get(['transactions.id', 'transaction_journal_id', 'identifier', 'category_transaction.category_id', 'category_transaction.id as ct_id']);
$results = [];
foreach ($set as $obj) {
$key = $obj->transaction_journal_id . '-' . $obj->identifier;
$category = (int)$obj->category_id;
// value exists and is not category:
if (isset($results[$key]) && $results[$key] !== $category) {
$this->error(
sprintf(
'Transaction #%d referred to the wrong category. Was category #%d but is fixed to be category #%d.', $obj->transaction_journal_id, $category, $results[$key]
)
);
DB::table('category_transaction')->where('id', $obj->ct_id)->update(['category_id' => $results[$key]]);
}
// value does not exist:
if ($category > 0 && !isset($results[$key])) {
$results[$key] = $category;
}
}
// budgets
$set = Transaction
::leftJoin('budget_transaction', 'budget_transaction.transaction_id', '=', 'transactions.id')
->whereNull('transactions.deleted_at')
->get(['transactions.id', 'transaction_journal_id', 'identifier', 'budget_transaction.budget_id', 'budget_transaction.id as ct_id']);
$results = [];
foreach ($set as $obj) {
$key = $obj->transaction_journal_id . '-' . $obj->identifier;
$budget = (int)$obj->budget_id;
// value exists and is not budget:
if (isset($results[$key]) && $results[$key] !== $budget) {
$this->error(
sprintf(
'Transaction #%d referred to the wrong budget. Was budget #%d but is fixed to be budget #%d.', $obj->transaction_journal_id, $budget, $results[$key]
)
);
DB::table('budget_transaction')->where('id', $obj->ct_id)->update(['budget_id' => $results[$key]]);
}
// value does not exist:
if ($budget > 0 && !isset($results[$key])) {
$results[$key] = $budget;
}
}
}
private function fixDoubleAmounts(): void
{
$count = 0;
// get invalid journals
@@ -186,8 +249,6 @@ class VerifyDatabase extends Command
if (0 === $count) {
$this->info('Amount integrity OK!');
}
return;
}
/**
@@ -217,8 +278,6 @@ class VerifyDatabase extends Command
return true;
}
);
return;
}
/**
@@ -246,7 +305,7 @@ class VerifyDatabase extends Command
/**
* Reports on budgets with no budget limits (which makes them pointless).
*/
private function reportBudgetLimits()
private function reportBudgetLimits(): void
{
$set = Budget::leftJoin('budget_limits', 'budget_limits.budget_id', '=', 'budgets.id')
->leftJoin('users', 'budgets.user_id', '=', 'users.id')
@@ -270,7 +329,7 @@ class VerifyDatabase extends Command
/**
* Reports on deleted accounts that still have not deleted transactions or journals attached to them.
*/
private function reportDeletedAccounts()
private function reportDeletedAccounts(): void
{
$set = Account::leftJoin('transactions', 'transactions.account_id', '=', 'accounts.id')
->leftJoin('transaction_journals', 'transaction_journals.id', '=', 'transactions.transaction_journal_id')
@@ -300,7 +359,7 @@ class VerifyDatabase extends Command
/**
* Report on journals with bad account types linked to them.
*/
private function reportIncorrectJournals()
private function reportIncorrectJournals(): void
{
$configuration = [
// a withdrawal can not have revenue account:
@@ -342,7 +401,7 @@ class VerifyDatabase extends Command
/**
* Any deleted transaction journals that have transactions that are NOT deleted:.
*/
private function reportJournals()
private function reportJournals(): void
{
$count = 0;
$set = TransactionJournal::leftJoin('transactions', 'transactions.transaction_journal_id', '=', 'transaction_journals.id')
@@ -373,7 +432,7 @@ class VerifyDatabase extends Command
/**
* Report on journals without transactions.
*/
private function reportNoTransactions()
private function reportNoTransactions(): void
{
$count = 0;
$set = TransactionJournal::leftJoin('transactions', 'transactions.transaction_journal_id', '=', 'transaction_journals.id')
@@ -397,7 +456,7 @@ class VerifyDatabase extends Command
*
* @param string $name
*/
private function reportObject(string $name)
private function reportObject(string $name): void
{
$plural = str_plural($name);
$class = sprintf('FireflyIII\Models\%s', ucfirst($name));
@@ -433,7 +492,7 @@ class VerifyDatabase extends Command
/**
* Reports for each user when the sum of their transactions is not zero.
*/
private function reportSum()
private function reportSum(): void
{
/** @var UserRepositoryInterface $userRepository */
$userRepository = app(UserRepositoryInterface::class);
@@ -452,7 +511,7 @@ class VerifyDatabase extends Command
/**
* Reports on deleted transactions that are connected to a not deleted journal.
*/
private function reportTransactions()
private function reportTransactions(): void
{
$set = Transaction::leftJoin('transaction_journals', 'transactions.transaction_journal_id', '=', 'transaction_journals.id')
->whereNotNull('transactions.deleted_at')

View File

@@ -85,7 +85,7 @@ class Handler extends ExceptionHandler
return response()->json(
[
'message' => $exception->getMessage(),
'exception' => get_class($exception),
'exception' => \get_class($exception),
'line' => $exception->getLine(),
'file' => $exception->getFile(),
'trace' => $exception->getTrace(),
@@ -93,7 +93,7 @@ class Handler extends ExceptionHandler
);
}
return response()->json(['message' => 'Internal Firefly III Exception. See log files.', 'exception' => get_class($exception)], 500);
return response()->json(['message' => 'Internal Firefly III Exception. See log files.', 'exception' => \get_class($exception)], 500);
}
if ($exception instanceof FireflyException || $exception instanceof ErrorException) {
@@ -131,7 +131,7 @@ class Handler extends ExceptionHandler
$userData['email'] = auth()->user()->email;
}
$data = [
'class' => get_class($exception),
'class' => \get_class($exception),
'errorMessage' => $exception->getMessage(),
'time' => date('r'),
'stackTrace' => $exception->getTraceAsString(),

View File

@@ -97,14 +97,16 @@ class AttachmentCollector extends BasicCollector implements CollectorInterface
$file = $attachment->fileName();
if ($this->uploadDisk->exists($file)) {
try {
$decrypted = Crypt::decrypt($this->uploadDisk->get($file));
$exportFile = $this->exportFileName($attachment);
$this->exportDisk->put($exportFile, $decrypted);
$this->getEntries()->push($exportFile);
$decrypted = Crypt::decrypt($this->uploadDisk->get($file));
} catch (DecryptException $e) {
Log::error('Catchable error: could not decrypt attachment #' . $attachment->id . ' because: ' . $e->getMessage());
return false;
}
}
$exportFile = $this->exportFileName($attachment);
$this->exportDisk->put($exportFile, $decrypted);
$this->getEntries()->push($exportFile);
return true;
}

View File

@@ -103,7 +103,7 @@ class UploadCollector extends BasicCollector implements CollectorInterface
Log::error(sprintf('Could not decrypt old import file "%s". Skipped because: %s', $key, $e->getMessage()));
}
if (strlen($content) > 0) {
if (\strlen($content) > 0) {
// add to export disk.
$date = $job->created_at->format('Y-m-d');
$file = sprintf('%s-Old %s import dated %s.%s', $this->job->key, strtoupper($job->file_type), $date, $job->file_type);

View File

@@ -199,7 +199,7 @@ final class Entry
$entry->transaction_id = $transaction->id;
$entry->date = $transaction->date->format('Ymd');
$entry->description = $transaction->description;
if (strlen((string)$transaction->transaction_description) > 0) {
if (\strlen((string)$transaction->transaction_description) > 0) {
$entry->description = $transaction->transaction_description . '(' . $transaction->description . ')';
}
$entry->currency_code = $transaction->transactionCurrency->code;

View File

@@ -39,6 +39,7 @@ use Illuminate\Support\Collection;
use Log;
use Storage;
use ZipArchive;
use FireflyIII\Models\TransactionJournal;
/**
* Class ExpandedProcessor.
@@ -310,13 +311,13 @@ class ExpandedProcessor implements ProcessorInterface
private function getNotes(array $array): array
{
$array = array_unique($array);
$notes = Note::where('notes.noteable_type', 'FireflyIII\\Models\\TransactionJournal')
$notes = Note::where('notes.noteable_type', TransactionJournal::class)
->whereIn('notes.noteable_id', $array)
->get(['notes.*']);
$return = [];
/** @var Note $note */
foreach ($notes as $note) {
if (strlen(trim((string)$note->text)) > 0) {
if (\strlen(trim((string)$note->text)) > 0) {
$id = (int)$note->noteable_id;
$return[$id] = $note->text;
}

View File

@@ -45,23 +45,20 @@ class BillFactory
*/
public function create(array $data): ?Bill
{
$matchArray = explode(',', $data['match']);
$matchArray = array_unique($matchArray);
$match = implode(',', $matchArray);
/** @var Bill $bill */
$bill = Bill::create(
[
'name' => $data['name'],
'match' => $match,
'amount_min' => $data['amount_min'],
'user_id' => $this->user->id,
'amount_max' => $data['amount_max'],
'date' => $data['date'],
'repeat_freq' => $data['repeat_freq'],
'skip' => $data['skip'],
'automatch' => $data['automatch'],
'active' => $data['active'],
'name' => $data['name'],
'match' => 'MIGRATED_TO_RULES',
'amount_min' => $data['amount_min'],
'user_id' => $this->user->id,
'transaction_currency_id' => $data['transaction_currency_id'],
'amount_max' => $data['amount_max'],
'date' => $data['date'],
'repeat_freq' => $data['repeat_freq'],
'skip' => $data['skip'],
'automatch' => true,
'active' => $data['active'],
]
);
@@ -94,7 +91,7 @@ class BillFactory
}
// then find by name:
if (strlen($billName) > 0) {
if (\strlen($billName) > 0) {
$bill = $this->findByName($billName);
if (null !== $bill) {
return $bill;

View File

@@ -47,7 +47,7 @@ class BudgetFactory
$budgetId = (int)$budgetId;
$budgetName = (string)$budgetName;
if (strlen($budgetName) === 0 && $budgetId === 0) {
if (\strlen($budgetName) === 0 && $budgetId === 0) {
return null;
}
@@ -60,7 +60,7 @@ class BudgetFactory
}
}
if (strlen($budgetName) > 0) {
if (\strlen($budgetName) > 0) {
$budget = $this->findByName($budgetName);
if (null !== $budget) {
return $budget;

View File

@@ -71,7 +71,7 @@ class CategoryFactory
Log::debug(sprintf('Going to find category with ID %d and name "%s"', $categoryId, $categoryName));
if (strlen($categoryName) === 0 && $categoryId === 0) {
if (\strlen($categoryName) === 0 && $categoryId === 0) {
return null;
}
// first by ID:
@@ -83,7 +83,7 @@ class CategoryFactory
}
}
if (strlen($categoryName) > 0) {
if (\strlen($categoryName) > 0) {
$category = $this->findByName($categoryName);
if (null !== $category) {
return $category;

View File

@@ -62,8 +62,8 @@ class PiggyBankEventFactory
$piggyRepos->setUser($journal->user);
// repetition exists?
$repetition = $piggyRepos->getRepetition($piggyBank, $journal->date);
if (null === $repetition->id) {
$repetition = $piggyRepos->getRepetition($piggyBank);
if (null === $repetition) {
Log::error(sprintf('No piggy bank repetition on %s!', $journal->date->format('Y-m-d')));
return null;

View File

@@ -45,7 +45,7 @@ class PiggyBankFactory
{
$piggyBankId = (int)$piggyBankId;
$piggyBankName = (string)$piggyBankName;
if (strlen($piggyBankName) === 0 && $piggyBankId === 0) {
if (\strlen($piggyBankName) === 0 && $piggyBankId === 0) {
return null;
}
// first find by ID:
@@ -58,7 +58,7 @@ class PiggyBankFactory
}
// then find by name:
if (strlen($piggyBankName) > 0) {
if (\strlen($piggyBankName) > 0) {
/** @var PiggyBank $piggyBank */
$piggyBank = $this->findByName($piggyBankName);
if (null !== $piggyBank) {

View File

@@ -71,7 +71,7 @@ class TagFactory
/** @var Tag $object */
foreach ($this->tags as $object) {
if ($object->tag === $tag) {
if (strtolower($object->tag) === strtolower($tag)) {
return $object;
}
}

View File

@@ -68,7 +68,7 @@ class TransactionCurrencyFactory
$currencyCode = (string)$currencyCode;
$currencyId = (int)$currencyId;
if (strlen($currencyCode) === 0 && (int)$currencyId === 0) {
if (\strlen($currencyCode) === 0 && (int)$currencyId === 0) {
return null;
}
@@ -80,7 +80,7 @@ class TransactionCurrencyFactory
}
}
// then by code:
if (strlen($currencyCode) > 0) {
if (\strlen($currencyCode) > 0) {
$currency = TransactionCurrency::whereCode($currencyCode)->first();
if (null !== $currency) {
return $currency;

View File

@@ -91,7 +91,7 @@ class TransactionJournalFactory
// store date meta fields (if present):
$fields = ['sepa-cc', 'sepa-ct-op', 'sepa-ct-id', 'sepa-db', 'sepa-country', 'sepa-ep', 'sepa-ci', 'interest_date', 'book_date', 'process_date',
'due_date', 'payment_date', 'invoice_date', 'internal_reference', 'bunq_payment_id'];
'due_date', 'payment_date', 'invoice_date', 'internal_reference', 'bunq_payment_id','importHash'];
foreach ($fields as $field) {
$this->storeMeta($journal, $data, $field);

View File

@@ -66,10 +66,10 @@ class ChartJsGenerator implements GeneratorInterface
{
reset($data);
$first = current($data);
$labels = is_array($first['entries']) ? array_keys($first['entries']) : [];
$labels = \is_array($first['entries']) ? array_keys($first['entries']) : [];
$chartData = [
'count' => count($data),
'count' => \count($data),
'labels' => $labels, // take ALL labels from the first set.
'datasets' => [],
];
@@ -119,7 +119,7 @@ class ChartJsGenerator implements GeneratorInterface
// different sort when values are positive and when they're negative.
asort($data);
$next = next($data);
if (!is_bool($next) && 1 === bccomp($next, '0')) {
if (!\is_bool($next) && 1 === bccomp($next, '0')) {
// next is positive, sort other way around.
arsort($data);
}

View File

@@ -42,7 +42,6 @@ class MonthReportGenerator implements ReportGeneratorInterface
/**
* @return string
*
*/
public function generate(): string
{

View File

@@ -41,8 +41,6 @@ class MonthReportGenerator implements ReportGeneratorInterface
/**
* @return string
*
*/
public function generate(): string
{

View File

@@ -40,8 +40,6 @@ class MultiYearReportGenerator implements ReportGeneratorInterface
/**
* @return string
*
*/
public function generate(): string
{

View File

@@ -40,8 +40,6 @@ class YearReportGenerator implements ReportGeneratorInterface
/**
* @return string
*
*/
public function generate(): string
{

View File

@@ -28,7 +28,6 @@ use FireflyIII\Models\RuleGroup;
use FireflyIII\Repositories\Journal\JournalRepositoryInterface as JRI;
use FireflyIII\Repositories\PiggyBank\PiggyBankRepositoryInterface as PRI;
use FireflyIII\Repositories\RuleGroup\RuleGroupRepositoryInterface as RGRI;
use FireflyIII\Support\Events\BillScanner;
use FireflyIII\TransactionRules\Processor;
/**
@@ -91,18 +90,4 @@ class StoredJournalEventHandler
return true;
}
/**
* This method calls a special bill scanner that will check if the stored journal is part of a bill.
*
* @param StoredTransactionJournal $storedJournalEvent
*
* @return bool
*/
public function scanBills(StoredTransactionJournal $storedJournalEvent): bool
{
$journal = $storedJournalEvent->journal;
BillScanner::scan($journal);
return true;
}
}

View File

@@ -26,7 +26,6 @@ use FireflyIII\Events\UpdatedTransactionJournal;
use FireflyIII\Models\Rule;
use FireflyIII\Models\RuleGroup;
use FireflyIII\Repositories\RuleGroup\RuleGroupRepositoryInterface;
use FireflyIII\Support\Events\BillScanner;
use FireflyIII\TransactionRules\Processor;
/**
@@ -80,18 +79,4 @@ class UpdatedJournalEventHandler
return true;
}
/**
* This method calls a special bill scanner that will check if the updated journal is part of a bill.
*
* @param UpdatedTransactionJournal $updatedJournalEvent
*
* @return bool
*/
public function scanBills(UpdatedTransactionJournal $updatedJournalEvent): bool
{
$journal = $updatedJournalEvent->journal;
BillScanner::scan($journal);
return true;
}
}

View File

@@ -108,8 +108,8 @@ class AttachmentHelper implements AttachmentHelperInterface
*/
public function saveAttachmentsForModel(Model $model, ?array $files): bool
{
Log::debug(sprintf('Now in saveAttachmentsForModel for model %s', get_class($model)));
if (is_array($files)) {
Log::debug(sprintf('Now in saveAttachmentsForModel for model %s', \get_class($model)));
if (\is_array($files)) {
Log::debug('$files is an array.');
/** @var UploadedFile $entry */
foreach ($files as $entry) {
@@ -136,7 +136,7 @@ class AttachmentHelper implements AttachmentHelperInterface
{
$md5 = md5_file($file->getRealPath());
$name = $file->getClientOriginalName();
$class = get_class($model);
$class = \get_class($model);
$count = $model->user->attachments()->where('md5', $md5)->where('attachable_id', $model->id)->where('attachable_type', $class)->count();
if ($count > 0) {
@@ -180,8 +180,8 @@ class AttachmentHelper implements AttachmentHelperInterface
$fileObject->rewind();
$content = $fileObject->fread($file->getSize());
$encrypted = Crypt::encrypt($content);
Log::debug(sprintf('Full file length is %d and upload size is %d.', strlen($content), $file->getSize()));
Log::debug(sprintf('Encrypted content is %d', strlen($encrypted)));
Log::debug(sprintf('Full file length is %d and upload size is %d.', \strlen($content), $file->getSize()));
Log::debug(sprintf('Encrypted content is %d', \strlen($encrypted)));
// store it:
$this->uploadDisk->put($attachment->fileName(), $encrypted);
@@ -210,7 +210,7 @@ class AttachmentHelper implements AttachmentHelperInterface
Log::debug(sprintf('Name is %s, and mime is %s', $name, $mime));
Log::debug('Valid mimes are', $this->allowedMimes);
if (!in_array($mime, $this->allowedMimes)) {
if (!\in_array($mime, $this->allowedMimes)) {
$msg = (string)trans('validation.file_invalid_mime', ['name' => $name, 'mime' => $mime]);
$this->errors->add('attachments', $msg);
Log::error($msg);

View File

@@ -298,7 +298,7 @@ class MetaPieChart implements MetaPieChartInterface
*/
protected function groupByFields(Collection $set, array $fields): array
{
if (0 === count($fields) && $this->tags->count() > 0) {
if (0 === \count($fields) && $this->tags->count() > 0) {
// do a special group on tags:
return $this->groupByTag($set); // @codeCoverageIgnore
}

View File

@@ -136,7 +136,7 @@ class JournalCollector implements JournalCollectorInterface
public function addFilter(string $filter): JournalCollectorInterface
{
$interfaces = class_implements($filter);
if (in_array(FilterInterface::class, $interfaces) && !in_array($filter, $this->filters)) {
if (\in_array(FilterInterface::class, $interfaces) && !\in_array($filter, $this->filters)) {
Log::debug(sprintf('Enabled filter %s', $filter));
$this->filters[] = $filter;
}
@@ -254,6 +254,9 @@ class JournalCollector implements JournalCollectorInterface
$key = 'query-' . substr($hash, -8);
$cache = new CacheProperties;
$cache->addProperty($key);
foreach ($this->filters as $filter) {
$cache->addProperty((string)$filter);
}
if ($cache->has()) {
Log::debug(sprintf('Return cache of query with ID "%s".', $key));
@@ -441,7 +444,7 @@ class JournalCollector implements JournalCollectorInterface
public function setBudgets(Collection $budgets): JournalCollectorInterface
{
$budgetIds = $budgets->pluck('id')->toArray();
if (0 === count($budgetIds)) {
if (0 === \count($budgetIds)) {
return $this;
}
$this->joinBudgetTables();
@@ -465,7 +468,7 @@ class JournalCollector implements JournalCollectorInterface
public function setCategories(Collection $categories): JournalCollectorInterface
{
$categoryIds = $categories->pluck('id')->toArray();
if (0 === count($categoryIds)) {
if (0 === \count($categoryIds)) {
return $this;
}
$this->joinCategoryTables();
@@ -640,7 +643,7 @@ class JournalCollector implements JournalCollectorInterface
*/
public function setTypes(array $types): JournalCollectorInterface
{
if (count($types) > 0) {
if (\count($types) > 0) {
Log::debug('Set query collector types', $types);
$this->query->whereIn('transaction_types.type', $types);
}
@@ -679,6 +682,7 @@ class JournalCollector implements JournalCollectorInterface
->orderBy('transaction_journals.order', 'ASC')
->orderBy('transaction_journals.id', 'DESC')
->orderBy('transaction_journals.description', 'DESC')
->orderBy('transactions.identifier', 'ASC')
->orderBy('transactions.amount', 'DESC');
$this->query = $query;
@@ -765,7 +769,7 @@ class JournalCollector implements JournalCollectorInterface
SplitIndicatorFilter::class => new SplitIndicatorFilter,
CountAttachmentsFilter::class => new CountAttachmentsFilter,
];
Log::debug(sprintf('Will run %d filters on the set.', count($this->filters)));
Log::debug(sprintf('Will run %d filters on the set.', \count($this->filters)));
foreach ($this->filters as $enabled) {
if (isset($filters[$enabled])) {
Log::debug(sprintf('Before filter %s: %d', $enabled, $set->count()));

View File

@@ -61,7 +61,7 @@ class InternalTransferFilter implements FilterInterface
return $transaction;
}
// both id's in $parameters?
if (in_array($transaction->account_id, $this->accounts) && in_array($transaction->opposing_account_id, $this->accounts)) {
if (\in_array($transaction->account_id, $this->accounts) && \in_array($transaction->opposing_account_id, $this->accounts)) {
Log::debug(
sprintf(
'Transaction #%d has #%d and #%d in set, so removed',

View File

@@ -58,7 +58,7 @@ class OpposingAccountFilter implements FilterInterface
function (Transaction $transaction) {
$opposing = $transaction->opposing_account_id;
// remove internal transfer
if (in_array($opposing, $this->accounts)) {
if (\in_array($opposing, $this->accounts)) {
Log::debug(sprintf('Filtered #%d because its opposite is in accounts.', $transaction->id), $this->accounts);
return null;

View File

@@ -80,7 +80,7 @@ class Help implements HelpInterface
$content = trim($result->body);
}
if (strlen($content) > 0) {
if (\strlen($content) > 0) {
Log::debug('Content is longer than zero. Expect something.');
$converter = new CommonMarkConverter();
$content = $converter->convertToHtml($content);
@@ -127,7 +127,7 @@ class Help implements HelpInterface
public function putInCache(string $route, string $language, string $content)
{
$key = sprintf(self::CACHEKEY, $route, $language);
if (strlen($content) > 0) {
if (\strlen($content) > 0) {
Log::debug(sprintf('Will store entry in cache: %s', $key));
Cache::put($key, $content, 10080); // a week.

View File

@@ -41,7 +41,6 @@ use Illuminate\Http\Request;
use Illuminate\Support\Collection;
use Log;
use Preferences;
use Session;
/**
* Class ReconcileController.
@@ -100,13 +99,13 @@ class ReconcileController extends Controller
'amount' => $pTransaction->amount,
];
Session::flash('preFilled', $preFilled);
session()->flash('preFilled', $preFilled);
// put previous url in session if not redirect from store (not "return_to_edit").
if (true !== session('reconcile.edit.fromUpdate')) {
$this->rememberPreviousUri('reconcile.edit.uri');
}
Session::forget('reconcile.edit.fromUpdate');
session()->forget('reconcile.edit.fromUpdate');
return view(
'accounts.reconcile.edit',
@@ -123,6 +122,7 @@ class ReconcileController extends Controller
* @return \Illuminate\Http\JsonResponse
*
* @throws FireflyException
* @throws \Throwable
*/
public function overview(Request $request, Account $account, Carbon $start, Carbon $end)
{
@@ -184,13 +184,13 @@ class ReconcileController extends Controller
return $this->redirectToOriginalAccount($account);
}
if (AccountType::ASSET !== $account->accountType->type) {
Session::flash('error', trans('firefly.must_be_asset_account'));
session()->flash('error', trans('firefly.must_be_asset_account'));
return redirect(route('accounts.index', [config('firefly.shortNamesByFullName.' . $account->accountType->type)]));
}
$currencyId = (int)$this->accountRepos->getMetaValue($account, 'currency_id');
$currency = $this->currencyRepos->findNull($currencyId);
if (0 === $currencyId) {
if (null === $currency) {
$currency = app('amount')->getDefaultCurrency(); // @codeCoverageIgnore
}
@@ -321,11 +321,13 @@ class ReconcileController extends Controller
'notes' => implode(', ', $data['transactions']),
];
$journal = $repository->store($journalData);
$repository->store($journalData);
}
Log::debug('End of routine.');
Session::flash('success', trans('firefly.reconciliation_stored'));
Preferences::mark();
session()->flash('success', trans('firefly.reconciliation_stored'));
return redirect(route('accounts.show', [$account->id]));
}
@@ -338,6 +340,7 @@ class ReconcileController extends Controller
* @return mixed
*
* @throws FireflyException
* @throws \Throwable
*/
public function transactions(Account $account, Carbon $start, Carbon $end)
{
@@ -350,7 +353,7 @@ class ReconcileController extends Controller
$currencyId = (int)$this->accountRepos->getMetaValue($account, 'currency_id');
$currency = $this->currencyRepos->findNull($currencyId);
if (0 === $currencyId) {
if (0 === $currency) {
$currency = app('amount')->getDefaultCurrency(); // @codeCoverageIgnore
}
@@ -369,7 +372,9 @@ class ReconcileController extends Controller
$collector->setAccounts(new Collection([$account]))
->setRange($selectionStart, $selectionEnd)->withBudgetInformation()->withOpposingAccount()->withCategoryInformation();
$transactions = $collector->getJournals();
$html = view('accounts.reconcile.transactions', compact('account', 'transactions', 'start', 'end', 'selectionStart', 'selectionEnd'))->render();
$html = view(
'accounts.reconcile.transactions', compact('account', 'transactions', 'currency', 'start', 'end', 'selectionStart', 'selectionEnd')
)->render();
return response()->json(['html' => $html, 'startBalance' => $startBalance, 'endBalance' => $endBalance]);
}
@@ -386,7 +391,7 @@ class ReconcileController extends Controller
return redirect(route('transactions.show', [$journal->id]));
}
if (0 === bccomp('0', $request->get('amount'))) {
Session::flash('error', trans('firefly.amount_cannot_be_zero'));
session()->flash('error', trans('firefly.amount_cannot_be_zero'));
return redirect(route('accounts.reconcile.edit', [$journal->id]))->withInput();
}
@@ -439,9 +444,10 @@ class ReconcileController extends Controller
$this->repository->update($journal, $data);
// @codeCoverageIgnoreStart
if (1 === (int)$request->get('return_to_edit')) {
Session::put('reconcile.edit.fromUpdate', true);
session()->put('reconcile.edit.fromUpdate', true);
return redirect(route('accounts.reconcile.edit', [$journal->id]))->withInput(['return_to_edit' => 1]);
}

View File

@@ -87,12 +87,10 @@ class AccountController extends Controller
*/
public function create(Request $request, string $what = 'asset')
{
$allCurrencies = $this->currencyRepos->get();
$currencySelectList = ExpandedForm::makeSelectList($allCurrencies);
$defaultCurrency = app('amount')->getDefaultCurrency();
$subTitleIcon = config('firefly.subIconsByIdentifier.' . $what);
$subTitle = trans('firefly.make_new_' . $what . '_account');
$roles = [];
$defaultCurrency = app('amount')->getDefaultCurrency();
$subTitleIcon = config('firefly.subIconsByIdentifier.' . $what);
$subTitle = trans('firefly.make_new_' . $what . '_account');
$roles = [];
foreach (config('firefly.accountRoles') as $role) {
$roles[$role] = (string)trans('firefly.account_role_' . $role);
}
@@ -106,7 +104,7 @@ class AccountController extends Controller
}
$request->session()->forget('accounts.create.fromStore');
return view('accounts.create', compact('subTitleIcon', 'what', 'subTitle', 'currencySelectList', 'allCurrencies', 'roles'));
return view('accounts.create', compact('subTitleIcon', 'what', 'subTitle', 'roles'));
}
/**
@@ -165,12 +163,10 @@ class AccountController extends Controller
*/
public function edit(Request $request, Account $account, AccountRepositoryInterface $repository)
{
$what = config('firefly.shortNamesByFullName')[$account->accountType->type];
$subTitle = trans('firefly.edit_' . $what . '_account', ['name' => $account->name]);
$subTitleIcon = config('firefly.subIconsByIdentifier.' . $what);
$allCurrencies = $this->currencyRepos->get();
$currencySelectList = ExpandedForm::makeSelectList($allCurrencies);
$roles = [];
$what = config('firefly.shortNamesByFullName')[$account->accountType->type];
$subTitle = trans('firefly.edit_' . $what . '_account', ['name' => $account->name]);
$subTitleIcon = config('firefly.subIconsByIdentifier.' . $what);
$roles = [];
foreach (config('firefly.accountRoles') as $role) {
$roles[$role] = (string)trans('firefly.account_role_' . $role);
}
@@ -217,8 +213,6 @@ class AccountController extends Controller
return view(
'accounts.edit',
compact(
'allCurrencies',
'currencySelectList',
'account',
'currency',
'subTitle',
@@ -386,7 +380,7 @@ class AccountController extends Controller
// update preferences if necessary:
$frontPage = Preferences::get('frontPageAccounts', [])->data;
if (count($frontPage) > 0 && AccountType::ASSET === $account->accountType->type) {
if (AccountType::ASSET === $account->accountType->type && \count($frontPage) > 0) {
// @codeCoverageIgnoreStart
$frontPage[] = $account->id;
Preferences::set('frontPageAccounts', $frontPage);

View File

@@ -29,7 +29,6 @@ use FireflyIII\Http\Requests\ConfigurationRequest;
use FireflyIII\Support\Facades\FireflyConfig;
use Preferences;
use Redirect;
use Session;
use View;
/**
@@ -91,7 +90,7 @@ class ConfigurationController extends Controller
FireflyConfig::set('is_demo_site', $data['is_demo_site']);
// flash message
Session::flash('success', (string)trans('firefly.configuration_updated'));
session()->flash('success', (string)trans('firefly.configuration_updated'));
Preferences::mark();
return Redirect::route('admin.configuration.index');

View File

@@ -28,7 +28,6 @@ use FireflyIII\Http\Middleware\IsDemoUser;
use FireflyIII\Http\Middleware\IsSandStormUser;
use Illuminate\Http\Request;
use Log;
use Session;
/**
* Class HomeController.
@@ -66,7 +65,7 @@ class HomeController extends Controller
$ipAddress = $request->ip();
Log::debug(sprintf('Now in testMessage() controller. IP is %s', $ipAddress));
event(new AdminRequestedTestMessage(auth()->user(), $ipAddress));
Session::flash('info', (string)trans('firefly.send_test_triggered'));
session()->flash('info', (string)trans('firefly.send_test_triggered'));
return redirect(route('admin.index'));
}

View File

@@ -32,7 +32,6 @@ use FireflyIII\Services\Github\Object\Release;
use FireflyIII\Services\Github\Request\UpdateRequest;
use Illuminate\Http\Request;
use Log;
use Session;
/**
* Class HomeController.
@@ -63,7 +62,6 @@ class UpdateController extends Controller
* @return \Illuminate\Contracts\View\Factory|\Illuminate\View\View
* @throws \Psr\Container\NotFoundExceptionInterface
* @throws \Psr\Container\ContainerExceptionInterface
* @throws \Illuminate\Container\EntryNotFoundException
*/
public function index()
{
@@ -90,7 +88,7 @@ class UpdateController extends Controller
$checkForUpdates = (int)$request->get('check_for_updates');
FireflyConfig::set('permission_update_check', $checkForUpdates);
FireflyConfig::set('last_update_check', time());
Session::flash('success', (string)trans('firefly.configuration_updated'));
session()->flash('success', (string)trans('firefly.configuration_updated'));
return redirect(route('admin.update-check'));
}

View File

@@ -30,7 +30,6 @@ use FireflyIII\Repositories\User\UserRepositoryInterface;
use FireflyIII\User;
use Log;
use Preferences;
use Session;
use View;
/**
@@ -78,7 +77,7 @@ class UserController extends Controller
public function destroy(User $user, UserRepositoryInterface $repository)
{
$repository->destroy($user);
Session::flash('success', (string)trans('firefly.user_deleted'));
session()->flash('success', (string)trans('firefly.user_deleted'));
return redirect(route('admin.users'));
}
@@ -94,7 +93,7 @@ class UserController extends Controller
if (true !== session('users.edit.fromUpdate')) {
$this->rememberPreviousUri('users.edit.uri');
}
Session::forget('users.edit.fromUpdate');
session()->forget('users.edit.fromUpdate');
$subTitle = (string)trans('firefly.edit_user', ['email' => $user->email]);
$subTitleIcon = 'fa-user-o';
@@ -175,19 +174,19 @@ class UserController extends Controller
$data = $request->getUserData();
// update password
if (strlen($data['password']) > 0) {
if (\strlen($data['password']) > 0) {
$repository->changePassword($user, $data['password']);
}
$repository->changeStatus($user, $data['blocked'], $data['blocked_code']);
$repository->updateEmail($user, $data['email']);
Session::flash('success', (string)trans('firefly.updated_user', ['email' => $user->email]));
session()->flash('success', (string)trans('firefly.updated_user', ['email' => $user->email]));
Preferences::mark();
if (1 === (int)$request->get('return_to_edit')) {
// @codeCoverageIgnoreStart
Session::put('users.edit.fromUpdate', true);
session()->put('users.edit.fromUpdate', true);
return redirect(route('admin.users.edit', [$user->id]))->withInput(['return_to_edit' => 1]);
// @codeCoverageIgnoreEnd

View File

@@ -117,7 +117,7 @@ class AttachmentController extends Controller
->header('Expires', '0')
->header('Cache-Control', 'must-revalidate, post-check=0, pre-check=0')
->header('Pragma', 'public')
->header('Content-Length', strlen($content));
->header('Content-Length', \strlen($content));
return $response;
}
@@ -147,6 +147,24 @@ class AttachmentController extends Controller
return view('attachments.edit', compact('attachment', 'subTitleIcon', 'subTitle'));
}
/**
* @return \Illuminate\Contracts\View\Factory|\Illuminate\View\View
*/
public function index()
{
$set = $this->repository->get()->reverse();
$set = $set->each(
function (Attachment $attachment) {
$attachment->file_exists = $this->repository->exists($attachment);
return $attachment;
}
);
return view('attachments.index', compact('set'));
}
/**
* @param AttachmentFormRequest $request
* @param Attachment $attachment

View File

@@ -29,7 +29,6 @@ use Illuminate\Auth\Events\Registered;
use Illuminate\Foundation\Auth\RegistersUsers;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\Validator;
use Session;
/**
* @codeCoverageIgnore
@@ -83,7 +82,7 @@ class RegisterController extends Controller
$this->guard()->login($user);
Session::flash('success', (string)trans('firefly.registered'));
session()->flash('success', (string)trans('firefly.registered'));
return $this->registered($request, $user)
?: redirect($this->redirectPath());

View File

@@ -59,7 +59,7 @@ class TwoFactorController extends Controller
return redirect(route('index'));
}
if (0 === strlen((string)$secret)) {
if (0 === \strlen((string)$secret)) {
throw new FireflyException('Your two factor authentication secret is empty, which it cannot be at this point. Please check the log files.');
}
$request->session()->flash('two-factor-secret', $secret);

View File

@@ -22,13 +22,16 @@ declare(strict_types=1);
namespace FireflyIII\Http\Controllers;
use ExpandedForm;
use FireflyIII\Helpers\Attachments\AttachmentHelperInterface;
use FireflyIII\Helpers\Collector\JournalCollectorInterface;
use FireflyIII\Http\Requests\BillFormRequest;
use FireflyIII\Models\Bill;
use FireflyIII\Models\Note;
use FireflyIII\Models\TransactionJournal;
use FireflyIII\Repositories\Bill\BillRepositoryInterface;
use FireflyIII\Repositories\Currency\CurrencyRepositoryInterface;
use FireflyIII\Repositories\RuleGroup\RuleGroupRepositoryInterface;
use FireflyIII\TransactionRules\TransactionMatcher;
use FireflyIII\Transformers\BillTransformer;
use Illuminate\Http\Request;
use Illuminate\Support\Collection;
@@ -72,17 +75,21 @@ class BillController extends Controller
}
/**
* @param Request $request
* @param Request $request
*
* @param CurrencyRepositoryInterface $repository
*
* @return View
*/
public function create(Request $request)
public function create(Request $request, CurrencyRepositoryInterface $repository)
{
$periods = [];
foreach (config('firefly.bill_periods') as $current) {
$periods[$current] = trans('firefly.' . $current);
$periods[$current] = strtolower((string)trans('firefly.repeat_freq_' . $current));
}
$subTitle = trans('firefly.create_new_bill');
$subTitle = trans('firefly.create_new_bill');
$defaultCurrency = app('amount')->getDefaultCurrency();
$currencies = ExpandedForm::makeSelectList($repository->get());
// put previous url in session if not redirect from store (not "create another").
if (true !== session('bills.create.fromStore')) {
@@ -90,7 +97,7 @@ class BillController extends Controller
}
$request->session()->forget('bills.create.fromStore');
return view('bills.create', compact('periods', 'subTitle'));
return view('bills.create', compact('periods', 'subTitle', 'currencies', 'defaultCurrency'));
}
/**
@@ -126,12 +133,13 @@ class BillController extends Controller
}
/**
* @param Request $request
* @param Bill $bill
* @param Request $request
* @param CurrencyRepositoryInterface $repository
* @param Bill $bill
*
* @return View
*/
public function edit(Request $request, Bill $bill)
public function edit(Request $request, CurrencyRepositoryInterface $repository, Bill $bill)
{
$periods = [];
foreach (config('firefly.bill_periods') as $current) {
@@ -147,6 +155,8 @@ class BillController extends Controller
$currency = app('amount')->getDefaultCurrency();
$bill->amount_min = round($bill->amount_min, $currency->decimal_places);
$bill->amount_max = round($bill->amount_max, $currency->decimal_places);
$defaultCurrency = app('amount')->getDefaultCurrency();
$currencies = ExpandedForm::makeSelectList($repository->get());
$preFilled = [
'notes' => '',
@@ -162,7 +172,7 @@ class BillController extends Controller
$request->session()->forget('bills.edit.fromUpdate');
return view('bills.edit', compact('subTitle', 'periods', 'bill'));
return view('bills.edit', compact('subTitle', 'periods', 'bill', 'defaultCurrency', 'currencies'));
}
/**
@@ -186,6 +196,21 @@ class BillController extends Controller
return $transformer->transform($bill);
}
);
$bills = $bills->sortBy(
function (array $bill) {
return (int)!$bill['active'] . strtolower($bill['name']);
}
);
// add info about rules:
$rules = $repository->getRulesForBills($paginator->getCollection());
$bills = $bills->map(
function (array $bill) use ($rules) {
$bill['rules'] = $rules[$bill['id']] ?? [];
return $bill;
}
);
$paginator->setPath(route('bills.index'));
@@ -198,6 +223,7 @@ class BillController extends Controller
* @param Bill $bill
*
* @return \Illuminate\Http\RedirectResponse|\Illuminate\Routing\Redirector
* @throws \FireflyIII\Exceptions\FireflyException
*/
public function rescan(Request $request, BillRepositoryInterface $repository, Bill $bill)
{
@@ -206,14 +232,22 @@ class BillController extends Controller
return redirect(URL::previous());
}
$journals = $repository->getPossiblyRelatedJournals($bill);
/** @var TransactionJournal $journal */
foreach ($journals as $journal) {
$repository->scan($bill, $journal);
$set = $repository->getRulesForBill($bill);
$total = 0;
foreach ($set as $rule) {
// simply fire off all rules?
/** @var TransactionMatcher $matcher */
$matcher = app(TransactionMatcher::class);
$matcher->setLimit(100000); // large upper limit
$matcher->setRange(100000); // large upper limit
$matcher->setRule($rule);
$matchingTransactions = $matcher->findTransactionsByRule();
$total += $matchingTransactions->count();
$repository->linkCollectionToBill($bill, $matchingTransactions);
}
$request->session()->flash('success', (string)trans('firefly.rescanned_bill'));
$request->session()->flash('success', (string)trans('firefly.rescanned_bill', ['total' => $total]));
Preferences::mark();
return redirect(URL::previous());
@@ -228,6 +262,8 @@ class BillController extends Controller
*/
public function show(Request $request, BillRepositoryInterface $repository, Bill $bill)
{
// add info about rules:
$rules = $repository->getRulesForBill($bill);
$subTitle = $bill->name;
$start = session('start');
$end = session('end');
@@ -238,7 +274,7 @@ class BillController extends Controller
$overallAverage = $repository->getOverallAverage($bill);
$manager = new Manager();
$manager->setSerializer(new DataArraySerializer());
$manager->parseIncludes(['attachments','notes']);
$manager->parseIncludes(['attachments', 'notes']);
// Make a resource out of the data and
$parameters = new ParameterBag();
@@ -256,16 +292,17 @@ class BillController extends Controller
$transactions->setPath(route('bills.show', [$bill->id]));
return view('bills.show', compact('transactions', 'yearAverage', 'overallAverage', 'year', 'object', 'bill', 'subTitle'));
return view('bills.show', compact('transactions', 'rules', 'yearAverage', 'overallAverage', 'year', 'object', 'bill', 'subTitle'));
}
/**
* @param BillFormRequest $request
* @param BillRepositoryInterface $repository
* @param BillFormRequest $request
* @param BillRepositoryInterface $repository
*
* @param RuleGroupRepositoryInterface $ruleGroupRepository
* @return \Illuminate\Http\RedirectResponse
*/
public function store(BillFormRequest $request, BillRepositoryInterface $repository)
public function store(BillFormRequest $request, BillRepositoryInterface $repository, RuleGroupRepositoryInterface $ruleGroupRepository)
{
$billData = $request->getBillData();
$bill = $repository->store($billData);
@@ -282,20 +319,33 @@ class BillController extends Controller
$this->attachments->saveAttachmentsForModel($bill, $files);
// flash messages
if (count($this->attachments->getMessages()->get('attachments')) > 0) {
if (\count($this->attachments->getMessages()->get('attachments')) > 0) {
$request->session()->flash('info', $this->attachments->getMessages()->get('attachments')); // @codeCoverageIgnore
}
// do return to original bill form?
$return = 'false';
if (1 === (int)$request->get('create_another')) {
// @codeCoverageIgnoreStart
$request->session()->put('bills.create.fromStore', true);
return redirect(route('bills.create'))->withInput();
// @codeCoverageIgnoreEnd
$return = 'true';
}
// redirect to previous URL.
return redirect($this->getPreviousUri('bills.create.uri'));
// find first rule group, or create one:
$count = $ruleGroupRepository->count();
if ($count === 0) {
$data = [
'title' => (string)trans('firefly.rulegroup_for_bills_title'),
'description' => (string)trans('firefly.rulegroup_for_bills_description'),
];
$group = $ruleGroupRepository->store($data);
}
if ($count > 0) {
$group = $ruleGroupRepository->getActiveGroups(auth()->user())->first();
}
// redirect to page that will create a new rule.
$params = http_build_query(['fromBill' => $bill->id, 'return' => $return]);
return redirect(route('rules.create', [$group->id]) . '?' . $params);
}
/**
@@ -318,7 +368,7 @@ class BillController extends Controller
$this->attachments->saveAttachmentsForModel($bill, $files);
// flash messages
if (count($this->attachments->getMessages()->get('attachments')) > 0) {
if (\count($this->attachments->getMessages()->get('attachments')) > 0) {
$request->session()->flash('info', $this->attachments->getMessages()->get('attachments')); // @codeCoverageIgnore
}

View File

@@ -87,16 +87,31 @@ class BudgetController extends Controller
$budgetLimit = $this->repository->updateLimitAmount($budget, $start, $end, $amount);
$largeDiff = false;
$warnText = '';
$average = '0';
$current = '0';
if (0 === bccomp($amount, '0')) {
$budgetLimit = null;
}
// if today is between start and end, use the diff in days between end and today (days left)
// otherwise, use diff between start and end.
$today = new Carbon;
if ($today->gte($start) && $today->lte($end)) {
$days = $end->diffInDays($today);
}
if ($today->lte($start) || $today->gte($end)) {
$days = $start->diffInDays($end);
}
$days = $days === 0 ? 1 : $days;
// calculate left in budget:
$spent = $repository->spentInPeriod(new Collection([$budget]), new Collection, $start, $end);
$currency = app('amount')->getDefaultCurrency();
$left = app('amount')->formatAnything($currency, bcadd($amount, $spent), true);
$spent = $repository->spentInPeriod(new Collection([$budget]), new Collection, $start, $end);
$currency = app('amount')->getDefaultCurrency();
$left = app('amount')->formatAnything($currency, bcadd($amount, $spent), true);
$leftPerDay = 'none';
// is user has money left, calculate.
if (1 === bccomp(bcadd($amount, $spent), '0')) {
$leftPerDay = app('amount')->formatAnything($currency, bcdiv(bcadd($amount, $spent), (string)$days), true);
}
// over or under budgeting, compared to previous budgets?
@@ -122,14 +137,15 @@ class BudgetController extends Controller
return response()->json(
[
'left' => $left,
'name' => $budget->name,
'limit' => $budgetLimit ? $budgetLimit->id : 0,
'amount' => $amount,
'current' => $current,
'average' => $average,
'large_diff' => $largeDiff,
'warn_text' => $warnText,
'left' => $left,
'name' => $budget->name,
'limit' => $budgetLimit ? $budgetLimit->id : 0,
'amount' => $amount,
'current' => $current,
'average' => $average,
'large_diff' => $largeDiff,
'left_per_day' => $leftPerDay,
'warn_text' => $warnText,
]
);
@@ -219,6 +235,17 @@ class BudgetController extends Controller
$page = 0 === (int)$request->get('page') ? 1 : (int)$request->get('page');
$pageSize = (int)Preferences::get('listPageSize', 50)->data;
// if today is between start and end, use the diff in days between end and today (days left)
// otherwise, use diff between start and end.
$today = new Carbon;
if ($today->gte($start) && $today->lte($end)) {
$days = $end->diffInDays($today);
}
if ($today->lte($start) || $today->gte($end)) {
$days = $start->diffInDays($end);
}
$days = $days === 0 ? 1 : $days;
// make date if present:
if (null !== $moment || '' !== (string)$moment) {
try {
@@ -283,27 +310,11 @@ class BudgetController extends Controller
$prevText = app('navigation')->periodShow($prev, $range);
return view(
'budgets.index',
compact(
'available',
'currentMonth',
'next',
'nextText',
'prev', 'allBudgets',
'prevText',
'periodStart',
'periodEnd',
'page',
'budgetInformation',
'inactive',
'budgets',
'spent',
'budgeted',
'previousLoop',
'nextLoop',
'start',
'end'
)
'budgets.index', compact(
'available', 'currentMonth', 'next', 'nextText', 'prev', 'allBudgets', 'prevText', 'periodStart', 'periodEnd', 'days', 'page',
'budgetInformation',
'inactive', 'budgets', 'spent', 'budgeted', 'previousLoop', 'nextLoop', 'start', 'end'
)
);
}
@@ -406,13 +417,13 @@ class BudgetController extends Controller
// prep for "all" view.
if ('all' === $moment) {
$subTitle = trans('firefly.all_journals_without_budget');
$first = $repository->first();
$start = $first->date ?? new Carbon;
$first = $repository->firstNull();
$start = null === $first ? new Carbon : $first->date;
$end = new Carbon;
}
// prep for "specific date" view.
if (strlen($moment) > 0 && 'all' !== $moment) {
if ('all' !== $moment && \strlen($moment) > 0) {
$start = new Carbon($moment);
$end = app('navigation')->endOfPeriod($start, $range);
$subTitle = trans(
@@ -423,7 +434,7 @@ class BudgetController extends Controller
}
// prep for current period
if (0 === strlen($moment)) {
if ('' === $moment) {
$start = clone session('start', app('navigation')->startOfPeriod(new Carbon, $range));
$end = clone session('end', app('navigation')->endOfPeriod(new Carbon, $range));
$periods = $this->getPeriodOverview();
@@ -638,9 +649,10 @@ class BudgetController extends Controller
*/
private function getPeriodOverview(): Collection
{
/** @var JournalRepositoryInterface $repository */
$repository = app(JournalRepositoryInterface::class);
$first = $repository->first();
$start = $first->date ?? new Carbon;
$first = $repository->firstNull();
$start = null === $first ? new Carbon : $first->date;
$range = Preferences::get('viewRange', '1M')->data;
$start = app('navigation')->startOfPeriod($start, $range);
$end = app('navigation')->endOfX(new Carbon, $range, null);

View File

@@ -185,13 +185,13 @@ class CategoryController extends Controller
// prep for "all" view.
if ('all' === $moment) {
$subTitle = trans('firefly.all_journals_without_category');
$first = $this->journalRepos->first();
$start = $first->date ?? new Carbon;
$first = $this->journalRepos->firstNull();
$start = null === $first ? new Carbon : $first->date;
$end = new Carbon;
}
// prep for "specific date" view.
if (strlen($moment) > 0 && 'all' !== $moment) {
if ('all' !== $moment && \strlen($moment) > 0) {
$start = app('navigation')->startOfPeriod(new Carbon($moment), $range);
$end = app('navigation')->endOfPeriod($start, $range);
$subTitle = trans(
@@ -202,7 +202,7 @@ class CategoryController extends Controller
}
// prep for current period
if (0 === strlen($moment)) {
if ('' === $moment) {
$start = clone session('start', app('navigation')->startOfPeriod(new Carbon, $range));
$end = clone session('end', app('navigation')->endOfPeriod(new Carbon, $range));
$periods = $this->getNoCategoryPeriodOverview($start);
@@ -255,7 +255,7 @@ class CategoryController extends Controller
}
// prep for "specific date" view.
if (strlen($moment) > 0 && 'all' !== $moment) {
if (\strlen($moment) > 0 && 'all' !== $moment) {
$start = app('navigation')->startOfPeriod(new Carbon($moment), $range);
$end = app('navigation')->endOfPeriod($start, $range);
$subTitle = trans(
@@ -268,7 +268,7 @@ class CategoryController extends Controller
}
// prep for current period
if (0 === strlen($moment)) {
if (0 === \strlen($moment)) {
/** @var Carbon $start */
$start = clone session('start', app('navigation')->startOfPeriod(new Carbon, $range));
/** @var Carbon $end */
@@ -351,8 +351,8 @@ class CategoryController extends Controller
private function getNoCategoryPeriodOverview(Carbon $theDate): Collection
{
$range = Preferences::get('viewRange', '1M')->data;
$first = $this->journalRepos->first();
$start = $first->date ?? new Carbon;
$first = $this->journalRepos->firstNull();
$start = null === $first ? new Carbon : $first->date;
$end = $theDate ?? new Carbon;
// properties for cache
@@ -431,8 +431,8 @@ class CategoryController extends Controller
private function getPeriodOverview(Category $category, Carbon $date): Collection
{
$range = Preferences::get('viewRange', '1M')->data;
$first = $this->journalRepos->first();
$start = $first->date ?? new Carbon;
$first = $this->journalRepos->firstNull();
$start = null === $first ? new Carbon : $first->date;
$end = $date ?? new Carbon;
$accounts = $this->accountRepos->getAccountsByType([AccountType::DEFAULT, AccountType::ASSET]);

View File

@@ -228,7 +228,7 @@ class AccountController extends Controller
Log::debug('Default set is ', $defaultSet);
$frontPage = Preferences::get('frontPageAccounts', $defaultSet);
Log::debug('Frontpage preference set is ', $frontPage->data);
if (0 === count($frontPage->data)) {
if (0 === \count($frontPage->data)) {
$frontPage->data = $defaultSet;
Log::debug('frontpage set is empty!');
$frontPage->save();
@@ -349,7 +349,7 @@ class AccountController extends Controller
$balance = (float)app('steam')->balance($account, $current);
$label = app('navigation')->periodShow($current, $step);
$chartData[$label] = $balance;
$current = app('navigation')->addPeriod($current, $step, 1);
$current = app('navigation')->addPeriod($current, $step, 0);
}
break;
// @codeCoverageIgnoreEnd
@@ -439,15 +439,19 @@ class AccountController extends Controller
/** @var CurrencyRepositoryInterface $repository */
$repository = app(CurrencyRepositoryInterface::class);
$chartData = [];
$default = app('amount')->getDefaultCurrency();
$chartData = [];
foreach ($accounts as $account) {
$currency = $repository->findNull((int)$account->getMeta('currency_id'));
$currentSet = [
$currency = $repository->findNull((int)$account->getMeta('currency_id'));
if (null === $currency) {
$currency = $default;
}
$currentSet = [
'label' => $account->name,
'currency_symbol' => $currency->symbol,
'entries' => [],
];
$currentStart = clone $start;
$range = app('steam')->balanceInRange($account, $start, clone $end);
$previous = array_values($range)[0];

View File

@@ -180,7 +180,7 @@ class BudgetReportController extends Controller
$chartData[$budget->id]['entries'][$label] = bcmul($currentExpenses, '-1');
$chartData[$budget->id . '-sum']['entries'][$label] = bcmul($sumOfExpenses[$budget->id], '-1');
if (count($budgetLimits) > 0) {
if (\count($budgetLimits) > 0) {
$budgetLimitId = $budgetLimits->first()->id;
$leftOfLimits[$budgetLimitId] = $leftOfLimits[$budgetLimitId] ?? (string)$budgetLimits->sum('amount');
$leftOfLimits[$budgetLimitId] = bcadd($leftOfLimits[$budgetLimitId], $currentExpenses);

View File

@@ -251,7 +251,7 @@ class CategoryReportController extends Controller
$newSet[$key] = $chartData[$key];
}
}
if (0 === count($newSet)) {
if (0 === \count($newSet)) {
$newSet = $chartData;
}
$data = $this->generator->multiSet($newSet);

View File

@@ -173,7 +173,7 @@ class ExpenseReportController extends Controller
$newSet[$key] = $chartData[$key];
}
}
if (0 === count($newSet)) {
if (0 === \count($newSet)) {
$newSet = $chartData; // @codeCoverageIgnore
}
$data = $this->generator->multiSet($newSet);

View File

@@ -22,12 +22,14 @@ declare(strict_types=1);
namespace FireflyIII\Http\Controllers\Chart;
use Carbon\Carbon;
use FireflyIII\Generator\Chart\Basic\GeneratorInterface;
use FireflyIII\Http\Controllers\Controller;
use FireflyIII\Models\PiggyBank;
use FireflyIII\Models\PiggyBankEvent;
use FireflyIII\Repositories\PiggyBank\PiggyBankRepositoryInterface;
use FireflyIII\Support\CacheProperties;
use Illuminate\Support\Collection;
/**
* Class PiggyBankController.
@@ -64,17 +66,54 @@ class PiggyBankController extends Controller
if ($cache->has()) {
return response()->json($cache->get()); // @codeCoverageIgnore
}
$set = $repository->getEvents($piggyBank);
$set = $set->reverse();
$set = $repository->getEvents($piggyBank);
$set = $set->reverse();
$chartData = [];
$sum = '0';
/** @var PiggyBankEvent $entry */
foreach ($set as $entry) {
$label = $entry->date->formatLocalized((string)trans('config.month_and_day'));
$sum = bcadd($sum, $entry->amount);
$chartData[$label] = $sum;
// get first event or start date of piggy bank or today
$startDate = $piggyBank->start_date ?? new Carbon;
/** @var PiggyBankEvent $first */
$firstEvent = $set->first();
$firstDate = null === $firstEvent ? new Carbon : $firstEvent->date;
// which ever is older:
$oldest = $startDate->lt($firstDate) ? $startDate : $firstDate;
$today = new Carbon;
// depending on diff, do something with range of chart.
$step = '1D';
$months = $oldest->diffInMonths($today);
if ($months > 3) {
$step = '1W'; // @codeCoverageIgnore
}
if ($months > 24) {
$step = '1M'; // @codeCoverageIgnore
}
if ($months > 100) {
$step = '1Y'; // @codeCoverageIgnore
}
$chartData = [];
while ($oldest <= $today) {
/** @var Collection $filtered */
$filtered = $set->filter(
function (PiggyBankEvent $event) use ($oldest) {
return $event->date->lte($oldest);
}
);
$currentSum = $filtered->sum('amount');
$label = $oldest->formatLocalized((string)trans('config.month_and_day'));
$chartData[$label] = $currentSum;
$oldest = app('navigation')->addPeriod($oldest, $step, 0);
}
/** @var Collection $filtered */
$finalFiltered = $set->filter(
function (PiggyBankEvent $event) use ($today) {
return $event->date->lte($today);
}
);
$finalSum = $filtered->sum('amount');
$finalLabel = $today->formatLocalized((string)trans('config.month_and_day'));
$chartData[$finalLabel] = $finalSum;
$data = $this->generator->singleSet($piggyBank->name, $chartData);
$cache->store($data);

View File

@@ -245,7 +245,7 @@ class TagReportController extends Controller
$newSet[$key] = $chartData[$key];
}
}
if (0 === count($newSet)) {
if (0 === \count($newSet)) {
$newSet = $chartData; // @codeCoverageIgnore
}
$data = $this->generator->multiSet($newSet);

View File

@@ -34,7 +34,6 @@ use Illuminate\Foundation\Validation\ValidatesRequests;
use Illuminate\Routing\Controller as BaseController;
use Log;
use Route;
use Session;
use URL;
use View;
@@ -93,11 +92,15 @@ class Controller extends BaseController
$shownDemo = true;
// either must be array and either must be > 0
if ((is_array($intro) || is_array($specialIntro)) && (count($intro) > 0 || count($specialIntro) > 0)) {
if ((\is_array($intro) || \is_array($specialIntro)) && (\count($intro) > 0 || \count($specialIntro) > 0)) {
$shownDemo = Preferences::get($key, false)->data;
Log::debug(sprintf('Check if user has already seen intro with key "%s". Result is %d', $key, $shownDemo));
}
// share language
$language = Preferences::get('language', config('firefly.default_language', 'en_US'))->data;
View::share('language', $language);
View::share('shownDemo', $shownDemo);
View::share('current_route_name', $page);
View::share('original_route_name', Route::currentRouteName());
@@ -154,12 +157,12 @@ class Controller extends BaseController
/** @var Transaction $transaction */
foreach ($transactions as $transaction) {
$account = $transaction->account;
if (in_array($account->accountType->type, $valid)) {
if (\in_array($account->accountType->type, $valid)) {
return redirect(route('accounts.show', [$account->id]));
}
}
// @codeCoverageIgnoreStart
Session::flash('error', (string)trans('firefly.cannot_redirect_to_account'));
session()->flash('error', (string)trans('firefly.cannot_redirect_to_account'));
return redirect(route('index'));
// @codeCoverageIgnoreEnd
@@ -170,6 +173,6 @@ class Controller extends BaseController
*/
protected function rememberPreviousUri(string $identifier)
{
Session::put($identifier, URL::previous());
session()->put($identifier, URL::previous());
}
}

View File

@@ -91,7 +91,7 @@ class ExportController extends Controller
->header('Expires', '0')
->header('Cache-Control', 'must-revalidate, post-check=0, pre-check=0')
->header('Pragma', 'public')
->header('Content-Length', strlen($content));
->header('Content-Length', \strlen($content));
return $response;
}

View File

@@ -93,7 +93,7 @@ class HelpController extends Controller
$content = $this->help->getFromGithub($route, $language);
// content will have 0 length when Github failed. Try en_US when it does:
if (0 === strlen($content)) {
if (0 === \strlen($content)) {
$language = 'en_US';
// also check cache first:
@@ -108,7 +108,7 @@ class HelpController extends Controller
}
// help still empty?
if (0 !== strlen($content)) {
if (0 !== \strlen($content)) {
$this->help->putInCache($route, $language, $content);
return $content;

View File

@@ -28,6 +28,7 @@ use Exception;
use FireflyIII\Events\RequestedVersionCheckStatus;
use FireflyIII\Exceptions\FireflyException;
use FireflyIII\Helpers\Collector\JournalCollectorInterface;
use FireflyIII\Http\Middleware\Installer;
use FireflyIII\Http\Middleware\IsDemoUser;
use FireflyIII\Http\Middleware\IsSandStormUser;
use FireflyIII\Models\AccountType;
@@ -54,8 +55,10 @@ class HomeController extends Controller
parent::__construct();
app('view')->share('title', 'Firefly III');
app('view')->share('mainTitleIcon', 'fa-fire');
$this->middleware(Installer::class);
$this->middleware(IsDemoUser::class)->except(['dateRange', 'index']);
$this->middleware(IsSandStormUser::class)->only('routes');
}
/**
@@ -208,7 +211,7 @@ class HomeController extends Controller
/** @var Route $route */
foreach ($set as $route) {
$name = $route->getName();
if (null !== $name && in_array('GET', $route->methods()) && strlen($name) > 0) {
if (null !== $name && \in_array('GET', $route->methods()) && \strlen($name) > 0) {
$found = false;
foreach ($ignore as $string) {

View File

@@ -114,7 +114,7 @@ class ConfigurationController extends Controller
// get possible warning from configurator:
$warning = $configurator->getWarningMessage();
if (strlen($warning) > 0) {
if (\strlen($warning) > 0) {
$request->session()->flash('warning', $warning);
}

View File

@@ -28,8 +28,10 @@ use FireflyIII\Http\Middleware\IsDemoUser;
use FireflyIII\Import\Routine\RoutineInterface;
use FireflyIII\Models\ImportJob;
use FireflyIII\Repositories\ImportJob\ImportJobRepositoryInterface;
use Illuminate\Http\Request;
use Illuminate\Http\Response as LaravelResponse;
use Log;
use Preferences;
use View;
@@ -113,7 +115,7 @@ class IndexController extends Controller
->header('Expires', '0')
->header('Cache-Control', 'must-revalidate, post-check=0, pre-check=0')
->header('Pragma', 'public')
->header('Content-Length', strlen($result));
->header('Content-Length', \strlen($result));
return $response;
}
@@ -132,6 +134,46 @@ class IndexController extends Controller
return view('import.index', compact('subTitle', 'subTitleIcon', 'routines'));
}
/**
* @param Request $request
* @param string $bank
*
* @return \Illuminate\Http\RedirectResponse|\Illuminate\Routing\Redirector
*/
public function reset(Request $request, string $bank)
{
if ($bank === 'bunq') {
// remove bunq related preferences.
Preferences::delete('bunq_api_key');
Preferences::delete('bunq_server_public_key');
Preferences::delete('bunq_private_key');
Preferences::delete('bunq_public_key');
Preferences::delete('bunq_installation_token');
Preferences::delete('bunq_installation_id');
Preferences::delete('bunq_device_server_id');
Preferences::delete('external_ip');
}
if ($bank === 'spectre') {
// remove spectre related preferences:
Preferences::delete('spectre_client_id');
Preferences::delete('spectre_app_secret');
Preferences::delete('spectre_service_secret');
Preferences::delete('spectre_app_id');
Preferences::delete('spectre_secret');
Preferences::delete('spectre_private_key');
Preferences::delete('spectre_public_key');
Preferences::delete('spectre_customer');
}
Preferences::mark();
$request->session()->flash('info', (string)trans('firefly.settings_reset_for_' . $bank));
return redirect(route('import.index'));
}
/**
* @param ImportJob $job
*

View File

@@ -59,7 +59,7 @@ class StatusController extends Controller
public function index(ImportJob $job)
{
$statuses = ['configured', 'running', 'finished', 'error'];
if (!in_array($job->status, $statuses)) {
if (!\in_array($job->status, $statuses)) {
return redirect(route('import.configure', [$job->key]));
}
$subTitle = trans('import.status_sub_title');

View File

@@ -28,6 +28,12 @@ use FireflyIII\Models\Account;
use FireflyIII\Models\AccountType;
use FireflyIII\Models\TransactionJournal;
use FireflyIII\Repositories\Account\AccountRepositoryInterface;
use FireflyIII\Repositories\Bill\BillRepositoryInterface;
use FireflyIII\Repositories\Budget\BudgetRepositoryInterface;
use FireflyIII\Repositories\Category\CategoryRepositoryInterface;
use FireflyIII\Repositories\Currency\CurrencyRepositoryInterface;
use FireflyIII\Repositories\Journal\JournalRepositoryInterface;
use FireflyIII\Repositories\Tag\TagRepositoryInterface;
use FireflyIII\Support\CacheProperties;
/**
@@ -35,6 +41,7 @@ use FireflyIII\Support\CacheProperties;
*/
class AutoCompleteController extends Controller
{
/**
* Returns a JSON list of all accounts.
*
@@ -68,6 +75,64 @@ class AutoCompleteController extends Controller
return response()->json($return);
}
/**
* Returns a JSON list of all bills.
*
* @param BillRepositoryInterface $repository
*
* @return \Illuminate\Http\JsonResponse
*/
public function bills(BillRepositoryInterface $repository)
{
$return = array_unique(
$repository->getActiveBills()->pluck('name')->toArray()
);
sort($return);
return response()->json($return);
}
/**
* @param BudgetRepositoryInterface $repository
*
* @return \Illuminate\Http\JsonResponse
*/
public function budgets(BudgetRepositoryInterface $repository)
{
$return = array_unique($repository->getBudgets()->pluck('name')->toArray());
sort($return);
return response()->json($return);
}
/**
* Returns a list of categories.
*
* @param CategoryRepositoryInterface $repository
*
* @return \Illuminate\Http\JsonResponse
*/
public function categories(CategoryRepositoryInterface $repository)
{
$return = array_unique($repository->getCategories()->pluck('name')->toArray());
sort($return);
return response()->json($return);
}
/**
* @param CurrencyRepositoryInterface $repository
*
* @return \Illuminate\Http\JsonResponse
*/
public function currencyNames(CurrencyRepositoryInterface $repository)
{
$return = $repository->get()->pluck('name')->toArray();
sort($return);
return response()->json($return);
}
/**
* Returns a JSON list of all beneficiaries.
*
@@ -150,6 +215,21 @@ class AutoCompleteController extends Controller
return response()->json($return);
}
/**
* Returns a JSON list of all beneficiaries.
*
* @param TagRepositoryInterface $tagRepository
*
* @return \Illuminate\Http\JsonResponse
*/
public function tags(TagRepositoryInterface $tagRepository)
{
$return = array_unique($tagRepository->get()->pluck('tag')->toArray());
sort($return);
return response()->json($return);
}
/**
* @param JournalCollectorInterface $collector
* @param string $what
@@ -167,4 +247,17 @@ class AutoCompleteController extends Controller
return response()->json($return);
}
/**
* @param JournalRepositoryInterface $repository
*
* @return \Illuminate\Http\JsonResponse
*/
public function transactionTypes(JournalRepositoryInterface $repository)
{
$return = array_unique($repository->getTransactionTypes()->pluck('type')->toArray());
sort($return);
return response()->json($return);
}
}

View File

@@ -158,7 +158,7 @@ class BoxController extends Controller
'incomes' => $incomes,
'expenses' => $expenses,
'sums' => $sums,
'size' => count($sums),
'size' => \count($sums),
];
$cache->store($response);

View File

@@ -35,8 +35,7 @@ class FrontpageController extends Controller
* @param PiggyBankRepositoryInterface $repository
*
* @return \Illuminate\Http\JsonResponse
*
* @throws \Throwable
*/
public function piggyBanks(PiggyBankRepositoryInterface $repository)
{
@@ -61,7 +60,7 @@ class FrontpageController extends Controller
}
}
$html = '';
if (count($info) > 0) {
if (\count($info) > 0) {
$html = view('json.piggy-banks', compact('info'))->render();
}

View File

@@ -43,7 +43,7 @@ class IntroController
Log::debug(sprintf('getIntroSteps for route "%s" and page "%s"', $route, $specificPage));
$steps = $this->getBasicSteps($route);
$specificSteps = $this->getSpecificSteps($route, $specificPage);
if (0 === count($specificSteps)) {
if (0 === \count($specificSteps)) {
Log::debug(sprintf('No specific steps for route "%s" and page "%s"', $route, $specificPage));
return response()->json($steps);
@@ -51,7 +51,7 @@ class IntroController
if ($this->hasOutroStep($route)) {
// @codeCoverageIgnoreStart
// save last step:
$lastStep = $steps[count($steps) - 1];
$lastStep = $steps[\count($steps) - 1];
// remove last step:
array_pop($steps);
// merge arrays and add last step again
@@ -136,7 +136,7 @@ class IntroController
$routeKey = str_replace('.', '_', $route);
$elements = config(sprintf('intro.%s', $routeKey));
$steps = [];
if (is_array($elements) && count($elements) > 0) {
if (\is_array($elements) && \count($elements) > 0) {
foreach ($elements as $key => $options) {
$currentStep = $options;
@@ -147,7 +147,7 @@ class IntroController
$steps[] = $currentStep;
}
}
Log::debug(sprintf('Total basic steps for %s is %d', $routeKey, count($steps)));
Log::debug(sprintf('Total basic steps for %s is %d', $routeKey, \count($steps)));
return $steps;
}
@@ -164,10 +164,10 @@ class IntroController
$routeKey = '';
// user is on page with specific instructions:
if (strlen($specificPage) > 0) {
if (\strlen($specificPage) > 0) {
$routeKey = str_replace('.', '_', $route);
$elements = config(sprintf('intro.%s', $routeKey . '_' . $specificPage));
if (is_array($elements) && count($elements) > 0) {
if (\is_array($elements) && \count($elements) > 0) {
foreach ($elements as $key => $options) {
$currentStep = $options;
@@ -179,7 +179,7 @@ class IntroController
}
}
}
Log::debug(sprintf('Total specific steps for route "%s" and page "%s" (routeKey is "%s") is %d', $route, $specificPage, $routeKey, count($steps)));
Log::debug(sprintf('Total specific steps for route "%s" and page "%s" (routeKey is "%s") is %d', $route, $specificPage, $routeKey, \count($steps)));
return $steps;
}

View File

@@ -22,10 +22,6 @@ declare(strict_types=1);
namespace FireflyIII\Http\Controllers;
use FireflyIII\Repositories\Budget\BudgetRepositoryInterface;
use FireflyIII\Repositories\Category\CategoryRepositoryInterface;
use FireflyIII\Repositories\Journal\JournalRepositoryInterface;
use FireflyIII\Repositories\Tag\TagRepositoryInterface;
use Illuminate\Http\Request;
/**
@@ -37,8 +33,7 @@ class JsonController extends Controller
* @param Request $request
*
* @return \Illuminate\Http\JsonResponse
*
* @throws \Throwable
*/
public function action(Request $request)
{
@@ -53,68 +48,11 @@ class JsonController extends Controller
return response()->json(['html' => $view]);
}
/**
* @param BudgetRepositoryInterface $repository
*
* @return \Illuminate\Http\JsonResponse
*/
public function budgets(BudgetRepositoryInterface $repository)
{
$return = array_unique($repository->getBudgets()->pluck('name')->toArray());
sort($return);
return response()->json($return);
}
/**
* Returns a list of categories.
*
* @param CategoryRepositoryInterface $repository
*
* @return \Illuminate\Http\JsonResponse
*/
public function categories(CategoryRepositoryInterface $repository)
{
$return = array_unique($repository->getCategories()->pluck('name')->toArray());
sort($return);
return response()->json($return);
}
/**
* Returns a JSON list of all beneficiaries.
*
* @param TagRepositoryInterface $tagRepository
*
* @return \Illuminate\Http\JsonResponse
*/
public function tags(TagRepositoryInterface $tagRepository)
{
$return = array_unique($tagRepository->get()->pluck('tag')->toArray());
sort($return);
return response()->json($return);
}
/**
* @param JournalRepositoryInterface $repository
*
* @return \Illuminate\Http\JsonResponse
*/
public function transactionTypes(JournalRepositoryInterface $repository)
{
$return = array_unique($repository->getTransactionTypes()->pluck('type')->toArray());
sort($return);
return response()->json($return);
}
/**
* @param Request $request
*
* @return \Illuminate\Http\JsonResponse
*
* @throws \Throwable
*/
public function trigger(Request $request)
{

View File

@@ -24,10 +24,10 @@ namespace FireflyIII\Http\Controllers;
use Carbon\Carbon;
use FireflyIII\Http\Requests\NewUserFormRequest;
use FireflyIII\Models\TransactionCurrency;
use FireflyIII\Repositories\Account\AccountRepositoryInterface;
use FireflyIII\Repositories\Currency\CurrencyRepositoryInterface;
use Preferences;
use Session;
use View;
/**
@@ -35,6 +35,9 @@ use View;
*/
class NewUserController extends Controller
{
/** @var AccountRepositoryInterface */
private $repository;
/**
* NewUserController constructor.
*/
@@ -44,55 +47,70 @@ class NewUserController extends Controller
$this->middleware(
function ($request, $next) {
$this->repository = app(AccountRepositoryInterface::class);
return $next($request);
}
);
}
/**
* @param AccountRepositoryInterface $repository
*
* @return \Illuminate\Http\RedirectResponse|\Illuminate\Routing\Redirector|View
*/
public function index(AccountRepositoryInterface $repository)
public function index()
{
app('view')->share('title', trans('firefly.welcome'));
app('view')->share('mainTitleIcon', 'fa-fire');
$types = config('firefly.accountTypesByIdentifier.asset');
$count = $repository->count($types);
$count = $this->repository->count($types);
$languages = [];
if ($count > 0) {
return redirect(route('index'));
}
return view('new-user.index');
return view('new-user.index', compact('languages'));
}
/**
* @param NewUserFormRequest $request
* @param AccountRepositoryInterface $repository
* @param CurrencyRepositoryInterface $currencyRepository
*
* @return \Illuminate\Http\RedirectResponse|\Illuminate\Routing\Redirector
*/
public function submit(NewUserFormRequest $request, AccountRepositoryInterface $repository, CurrencyRepositoryInterface $currencyRepository)
public function submit(NewUserFormRequest $request, CurrencyRepositoryInterface $currencyRepository)
{
// create normal asset account:
$this->createAssetAccount($request, $repository);
$language = $request->string('language');
if (!array_key_exists($language, config('firefly.languages'))) {
$language = 'en_US';
// create savings account
$this->createSavingsAccount($request, $repository);
}
// also store currency preference from input:
// set language preference:
Preferences::set('language', $language);
// Store currency preference from input:
$currency = $currencyRepository->findNull((int)$request->input('amount_currency_id_bank_balance'));
if (null !== $currency) {
// store currency preference:
Preferences::set('currencyPreference', $currency->code);
Preferences::mark();
// if is null, set to EUR:
if (null === $currency) {
$currency = $currencyRepository->findByCodeNull('EUR');
}
// create normal asset account:
$this->createAssetAccount($request, $currency);
// create savings account
$this->createSavingsAccount($request, $currency, $language);
// create cash wallet account
$this->createCashWalletAccount($currency, $language);
// store currency preference:
Preferences::set('currencyPreference', $currency->code);
Preferences::mark();
// set default optional fields:
$visibleFields = [
'interest_date' => true,
@@ -107,19 +125,19 @@ class NewUserController extends Controller
];
Preferences::set('transaction_journal_optional_fields', $visibleFields);
Session::flash('success', (string)trans('firefly.stored_new_accounts_new_user'));
session()->flash('success', (string)trans('firefly.stored_new_accounts_new_user'));
Preferences::mark();
return redirect(route('index'));
}
/**
* @param NewUserFormRequest $request
* @param AccountRepositoryInterface $repository
* @param NewUserFormRequest $request
* @param TransactionCurrency $currency
*
* @return bool
*/
private function createAssetAccount(NewUserFormRequest $request, AccountRepositoryInterface $repository): bool
private function createAssetAccount(NewUserFormRequest $request, TransactionCurrency $currency): bool
{
$assetAccount = [
'name' => $request->get('bank_name'),
@@ -131,24 +149,51 @@ class NewUserController extends Controller
'accountRole' => 'defaultAsset',
'openingBalance' => $request->input('bank_balance'),
'openingBalanceDate' => new Carbon,
'currency_id' => (int)$request->input('amount_currency_id_bank_balance'),
'currency_id' => $currency->id,
];
$repository->store($assetAccount);
$this->repository->store($assetAccount);
return true;
}
/**
* @param NewUserFormRequest $request
* @param AccountRepositoryInterface $repository
* @param TransactionCurrency $currency
* @param string $language
*
* @return bool
*/
private function createSavingsAccount(NewUserFormRequest $request, AccountRepositoryInterface $repository): bool
private function createCashWalletAccount(TransactionCurrency $currency, string $language): bool
{
$assetAccount = [
'name' => (string)trans('firefly.cash_wallet', [], $language),
'iban' => null,
'accountType' => 'asset',
'virtualBalance' => 0,
'account_type_id' => null,
'active' => true,
'accountRole' => 'cashWalletAsset',
'openingBalance' => null,
'openingBalanceDate' => null,
'currency_id' => $currency->id,
];
$this->repository->store($assetAccount);
return true;
}
/**
* @param NewUserFormRequest $request
* @param TransactionCurrency $currency
* @param string $language
*
* @return bool
*/
private function createSavingsAccount(NewUserFormRequest $request, TransactionCurrency $currency, string $language): bool
{
$savingsAccount = [
'name' => $request->get('bank_name') . ' savings account',
'name' => (string)trans('firefly.new_savings_account', ['bank_name' => $request->get('bank_name')], $language),
'iban' => null,
'accountType' => 'asset',
'account_type_id' => null,
@@ -157,9 +202,9 @@ class NewUserController extends Controller
'accountRole' => 'savingAsset',
'openingBalance' => $request->input('savings_balance'),
'openingBalanceDate' => new Carbon,
'currency_id' => (int)$request->input('amount_currency_id_bank_balance'),
'currency_id' => $currency->id,
];
$repository->store($savingsAccount);
$this->repository->store($savingsAccount);
return true;
}

View File

@@ -25,13 +25,17 @@ namespace FireflyIII\Http\Controllers;
use Carbon\Carbon;
use FireflyIII\Http\Requests\PiggyBankFormRequest;
use FireflyIII\Models\PiggyBank;
use FireflyIII\Repositories\Account\AccountRepositoryInterface;
use FireflyIII\Repositories\Currency\CurrencyRepositoryInterface;
use FireflyIII\Repositories\PiggyBank\PiggyBankRepositoryInterface;
use FireflyIII\Transformers\AccountTransformer;
use FireflyIII\Transformers\PiggyBankTransformer;
use Illuminate\Http\Request;
use Illuminate\Pagination\LengthAwarePaginator;
use Illuminate\Support\Collection;
use Log;
use Preferences;
use Session;
use Steam;
use Symfony\Component\HttpFoundation\ParameterBag;
use View;
/**
@@ -39,6 +43,14 @@ use View;
*/
class PiggyBankController extends Controller
{
/** @var AccountRepositoryInterface */
private $accountRepos;
/** @var CurrencyRepositoryInterface */
private $currencyRepos;
/** @var PiggyBankRepositoryInterface */
private $piggyRepos;
/**
*
*/
@@ -51,6 +63,10 @@ class PiggyBankController extends Controller
app('view')->share('title', trans('firefly.piggyBanks'));
app('view')->share('mainTitleIcon', 'fa-sort-amount-asc');
$this->piggyRepos = app(PiggyBankRepositoryInterface::class);
$this->currencyRepos = app(CurrencyRepositoryInterface::class);
$this->accountRepos = app(AccountRepositoryInterface::class);
return $next($request);
}
);
@@ -59,43 +75,53 @@ class PiggyBankController extends Controller
/**
* Add money to piggy bank.
*
* @param PiggyBank $piggyBank
*
* @param PiggyBankRepositoryInterface $repository
* @param PiggyBank $piggyBank
*
* @return View
*/
public function add(PiggyBank $piggyBank, PiggyBankRepositoryInterface $repository)
public function add(PiggyBank $piggyBank)
{
/** @var Carbon $date */
$date = session('end', Carbon::now()->endOfMonth());
$leftOnAccount = $piggyBank->leftOnAccount($date);
$savedSoFar = $repository->getCurrentAmount($piggyBank);
$leftOnAccount = $this->piggyRepos->leftOnAccount($piggyBank, $date);
$savedSoFar = $this->piggyRepos->getCurrentAmount($piggyBank);
$leftToSave = bcsub($piggyBank->targetamount, $savedSoFar);
$maxAmount = min($leftOnAccount, $leftToSave);
return view('piggy-banks.add', compact('piggyBank', 'maxAmount'));
// get currency:
$currency = app('amount')->getDefaultCurrency();
$currencyId = (int)$this->accountRepos->getMetaValue($piggyBank->account, 'currency_id');
if ($currencyId > 0) {
$currency = $this->currencyRepos->findNull($currencyId);
}
return view('piggy-banks.add', compact('piggyBank', 'maxAmount', 'currency'));
}
/**
* Add money to piggy bank (for mobile devices).
*
* @param PiggyBank $piggyBank
*
* @param PiggyBankRepositoryInterface $repository
* @param PiggyBank $piggyBank
*
* @return View
*/
public function addMobile(PiggyBank $piggyBank, PiggyBankRepositoryInterface $repository)
public function addMobile(PiggyBank $piggyBank)
{
/** @var Carbon $date */
$date = session('end', Carbon::now()->endOfMonth());
$leftOnAccount = $piggyBank->leftOnAccount($date);
$savedSoFar = $repository->getCurrentAmount($piggyBank);
$leftOnAccount = $this->piggyRepos->leftOnAccount($piggyBank, $date);
$savedSoFar = $this->piggyRepos->getCurrentAmount($piggyBank);
$leftToSave = bcsub($piggyBank->targetamount, $savedSoFar);
$maxAmount = min($leftOnAccount, $leftToSave);
return view('piggy-banks.add-mobile', compact('piggyBank', 'maxAmount'));
// get currency:
$currency = app('amount')->getDefaultCurrency();
$currencyId = (int)$this->accountRepos->getMetaValue($piggyBank->account, 'currency_id');
if ($currencyId > 0) {
$currency = $this->currencyRepos->findNull($currencyId);
}
return view('piggy-banks.add-mobile', compact('piggyBank', 'maxAmount', 'currency'));
}
/**
@@ -110,7 +136,7 @@ class PiggyBankController extends Controller
if (true !== session('piggy-banks.create.fromStore')) {
$this->rememberPreviousUri('piggy-banks.create.uri');
}
Session::forget('piggy-banks.create.fromStore');
session()->forget('piggy-banks.create.fromStore');
return view('piggy-banks.create', compact('subTitle', 'subTitleIcon'));
}
@@ -131,16 +157,15 @@ class PiggyBankController extends Controller
}
/**
* @param PiggyBankRepositoryInterface $repository
* @param PiggyBank $piggyBank
* @param PiggyBank $piggyBank
*
* @return \Illuminate\Http\RedirectResponse
*/
public function destroy(PiggyBankRepositoryInterface $repository, PiggyBank $piggyBank)
public function destroy(PiggyBank $piggyBank)
{
Session::flash('success', (string)trans('firefly.deleted_piggy_bank', ['name' => $piggyBank->name]));
session()->flash('success', (string)trans('firefly.deleted_piggy_bank', ['name' => $piggyBank->name]));
Preferences::mark();
$repository->destroy($piggyBank);
$this->piggyRepos->destroy($piggyBank);
return redirect($this->getPreviousUri('piggy-banks.delete.uri'));
}
@@ -172,87 +197,85 @@ class PiggyBankController extends Controller
'startdate' => $startDate,
'note' => null === $note ? '' : $note->text,
];
Session::flash('preFilled', $preFilled);
session()->flash('preFilled', $preFilled);
// put previous url in session if not redirect from store (not "return_to_edit").
if (true !== session('piggy-banks.edit.fromUpdate')) {
$this->rememberPreviousUri('piggy-banks.edit.uri');
}
Session::forget('piggy-banks.edit.fromUpdate');
session()->forget('piggy-banks.edit.fromUpdate');
return view('piggy-banks.edit', compact('subTitle', 'subTitleIcon', 'piggyBank', 'preFilled'));
}
/**
* @param Request $request
* @param PiggyBankRepositoryInterface $piggyRepository
* @param Request $request
*
* @return View
*/
public function index(Request $request, PiggyBankRepositoryInterface $piggyRepository)
public function index(Request $request)
{
$collection = $piggyRepository->getPiggyBanks();
$collection = $this->piggyRepos->getPiggyBanks();
$total = $collection->count();
$page = 0 === (int)$request->get('page') ? 1 : (int)$request->get('page');
$pageSize = (int)Preferences::get('listPageSize', 50)->data;
$accounts = [];
/** @var Carbon $end */
$end = session('end', Carbon::now()->endOfMonth());
$accounts = [];
Log::debug('Looping piggues');
/** @var PiggyBank $piggyBank */
foreach ($collection as $piggyBank) {
// transform piggies using the transformer:
$parameters = new ParameterBag;
$parameters->set('end', $end);
$transformed = new Collection;
$transformer = new PiggyBankTransformer(new ParameterBag);
$accountTransformer = new AccountTransformer($parameters);
/** @var PiggyBank $piggy */
foreach ($collection as $piggy) {
$array = $transformer->transform($piggy);
$account = $accountTransformer->transform($piggy->account);
$accountId = $account['id'];
if (!isset($accounts[$accountId])) {
// create new:
$accounts[$accountId] = $account;
$piggyBank->savedSoFar = $piggyRepository->getCurrentAmount($piggyBank);
$piggyBank->percentage = (int)(0 !== bccomp('0', $piggyBank->savedSoFar) ? $piggyBank->savedSoFar / $piggyBank->targetamount * 100 : 0);
$piggyBank->leftToSave = bcsub($piggyBank->targetamount, (string)$piggyBank->savedSoFar);
$piggyBank->percentage = $piggyBank->percentage > 100 ? 100 : $piggyBank->percentage;
// add some interesting details:
$accounts[$accountId]['left'] = $accounts[$accountId]['current_balance'];
$accounts[$accountId]['saved'] = 0;
$accounts[$accountId]['target'] = 0;
$accounts[$accountId]['to_save'] = 0;
}
// Fill account information:
$account = $piggyBank->account;
$new = false;
if (!isset($accounts[$account->id])) {
$new = true;
$accounts[$account->id] = [
'name' => $account->name,
'balance' => Steam::balanceIgnoreVirtual($account, $end),
'leftForPiggyBanks' => $piggyBank->leftOnAccount($end),
'sumOfSaved' => (string)$piggyBank->savedSoFar,
'sumOfTargets' => $piggyBank->targetamount,
'leftToSave' => $piggyBank->leftToSave,
];
}
if (isset($accounts[$account->id]) && false === $new) {
$accounts[$account->id]['sumOfSaved'] = bcadd($accounts[$account->id]['sumOfSaved'], (string)$piggyBank->savedSoFar);
$accounts[$account->id]['sumOfTargets'] = bcadd($accounts[$account->id]['sumOfTargets'], $piggyBank->targetamount);
$accounts[$account->id]['leftToSave'] = bcadd($accounts[$account->id]['leftToSave'], $piggyBank->leftToSave);
}
// calculate new interesting fields:
$accounts[$accountId]['left'] -= $array['current_amount'];
$accounts[$accountId]['saved'] += $array['current_amount'];
$accounts[$accountId]['target'] += $array['target_amount'];
$accounts[$accountId]['to_save'] += ($array['target_amount'] - $array['current_amount']);
$array['account_name'] = $account['name'];
$transformed->push($array);
}
// paginate piggy banks
$collection = $collection->slice(($page - 1) * $pageSize, $pageSize);
$piggyBanks = new LengthAwarePaginator($collection, $total, $pageSize, $page);
$transformed = $transformed->slice(($page - 1) * $pageSize, $pageSize);
$piggyBanks = new LengthAwarePaginator($transformed, $total, $pageSize, $page);
$piggyBanks->setPath(route('piggy-banks.index'));
return view('piggy-banks.index', compact('piggyBanks', 'accounts'));
}
/**
* @param Request $request
* @param PiggyBankRepositoryInterface $repository
* @param Request $request
*
* @return \Illuminate\Http\JsonResponse
*/
public function order(Request $request, PiggyBankRepositoryInterface $repository)
public function order(Request $request)
{
$data = $request->get('order');
// set all users piggy banks to zero:
$repository->reset();
$this->piggyRepos->reset();
if (is_array($data)) {
if (\is_array($data)) {
foreach ($data as $order => $id) {
$repository->setOrder((int)$id, $order + 1);
$this->piggyRepos->setOrder((int)$id, $order + 1);
}
}
@@ -260,19 +283,22 @@ class PiggyBankController extends Controller
}
/**
* @param Request $request
* @param PiggyBankRepositoryInterface $repository
* @param PiggyBank $piggyBank
* @param Request $request
* @param PiggyBank $piggyBank
*
* @return \Illuminate\Http\RedirectResponse
*/
public function postAdd(Request $request, PiggyBankRepositoryInterface $repository, PiggyBank $piggyBank)
public function postAdd(Request $request, PiggyBank $piggyBank)
{
$amount = $request->get('amount') ?? '0';
$currency = app('amount')->getDefaultCurrency();
if ($repository->canAddAmount($piggyBank, $amount)) {
$repository->addAmount($piggyBank, $amount);
Session::flash(
$amount = $request->get('amount') ?? '0';
$currency = app('amount')->getDefaultCurrency();
$currencyId = (int)$this->accountRepos->getMetaValue($piggyBank->account, 'currency_id');
if ($currencyId > 0) {
$currency = $this->currencyRepos->findNull($currencyId);
}
if ($this->piggyRepos->canAddAmount($piggyBank, $amount)) {
$this->piggyRepos->addAmount($piggyBank, $amount);
session()->flash(
'success',
(string)trans(
'firefly.added_amount_to_piggy',
@@ -285,7 +311,7 @@ class PiggyBankController extends Controller
}
Log::error('Cannot add ' . $amount . ' because canAddAmount returned false.');
Session::flash(
session()->flash(
'error',
(string)trans(
'firefly.cannot_add_amount_piggy',
@@ -297,19 +323,22 @@ class PiggyBankController extends Controller
}
/**
* @param Request $request
* @param PiggyBankRepositoryInterface $repository
* @param PiggyBank $piggyBank
* @param Request $request
* @param PiggyBank $piggyBank
*
* @return \Illuminate\Http\RedirectResponse
*/
public function postRemove(Request $request, PiggyBankRepositoryInterface $repository, PiggyBank $piggyBank)
public function postRemove(Request $request, PiggyBank $piggyBank)
{
$amount = $request->get('amount') ?? '0';
$currency = app('amount')->getDefaultCurrency();
if ($repository->canRemoveAmount($piggyBank, $amount)) {
$repository->removeAmount($piggyBank, $amount);
Session::flash(
$amount = $request->get('amount') ?? '0';
$currency = app('amount')->getDefaultCurrency();
$currencyId = (int)$this->accountRepos->getMetaValue($piggyBank->account, 'currency_id');
if ($currencyId > 0) {
$currency = $this->currencyRepos->findNull($currencyId);
}
if ($this->piggyRepos->canRemoveAmount($piggyBank, $amount)) {
$this->piggyRepos->removeAmount($piggyBank, $amount);
session()->flash(
'success',
(string)trans(
'firefly.removed_amount_from_piggy',
@@ -323,7 +352,7 @@ class PiggyBankController extends Controller
$amount = (string)round($request->get('amount'), 12);
Session::flash(
session()->flash(
'error',
(string)trans(
'firefly.cannot_remove_from_piggy',
@@ -341,7 +370,15 @@ class PiggyBankController extends Controller
*/
public function remove(PiggyBank $piggyBank)
{
return view('piggy-banks.remove', compact('piggyBank'));
$repetition = $this->piggyRepos->getRepetition($piggyBank);
// get currency:
$currency = app('amount')->getDefaultCurrency();
$currencyId = (int)$this->accountRepos->getMetaValue($piggyBank->account, 'currency_id');
if ($currencyId > 0) {
$currency = $this->currencyRepos->findNull($currencyId);
}
return view('piggy-banks.remove', compact('piggyBank', 'repetition', 'currency'));
}
/**
@@ -353,44 +390,51 @@ class PiggyBankController extends Controller
*/
public function removeMobile(PiggyBank $piggyBank)
{
return view('piggy-banks.remove-mobile', compact('piggyBank'));
$repetition = $this->piggyRepos->getRepetition($piggyBank);
// get currency:
$currency = app('amount')->getDefaultCurrency();
$currencyId = (int)$this->accountRepos->getMetaValue($piggyBank->account, 'currency_id');
if ($currencyId > 0) {
$currency = $this->currencyRepos->findNull($currencyId);
}
return view('piggy-banks.remove-mobile', compact('piggyBank', 'repetition', 'currency'));
}
/**
* @param PiggyBankRepositoryInterface $repository
* @param PiggyBank $piggyBank
* @param PiggyBank $piggyBank
*
* @return View
*/
public function show(PiggyBankRepositoryInterface $repository, PiggyBank $piggyBank)
public function show(PiggyBank $piggyBank)
{
$note = $piggyBank->notes()->first();
$events = $repository->getEvents($piggyBank);
$events = $this->piggyRepos->getEvents($piggyBank);
$subTitle = $piggyBank->name;
return view('piggy-banks.show', compact('piggyBank', 'events', 'subTitle', 'note'));
}
/**
* @param PiggyBankFormRequest $request
* @param PiggyBankRepositoryInterface $repository
* @param PiggyBankFormRequest $request
*
* @return \Illuminate\Http\RedirectResponse|\Illuminate\Routing\Redirector
*/
public function store(PiggyBankFormRequest $request, PiggyBankRepositoryInterface $repository)
public function store(PiggyBankFormRequest $request)
{
$data = $request->getPiggyBankData();
if (null === $data['startdate']) {
$data['startdate'] = new Carbon;
}
$piggyBank = $repository->store($data);
$piggyBank = $this->piggyRepos->store($data);
Session::flash('success', (string)trans('firefly.stored_piggy_bank', ['name' => $piggyBank->name]));
session()->flash('success', (string)trans('firefly.stored_piggy_bank', ['name' => $piggyBank->name]));
Preferences::mark();
if (1 === (int)$request->get('create_another')) {
// @codeCoverageIgnoreStart
Session::put('piggy-banks.create.fromStore', true);
session()->put('piggy-banks.create.fromStore', true);
return redirect(route('piggy-banks.create'))->withInput();
// @codeCoverageIgnoreEnd
@@ -400,23 +444,22 @@ class PiggyBankController extends Controller
}
/**
* @param PiggyBankRepositoryInterface $repository
* @param PiggyBankFormRequest $request
* @param PiggyBank $piggyBank
* @param PiggyBankFormRequest $request
* @param PiggyBank $piggyBank
*
* @return \Illuminate\Http\RedirectResponse|\Illuminate\Routing\Redirector
*/
public function update(PiggyBankRepositoryInterface $repository, PiggyBankFormRequest $request, PiggyBank $piggyBank)
public function update(PiggyBankFormRequest $request, PiggyBank $piggyBank)
{
$data = $request->getPiggyBankData();
$piggyBank = $repository->update($piggyBank, $data);
$piggyBank = $this->piggyRepos->update($piggyBank, $data);
Session::flash('success', (string)trans('firefly.updated_piggy_bank', ['name' => $piggyBank->name]));
session()->flash('success', (string)trans('firefly.updated_piggy_bank', ['name' => $piggyBank->name]));
Preferences::mark();
if (1 === (int)$request->get('return_to_edit')) {
// @codeCoverageIgnoreStart
Session::put('piggy-banks.edit.fromUpdate', true);
session()->put('piggy-banks.edit.fromUpdate', true);
return redirect(route('piggy-banks.edit', [$piggyBank->id]));
// @codeCoverageIgnoreEnd

View File

@@ -114,11 +114,12 @@ class ReportController extends Controller
}
/**
* @param $attributes
* @param array $attributes
*
* @return string
*
* @throws FireflyException
* @throws \Throwable
*/
private function balanceAmount(array $attributes): string
{
@@ -155,8 +156,7 @@ class ReportController extends Controller
* @param array $attributes
*
* @return string
*
* @throws \Throwable
*/
private function budgetSpentAmount(array $attributes): string
{
@@ -173,8 +173,7 @@ class ReportController extends Controller
* @param array $attributes
*
* @return string
*
* @throws \Throwable
*/
private function categoryEntry(array $attributes): string
{
@@ -191,8 +190,7 @@ class ReportController extends Controller
* @param array $attributes
*
* @return string
*
* @throws \Throwable
*/
private function expenseEntry(array $attributes): string
{
@@ -209,8 +207,7 @@ class ReportController extends Controller
* @param array $attributes
*
* @return string
*
* @throws \Throwable
*/
private function incomeEntry(array $attributes): string
{

View File

@@ -27,7 +27,6 @@ use FireflyIII\Repositories\Account\AccountRepositoryInterface;
use FireflyIII\Repositories\User\UserRepositoryInterface;
use Illuminate\Http\Request;
use Preferences;
use Session;
use View;
/**
@@ -95,7 +94,7 @@ class PreferencesController extends Controller
{
// front page accounts
$frontPageAccounts = [];
if (is_array($request->get('frontPageAccounts'))) {
if (\is_array($request->get('frontPageAccounts'))) {
foreach ($request->get('frontPageAccounts') as $id) {
$frontPageAccounts[] = (int)$id;
}
@@ -105,9 +104,9 @@ class PreferencesController extends Controller
// view range:
Preferences::set('viewRange', $request->get('viewRange'));
// forget session values:
Session::forget('start');
Session::forget('end');
Session::forget('range');
session()->forget('start');
session()->forget('end');
session()->forget('range');
// custom fiscal year
$customFiscalYear = 1 === (int)$request->get('customFiscalYear');
@@ -143,7 +142,7 @@ class PreferencesController extends Controller
];
Preferences::set('transaction_journal_optional_fields', $optionalTj);
Session::flash('success', (string)trans('firefly.saved_preferences'));
session()->flash('success', (string)trans('firefly.saved_preferences'));
Preferences::mark();
return redirect(route('preferences.index'));

View File

@@ -44,7 +44,6 @@ use Laravel\Passport\Passport;
use Log;
use phpseclib\Crypt\RSA;
use Preferences;
use Session;
use View;
/**
@@ -107,7 +106,7 @@ class ProfileController extends Controller
{
$domain = $this->getDomain();
$secret = Google2FA::generateSecretKey();
Session::flash('two-factor-secret', $secret);
session()->flash('two-factor-secret', $secret);
$image = Google2FA::getQRCodeInline($domain, auth()->user()->email, $secret, 200);
return view('profile.code', compact('image'));
@@ -143,7 +142,7 @@ class ProfileController extends Controller
$repository->unblockUser($user);
// return to login.
Session::flash('success', (string)trans('firefly.login_with_new_email'));
session()->flash('success', (string)trans('firefly.login_with_new_email'));
return redirect(route('login'));
}
@@ -167,8 +166,8 @@ class ProfileController extends Controller
{
Preferences::delete('twoFactorAuthEnabled');
Preferences::delete('twoFactorAuthSecret');
Session::flash('success', (string)trans('firefly.pref_two_factor_auth_disabled'));
Session::flash('info', (string)trans('firefly.pref_two_factor_auth_remove_it'));
session()->flash('success', (string)trans('firefly.pref_two_factor_auth_disabled'));
session()->flash('info', (string)trans('firefly.pref_two_factor_auth_remove_it'));
return redirect(route('profile.index'));
}
@@ -242,7 +241,7 @@ class ProfileController extends Controller
$newEmail = $request->string('email');
$oldEmail = $user->email;
if ($newEmail === $user->email) {
Session::flash('error', (string)trans('firefly.email_not_changed'));
session()->flash('error', (string)trans('firefly.email_not_changed'));
return redirect(route('profile.change-email'))->withInput();
}
@@ -252,7 +251,7 @@ class ProfileController extends Controller
Auth::guard()->logout();
$request->session()->invalidate();
Session::flash('success', (string)trans('firefly.email_changed'));
session()->flash('success', (string)trans('firefly.email_changed'));
return redirect(route('index'));
}
@@ -267,7 +266,7 @@ class ProfileController extends Controller
// force user logout.
Auth::guard()->logout();
$request->session()->invalidate();
Session::flash('success', (string)trans('firefly.email_changed'));
session()->flash('success', (string)trans('firefly.email_changed'));
return redirect(route('index'));
}
@@ -287,13 +286,13 @@ class ProfileController extends Controller
try {
$this->validatePassword(auth()->user(), $current, $new);
} catch (ValidationException $e) {
Session::flash('error', $e->getMessage());
session()->flash('error', $e->getMessage());
return redirect(route('profile.change-password'));
}
$repository->changePassword(auth()->user(), $request->get('new_password'));
Session::flash('success', (string)trans('firefly.password_changed'));
session()->flash('success', (string)trans('firefly.password_changed'));
return redirect(route('profile.index'));
}
@@ -307,9 +306,9 @@ class ProfileController extends Controller
public function postCode(TokenFormRequest $request)
{
Preferences::set('twoFactorAuthEnabled', 1);
Preferences::set('twoFactorAuthSecret', Session::get('two-factor-secret'));
Preferences::set('twoFactorAuthSecret', session()->get('two-factor-secret'));
Session::flash('success', (string)trans('firefly.saved_preferences'));
session()->flash('success', (string)trans('firefly.saved_preferences'));
Preferences::mark();
return redirect(route('profile.index'));
@@ -324,7 +323,7 @@ class ProfileController extends Controller
public function postDeleteAccount(UserRepositoryInterface $repository, DeleteAccountFormRequest $request)
{
if (!Hash::check($request->get('password'), auth()->user()->password)) {
Session::flash('error', (string)trans('firefly.invalid_password'));
session()->flash('error', (string)trans('firefly.invalid_password'));
return redirect(route('profile.delete-account'));
}
@@ -332,7 +331,7 @@ class ProfileController extends Controller
Log::info(sprintf('User #%d has opted to delete their account', auth()->user()->id));
// make repository delete user:
auth()->logout();
Session::flush();
session()->flush();
$repository->destroy($user);
return redirect(route('index'));
@@ -345,7 +344,7 @@ class ProfileController extends Controller
{
$token = auth()->user()->generateAccessToken();
Preferences::set('access_token', $token);
Session::flash('success', (string)trans('firefly.token_regenerated'));
session()->flash('success', (string)trans('firefly.token_regenerated'));
return redirect(route('profile.index'));
}
@@ -395,7 +394,7 @@ class ProfileController extends Controller
$repository->unblockUser($user);
// return to login.
Session::flash('success', (string)trans('firefly.login_with_old_email'));
session()->flash('success', (string)trans('firefly.login_with_old_email'));
return redirect(route('login'));
}

View File

@@ -40,7 +40,7 @@ class AccountController extends Controller
*
* @return mixed|string
*
* @throws \Throwable
*/
public function general(Collection $accounts, Carbon $start, Carbon $end)
{

View File

@@ -40,8 +40,7 @@ class BalanceController extends Controller
* @param Carbon $end
*
* @return mixed|string
*
* @throws \Throwable
*/
public function general(BalanceReportHelperInterface $helper, Collection $accounts, Carbon $start, Carbon $end)
{

View File

@@ -41,8 +41,7 @@ class BudgetController extends Controller
* @param Carbon $end
*
* @return mixed|string
*
* @throws \Throwable
*/
public function general(BudgetReportHelperInterface $helper, Collection $accounts, Carbon $start, Carbon $end)
{
@@ -70,8 +69,7 @@ class BudgetController extends Controller
* @param Carbon $end
*
* @return mixed|string
*
* @throws \Throwable
*/
public function period(Collection $accounts, Carbon $start, Carbon $end)
{

View File

@@ -40,8 +40,7 @@ class CategoryController extends Controller
* @param Carbon $end
*
* @return mixed|string
*
* @throws \Throwable
*/
public function expenses(Collection $accounts, Carbon $start, Carbon $end)
{
@@ -68,13 +67,13 @@ class CategoryController extends Controller
}
/**
* @param Carbon $start
* @param Carbon $end
* @param Collection $accounts
*
* @return string
* @param Carbon $start
* @param Carbon $end
*
* @return string
* @throws \Throwable
*/
public function income(Collection $accounts, Carbon $start, Carbon $end)
{
@@ -107,9 +106,8 @@ class CategoryController extends Controller
*
* @return mixed|string
*
* @throws \Throwable
* @internal param ReportHelperInterface $helper
*
*/
public function operations(Collection $accounts, Carbon $start, Carbon $end)
{

View File

@@ -67,8 +67,7 @@ class ExpenseController extends Controller
* @param Carbon $end
*
* @return string
*
* @throws \Throwable
*/
public function budget(Collection $accounts, Collection $expense, Carbon $start, Carbon $end)
{
@@ -115,8 +114,7 @@ class ExpenseController extends Controller
* @param Carbon $end
*
* @return string
*
* @throws \Throwable
*/
public function category(Collection $accounts, Collection $expense, Carbon $start, Carbon $end)
{
@@ -173,8 +171,7 @@ class ExpenseController extends Controller
* @param Carbon $end
*
* @return array|mixed|string
*
* @throws \Throwable
*/
public function spent(Collection $accounts, Collection $expense, Carbon $start, Carbon $end)
{
@@ -218,8 +215,7 @@ class ExpenseController extends Controller
* @param Carbon $end
*
* @return string
*
* @throws \Throwable
*/
public function topExpense(Collection $accounts, Collection $expense, Carbon $start, Carbon $end)
{
@@ -262,8 +258,7 @@ class ExpenseController extends Controller
* @param Carbon $end
*
* @return mixed|string
*
* @throws \Throwable
*/
public function topIncome(Collection $accounts, Collection $expense, Carbon $start, Carbon $end)
{

View File

@@ -40,8 +40,7 @@ class OperationsController extends Controller
* @param Carbon $end
*
* @return mixed|string
*
* @throws \Throwable
*/
public function expenses(AccountTaskerInterface $tasker, Collection $accounts, Carbon $start, Carbon $end)
{
@@ -69,8 +68,7 @@ class OperationsController extends Controller
* @param Carbon $end
*
* @return string
*
* @throws \Throwable
*/
public function income(AccountTaskerInterface $tasker, Collection $accounts, Carbon $start, Carbon $end)
{
@@ -99,8 +97,7 @@ class OperationsController extends Controller
* @param Carbon $end
*
* @return mixed|string
*
* @throws \Throwable
*/
public function operations(AccountTaskerInterface $tasker, Collection $accounts, Carbon $start, Carbon $end)
{

View File

@@ -36,7 +36,6 @@ use Illuminate\Http\RedirectResponse;
use Illuminate\Support\Collection;
use Log;
use Preferences;
use Session;
use View;
/**
@@ -325,25 +324,25 @@ class ReportController extends Controller
if (0 === $request->getAccountList()->count()) {
Log::debug('Account count is zero');
Session::flash('error', trans('firefly.select_more_than_one_account'));
session()->flash('error', trans('firefly.select_more_than_one_account'));
return redirect(route('reports.index'));
}
if (0 === $request->getCategoryList()->count() && 'category' === $reportType) {
Session::flash('error', trans('firefly.select_more_than_one_category'));
session()->flash('error', trans('firefly.select_more_than_one_category'));
return redirect(route('reports.index'));
}
if (0 === $request->getBudgetList()->count() && 'budget' === $reportType) {
Session::flash('error', trans('firefly.select_more_than_one_budget'));
session()->flash('error', trans('firefly.select_more_than_one_budget'));
return redirect(route('reports.index'));
}
if (0 === $request->getTagList()->count() && 'tag' === $reportType) {
Session::flash('error', trans('firefly.select_more_than_one_tag'));
session()->flash('error', trans('firefly.select_more_than_one_tag'));
return redirect(route('reports.index'));
}
@@ -416,8 +415,7 @@ class ReportController extends Controller
/**
* @return string
*
* @throws \Throwable
*/
private function accountReportOptions(): string
{
@@ -428,7 +426,7 @@ class ReportController extends Controller
$set = new Collection;
$names = $revenue->pluck('name')->toArray();
foreach ($expense as $exp) {
if (in_array($exp->name, $names)) {
if (\in_array($exp->name, $names)) {
$set->push($exp);
}
}
@@ -438,8 +436,7 @@ class ReportController extends Controller
/**
* @return string
*
* @throws \Throwable
*/
private function budgetReportOptions(): string
{
@@ -452,8 +449,7 @@ class ReportController extends Controller
/**
* @return string
*
* @throws \Throwable
*/
private function categoryReportOptions(): string
{
@@ -466,8 +462,7 @@ class ReportController extends Controller
/**
* @return string
*
* @throws \Throwable
*/
private function noReportOptions(): string
{
@@ -476,8 +471,7 @@ class ReportController extends Controller
/**
* @return string
*
* @throws \Throwable
*/
private function tagReportOptions(): string
{

View File

@@ -24,22 +24,28 @@ namespace FireflyIII\Http\Controllers;
use Carbon\Carbon;
use ExpandedForm;
use FireflyIII\Exceptions\FireflyException;
use FireflyIII\Http\Requests\RuleFormRequest;
use FireflyIII\Http\Requests\SelectTransactionsRequest;
use FireflyIII\Http\Requests\TestRuleFormRequest;
use FireflyIII\Jobs\ExecuteRuleOnExistingTransactions;
use FireflyIII\Models\AccountType;
use FireflyIII\Models\Bill;
use FireflyIII\Models\Rule;
use FireflyIII\Models\RuleAction;
use FireflyIII\Models\RuleGroup;
use FireflyIII\Models\RuleTrigger;
use FireflyIII\Repositories\Account\AccountRepositoryInterface;
use FireflyIII\Repositories\Bill\BillRepositoryInterface;
use FireflyIII\Repositories\Rule\RuleRepositoryInterface;
use FireflyIII\Repositories\RuleGroup\RuleGroupRepositoryInterface;
use FireflyIII\TransactionRules\TransactionMatcher;
use Illuminate\Http\JsonResponse;
use Illuminate\Http\Request;
use Illuminate\Support\Collection;
use Log;
use Preferences;
use Session;
use Throwable;
use View;
/**
@@ -47,6 +53,15 @@ use View;
*/
class RuleController extends Controller
{
/** @var AccountRepositoryInterface */
private $accountRepos;
/** @var BillRepositoryInterface */
private $billRepos;
/** @var RuleGroupRepositoryInterface */
private $ruleGroupRepos;
/** @var RuleRepositoryInterface */
private $ruleRepos;
/**
* RuleController constructor.
*/
@@ -59,6 +74,11 @@ class RuleController extends Controller
app('view')->share('title', trans('firefly.rules'));
app('view')->share('mainTitleIcon', 'fa-random');
$this->accountRepos = app(AccountRepositoryInterface::class);
$this->billRepos = app(BillRepositoryInterface::class);
$this->ruleGroupRepos = app(RuleGroupRepositoryInterface::class);
$this->ruleRepos = app(RuleRepositoryInterface::class);
return $next($request);
}
);
@@ -72,42 +92,67 @@ class RuleController extends Controller
*
* @return View
*
*/
public function create(Request $request, RuleGroup $ruleGroup)
{
// count for possible present previous entered triggers/actions.
$triggerCount = 0;
$actionCount = 0;
$this->createDefaultRuleGroup();
$this->createDefaultRule();
$bill = null;
$billId = (int)$request->get('fromBill');
$preFilled = [
'strict' => true,
];
$groups = ExpandedForm::makeSelectList($this->ruleGroupRepos->get());
$oldTriggers = [];
$oldActions = [];
$returnToBill = false;
// collection of those triggers/actions.
$oldTriggers = [];
$oldActions = [];
if ($request->get('return') === 'true') {
$returnToBill = true;
}
// has bill?
if ($billId > 0) {
$bill = $this->billRepos->find($billId);
}
// has old input?
if ($request->old()) {
// process old triggers.
$oldTriggers = $this->getPreviousTriggers($request);
$triggerCount = count($oldTriggers);
// process old actions
$oldTriggers = $this->getPreviousTriggers($request);
$oldActions = $this->getPreviousActions($request);
$actionCount = count($oldActions);
}
// has existing bill refered to in URI?
if (null !== $bill && !$request->old()) {
// create some sensible defaults:
$preFilled['title'] = trans('firefly.new_rule_for_bill_title', ['name' => $bill->name]);
$preFilled['description'] = trans('firefly.new_rule_for_bill_description', ['name' => $bill->name]);
// get triggers and actions for bill:
$oldTriggers = $this->getTriggersForBill($bill);
$oldActions = $this->getActionsForBill($bill);
}
$triggerCount = \count($oldTriggers);
$actionCount = \count($oldActions);
$subTitleIcon = 'fa-clone';
$subTitle = trans('firefly.make_new_rule', ['title' => $ruleGroup->title]);
$request->session()->flash('preFilled', $preFilled);
// put previous url in session if not redirect from store (not "create another").
if (true !== session('rules.create.fromStore')) {
$this->rememberPreviousUri('rules.create.uri');
}
Session::forget('rules.create.fromStore');
session()->forget('rules.create.fromStore');
return view(
'rules.rule.create',
compact('subTitleIcon', 'oldTriggers', 'oldActions', 'triggerCount', 'actionCount', 'ruleGroup', 'subTitle')
compact(
'subTitleIcon', 'oldTriggers', 'returnToBill', 'groups', 'preFilled', 'bill', 'oldActions', 'triggerCount', 'actionCount', 'ruleGroup',
'subTitle'
)
);
}
@@ -131,112 +176,90 @@ class RuleController extends Controller
/**
* Actually destroy the given rule.
*
* @param Rule $rule
* @param RuleRepositoryInterface $repository
* @param Rule $rule
*
* @return \Illuminate\Http\RedirectResponse
*/
public function destroy(RuleRepositoryInterface $repository, Rule $rule)
public function destroy(Rule $rule)
{
$title = $rule->title;
$repository->destroy($rule);
$this->ruleRepos->destroy($rule);
Session::flash('success', trans('firefly.deleted_rule', ['title' => $title]));
session()->flash('success', trans('firefly.deleted_rule', ['title' => $title]));
Preferences::mark();
return redirect($this->getPreviousUri('rules.delete.uri'));
}
/**
* @param RuleRepositoryInterface $repository
* @param Rule $rule
* @param Rule $rule
*
* @return \Illuminate\Http\RedirectResponse|\Illuminate\Routing\Redirector
*/
public function down(RuleRepositoryInterface $repository, Rule $rule)
public function down(Rule $rule)
{
$repository->moveDown($rule);
$this->ruleRepos->moveDown($rule);
return redirect(route('rules.index'));
}
/**
* @param Request $request
* @param RuleRepositoryInterface $repository
* @param Rule $rule
* @param Request $request
* @param Rule $rule
*
* @return View
*
*/
public function edit(Request $request, RuleRepositoryInterface $repository, Rule $rule)
public function edit(Request $request, Rule $rule)
{
/** @var RuleGroupRepositoryInterface $ruleGroupRepository */
$ruleGroupRepository = app(RuleGroupRepositoryInterface::class);
$ruleGroups = ExpandedForm::makeSelectList($ruleGroupRepository->get());
$triggerCount = 0;
$actionCount = 0;
$oldActions = [];
$oldTriggers = [];
$ruleGroups = ExpandedForm::makeSelectList($this->ruleGroupRepos->get());
$triggerCount = 0;
$actionCount = 0;
$oldActions = [];
$oldTriggers = [];
// has old input?
if (count($request->old()) > 0) {
if (\count($request->old()) > 0) {
$oldTriggers = $this->getPreviousTriggers($request);
$triggerCount = count($oldTriggers);
$triggerCount = \count($oldTriggers);
$oldActions = $this->getPreviousActions($request);
$actionCount = count($oldActions);
$actionCount = \count($oldActions);
}
// overrule old input when it as no rule data:
if (0 === $triggerCount && 0 === $actionCount) {
$oldTriggers = $this->getCurrentTriggers($rule);
$triggerCount = count($oldTriggers);
$triggerCount = \count($oldTriggers);
$oldActions = $this->getCurrentActions($rule);
$actionCount = count($oldActions);
$actionCount = \count($oldActions);
}
// get rule trigger for update / store-journal:
$primaryTrigger = $repository->getPrimaryTrigger($rule);
$primaryTrigger = $this->ruleRepos->getPrimaryTrigger($rule);
$subTitle = trans('firefly.edit_rule', ['title' => $rule->title]);
// put previous url in session if not redirect from store (not "return_to_edit").
if (true !== session('rules.edit.fromUpdate')) {
$this->rememberPreviousUri('rules.edit.uri');
}
Session::forget('rules.edit.fromUpdate');
session()->forget('rules.edit.fromUpdate');
return view(
'rules.rule.edit',
compact(
'rule',
'subTitle',
'primaryTrigger',
'oldTriggers',
'oldActions',
'triggerCount',
'actionCount',
'ruleGroups'
)
);
return view('rules.rule.edit', compact('rule', 'subTitle', 'primaryTrigger', 'oldTriggers', 'oldActions', 'triggerCount', 'actionCount', 'ruleGroups'));
}
/**
* Execute the given rule on a set of existing transactions.
*
* @param SelectTransactionsRequest $request
* @param AccountRepositoryInterface $repository
* @param Rule $rule
* @param SelectTransactionsRequest $request
* @param Rule $rule
*
* @return \Illuminate\Http\RedirectResponse
*
* @internal param RuleGroup $ruleGroup
*/
public function execute(SelectTransactionsRequest $request, AccountRepositoryInterface $repository, Rule $rule)
public function execute(SelectTransactionsRequest $request, Rule $rule)
{
// Get parameters specified by the user
$accounts = $repository->getAccountsById($request->get('accounts'));
$accounts = $this->accountRepos->getAccountsById($request->get('accounts'));
$startDate = new Carbon($request->get('start_date'));
$endDate = new Carbon($request->get('end_date'));
@@ -253,69 +276,64 @@ class RuleController extends Controller
$this->dispatch($job);
// Tell the user that the job is queued
Session::flash('success', (string)trans('firefly.applied_rule_selection', ['title' => $rule->title]));
session()->flash('success', (string)trans('firefly.applied_rule_selection', ['title' => $rule->title]));
return redirect()->route('rules.index');
}
/**
* @param RuleGroupRepositoryInterface $repository
*
* @return View
*/
public function index(RuleGroupRepositoryInterface $repository)
public function index()
{
$this->createDefaultRuleGroup();
$this->createDefaultRule();
$ruleGroups = $repository->getRuleGroupsWithRules(auth()->user());
$ruleGroups = $this->ruleGroupRepos->getRuleGroupsWithRules(auth()->user());
return view('rules.index', compact('ruleGroups'));
}
/**
* @param Request $request
* @param RuleRepositoryInterface $repository
* @param Rule $rule
* @param Request $request
* @param Rule $rule
*
* @return \Illuminate\Http\JsonResponse
* @return JsonResponse
*/
public function reorderRuleActions(Request $request, RuleRepositoryInterface $repository, Rule $rule)
public function reorderRuleActions(Request $request, Rule $rule): JsonResponse
{
$ids = $request->get('actions');
if (is_array($ids)) {
$repository->reorderRuleActions($rule, $ids);
if (\is_array($ids)) {
$this->ruleRepos->reorderRuleActions($rule, $ids);
}
return response()->json('true');
}
/**
* @param Request $request
* @param RuleRepositoryInterface $repository
* @param Rule $rule
* @param Request $request
* @param Rule $rule
*
* @return \Illuminate\Http\JsonResponse
* @return JsonResponse
*/
public function reorderRuleTriggers(Request $request, RuleRepositoryInterface $repository, Rule $rule)
public function reorderRuleTriggers(Request $request, Rule $rule): JsonResponse
{
$ids = $request->get('triggers');
if (is_array($ids)) {
$repository->reorderRuleTriggers($rule, $ids);
if (\is_array($ids)) {
$this->ruleRepos->reorderRuleTriggers($rule, $ids);
}
return response()->json('true');
}
/**
* @param AccountRepositoryInterface $repository
* @param Rule $rule
* @param Rule $rule
*
* @return \Illuminate\Contracts\View\Factory|\Illuminate\View\View
*/
public function selectTransactions(AccountRepositoryInterface $repository, Rule $rule)
public function selectTransactions(Rule $rule)
{
// does the user have shared accounts?
$accounts = $repository->getAccountsByType([AccountType::ASSET]);
$accounts = $this->accountRepos->getAccountsByType([AccountType::ASSET]);
$accountList = ExpandedForm::makeSelectList($accounts);
$checkedAccounts = array_keys($accountList);
$first = session('first')->format('Y-m-d');
@@ -326,26 +344,33 @@ class RuleController extends Controller
}
/**
* @param RuleFormRequest $request
* @param RuleRepositoryInterface $repository
* @param RuleGroup $ruleGroup
* @param RuleFormRequest $request
*
* @return \Illuminate\Http\RedirectResponse|\Illuminate\Routing\Redirector
*/
public function store(RuleFormRequest $request, RuleRepositoryInterface $repository, RuleGroup $ruleGroup)
public function store(RuleFormRequest $request)
{
$data = $request->getRuleData();
$data['rule_group_id'] = $ruleGroup->id;
$rule = $repository->store($data);
Session::flash('success', trans('firefly.stored_new_rule', ['title' => $rule->title]));
$data = $request->getRuleData();
$rule = $this->ruleRepos->store($data);
session()->flash('success', trans('firefly.stored_new_rule', ['title' => $rule->title]));
Preferences::mark();
// redirect to show bill.
if ($request->get('return_to_bill') === 'true' && (int)$request->get('bill_id') > 0) {
return redirect(route('bills.show', [(int)$request->get('bill_id')]));
}
// redirect to new bill creation.
if ((int)$request->get('bill_id') > 0) {
return redirect($this->getPreviousUri('bills.create.uri'));
}
if (1 === (int)$request->get('create_another')) {
// @codeCoverageIgnoreStart
Session::put('rules.create.fromStore', true);
session()->put('rules.create.fromStore', true);
return redirect(route('rules.create', [$ruleGroup]))->withInput();
return redirect(route('rules.create', [$data['rule_group_id']]))->withInput();
// @codeCoverageIgnoreEnd
}
@@ -362,40 +387,50 @@ class RuleController extends Controller
*
* @param TestRuleFormRequest $request
*
* @return \Illuminate\Http\JsonResponse
*
* @return JsonResponse
*/
public function testTriggers(TestRuleFormRequest $request)
public function testTriggers(TestRuleFormRequest $request): JsonResponse
{
// build trigger array from response
$triggers = $this->getValidTriggerList($request);
if (0 === count($triggers)) {
if (0 === \count($triggers)) {
return response()->json(['html' => '', 'warning' => trans('firefly.warning_no_valid_triggers')]); // @codeCoverageIgnore
}
$limit = (int)config('firefly.test-triggers.limit');
$range = (int)config('firefly.test-triggers.range');
$limit = (int)config('firefly.test-triggers.limit');
$range = (int)config('firefly.test-triggers.range');
$matchingTransactions = new Collection;
/** @var TransactionMatcher $matcher */
$matcher = app(TransactionMatcher::class);
$matcher->setLimit($limit);
$matcher->setRange($range);
$matcher->setTriggers($triggers);
$matchingTransactions = $matcher->findTransactionsByTriggers();
try {
$matchingTransactions = $matcher->findTransactionsByTriggers();
} catch (FireflyException $exception) {
Log::error(sprintf('Could not grab transactions in testTriggers(): %s', $exception->getMessage()));
Log::error($exception->getTraceAsString());
}
// Warn the user if only a subset of transactions is returned
$warning = '';
if (count($matchingTransactions) === $limit) {
if ($matchingTransactions->count() === $limit) {
$warning = trans('firefly.warning_transaction_subset', ['max_num_transactions' => $limit]); // @codeCoverageIgnore
}
if (0 === count($matchingTransactions)) {
if (0 === $matchingTransactions->count()) {
$warning = trans('firefly.warning_no_matching_transactions', ['num_transactions' => $range]); // @codeCoverageIgnore
}
// Return json response
$view = view('list.journals-tiny', ['transactions' => $matchingTransactions])->render();
$view = 'ERROR, see logs.';
try {
$view = view('list.journals-tiny', ['transactions' => $matchingTransactions])->render();
} catch (Throwable $exception) {
Log::error(sprintf('Could not render view in testTriggers(): %s', $exception->getMessage()));
Log::error($exception->getTraceAsString());
}
return response()->json(['html' => $view, 'warning' => $warning]);
}
@@ -408,77 +443,84 @@ class RuleController extends Controller
* to find transaction journals matching the users input. A maximum range of transactions to try (range) and
* a maximum number of transactions to return (limit) are set as well.
*
*
* @param Rule $rule
*
* @return \Illuminate\Http\JsonResponse
*
* @return JsonResponse
*/
public function testTriggersByRule(Rule $rule)
public function testTriggersByRule(Rule $rule): JsonResponse
{
$triggers = $rule->ruleTriggers;
if (0 === count($triggers)) {
if (0 === \count($triggers)) {
return response()->json(['html' => '', 'warning' => trans('firefly.warning_no_valid_triggers')]); // @codeCoverageIgnore
}
$limit = (int)config('firefly.test-triggers.limit');
$range = (int)config('firefly.test-triggers.range');
$limit = (int)config('firefly.test-triggers.limit');
$range = (int)config('firefly.test-triggers.range');
$matchingTransactions = new Collection;
/** @var TransactionMatcher $matcher */
$matcher = app(TransactionMatcher::class);
$matcher->setLimit($limit);
$matcher->setRange($range);
$matcher->setRule($rule);
$matchingTransactions = $matcher->findTransactionsByRule();
try {
$matchingTransactions = $matcher->findTransactionsByRule();
} catch (FireflyException $exception) {
Log::error(sprintf('Could not grab transactions in testTriggersByRule(): %s', $exception->getMessage()));
Log::error($exception->getTraceAsString());
}
// Warn the user if only a subset of transactions is returned
$warning = '';
if (count($matchingTransactions) === $limit) {
if ($matchingTransactions->count() === $limit) {
$warning = trans('firefly.warning_transaction_subset', ['max_num_transactions' => $limit]); // @codeCoverageIgnore
}
if (0 === count($matchingTransactions)) {
if (0 === $matchingTransactions->count()) {
$warning = trans('firefly.warning_no_matching_transactions', ['num_transactions' => $range]); // @codeCoverageIgnore
}
// Return json response
$view = view('list.journals-tiny', ['transactions' => $matchingTransactions])->render();
$view = 'ERROR, see logs.';
try {
$view = view('list.journals-tiny', ['transactions' => $matchingTransactions])->render();
} catch (Throwable $exception) {
Log::error(sprintf('Could not render view in testTriggersByRule(): %s', $exception->getMessage()));
Log::error($exception->getTraceAsString());
}
return response()->json(['html' => $view, 'warning' => $warning]);
}
/**
* @param RuleRepositoryInterface $repository
* @param Rule $rule
* @param Rule $rule
*
* @return \Illuminate\Http\RedirectResponse|\Illuminate\Routing\Redirector
*/
public function up(RuleRepositoryInterface $repository, Rule $rule)
public function up(Rule $rule)
{
$repository->moveUp($rule);
$this->ruleRepos->moveUp($rule);
return redirect(route('rules.index'));
}
/**
* @param RuleRepositoryInterface $repository
* @param RuleFormRequest $request
* @param Rule $rule
* @param RuleFormRequest $request
* @param Rule $rule
*
* @return \Illuminate\Http\RedirectResponse|\Illuminate\Routing\Redirector
*/
public function update(RuleRepositoryInterface $repository, RuleFormRequest $request, Rule $rule)
public function update(RuleFormRequest $request, Rule $rule)
{
$data = $request->getRuleData();
$repository->update($rule, $data);
$this->ruleRepos->update($rule, $data);
Session::flash('success', trans('firefly.updated_rule', ['title' => $rule->title]));
session()->flash('success', trans('firefly.updated_rule', ['title' => $rule->title]));
Preferences::mark();
if (1 === (int)$request->get('return_to_edit')) {
// @codeCoverageIgnoreStart
Session::put('rules.edit.fromUpdate', true);
session()->put('rules.edit.fromUpdate', true);
return redirect(route('rules.edit', [$rule->id]))->withInput(['return_to_edit' => 1]);
// @codeCoverageIgnoreEnd
@@ -487,14 +529,14 @@ class RuleController extends Controller
return redirect($this->getPreviousUri('rules.edit.uri'));
}
private function createDefaultRule()
/**
*
*/
private function createDefaultRule(): void
{
/** @var RuleRepositoryInterface $repository */
$repository = app(RuleRepositoryInterface::class);
if (0 === $repository->count()) {
if (0 === $this->ruleRepos->count()) {
$data = [
'rule_group_id' => $repository->getFirstRuleGroup()->id,
'rule_group_id' => $this->ruleRepos->getFirstRuleGroup()->id,
'stop_processing' => 0,
'title' => trans('firefly.default_rule_name'),
'description' => trans('firefly.default_rule_description'),
@@ -512,53 +554,46 @@ class RuleController extends Controller
'rule-actions' => ['prepend_description', 'set_category'],
];
$repository->store($data);
$this->ruleRepos->store($data);
}
}
/**
*
*/
private function createDefaultRuleGroup()
private function createDefaultRuleGroup(): void
{
/** @var RuleGroupRepositoryInterface $repository */
$repository = app(RuleGroupRepositoryInterface::class);
if (0 === $repository->count()) {
if (0 === $this->ruleGroupRepos->count()) {
$data = [
'title' => trans('firefly.default_rule_group_name'),
'description' => trans('firefly.default_rule_group_description'),
];
$repository->store($data);
$this->ruleGroupRepos->store($data);
}
}
/**
* @param Rule $rule
* @param Bill $bill
*
* @return array
*
*/
private function getCurrentActions(Rule $rule)
private function getActionsForBill(Bill $bill): array
{
$index = 0;
$actions = [];
/** @var RuleAction $entry */
foreach ($rule->ruleActions as $entry) {
$count = ($index + 1);
try {
$actions[] = view(
'rules.partials.action',
[
'oldAction' => $entry->action_type,
'oldValue' => $entry->action_value,
'oldChecked' => $entry->stop_processing,
'count' => $count,
'oldAction' => 'link_to_bill',
'oldValue' => $bill->name,
'oldChecked' => false,
'count' => 1,
]
)->render();
++$index;
} catch (Throwable $e) {
Log::error(sprintf('Throwable was thrown in getActionsForBill(): %s', $e->getMessage()));
Log::error($e->getTraceAsString());
}
return $actions;
@@ -571,7 +606,41 @@ class RuleController extends Controller
*
*/
private function getCurrentTriggers(Rule $rule)
private function getCurrentActions(Rule $rule): array
{
$index = 0;
$actions = [];
/** @var RuleAction $entry */
foreach ($rule->ruleActions as $entry) {
$count = ($index + 1);
try {
$actions[] = view(
'rules.partials.action',
[
'oldAction' => $entry->action_type,
'oldValue' => $entry->action_value,
'oldChecked' => $entry->stop_processing,
'count' => $count,
]
)->render();
} catch (Throwable $e) {
Log::debug(sprintf('Throwable was thrown in getCurrentActions(): %s', $e->getMessage()));
Log::error($e->getTraceAsString());
}
++$index;
}
return $actions;
}
/**
* @param Rule $rule
*
* @return array
*
*/
private function getCurrentTriggers(Rule $rule): array
{
$index = 0;
$triggers = [];
@@ -579,16 +648,21 @@ class RuleController extends Controller
/** @var RuleTrigger $entry */
foreach ($rule->ruleTriggers as $entry) {
if ('user_action' !== $entry->trigger_type) {
$count = ($index + 1);
$triggers[] = view(
'rules.partials.trigger',
[
'oldTrigger' => $entry->trigger_type,
'oldValue' => $entry->trigger_value,
'oldChecked' => $entry->stop_processing,
'count' => $count,
]
)->render();
$count = ($index + 1);
try {
$triggers[] = view(
'rules.partials.trigger',
[
'oldTrigger' => $entry->trigger_type,
'oldValue' => $entry->trigger_value,
'oldChecked' => $entry->stop_processing,
'count' => $count,
]
)->render();
} catch (Throwable $e) {
Log::debug(sprintf('Throwable was thrown in getCurrentTriggers(): %s', $e->getMessage()));
Log::error($e->getTraceAsString());
}
++$index;
}
}
@@ -601,26 +675,30 @@ class RuleController extends Controller
*
* @return array
*
*/
private function getPreviousActions(Request $request)
private function getPreviousActions(Request $request): array
{
$newIndex = 0;
$actions = [];
/** @var array $oldActions */
$oldActions = is_array($request->old('rule-action')) ? $request->old('rule-action') : [];
$oldActions = \is_array($request->old('rule-action')) ? $request->old('rule-action') : [];
foreach ($oldActions as $index => $entry) {
$count = ($newIndex + 1);
$checked = isset($request->old('rule-action-stop')[$index]) ? true : false;
$actions[] = view(
'rules.partials.action',
[
'oldAction' => $entry,
'oldValue' => $request->old('rule-action-value')[$index],
'oldChecked' => $checked,
'count' => $count,
]
)->render();
$count = ($newIndex + 1);
$checked = isset($request->old('rule-action-stop')[$index]) ? true : false;
try {
$actions[] = view(
'rules.partials.action',
[
'oldAction' => $entry,
'oldValue' => $request->old('rule-action-value')[$index],
'oldChecked' => $checked,
'count' => $count,
]
)->render();
} catch (Throwable $e) {
Log::debug(sprintf('Throwable was thrown in getPreviousActions(): %s', $e->getMessage()));
Log::error($e->getTraceAsString());
}
++$newIndex;
}
@@ -634,25 +712,87 @@ class RuleController extends Controller
*
*/
private function getPreviousTriggers(Request $request)
private function getPreviousTriggers(Request $request): array
{
$newIndex = 0;
$triggers = [];
/** @var array $oldTriggers */
$oldTriggers = is_array($request->old('rule-trigger')) ? $request->old('rule-trigger') : [];
$oldTriggers = \is_array($request->old('rule-trigger')) ? $request->old('rule-trigger') : [];
foreach ($oldTriggers as $index => $entry) {
$count = ($newIndex + 1);
$oldChecked = isset($request->old('rule-trigger-stop')[$index]) ? true : false;
try {
$triggers[] = view(
'rules.partials.trigger',
[
'oldTrigger' => $entry,
'oldValue' => $request->old('rule-trigger-value')[$index],
'oldChecked' => $oldChecked,
'count' => $count,
]
)->render();
} catch (Throwable $e) {
Log::debug(sprintf('Throwable was thrown in getPreviousTriggers(): %s', $e->getMessage()));
Log::error($e->getTraceAsString());
}
++$newIndex;
}
return $triggers;
}
/**
* Create fake triggers to match the bill's properties
*
* @param Bill $bill
*
* @return array
*/
private function getTriggersForBill(Bill $bill): array
{
$triggers = [];
try {
$triggers[] = view(
'rules.partials.trigger',
[
'oldTrigger' => $entry,
'oldValue' => $request->old('rule-trigger-value')[$index],
'oldChecked' => $oldChecked,
'count' => $count,
'oldTrigger' => 'currency_is',
'oldValue' => $bill->transactionCurrency()->first()->name,
'oldChecked' => false,
'count' => 1,
]
)->render();
++$newIndex;
$triggers[] = view(
'rules.partials.trigger',
[
'oldTrigger' => 'amount_more',
'oldValue' => round($bill->amount_min, 12),
'oldChecked' => false,
'count' => 2,
]
)->render();
$triggers[] = view(
'rules.partials.trigger',
[
'oldTrigger' => 'amount_less',
'oldValue' => round($bill->amount_max, 12),
'oldChecked' => false,
'count' => 3,
]
)->render();
$triggers[] = view(
'rules.partials.trigger',
[
'oldTrigger' => 'description_contains',
'oldValue' => $bill->name, 12,
'oldChecked' => false,
'count' => 4,
]
)->render();
} catch (Throwable $e) {
Log::debug(sprintf('Throwable was thrown in getTriggersForBill(): %s', $e->getMessage()));
Log::debug($e->getTraceAsString());
}
return $triggers;
@@ -671,7 +811,7 @@ class RuleController extends Controller
'rule-trigger-values' => $request->get('rule-trigger-value'),
'rule-trigger-stop' => $request->get('rule-trigger-stop'),
];
if (is_array($data['rule-triggers'])) {
if (\is_array($data['rule-triggers'])) {
foreach ($data['rule-triggers'] as $index => $triggerType) {
$data['rule-trigger-stop'][$index] = (int)($data['rule-trigger-stop'][$index] ?? 0.0);
$triggers[] = [

View File

@@ -33,7 +33,6 @@ use FireflyIII\Repositories\Account\AccountRepositoryInterface;
use FireflyIII\Repositories\RuleGroup\RuleGroupRepositoryInterface;
use Illuminate\Http\Request;
use Preferences;
use Session;
use View;
/**
@@ -70,7 +69,7 @@ class RuleGroupController extends Controller
if (true !== session('rule-groups.create.fromStore')) {
$this->rememberPreviousUri('rule-groups.create.uri');
}
Session::forget('rule-groups.create.fromStore');
session()->forget('rule-groups.create.fromStore');
return view('rules.rule-group.create', compact('subTitleIcon', 'subTitle'));
}
@@ -108,7 +107,7 @@ class RuleGroupController extends Controller
$repository->destroy($ruleGroup, $moveTo);
Session::flash('success', (string)trans('firefly.deleted_rule_group', ['title' => $title]));
session()->flash('success', (string)trans('firefly.deleted_rule_group', ['title' => $title]));
Preferences::mark();
return redirect($this->getPreviousUri('rule-groups.delete.uri'));
@@ -140,7 +139,7 @@ class RuleGroupController extends Controller
if (true !== session('rule-groups.edit.fromUpdate')) {
$this->rememberPreviousUri('rule-groups.edit.uri');
}
Session::forget('rule-groups.edit.fromUpdate');
session()->forget('rule-groups.edit.fromUpdate');
return view('rules.rule-group.edit', compact('ruleGroup', 'subTitle'));
}
@@ -174,7 +173,7 @@ class RuleGroupController extends Controller
$this->dispatch($job);
// Tell the user that the job is queued
Session::flash('success', (string)trans('firefly.applied_rule_group_selection', ['title' => $ruleGroup->title]));
session()->flash('success', (string)trans('firefly.applied_rule_group_selection', ['title' => $ruleGroup->title]));
return redirect()->route('rules.index');
}
@@ -209,12 +208,12 @@ class RuleGroupController extends Controller
$data = $request->getRuleGroupData();
$ruleGroup = $repository->store($data);
Session::flash('success', (string)trans('firefly.created_new_rule_group', ['title' => $ruleGroup->title]));
session()->flash('success', (string)trans('firefly.created_new_rule_group', ['title' => $ruleGroup->title]));
Preferences::mark();
if (1 === (int)$request->get('create_another')) {
// @codeCoverageIgnoreStart
Session::put('rule-groups.create.fromStore', true);
session()->put('rule-groups.create.fromStore', true);
return redirect(route('rule-groups.create'))->withInput();
// @codeCoverageIgnoreEnd
@@ -253,12 +252,12 @@ class RuleGroupController extends Controller
$repository->update($ruleGroup, $data);
Session::flash('success', (string)trans('firefly.updated_rule_group', ['title' => $ruleGroup->title]));
session()->flash('success', (string)trans('firefly.updated_rule_group', ['title' => $ruleGroup->title]));
Preferences::mark();
if (1 === (int)$request->get('return_to_edit')) {
// @codeCoverageIgnoreStart
Session::put('rule-groups.edit.fromUpdate', true);
session()->put('rule-groups.edit.fromUpdate', true);
return redirect(route('rule-groups.edit', [$ruleGroup->id]))->withInput(['return_to_edit' => 1]);
// @codeCoverageIgnoreEnd

View File

@@ -73,8 +73,7 @@ class SearchController extends Controller
* @param SearchInterface $searcher
*
* @return \Illuminate\Http\JsonResponse
*
* @throws \Throwable
*/
public function search(Request $request, SearchInterface $searcher)
{

View File

@@ -25,7 +25,9 @@ namespace FireflyIII\Http\Controllers\System;
use Artisan;
use Exception;
use FireflyIII\Http\Controllers\Controller;
use Illuminate\Http\JsonResponse;
use Laravel\Passport\Passport;
use Log;
use phpseclib\Crypt\RSA;
@@ -35,6 +37,12 @@ use phpseclib\Crypt\RSA;
*/
class InstallController extends Controller
{
/** @var string */
public const FORBIDDEN_ERROR = 'Internal PHP function "proc_close" is disabled for your installation. Auto-migration is not possible.';
/** @var string */
public const BASEDIR_ERROR = 'Firefly III cannot execute the upgrade commands. It is not allowed to because of an open_basedir restriction.';
/** @var string */
public const OTHER_ERROR = 'An unknown error prevented Firefly III from executing the upgrade commands. Sorry.';
/** @noinspection MagicMethodsValidityInspection */
/** @noinspection PhpMissingParentConstructorInspection */
/**
@@ -58,6 +66,9 @@ class InstallController extends Controller
*/
public function keys()
{
if ($this->hasForbiddenFunctions()) {
return response()->json(['error' => true, 'message' => self::FORBIDDEN_ERROR]);
}
// create keys manually because for some reason the passport namespace
// does not exist
$rsa = new RSA();
@@ -69,37 +80,65 @@ class InstallController extends Controller
];
if (file_exists($publicKey) || file_exists($privateKey)) {
return response()->json(['OK']);
return response()->json(['error' => false, 'message' => 'OK']);
}
file_put_contents($publicKey, array_get($keys, 'publickey'));
file_put_contents($privateKey, array_get($keys, 'privatekey'));
return response()->json(['OK']);
return response()->json(['error' => false, 'message' => 'OK']);
}
/**
* @return JsonResponse
*/
public function migrate(): JsonResponse
{
if ($this->hasForbiddenFunctions()) {
return response()->json(['error' => true, 'message' => self::FORBIDDEN_ERROR]);
}
try {
Log::debug('Am now calling migrate routine...');
Artisan::call('migrate', ['--seed' => true, '--force' => true]);
Log::debug(Artisan::output());
} catch (Exception $e) {
Log::error($e->getMessage());
Log::error($e->getTraceAsString());
if (strpos($e->getMessage(), 'open_basedir restriction in effect')) {
return response()->json(['error' => true, 'message' => self::BASEDIR_ERROR]);
}
return response()->json(['error' => true, 'message' => self::OTHER_ERROR]);
}
return response()->json(['error' => false, 'message' => 'OK']);
}
/**
* @return \Illuminate\Http\JsonResponse
*/
public function migrate()
public function upgrade(): JsonResponse
{
Log::debug('Am now calling migrate routine...');
Artisan::call('migrate', ['--seed' => true, '--force' => true]);
Log::debug(Artisan::output());
if ($this->hasForbiddenFunctions()) {
return response()->json(['error' => true, 'message' => self::FORBIDDEN_ERROR]);
}
try {
Log::debug('Am now calling upgrade database routine...');
Artisan::call('firefly:upgrade-database');
Log::debug(Artisan::output());
} catch (Exception $e) {
Log::error($e->getMessage());
Log::error($e->getTraceAsString());
if (strpos($e->getMessage(), 'open_basedir restriction in effect')) {
return response()->json(['error' => true, 'message' => self::BASEDIR_ERROR]);
}
return response()->json(['OK']);
}
return response()->json(['error' => true, 'message' => self::OTHER_ERROR]);
}
/**
* @return \Illuminate\Http\JsonResponse
*/
public function upgrade()
{
Log::debug('Am now calling upgrade database routine...');
Artisan::call('firefly:upgrade-database');
Log::debug(Artisan::output());
return response()->json(['OK']);
return response()->json(['error' => false, 'message' => 'OK']);
}
/**
@@ -107,11 +146,47 @@ class InstallController extends Controller
*/
public function verify()
{
Log::debug('Am now calling verify database routine...');
Artisan::call('firefly:verify');
Log::debug(Artisan::output());
if ($this->hasForbiddenFunctions()) {
return response()->json(['error' => true, 'message' => self::FORBIDDEN_ERROR]);
}
try {
Log::debug('Am now calling verify database routine...');
Artisan::call('firefly:verify');
Log::debug(Artisan::output());
} catch (Exception $e) {
Log::error($e->getMessage());
Log::error($e->getTraceAsString());
if (strpos($e->getMessage(), 'open_basedir restriction in effect')) {
return response()->json(['error' => true, 'message' => self::BASEDIR_ERROR]);
}
return response()->json(['OK']);
return response()->json(['error' => true, 'message' => self::OTHER_ERROR]);
}
return response()->json(['error' => false, 'message' => 'OK']);
}
/**
* @return bool
*/
private function hasForbiddenFunctions(): bool
{
$list = ['proc_close'];
$forbidden = explode(',', ini_get('disable_functions'));
$trimmed = array_map(
function (string $value) {
return trim($value);
}, $forbidden
);
foreach ($list as $entry) {
if (\in_array($entry, $trimmed, true)) {
Log::error('Method "%s" is FORBIDDEN, so the console command cannot be executed.');
return true;
}
}
return false;
}
}

View File

@@ -32,7 +32,6 @@ use FireflyIII\Support\CacheProperties;
use Illuminate\Http\Request;
use Illuminate\Support\Collection;
use Preferences;
use Session;
use View;
/**
@@ -86,7 +85,7 @@ class TagController extends Controller
if (true !== session('tags.create.fromStore')) {
$this->rememberPreviousUri('tags.create.uri');
}
Session::forget('tags.create.fromStore');
session()->forget('tags.create.fromStore');
return view('tags.create', compact('subTitle', 'subTitleIcon', 'apiKey'));
}
@@ -118,7 +117,7 @@ class TagController extends Controller
$tagName = $tag->tag;
$this->repository->destroy($tag);
Session::flash('success', (string)trans('firefly.deleted_tag', ['tag' => $tagName]));
session()->flash('success', (string)trans('firefly.deleted_tag', ['tag' => $tagName]));
Preferences::mark();
return redirect($this->getPreviousUri('tags.delete.uri'));
@@ -141,7 +140,7 @@ class TagController extends Controller
if (true !== session('tags.edit.fromUpdate')) {
$this->rememberPreviousUri('tags.edit.uri');
}
Session::forget('tags.edit.fromUpdate');
session()->forget('tags.edit.fromUpdate');
return view('tags.edit', compact('tag', 'subTitle', 'subTitleIcon', 'apiKey'));
}
@@ -171,6 +170,7 @@ class TagController extends Controller
$now = new Carbon;
$clouds = [];
$clouds['no-date'] = $repository->tagCloud(null);
while ($now > $start) {
$year = $now->year;
$clouds[$year] = $repository->tagCloud($year);
@@ -213,7 +213,7 @@ class TagController extends Controller
}
// prep for "specific date" view.
if (strlen($moment) > 0 && 'all' !== $moment) {
if (\strlen($moment) > 0 && 'all' !== $moment) {
$start = new Carbon($moment);
$end = app('navigation')->endOfPeriod($start, $range);
$subTitle = trans(
@@ -226,7 +226,7 @@ class TagController extends Controller
}
// prep for current period
if (0 === strlen($moment)) {
if (0 === \strlen($moment)) {
/** @var Carbon $start */
$start = clone session('start', app('navigation')->startOfPeriod(new Carbon, $range));
/** @var Carbon $end */
@@ -260,12 +260,12 @@ class TagController extends Controller
$data = $request->collectTagData();
$this->repository->store($data);
Session::flash('success', (string)trans('firefly.created_tag', ['tag' => $data['tag']]));
session()->flash('success', (string)trans('firefly.created_tag', ['tag' => $data['tag']]));
Preferences::mark();
if (1 === (int)$request->get('create_another')) {
// @codeCoverageIgnoreStart
Session::put('tags.create.fromStore', true);
session()->put('tags.create.fromStore', true);
return redirect(route('tags.create'))->withInput();
// @codeCoverageIgnoreEnd
@@ -285,12 +285,12 @@ class TagController extends Controller
$data = $request->collectTagData();
$this->repository->update($tag, $data);
Session::flash('success', (string)trans('firefly.updated_tag', ['tag' => $data['tag']]));
session()->flash('success', (string)trans('firefly.updated_tag', ['tag' => $data['tag']]));
Preferences::mark();
if (1 === (int)$request->get('return_to_edit')) {
// @codeCoverageIgnoreStart
Session::put('tags.edit.fromUpdate', true);
session()->put('tags.edit.fromUpdate', true);
return redirect(route('tags.edit', [$tag->id]))->withInput(['return_to_edit' => 1]);
// @codeCoverageIgnoreEnd

View File

@@ -28,11 +28,8 @@ use ExpandedForm;
use FireflyIII\Http\Controllers\Controller;
use FireflyIII\Http\Requests\BulkEditJournalRequest;
use FireflyIII\Models\TransactionJournal;
use FireflyIII\Models\TransactionType;
use FireflyIII\Repositories\Budget\BudgetRepositoryInterface;
use FireflyIII\Repositories\Journal\JournalRepositoryInterface;
use FireflyIII\Services\Internal\Update\JournalUpdateService;
use Illuminate\Http\Request;
use Illuminate\Support\Collection;
use Log;
use Preferences;
@@ -66,113 +63,69 @@ class BulkController extends Controller
}
/**
* @param Request $request
* @param Collection $journals
*
* @return View
*/
public function edit(Request $request, Collection $journals)
public function edit(Collection $journals)
{
$subTitle = trans('firefly.mass_bulk_journals');
// skip transactions that have multiple destinations, multiple sources or are an opening balance.
$filtered = new Collection;
$messages = [];
/** @var TransactionJournal $journal */
foreach ($journals as $journal) {
$sources = $this->repository->getJournalSourceAccounts($journal);
$destinations = $this->repository->getJournalDestinationAccounts($journal);
if ($sources->count() > 1) {
$messages[] = trans('firefly.cannot_edit_multiple_source', ['description' => $journal->description, 'id' => $journal->id]);
continue;
}
if ($destinations->count() > 1) {
$messages[] = trans('firefly.cannot_edit_multiple_dest', ['description' => $journal->description, 'id' => $journal->id]);
continue;
}
if (TransactionType::OPENING_BALANCE === $this->repository->getTransactionType($journal)) {
$messages[] = trans('firefly.cannot_edit_opening_balance');
continue;
}
// cannot edit reconciled transactions / journals:
if ($this->repository->isJournalReconciled($journal)) {
$messages[] = trans('firefly.cannot_edit_reconciled', ['description' => $journal->description, 'id' => $journal->id]);
continue;
}
$filtered->push($journal);
}
if (count($messages) > 0) {
$request->session()->flash('info', $messages);
}
// put previous url in session
$this->rememberPreviousUri('transactions.bulk-edit.uri');
// get list of budgets:
/** @var BudgetRepositoryInterface $repository */
$repository = app(BudgetRepositoryInterface::class);
$budgetList = ExpandedForm::makeSelectListWithEmpty($repository->getActiveBudgets());
// collect some useful meta data for the mass edit:
$filtered->each(
$journals->each(
function (TransactionJournal $journal) {
$journal->transaction_count = $journal->transactions()->count();
}
);
if (0 === $filtered->count()) {
$request->session()->flash('error', trans('firefly.no_edit_multiple_left'));
}
$journals = $filtered;
return view('transactions.bulk.edit', compact('journals', 'subTitle', 'budgetList'));
}
/**
* @param BulkEditJournalRequest $request
* @param JournalRepositoryInterface $repository
*
* @return mixed
*/
public function update(BulkEditJournalRequest $request, JournalRepositoryInterface $repository)
public function update(BulkEditJournalRequest $request)
{
/** @var JournalUpdateService $service */
$service = app(JournalUpdateService::class);
$journalIds = $request->get('journals');
$journalIds = \is_array($journalIds) ? $journalIds : [];
$ignoreCategory = (int)$request->get('ignore_category') === 1;
$ignoreBudget = (int)$request->get('ignore_budget') === 1;
$ignoreTags = (int)$request->get('ignore_tags') === 1;
$count = 0;
if (is_array($journalIds)) {
foreach ($journalIds as $journalId) {
$journal = $repository->find((int)$journalId);
if (null !== $journal) {
$count++;
Log::debug(sprintf('Found journal #%d', $journal->id));
// update category if not told to ignore
if ($ignoreCategory === false) {
Log::debug(sprintf('Set category to %s', $request->string('category')));
foreach ($journalIds as $journalId) {
$journal = $this->repository->findNull((int)$journalId);
if (null === $journal) {
continue;
}
$repository->updateCategory($journal, $request->string('category'));
}
// update budget if not told to ignore (and is withdrawal)
if ($ignoreBudget === false) {
Log::debug(sprintf('Set budget to %d', $request->integer('budget_id')));
$repository->updateBudget($journal, $request->integer('budget_id'));
}
if ($ignoreTags === false) {
Log::debug(sprintf('Set tags to %s', $request->string('budget_id')));
$repository->updateTags($journal, ['tags' => explode(',', $request->string('tags'))]);
}
// update tags if not told to ignore (and is withdrawal)
}
$count++;
Log::debug(sprintf('Found journal #%d', $journal->id));
// update category if not told to ignore
if ($ignoreCategory === false) {
Log::debug(sprintf('Set category to %s', $request->string('category')));
$this->repository->updateCategory($journal, $request->string('category'));
}
// update budget if not told to ignore (and is withdrawal)
if ($ignoreBudget === false) {
Log::debug(sprintf('Set budget to %d', $request->integer('budget_id')));
$this->repository->updateBudget($journal, $request->integer('budget_id'));
}
// update tags:
if ($ignoreTags === false) {
Log::debug(sprintf('Set tags to %s', $request->string('budget_id')));
$this->repository->updateTags($journal, ['tags' => explode(',', $request->string('tags'))]);
}
}
@@ -182,5 +135,4 @@ class BulkController extends Controller
// redirect to previous URL:
return redirect($this->getPreviousUri('transactions.bulk-edit.uri'));
}
}

View File

@@ -30,7 +30,6 @@ use FireflyIII\Models\TransactionType;
use FireflyIII\Repositories\Account\AccountRepositoryInterface;
use FireflyIII\Repositories\Journal\JournalRepositoryInterface;
use Illuminate\Http\Request;
use Session;
use View;
/**
@@ -81,14 +80,14 @@ class ConvertController extends Controller
// cannot convert to its own type.
if ($sourceType->type === $destinationType->type) {
Session::flash('info', trans('firefly.convert_is_already_type_' . $destinationType->type));
session()->flash('info', trans('firefly.convert_is_already_type_' . $destinationType->type));
return redirect(route('transactions.show', [$journal->id]));
}
// cannot convert split.
if ($journal->transactions()->count() > 2) {
Session::flash('error', trans('firefly.cannot_convert_split_journal'));
session()->flash('error', trans('firefly.cannot_convert_split_journal'));
return redirect(route('transactions.show', [$journal->id]));
}
@@ -98,36 +97,23 @@ class ConvertController extends Controller
$destinationAccount = $this->repository->getJournalDestinationAccounts($journal)->first();
return view(
'transactions.convert',
compact(
'sourceType',
'destinationType',
'journal',
'positiveAmount',
'sourceAccount',
'destinationAccount',
'sourceType',
'subTitle',
'subTitleIcon'
)
'transactions.convert', compact(
'sourceType', 'destinationType', 'journal', 'positiveAmount', 'sourceAccount', 'destinationAccount', 'sourceType', 'subTitle', 'subTitleIcon'
)
);
// convert withdrawal to deposit requires a new source account ()
// or to transfer requires
}
/**
* @param Request $request
* @param JournalRepositoryInterface $repository
* @param TransactionType $destinationType
* @param TransactionJournal $journal
* @param Request $request
* @param TransactionType $destinationType
* @param TransactionJournal $journal
*
* @return \Illuminate\Http\RedirectResponse|\Illuminate\Routing\Redirector
*
* @throws FireflyException
* @throws FireflyException
*/
public function postIndex(Request $request, JournalRepositoryInterface $repository, TransactionType $destinationType, TransactionJournal $journal)
public function postIndex(Request $request, TransactionType $destinationType, TransactionJournal $journal)
{
// @codeCoverageIgnoreStart
if ($this->isOpeningBalance($journal)) {
@@ -138,13 +124,13 @@ class ConvertController extends Controller
$data = $request->all();
if ($journal->transactionType->type === $destinationType->type) {
Session::flash('error', trans('firefly.convert_is_already_type_' . $destinationType->type));
session()->flash('error', trans('firefly.convert_is_already_type_' . $destinationType->type));
return redirect(route('transactions.show', [$journal->id]));
}
if ($journal->transactions()->count() > 2) {
Session::flash('error', trans('firefly.cannot_convert_split_journal'));
session()->flash('error', trans('firefly.cannot_convert_split_journal'));
return redirect(route('transactions.show', [$journal->id]));
}
@@ -154,13 +140,13 @@ class ConvertController extends Controller
$destination = $this->getDestinationAccount($journal, $destinationType, $data);
// update the journal:
$errors = $repository->convert($journal, $destinationType, $source, $destination);
$errors = $this->repository->convert($journal, $destinationType, $source, $destination);
if ($errors->count() > 0) {
return redirect(route('transactions.convert.index', [strtolower($destinationType->type), $journal->id]))->withErrors($errors)->withInput();
}
Session::flash('success', trans('firefly.converted_to_' . $destinationType->type));
session()->flash('success', trans('firefly.converted_to_' . $destinationType->type));
return redirect(route('transactions.show', [$journal->id]));
}

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