diff --git a/.ci/all.sh b/.ci/all.sh
new file mode 100755
index 0000000000..e8a7f272e4
--- /dev/null
+++ b/.ci/all.sh
@@ -0,0 +1,27 @@
+#!/usr/bin/env bash
+
+#
+# all.sh
+# Copyright (c) 2024 james@firefly-iii.org
+#
+# This file is part of Firefly III (https://github.com/firefly-iii).
+#
+# This program is free software: you can redistribute it and/or modify
+# it under the terms of the GNU Affero General Public License as
+# published by the Free Software Foundation, either version 3 of the
+# License, or (at your option) any later version.
+#
+# This program 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 Affero General Public License for more details.
+#
+# You should have received a copy of the GNU Affero General Public License
+# along with this program. If not, see .
+#
+
+SCRIPT_DIR="$( cd -- "$( dirname -- "${BASH_SOURCE[0]}" )" &> /dev/null && pwd )"
+
+$SCRIPT_DIR/phpcs.sh
+$SCRIPT_DIR/phpstan.sh
+$SCRIPT_DIR/phpmd.sh
diff --git a/.ci/php-cs-fixer/.php-cs-fixer.php b/.ci/php-cs-fixer/.php-cs-fixer.php
index 1e5a1c2dff..9fc7397742 100644
--- a/.ci/php-cs-fixer/.php-cs-fixer.php
+++ b/.ci/php-cs-fixer/.php-cs-fixer.php
@@ -35,10 +35,39 @@ $finder = PhpCsFixer\Finder::create()
$config = new PhpCsFixer\Config();
-return $config->setRules([
- '@PSR12' => true,
- 'declare_strict_types' => true,
- 'strict_param' => true,
- 'array_syntax' => ['syntax' => 'short'],
- ])
+return $config->setRules(
+ [
+ // rule sets
+ '@PHP83Migration' => true,
+ '@PhpCsFixer' => true,
+ '@PhpCsFixer:risky' => true,
+ '@PSR12' => true,
+ '@PSR12:risky' => true,
+ 'declare_strict_types' => true,
+ 'strict_param' => true,
+ 'no_unused_imports' => true,
+ 'single_space_around_construct' => true,
+ 'statement_indentation' => true,
+ 'void_return' => true,
+
+ // disabled rules
+ 'native_function_invocation' => false, // annoying
+ 'php_unit_data_provider_name' => false, // bloody annoying long test names
+ 'static_lambda' => false, // breaks the Response macro for API's.
+ 'phpdoc_summary' => false, // annoying.
+ 'comment_to_phpdoc' => false, // breaks phpstan lines in combination with PHPStorm.
+ 'type_declaration_spaces' => false,
+ 'cast_spaces' => false,
+
+ // complex rules
+ 'array_syntax' => ['syntax' => 'short'],
+ 'binary_operator_spaces' => [
+ 'default' => 'at_least_single_space',
+ 'operators' => [
+ '=>' => 'align_single_space_by_scope',
+ '=' => 'align_single_space_minimal_by_scope',
+ '??=' => 'align_single_space_minimal_by_scope',
+ ],
+ ],
+ ])
->setFinder($finder);
diff --git a/.ci/php-cs-fixer/composer.lock b/.ci/php-cs-fixer/composer.lock
index b783d43031..32efdba47e 100644
--- a/.ci/php-cs-fixer/composer.lock
+++ b/.ci/php-cs-fixer/composer.lock
@@ -226,50 +226,49 @@
},
{
"name": "friendsofphp/php-cs-fixer",
- "version": "v3.35.1",
+ "version": "v3.51.0",
"source": {
"type": "git",
"url": "https://github.com/PHP-CS-Fixer/PHP-CS-Fixer.git",
- "reference": "ec1ccc264994b6764882669973ca435cf05bab08"
+ "reference": "127fa74f010da99053e3f5b62672615b72dd6efd"
},
"dist": {
"type": "zip",
- "url": "https://api.github.com/repos/PHP-CS-Fixer/PHP-CS-Fixer/zipball/ec1ccc264994b6764882669973ca435cf05bab08",
- "reference": "ec1ccc264994b6764882669973ca435cf05bab08",
+ "url": "https://api.github.com/repos/PHP-CS-Fixer/PHP-CS-Fixer/zipball/127fa74f010da99053e3f5b62672615b72dd6efd",
+ "reference": "127fa74f010da99053e3f5b62672615b72dd6efd",
"shasum": ""
},
"require": {
- "composer/semver": "^3.3",
+ "composer/semver": "^3.4",
"composer/xdebug-handler": "^3.0.3",
+ "ext-filter": "*",
"ext-json": "*",
"ext-tokenizer": "*",
"php": "^7.4 || ^8.0",
- "sebastian/diff": "^4.0 || ^5.0",
- "symfony/console": "^5.4 || ^6.0",
- "symfony/event-dispatcher": "^5.4 || ^6.0",
- "symfony/filesystem": "^5.4 || ^6.0",
- "symfony/finder": "^5.4 || ^6.0",
- "symfony/options-resolver": "^5.4 || ^6.0",
- "symfony/polyfill-mbstring": "^1.27",
- "symfony/polyfill-php80": "^1.27",
- "symfony/polyfill-php81": "^1.27",
- "symfony/process": "^5.4 || ^6.0",
- "symfony/stopwatch": "^5.4 || ^6.0"
+ "sebastian/diff": "^4.0 || ^5.0 || ^6.0",
+ "symfony/console": "^5.4 || ^6.0 || ^7.0",
+ "symfony/event-dispatcher": "^5.4 || ^6.0 || ^7.0",
+ "symfony/filesystem": "^5.4 || ^6.0 || ^7.0",
+ "symfony/finder": "^5.4 || ^6.0 || ^7.0",
+ "symfony/options-resolver": "^5.4 || ^6.0 || ^7.0",
+ "symfony/polyfill-mbstring": "^1.28",
+ "symfony/polyfill-php80": "^1.28",
+ "symfony/polyfill-php81": "^1.28",
+ "symfony/process": "^5.4 || ^6.0 || ^7.0",
+ "symfony/stopwatch": "^5.4 || ^6.0 || ^7.0"
},
"require-dev": {
"facile-it/paraunit": "^1.3 || ^2.0",
"justinrainbow/json-schema": "^5.2",
- "keradus/cli-executor": "^2.0",
+ "keradus/cli-executor": "^2.1",
"mikey179/vfsstream": "^1.6.11",
- "php-coveralls/php-coveralls": "^2.5.3",
+ "php-coveralls/php-coveralls": "^2.7",
"php-cs-fixer/accessible-object": "^1.1",
- "php-cs-fixer/phpunit-constraint-isidenticalstring": "^1.2",
- "php-cs-fixer/phpunit-constraint-xmlmatchesxsd": "^1.2.1",
- "phpspec/prophecy": "^1.16",
- "phpspec/prophecy-phpunit": "^2.0",
- "phpunit/phpunit": "^9.5",
- "symfony/phpunit-bridge": "^6.2.3",
- "symfony/yaml": "^5.4 || ^6.0"
+ "php-cs-fixer/phpunit-constraint-isidenticalstring": "^1.4",
+ "php-cs-fixer/phpunit-constraint-xmlmatchesxsd": "^1.4",
+ "phpunit/phpunit": "^9.6 || ^10.5.5 || ^11.0.2",
+ "symfony/var-dumper": "^5.4 || ^6.0 || ^7.0",
+ "symfony/yaml": "^5.4 || ^6.0 || ^7.0"
},
"suggest": {
"ext-dom": "For handling output formats in XML",
@@ -307,7 +306,7 @@
],
"support": {
"issues": "https://github.com/PHP-CS-Fixer/PHP-CS-Fixer/issues",
- "source": "https://github.com/PHP-CS-Fixer/PHP-CS-Fixer/tree/v3.35.1"
+ "source": "https://github.com/PHP-CS-Fixer/PHP-CS-Fixer/tree/v3.51.0"
},
"funding": [
{
@@ -315,7 +314,7 @@
"type": "github"
}
],
- "time": "2023-10-12T13:47:26+00:00"
+ "time": "2024-02-28T19:50:06+00:00"
},
{
"name": "psr/container",
@@ -472,29 +471,29 @@
},
{
"name": "sebastian/diff",
- "version": "5.0.3",
+ "version": "6.0.1",
"source": {
"type": "git",
"url": "https://github.com/sebastianbergmann/diff.git",
- "reference": "912dc2fbe3e3c1e7873313cc801b100b6c68c87b"
+ "reference": "ab83243ecc233de5655b76f577711de9f842e712"
},
"dist": {
"type": "zip",
- "url": "https://api.github.com/repos/sebastianbergmann/diff/zipball/912dc2fbe3e3c1e7873313cc801b100b6c68c87b",
- "reference": "912dc2fbe3e3c1e7873313cc801b100b6c68c87b",
+ "url": "https://api.github.com/repos/sebastianbergmann/diff/zipball/ab83243ecc233de5655b76f577711de9f842e712",
+ "reference": "ab83243ecc233de5655b76f577711de9f842e712",
"shasum": ""
},
"require": {
- "php": ">=8.1"
+ "php": ">=8.2"
},
"require-dev": {
- "phpunit/phpunit": "^10.0",
+ "phpunit/phpunit": "^11.0",
"symfony/process": "^4.2 || ^5"
},
"type": "library",
"extra": {
"branch-alias": {
- "dev-main": "5.0-dev"
+ "dev-main": "6.0-dev"
}
},
"autoload": {
@@ -527,7 +526,7 @@
"support": {
"issues": "https://github.com/sebastianbergmann/diff/issues",
"security": "https://github.com/sebastianbergmann/diff/security/policy",
- "source": "https://github.com/sebastianbergmann/diff/tree/5.0.3"
+ "source": "https://github.com/sebastianbergmann/diff/tree/6.0.1"
},
"funding": [
{
@@ -535,47 +534,50 @@
"type": "github"
}
],
- "time": "2023-05-01T07:48:21+00:00"
+ "time": "2024-03-02T07:30:33+00:00"
},
{
"name": "symfony/console",
- "version": "v6.3.4",
+ "version": "v7.0.4",
"source": {
"type": "git",
"url": "https://github.com/symfony/console.git",
- "reference": "eca495f2ee845130855ddf1cf18460c38966c8b6"
+ "reference": "6b099f3306f7c9c2d2786ed736d0026b2903205f"
},
"dist": {
"type": "zip",
- "url": "https://api.github.com/repos/symfony/console/zipball/eca495f2ee845130855ddf1cf18460c38966c8b6",
- "reference": "eca495f2ee845130855ddf1cf18460c38966c8b6",
+ "url": "https://api.github.com/repos/symfony/console/zipball/6b099f3306f7c9c2d2786ed736d0026b2903205f",
+ "reference": "6b099f3306f7c9c2d2786ed736d0026b2903205f",
"shasum": ""
},
"require": {
- "php": ">=8.1",
- "symfony/deprecation-contracts": "^2.5|^3",
+ "php": ">=8.2",
"symfony/polyfill-mbstring": "~1.0",
"symfony/service-contracts": "^2.5|^3",
- "symfony/string": "^5.4|^6.0"
+ "symfony/string": "^6.4|^7.0"
},
"conflict": {
- "symfony/dependency-injection": "<5.4",
- "symfony/dotenv": "<5.4",
- "symfony/event-dispatcher": "<5.4",
- "symfony/lock": "<5.4",
- "symfony/process": "<5.4"
+ "symfony/dependency-injection": "<6.4",
+ "symfony/dotenv": "<6.4",
+ "symfony/event-dispatcher": "<6.4",
+ "symfony/lock": "<6.4",
+ "symfony/process": "<6.4"
},
"provide": {
"psr/log-implementation": "1.0|2.0|3.0"
},
"require-dev": {
"psr/log": "^1|^2|^3",
- "symfony/config": "^5.4|^6.0",
- "symfony/dependency-injection": "^5.4|^6.0",
- "symfony/event-dispatcher": "^5.4|^6.0",
- "symfony/lock": "^5.4|^6.0",
- "symfony/process": "^5.4|^6.0",
- "symfony/var-dumper": "^5.4|^6.0"
+ "symfony/config": "^6.4|^7.0",
+ "symfony/dependency-injection": "^6.4|^7.0",
+ "symfony/event-dispatcher": "^6.4|^7.0",
+ "symfony/http-foundation": "^6.4|^7.0",
+ "symfony/http-kernel": "^6.4|^7.0",
+ "symfony/lock": "^6.4|^7.0",
+ "symfony/messenger": "^6.4|^7.0",
+ "symfony/process": "^6.4|^7.0",
+ "symfony/stopwatch": "^6.4|^7.0",
+ "symfony/var-dumper": "^6.4|^7.0"
},
"type": "library",
"autoload": {
@@ -609,7 +611,7 @@
"terminal"
],
"support": {
- "source": "https://github.com/symfony/console/tree/v6.3.4"
+ "source": "https://github.com/symfony/console/tree/v7.0.4"
},
"funding": [
{
@@ -625,11 +627,11 @@
"type": "tidelift"
}
],
- "time": "2023-08-16T10:10:12+00:00"
+ "time": "2024-02-22T20:27:20+00:00"
},
{
"name": "symfony/deprecation-contracts",
- "version": "v3.3.0",
+ "version": "v3.4.0",
"source": {
"type": "git",
"url": "https://github.com/symfony/deprecation-contracts.git",
@@ -676,7 +678,7 @@
"description": "A generic function and convention to trigger deprecation notices",
"homepage": "https://symfony.com",
"support": {
- "source": "https://github.com/symfony/deprecation-contracts/tree/v3.3.0"
+ "source": "https://github.com/symfony/deprecation-contracts/tree/v3.4.0"
},
"funding": [
{
@@ -696,24 +698,24 @@
},
{
"name": "symfony/event-dispatcher",
- "version": "v6.3.2",
+ "version": "v7.0.3",
"source": {
"type": "git",
"url": "https://github.com/symfony/event-dispatcher.git",
- "reference": "adb01fe097a4ee930db9258a3cc906b5beb5cf2e"
+ "reference": "834c28d533dd0636f910909d01b9ff45cc094b5e"
},
"dist": {
"type": "zip",
- "url": "https://api.github.com/repos/symfony/event-dispatcher/zipball/adb01fe097a4ee930db9258a3cc906b5beb5cf2e",
- "reference": "adb01fe097a4ee930db9258a3cc906b5beb5cf2e",
+ "url": "https://api.github.com/repos/symfony/event-dispatcher/zipball/834c28d533dd0636f910909d01b9ff45cc094b5e",
+ "reference": "834c28d533dd0636f910909d01b9ff45cc094b5e",
"shasum": ""
},
"require": {
- "php": ">=8.1",
+ "php": ">=8.2",
"symfony/event-dispatcher-contracts": "^2.5|^3"
},
"conflict": {
- "symfony/dependency-injection": "<5.4",
+ "symfony/dependency-injection": "<6.4",
"symfony/service-contracts": "<2.5"
},
"provide": {
@@ -722,13 +724,13 @@
},
"require-dev": {
"psr/log": "^1|^2|^3",
- "symfony/config": "^5.4|^6.0",
- "symfony/dependency-injection": "^5.4|^6.0",
- "symfony/error-handler": "^5.4|^6.0",
- "symfony/expression-language": "^5.4|^6.0",
- "symfony/http-foundation": "^5.4|^6.0",
+ "symfony/config": "^6.4|^7.0",
+ "symfony/dependency-injection": "^6.4|^7.0",
+ "symfony/error-handler": "^6.4|^7.0",
+ "symfony/expression-language": "^6.4|^7.0",
+ "symfony/http-foundation": "^6.4|^7.0",
"symfony/service-contracts": "^2.5|^3",
- "symfony/stopwatch": "^5.4|^6.0"
+ "symfony/stopwatch": "^6.4|^7.0"
},
"type": "library",
"autoload": {
@@ -756,7 +758,7 @@
"description": "Provides tools that allow your application components to communicate with each other by dispatching events and listening to them",
"homepage": "https://symfony.com",
"support": {
- "source": "https://github.com/symfony/event-dispatcher/tree/v6.3.2"
+ "source": "https://github.com/symfony/event-dispatcher/tree/v7.0.3"
},
"funding": [
{
@@ -772,11 +774,11 @@
"type": "tidelift"
}
],
- "time": "2023-07-06T06:56:43+00:00"
+ "time": "2024-01-23T15:02:46+00:00"
},
{
"name": "symfony/event-dispatcher-contracts",
- "version": "v3.3.0",
+ "version": "v3.4.0",
"source": {
"type": "git",
"url": "https://github.com/symfony/event-dispatcher-contracts.git",
@@ -832,7 +834,7 @@
"standards"
],
"support": {
- "source": "https://github.com/symfony/event-dispatcher-contracts/tree/v3.3.0"
+ "source": "https://github.com/symfony/event-dispatcher-contracts/tree/v3.4.0"
},
"funding": [
{
@@ -852,20 +854,20 @@
},
{
"name": "symfony/filesystem",
- "version": "v6.3.1",
+ "version": "v7.0.3",
"source": {
"type": "git",
"url": "https://github.com/symfony/filesystem.git",
- "reference": "edd36776956f2a6fcf577edb5b05eb0e3bdc52ae"
+ "reference": "2890e3a825bc0c0558526c04499c13f83e1b6b12"
},
"dist": {
"type": "zip",
- "url": "https://api.github.com/repos/symfony/filesystem/zipball/edd36776956f2a6fcf577edb5b05eb0e3bdc52ae",
- "reference": "edd36776956f2a6fcf577edb5b05eb0e3bdc52ae",
+ "url": "https://api.github.com/repos/symfony/filesystem/zipball/2890e3a825bc0c0558526c04499c13f83e1b6b12",
+ "reference": "2890e3a825bc0c0558526c04499c13f83e1b6b12",
"shasum": ""
},
"require": {
- "php": ">=8.1",
+ "php": ">=8.2",
"symfony/polyfill-ctype": "~1.8",
"symfony/polyfill-mbstring": "~1.8"
},
@@ -895,7 +897,7 @@
"description": "Provides basic utilities for the filesystem",
"homepage": "https://symfony.com",
"support": {
- "source": "https://github.com/symfony/filesystem/tree/v6.3.1"
+ "source": "https://github.com/symfony/filesystem/tree/v7.0.3"
},
"funding": [
{
@@ -911,27 +913,27 @@
"type": "tidelift"
}
],
- "time": "2023-06-01T08:30:39+00:00"
+ "time": "2024-01-23T15:02:46+00:00"
},
{
"name": "symfony/finder",
- "version": "v6.3.5",
+ "version": "v7.0.0",
"source": {
"type": "git",
"url": "https://github.com/symfony/finder.git",
- "reference": "a1b31d88c0e998168ca7792f222cbecee47428c4"
+ "reference": "6e5688d69f7cfc4ed4a511e96007e06c2d34ce56"
},
"dist": {
"type": "zip",
- "url": "https://api.github.com/repos/symfony/finder/zipball/a1b31d88c0e998168ca7792f222cbecee47428c4",
- "reference": "a1b31d88c0e998168ca7792f222cbecee47428c4",
+ "url": "https://api.github.com/repos/symfony/finder/zipball/6e5688d69f7cfc4ed4a511e96007e06c2d34ce56",
+ "reference": "6e5688d69f7cfc4ed4a511e96007e06c2d34ce56",
"shasum": ""
},
"require": {
- "php": ">=8.1"
+ "php": ">=8.2"
},
"require-dev": {
- "symfony/filesystem": "^6.0"
+ "symfony/filesystem": "^6.4|^7.0"
},
"type": "library",
"autoload": {
@@ -959,7 +961,7 @@
"description": "Finds files and directories via an intuitive fluent interface",
"homepage": "https://symfony.com",
"support": {
- "source": "https://github.com/symfony/finder/tree/v6.3.5"
+ "source": "https://github.com/symfony/finder/tree/v7.0.0"
},
"funding": [
{
@@ -975,24 +977,24 @@
"type": "tidelift"
}
],
- "time": "2023-09-26T12:56:25+00:00"
+ "time": "2023-10-31T17:59:56+00:00"
},
{
"name": "symfony/options-resolver",
- "version": "v6.3.0",
+ "version": "v7.0.0",
"source": {
"type": "git",
"url": "https://github.com/symfony/options-resolver.git",
- "reference": "a10f19f5198d589d5c33333cffe98dc9820332dd"
+ "reference": "700ff4096e346f54cb628ea650767c8130f1001f"
},
"dist": {
"type": "zip",
- "url": "https://api.github.com/repos/symfony/options-resolver/zipball/a10f19f5198d589d5c33333cffe98dc9820332dd",
- "reference": "a10f19f5198d589d5c33333cffe98dc9820332dd",
+ "url": "https://api.github.com/repos/symfony/options-resolver/zipball/700ff4096e346f54cb628ea650767c8130f1001f",
+ "reference": "700ff4096e346f54cb628ea650767c8130f1001f",
"shasum": ""
},
"require": {
- "php": ">=8.1",
+ "php": ">=8.2",
"symfony/deprecation-contracts": "^2.5|^3"
},
"type": "library",
@@ -1026,7 +1028,7 @@
"options"
],
"support": {
- "source": "https://github.com/symfony/options-resolver/tree/v6.3.0"
+ "source": "https://github.com/symfony/options-resolver/tree/v7.0.0"
},
"funding": [
{
@@ -1042,20 +1044,20 @@
"type": "tidelift"
}
],
- "time": "2023-05-12T14:21:09+00:00"
+ "time": "2023-08-08T10:20:21+00:00"
},
{
"name": "symfony/polyfill-ctype",
- "version": "v1.28.0",
+ "version": "v1.29.0",
"source": {
"type": "git",
"url": "https://github.com/symfony/polyfill-ctype.git",
- "reference": "ea208ce43cbb04af6867b4fdddb1bdbf84cc28cb"
+ "reference": "ef4d7e442ca910c4764bce785146269b30cb5fc4"
},
"dist": {
"type": "zip",
- "url": "https://api.github.com/repos/symfony/polyfill-ctype/zipball/ea208ce43cbb04af6867b4fdddb1bdbf84cc28cb",
- "reference": "ea208ce43cbb04af6867b4fdddb1bdbf84cc28cb",
+ "url": "https://api.github.com/repos/symfony/polyfill-ctype/zipball/ef4d7e442ca910c4764bce785146269b30cb5fc4",
+ "reference": "ef4d7e442ca910c4764bce785146269b30cb5fc4",
"shasum": ""
},
"require": {
@@ -1069,9 +1071,6 @@
},
"type": "library",
"extra": {
- "branch-alias": {
- "dev-main": "1.28-dev"
- },
"thanks": {
"name": "symfony/polyfill",
"url": "https://github.com/symfony/polyfill"
@@ -1108,7 +1107,7 @@
"portable"
],
"support": {
- "source": "https://github.com/symfony/polyfill-ctype/tree/v1.28.0"
+ "source": "https://github.com/symfony/polyfill-ctype/tree/v1.29.0"
},
"funding": [
{
@@ -1124,20 +1123,20 @@
"type": "tidelift"
}
],
- "time": "2023-01-26T09:26:14+00:00"
+ "time": "2024-01-29T20:11:03+00:00"
},
{
"name": "symfony/polyfill-intl-grapheme",
- "version": "v1.28.0",
+ "version": "v1.29.0",
"source": {
"type": "git",
"url": "https://github.com/symfony/polyfill-intl-grapheme.git",
- "reference": "875e90aeea2777b6f135677f618529449334a612"
+ "reference": "32a9da87d7b3245e09ac426c83d334ae9f06f80f"
},
"dist": {
"type": "zip",
- "url": "https://api.github.com/repos/symfony/polyfill-intl-grapheme/zipball/875e90aeea2777b6f135677f618529449334a612",
- "reference": "875e90aeea2777b6f135677f618529449334a612",
+ "url": "https://api.github.com/repos/symfony/polyfill-intl-grapheme/zipball/32a9da87d7b3245e09ac426c83d334ae9f06f80f",
+ "reference": "32a9da87d7b3245e09ac426c83d334ae9f06f80f",
"shasum": ""
},
"require": {
@@ -1148,9 +1147,6 @@
},
"type": "library",
"extra": {
- "branch-alias": {
- "dev-main": "1.28-dev"
- },
"thanks": {
"name": "symfony/polyfill",
"url": "https://github.com/symfony/polyfill"
@@ -1189,7 +1185,7 @@
"shim"
],
"support": {
- "source": "https://github.com/symfony/polyfill-intl-grapheme/tree/v1.28.0"
+ "source": "https://github.com/symfony/polyfill-intl-grapheme/tree/v1.29.0"
},
"funding": [
{
@@ -1205,20 +1201,20 @@
"type": "tidelift"
}
],
- "time": "2023-01-26T09:26:14+00:00"
+ "time": "2024-01-29T20:11:03+00:00"
},
{
"name": "symfony/polyfill-intl-normalizer",
- "version": "v1.28.0",
+ "version": "v1.29.0",
"source": {
"type": "git",
"url": "https://github.com/symfony/polyfill-intl-normalizer.git",
- "reference": "8c4ad05dd0120b6a53c1ca374dca2ad0a1c4ed92"
+ "reference": "bc45c394692b948b4d383a08d7753968bed9a83d"
},
"dist": {
"type": "zip",
- "url": "https://api.github.com/repos/symfony/polyfill-intl-normalizer/zipball/8c4ad05dd0120b6a53c1ca374dca2ad0a1c4ed92",
- "reference": "8c4ad05dd0120b6a53c1ca374dca2ad0a1c4ed92",
+ "url": "https://api.github.com/repos/symfony/polyfill-intl-normalizer/zipball/bc45c394692b948b4d383a08d7753968bed9a83d",
+ "reference": "bc45c394692b948b4d383a08d7753968bed9a83d",
"shasum": ""
},
"require": {
@@ -1229,9 +1225,6 @@
},
"type": "library",
"extra": {
- "branch-alias": {
- "dev-main": "1.28-dev"
- },
"thanks": {
"name": "symfony/polyfill",
"url": "https://github.com/symfony/polyfill"
@@ -1273,7 +1266,7 @@
"shim"
],
"support": {
- "source": "https://github.com/symfony/polyfill-intl-normalizer/tree/v1.28.0"
+ "source": "https://github.com/symfony/polyfill-intl-normalizer/tree/v1.29.0"
},
"funding": [
{
@@ -1289,20 +1282,20 @@
"type": "tidelift"
}
],
- "time": "2023-01-26T09:26:14+00:00"
+ "time": "2024-01-29T20:11:03+00:00"
},
{
"name": "symfony/polyfill-mbstring",
- "version": "v1.28.0",
+ "version": "v1.29.0",
"source": {
"type": "git",
"url": "https://github.com/symfony/polyfill-mbstring.git",
- "reference": "42292d99c55abe617799667f454222c54c60e229"
+ "reference": "9773676c8a1bb1f8d4340a62efe641cf76eda7ec"
},
"dist": {
"type": "zip",
- "url": "https://api.github.com/repos/symfony/polyfill-mbstring/zipball/42292d99c55abe617799667f454222c54c60e229",
- "reference": "42292d99c55abe617799667f454222c54c60e229",
+ "url": "https://api.github.com/repos/symfony/polyfill-mbstring/zipball/9773676c8a1bb1f8d4340a62efe641cf76eda7ec",
+ "reference": "9773676c8a1bb1f8d4340a62efe641cf76eda7ec",
"shasum": ""
},
"require": {
@@ -1316,9 +1309,6 @@
},
"type": "library",
"extra": {
- "branch-alias": {
- "dev-main": "1.28-dev"
- },
"thanks": {
"name": "symfony/polyfill",
"url": "https://github.com/symfony/polyfill"
@@ -1356,7 +1346,7 @@
"shim"
],
"support": {
- "source": "https://github.com/symfony/polyfill-mbstring/tree/v1.28.0"
+ "source": "https://github.com/symfony/polyfill-mbstring/tree/v1.29.0"
},
"funding": [
{
@@ -1372,20 +1362,20 @@
"type": "tidelift"
}
],
- "time": "2023-07-28T09:04:16+00:00"
+ "time": "2024-01-29T20:11:03+00:00"
},
{
"name": "symfony/polyfill-php80",
- "version": "v1.28.0",
+ "version": "v1.29.0",
"source": {
"type": "git",
"url": "https://github.com/symfony/polyfill-php80.git",
- "reference": "6caa57379c4aec19c0a12a38b59b26487dcfe4b5"
+ "reference": "87b68208d5c1188808dd7839ee1e6c8ec3b02f1b"
},
"dist": {
"type": "zip",
- "url": "https://api.github.com/repos/symfony/polyfill-php80/zipball/6caa57379c4aec19c0a12a38b59b26487dcfe4b5",
- "reference": "6caa57379c4aec19c0a12a38b59b26487dcfe4b5",
+ "url": "https://api.github.com/repos/symfony/polyfill-php80/zipball/87b68208d5c1188808dd7839ee1e6c8ec3b02f1b",
+ "reference": "87b68208d5c1188808dd7839ee1e6c8ec3b02f1b",
"shasum": ""
},
"require": {
@@ -1393,9 +1383,6 @@
},
"type": "library",
"extra": {
- "branch-alias": {
- "dev-main": "1.28-dev"
- },
"thanks": {
"name": "symfony/polyfill",
"url": "https://github.com/symfony/polyfill"
@@ -1439,7 +1426,7 @@
"shim"
],
"support": {
- "source": "https://github.com/symfony/polyfill-php80/tree/v1.28.0"
+ "source": "https://github.com/symfony/polyfill-php80/tree/v1.29.0"
},
"funding": [
{
@@ -1455,20 +1442,20 @@
"type": "tidelift"
}
],
- "time": "2023-01-26T09:26:14+00:00"
+ "time": "2024-01-29T20:11:03+00:00"
},
{
"name": "symfony/polyfill-php81",
- "version": "v1.28.0",
+ "version": "v1.29.0",
"source": {
"type": "git",
"url": "https://github.com/symfony/polyfill-php81.git",
- "reference": "7581cd600fa9fd681b797d00b02f068e2f13263b"
+ "reference": "c565ad1e63f30e7477fc40738343c62b40bc672d"
},
"dist": {
"type": "zip",
- "url": "https://api.github.com/repos/symfony/polyfill-php81/zipball/7581cd600fa9fd681b797d00b02f068e2f13263b",
- "reference": "7581cd600fa9fd681b797d00b02f068e2f13263b",
+ "url": "https://api.github.com/repos/symfony/polyfill-php81/zipball/c565ad1e63f30e7477fc40738343c62b40bc672d",
+ "reference": "c565ad1e63f30e7477fc40738343c62b40bc672d",
"shasum": ""
},
"require": {
@@ -1476,9 +1463,6 @@
},
"type": "library",
"extra": {
- "branch-alias": {
- "dev-main": "1.28-dev"
- },
"thanks": {
"name": "symfony/polyfill",
"url": "https://github.com/symfony/polyfill"
@@ -1518,7 +1502,7 @@
"shim"
],
"support": {
- "source": "https://github.com/symfony/polyfill-php81/tree/v1.28.0"
+ "source": "https://github.com/symfony/polyfill-php81/tree/v1.29.0"
},
"funding": [
{
@@ -1534,24 +1518,24 @@
"type": "tidelift"
}
],
- "time": "2023-01-26T09:26:14+00:00"
+ "time": "2024-01-29T20:11:03+00:00"
},
{
"name": "symfony/process",
- "version": "v6.3.4",
+ "version": "v7.0.4",
"source": {
"type": "git",
"url": "https://github.com/symfony/process.git",
- "reference": "0b5c29118f2e980d455d2e34a5659f4579847c54"
+ "reference": "0e7727191c3b71ebec6d529fa0e50a01ca5679e9"
},
"dist": {
"type": "zip",
- "url": "https://api.github.com/repos/symfony/process/zipball/0b5c29118f2e980d455d2e34a5659f4579847c54",
- "reference": "0b5c29118f2e980d455d2e34a5659f4579847c54",
+ "url": "https://api.github.com/repos/symfony/process/zipball/0e7727191c3b71ebec6d529fa0e50a01ca5679e9",
+ "reference": "0e7727191c3b71ebec6d529fa0e50a01ca5679e9",
"shasum": ""
},
"require": {
- "php": ">=8.1"
+ "php": ">=8.2"
},
"type": "library",
"autoload": {
@@ -1579,7 +1563,7 @@
"description": "Executes commands in sub-processes",
"homepage": "https://symfony.com",
"support": {
- "source": "https://github.com/symfony/process/tree/v6.3.4"
+ "source": "https://github.com/symfony/process/tree/v7.0.4"
},
"funding": [
{
@@ -1595,25 +1579,25 @@
"type": "tidelift"
}
],
- "time": "2023-08-07T10:39:22+00:00"
+ "time": "2024-02-22T20:27:20+00:00"
},
{
"name": "symfony/service-contracts",
- "version": "v3.3.0",
+ "version": "v3.4.1",
"source": {
"type": "git",
"url": "https://github.com/symfony/service-contracts.git",
- "reference": "40da9cc13ec349d9e4966ce18b5fbcd724ab10a4"
+ "reference": "fe07cbc8d837f60caf7018068e350cc5163681a0"
},
"dist": {
"type": "zip",
- "url": "https://api.github.com/repos/symfony/service-contracts/zipball/40da9cc13ec349d9e4966ce18b5fbcd724ab10a4",
- "reference": "40da9cc13ec349d9e4966ce18b5fbcd724ab10a4",
+ "url": "https://api.github.com/repos/symfony/service-contracts/zipball/fe07cbc8d837f60caf7018068e350cc5163681a0",
+ "reference": "fe07cbc8d837f60caf7018068e350cc5163681a0",
"shasum": ""
},
"require": {
"php": ">=8.1",
- "psr/container": "^2.0"
+ "psr/container": "^1.1|^2.0"
},
"conflict": {
"ext-psr": "<1.1|>=2"
@@ -1661,7 +1645,7 @@
"standards"
],
"support": {
- "source": "https://github.com/symfony/service-contracts/tree/v3.3.0"
+ "source": "https://github.com/symfony/service-contracts/tree/v3.4.1"
},
"funding": [
{
@@ -1677,24 +1661,24 @@
"type": "tidelift"
}
],
- "time": "2023-05-23T14:45:45+00:00"
+ "time": "2023-12-26T14:02:43+00:00"
},
{
"name": "symfony/stopwatch",
- "version": "v6.3.0",
+ "version": "v7.0.3",
"source": {
"type": "git",
"url": "https://github.com/symfony/stopwatch.git",
- "reference": "fc47f1015ec80927ff64ba9094dfe8b9d48fe9f2"
+ "reference": "983900d6fddf2b0cbaacacbbad07610854bd8112"
},
"dist": {
"type": "zip",
- "url": "https://api.github.com/repos/symfony/stopwatch/zipball/fc47f1015ec80927ff64ba9094dfe8b9d48fe9f2",
- "reference": "fc47f1015ec80927ff64ba9094dfe8b9d48fe9f2",
+ "url": "https://api.github.com/repos/symfony/stopwatch/zipball/983900d6fddf2b0cbaacacbbad07610854bd8112",
+ "reference": "983900d6fddf2b0cbaacacbbad07610854bd8112",
"shasum": ""
},
"require": {
- "php": ">=8.1",
+ "php": ">=8.2",
"symfony/service-contracts": "^2.5|^3"
},
"type": "library",
@@ -1723,7 +1707,7 @@
"description": "Provides a way to profile code",
"homepage": "https://symfony.com",
"support": {
- "source": "https://github.com/symfony/stopwatch/tree/v6.3.0"
+ "source": "https://github.com/symfony/stopwatch/tree/v7.0.3"
},
"funding": [
{
@@ -1739,24 +1723,24 @@
"type": "tidelift"
}
],
- "time": "2023-02-16T10:14:28+00:00"
+ "time": "2024-01-23T15:02:46+00:00"
},
{
"name": "symfony/string",
- "version": "v6.3.5",
+ "version": "v7.0.4",
"source": {
"type": "git",
"url": "https://github.com/symfony/string.git",
- "reference": "13d76d0fb049051ed12a04bef4f9de8715bea339"
+ "reference": "f5832521b998b0bec40bee688ad5de98d4cf111b"
},
"dist": {
"type": "zip",
- "url": "https://api.github.com/repos/symfony/string/zipball/13d76d0fb049051ed12a04bef4f9de8715bea339",
- "reference": "13d76d0fb049051ed12a04bef4f9de8715bea339",
+ "url": "https://api.github.com/repos/symfony/string/zipball/f5832521b998b0bec40bee688ad5de98d4cf111b",
+ "reference": "f5832521b998b0bec40bee688ad5de98d4cf111b",
"shasum": ""
},
"require": {
- "php": ">=8.1",
+ "php": ">=8.2",
"symfony/polyfill-ctype": "~1.8",
"symfony/polyfill-intl-grapheme": "~1.0",
"symfony/polyfill-intl-normalizer": "~1.0",
@@ -1766,11 +1750,11 @@
"symfony/translation-contracts": "<2.5"
},
"require-dev": {
- "symfony/error-handler": "^5.4|^6.0",
- "symfony/http-client": "^5.4|^6.0",
- "symfony/intl": "^6.2",
+ "symfony/error-handler": "^6.4|^7.0",
+ "symfony/http-client": "^6.4|^7.0",
+ "symfony/intl": "^6.4|^7.0",
"symfony/translation-contracts": "^2.5|^3.0",
- "symfony/var-exporter": "^5.4|^6.0"
+ "symfony/var-exporter": "^6.4|^7.0"
},
"type": "library",
"autoload": {
@@ -1809,7 +1793,7 @@
"utf8"
],
"support": {
- "source": "https://github.com/symfony/string/tree/v6.3.5"
+ "source": "https://github.com/symfony/string/tree/v7.0.4"
},
"funding": [
{
@@ -1825,7 +1809,7 @@
"type": "tidelift"
}
],
- "time": "2023-09-18T10:38:32+00:00"
+ "time": "2024-02-01T13:17:36+00:00"
}
],
"packages-dev": [],
@@ -1836,5 +1820,5 @@
"prefer-lowest": false,
"platform": [],
"platform-dev": [],
- "plugin-api-version": "2.3.0"
+ "plugin-api-version": "2.6.0"
}
diff --git a/.ci/phpcs.sh b/.ci/phpcs.sh
index 49c6420f04..29b38f892e 100755
--- a/.ci/phpcs.sh
+++ b/.ci/phpcs.sh
@@ -28,11 +28,29 @@ SCRIPT_DIR="$( cd -- "$( dirname -- "${BASH_SOURCE[0]}" )" &> /dev/null && pwd )
# enable test .env file.
# cp .ci/.env.ci .env
+OUTPUT_FORMAT=txt
+EXTRA_PARAMS=""
+
+if [[ $GITHUB_ACTIONS = "true" ]]
+then
+ OUTPUT_FORMAT=txt
+ EXTRA_PARAMS=""
+fi
+
# clean up php code
cd $SCRIPT_DIR/php-cs-fixer
composer update --quiet
rm -f .php-cs-fixer.cache
-PHP_CS_FIXER_IGNORE_ENV=true ./vendor/bin/php-cs-fixer fix --config $SCRIPT_DIR/php-cs-fixer/.php-cs-fixer.php --allow-risky=yes
+PHP_CS_FIXER_IGNORE_ENV=true
+./vendor/bin/php-cs-fixer fix \
+ --config $SCRIPT_DIR/php-cs-fixer/.php-cs-fixer.php \
+ --format=$OUTPUT_FORMAT \
+ --allow-risky=yes $EXTRA_PARAMS
+
+EXIT_CODE=$?
+
+echo "Exit code for CS fixer is $EXIT_CODE."
+
cd $SCRIPT_DIR/..
-exit 0
+exit $EXIT_CODE
diff --git a/.ci/phpmd.sh b/.ci/phpmd.sh
old mode 100644
new mode 100755
index 0cbadc94c6..393305ed74
--- a/.ci/phpmd.sh
+++ b/.ci/phpmd.sh
@@ -22,16 +22,29 @@
SCRIPT_DIR="$( cd -- "$( dirname -- "${BASH_SOURCE[0]}" )" &> /dev/null && pwd )"
+OUTPUT_FORMAT=text
+
+if [[ $GITHUB_ACTIONS = "true" ]]
+then
+ OUTPUT_FORMAT=github
+fi
+
cd $SCRIPT_DIR/phpmd
composer update --quiet
./vendor/bin/phpmd \
- $SCRIPT_DIR/../app text phpmd.xml \
+ $SCRIPT_DIR/../app,$SCRIPT_DIR/../database,$SCRIPT_DIR/../routes,$SCRIPT_DIR/../config \
+ $OUTPUT_FORMAT phpmd.xml \
--exclude $SCRIPT_DIR/../app/resources/** \
--exclude $SCRIPT_DIR/../app/frontend/** \
--exclude $SCRIPT_DIR/../app/public/** \
- --exclude $SCRIPT_DIR/../app/vendor/** \
+ --exclude $SCRIPT_DIR/../app/vendor/**
+
+EXIT_CODE=$?
cd $SCRIPT_DIR/..
-exit 0
+echo "Exit code is $EXIT_CODE."
+
+# for the time being, exit 0
+exit $EXIT_CODE
diff --git a/.ci/phpmd/composer.lock b/.ci/phpmd/composer.lock
index 88f4ba6d7f..a561f0b918 100644
--- a/.ci/phpmd/composer.lock
+++ b/.ci/phpmd/composer.lock
@@ -9,16 +9,16 @@
"packages-dev": [
{
"name": "composer/pcre",
- "version": "3.1.0",
+ "version": "3.1.1",
"source": {
"type": "git",
"url": "https://github.com/composer/pcre.git",
- "reference": "4bff79ddd77851fe3cdd11616ed3f92841ba5bd2"
+ "reference": "00104306927c7a0919b4ced2aaa6782c1e61a3c9"
},
"dist": {
"type": "zip",
- "url": "https://api.github.com/repos/composer/pcre/zipball/4bff79ddd77851fe3cdd11616ed3f92841ba5bd2",
- "reference": "4bff79ddd77851fe3cdd11616ed3f92841ba5bd2",
+ "url": "https://api.github.com/repos/composer/pcre/zipball/00104306927c7a0919b4ced2aaa6782c1e61a3c9",
+ "reference": "00104306927c7a0919b4ced2aaa6782c1e61a3c9",
"shasum": ""
},
"require": {
@@ -60,7 +60,7 @@
],
"support": {
"issues": "https://github.com/composer/pcre/issues",
- "source": "https://github.com/composer/pcre/tree/3.1.0"
+ "source": "https://github.com/composer/pcre/tree/3.1.1"
},
"funding": [
{
@@ -76,7 +76,7 @@
"type": "tidelift"
}
],
- "time": "2022-11-17T09:50:14+00:00"
+ "time": "2023-10-11T07:11:09+00:00"
},
{
"name": "composer/xdebug-handler",
@@ -146,28 +146,28 @@
},
{
"name": "pdepend/pdepend",
- "version": "2.14.0",
+ "version": "2.16.2",
"source": {
"type": "git",
"url": "https://github.com/pdepend/pdepend.git",
- "reference": "1121d4b04af06e33e9659bac3a6741b91cab1de1"
+ "reference": "f942b208dc2a0868454d01b29f0c75bbcfc6ed58"
},
"dist": {
"type": "zip",
- "url": "https://api.github.com/repos/pdepend/pdepend/zipball/1121d4b04af06e33e9659bac3a6741b91cab1de1",
- "reference": "1121d4b04af06e33e9659bac3a6741b91cab1de1",
+ "url": "https://api.github.com/repos/pdepend/pdepend/zipball/f942b208dc2a0868454d01b29f0c75bbcfc6ed58",
+ "reference": "f942b208dc2a0868454d01b29f0c75bbcfc6ed58",
"shasum": ""
},
"require": {
"php": ">=5.3.7",
- "symfony/config": "^2.3.0|^3|^4|^5|^6.0",
- "symfony/dependency-injection": "^2.3.0|^3|^4|^5|^6.0",
- "symfony/filesystem": "^2.3.0|^3|^4|^5|^6.0"
+ "symfony/config": "^2.3.0|^3|^4|^5|^6.0|^7.0",
+ "symfony/dependency-injection": "^2.3.0|^3|^4|^5|^6.0|^7.0",
+ "symfony/filesystem": "^2.3.0|^3|^4|^5|^6.0|^7.0",
+ "symfony/polyfill-mbstring": "^1.19"
},
"require-dev": {
"easy-doc/easy-doc": "0.0.0|^1.2.3",
"gregwar/rst": "^1.0",
- "phpunit/phpunit": "^4.8.36|^5.7.27",
"squizlabs/php_codesniffer": "^2.0.0"
},
"bin": [
@@ -197,7 +197,7 @@
],
"support": {
"issues": "https://github.com/pdepend/pdepend/issues",
- "source": "https://github.com/pdepend/pdepend/tree/2.14.0"
+ "source": "https://github.com/pdepend/pdepend/tree/2.16.2"
},
"funding": [
{
@@ -205,26 +205,26 @@
"type": "tidelift"
}
],
- "time": "2023-05-26T13:15:18+00:00"
+ "time": "2023-12-17T18:09:59+00:00"
},
{
"name": "phpmd/phpmd",
- "version": "2.13.0",
+ "version": "2.15.0",
"source": {
"type": "git",
"url": "https://github.com/phpmd/phpmd.git",
- "reference": "dad0228156856b3ad959992f9748514fa943f3e3"
+ "reference": "74a1f56e33afad4128b886e334093e98e1b5e7c0"
},
"dist": {
"type": "zip",
- "url": "https://api.github.com/repos/phpmd/phpmd/zipball/dad0228156856b3ad959992f9748514fa943f3e3",
- "reference": "dad0228156856b3ad959992f9748514fa943f3e3",
+ "url": "https://api.github.com/repos/phpmd/phpmd/zipball/74a1f56e33afad4128b886e334093e98e1b5e7c0",
+ "reference": "74a1f56e33afad4128b886e334093e98e1b5e7c0",
"shasum": ""
},
"require": {
"composer/xdebug-handler": "^1.0 || ^2.0 || ^3.0",
"ext-xml": "*",
- "pdepend/pdepend": "^2.12.1",
+ "pdepend/pdepend": "^2.16.1",
"php": ">=5.3.9"
},
"require-dev": {
@@ -233,8 +233,7 @@
"ext-simplexml": "*",
"gregwar/rst": "^1.0",
"mikey179/vfsstream": "^1.6.8",
- "phpunit/phpunit": "^4.8.36 || ^5.7.27",
- "squizlabs/php_codesniffer": "^2.0"
+ "squizlabs/php_codesniffer": "^2.9.2 || ^3.7.2"
},
"bin": [
"src/bin/phpmd"
@@ -271,6 +270,7 @@
"description": "PHPMD is a spin-off project of PHP Depend and aims to be a PHP equivalent of the well known Java tool PMD.",
"homepage": "https://phpmd.org/",
"keywords": [
+ "dev",
"mess detection",
"mess detector",
"pdepend",
@@ -280,7 +280,7 @@
"support": {
"irc": "irc://irc.freenode.org/phpmd",
"issues": "https://github.com/phpmd/phpmd/issues",
- "source": "https://github.com/phpmd/phpmd/tree/2.13.0"
+ "source": "https://github.com/phpmd/phpmd/tree/2.15.0"
},
"funding": [
{
@@ -288,7 +288,7 @@
"type": "tidelift"
}
],
- "time": "2022-09-10T08:44:15+00:00"
+ "time": "2023-12-11T08:22:20+00:00"
},
{
"name": "psr/container",
@@ -395,34 +395,34 @@
},
{
"name": "symfony/config",
- "version": "v6.3.0",
+ "version": "v7.0.4",
"source": {
"type": "git",
"url": "https://github.com/symfony/config.git",
- "reference": "a5e00dec161b08c946a2c16eed02adbeedf827ae"
+ "reference": "44deeba7233f08f383185ffa37dace3b3bc87364"
},
"dist": {
"type": "zip",
- "url": "https://api.github.com/repos/symfony/config/zipball/a5e00dec161b08c946a2c16eed02adbeedf827ae",
- "reference": "a5e00dec161b08c946a2c16eed02adbeedf827ae",
+ "url": "https://api.github.com/repos/symfony/config/zipball/44deeba7233f08f383185ffa37dace3b3bc87364",
+ "reference": "44deeba7233f08f383185ffa37dace3b3bc87364",
"shasum": ""
},
"require": {
- "php": ">=8.1",
+ "php": ">=8.2",
"symfony/deprecation-contracts": "^2.5|^3",
- "symfony/filesystem": "^5.4|^6.0",
+ "symfony/filesystem": "^6.4|^7.0",
"symfony/polyfill-ctype": "~1.8"
},
"conflict": {
- "symfony/finder": "<5.4",
+ "symfony/finder": "<6.4",
"symfony/service-contracts": "<2.5"
},
"require-dev": {
- "symfony/event-dispatcher": "^5.4|^6.0",
- "symfony/finder": "^5.4|^6.0",
- "symfony/messenger": "^5.4|^6.0",
+ "symfony/event-dispatcher": "^6.4|^7.0",
+ "symfony/finder": "^6.4|^7.0",
+ "symfony/messenger": "^6.4|^7.0",
"symfony/service-contracts": "^2.5|^3",
- "symfony/yaml": "^5.4|^6.0"
+ "symfony/yaml": "^6.4|^7.0"
},
"type": "library",
"autoload": {
@@ -450,7 +450,7 @@
"description": "Helps you find, load, combine, autofill and validate configuration values of any kind",
"homepage": "https://symfony.com",
"support": {
- "source": "https://github.com/symfony/config/tree/v6.3.0"
+ "source": "https://github.com/symfony/config/tree/v7.0.4"
},
"funding": [
{
@@ -466,44 +466,43 @@
"type": "tidelift"
}
],
- "time": "2023-04-25T10:46:17+00:00"
+ "time": "2024-02-26T07:52:39+00:00"
},
{
"name": "symfony/dependency-injection",
- "version": "v6.3.1",
+ "version": "v7.0.4",
"source": {
"type": "git",
"url": "https://github.com/symfony/dependency-injection.git",
- "reference": "7abf242af21f196b65f20ab00ff251fdf3889b8d"
+ "reference": "47f37af245df8457ea63409fc242b3cc825ce5eb"
},
"dist": {
"type": "zip",
- "url": "https://api.github.com/repos/symfony/dependency-injection/zipball/7abf242af21f196b65f20ab00ff251fdf3889b8d",
- "reference": "7abf242af21f196b65f20ab00ff251fdf3889b8d",
+ "url": "https://api.github.com/repos/symfony/dependency-injection/zipball/47f37af245df8457ea63409fc242b3cc825ce5eb",
+ "reference": "47f37af245df8457ea63409fc242b3cc825ce5eb",
"shasum": ""
},
"require": {
- "php": ">=8.1",
+ "php": ">=8.2",
"psr/container": "^1.1|^2.0",
"symfony/deprecation-contracts": "^2.5|^3",
- "symfony/service-contracts": "^2.5|^3.0",
- "symfony/var-exporter": "^6.2.10"
+ "symfony/service-contracts": "^3.3",
+ "symfony/var-exporter": "^6.4|^7.0"
},
"conflict": {
"ext-psr": "<1.1|>=2",
- "symfony/config": "<6.1",
- "symfony/finder": "<5.4",
- "symfony/proxy-manager-bridge": "<6.3",
- "symfony/yaml": "<5.4"
+ "symfony/config": "<6.4",
+ "symfony/finder": "<6.4",
+ "symfony/yaml": "<6.4"
},
"provide": {
"psr/container-implementation": "1.1|2.0",
"symfony/service-implementation": "1.1|2.0|3.0"
},
"require-dev": {
- "symfony/config": "^6.1",
- "symfony/expression-language": "^5.4|^6.0",
- "symfony/yaml": "^5.4|^6.0"
+ "symfony/config": "^6.4|^7.0",
+ "symfony/expression-language": "^6.4|^7.0",
+ "symfony/yaml": "^6.4|^7.0"
},
"type": "library",
"autoload": {
@@ -531,7 +530,7 @@
"description": "Allows you to standardize and centralize the way objects are constructed in your application",
"homepage": "https://symfony.com",
"support": {
- "source": "https://github.com/symfony/dependency-injection/tree/v6.3.1"
+ "source": "https://github.com/symfony/dependency-injection/tree/v7.0.4"
},
"funding": [
{
@@ -547,11 +546,11 @@
"type": "tidelift"
}
],
- "time": "2023-06-24T11:51:27+00:00"
+ "time": "2024-02-22T20:27:20+00:00"
},
{
"name": "symfony/deprecation-contracts",
- "version": "v3.3.0",
+ "version": "v3.4.0",
"source": {
"type": "git",
"url": "https://github.com/symfony/deprecation-contracts.git",
@@ -598,7 +597,7 @@
"description": "A generic function and convention to trigger deprecation notices",
"homepage": "https://symfony.com",
"support": {
- "source": "https://github.com/symfony/deprecation-contracts/tree/v3.3.0"
+ "source": "https://github.com/symfony/deprecation-contracts/tree/v3.4.0"
},
"funding": [
{
@@ -618,20 +617,20 @@
},
{
"name": "symfony/filesystem",
- "version": "v6.3.1",
+ "version": "v7.0.3",
"source": {
"type": "git",
"url": "https://github.com/symfony/filesystem.git",
- "reference": "edd36776956f2a6fcf577edb5b05eb0e3bdc52ae"
+ "reference": "2890e3a825bc0c0558526c04499c13f83e1b6b12"
},
"dist": {
"type": "zip",
- "url": "https://api.github.com/repos/symfony/filesystem/zipball/edd36776956f2a6fcf577edb5b05eb0e3bdc52ae",
- "reference": "edd36776956f2a6fcf577edb5b05eb0e3bdc52ae",
+ "url": "https://api.github.com/repos/symfony/filesystem/zipball/2890e3a825bc0c0558526c04499c13f83e1b6b12",
+ "reference": "2890e3a825bc0c0558526c04499c13f83e1b6b12",
"shasum": ""
},
"require": {
- "php": ">=8.1",
+ "php": ">=8.2",
"symfony/polyfill-ctype": "~1.8",
"symfony/polyfill-mbstring": "~1.8"
},
@@ -661,7 +660,7 @@
"description": "Provides basic utilities for the filesystem",
"homepage": "https://symfony.com",
"support": {
- "source": "https://github.com/symfony/filesystem/tree/v6.3.1"
+ "source": "https://github.com/symfony/filesystem/tree/v7.0.3"
},
"funding": [
{
@@ -677,20 +676,20 @@
"type": "tidelift"
}
],
- "time": "2023-06-01T08:30:39+00:00"
+ "time": "2024-01-23T15:02:46+00:00"
},
{
"name": "symfony/polyfill-ctype",
- "version": "v1.27.0",
+ "version": "v1.29.0",
"source": {
"type": "git",
"url": "https://github.com/symfony/polyfill-ctype.git",
- "reference": "5bbc823adecdae860bb64756d639ecfec17b050a"
+ "reference": "ef4d7e442ca910c4764bce785146269b30cb5fc4"
},
"dist": {
"type": "zip",
- "url": "https://api.github.com/repos/symfony/polyfill-ctype/zipball/5bbc823adecdae860bb64756d639ecfec17b050a",
- "reference": "5bbc823adecdae860bb64756d639ecfec17b050a",
+ "url": "https://api.github.com/repos/symfony/polyfill-ctype/zipball/ef4d7e442ca910c4764bce785146269b30cb5fc4",
+ "reference": "ef4d7e442ca910c4764bce785146269b30cb5fc4",
"shasum": ""
},
"require": {
@@ -704,9 +703,6 @@
},
"type": "library",
"extra": {
- "branch-alias": {
- "dev-main": "1.27-dev"
- },
"thanks": {
"name": "symfony/polyfill",
"url": "https://github.com/symfony/polyfill"
@@ -743,7 +739,7 @@
"portable"
],
"support": {
- "source": "https://github.com/symfony/polyfill-ctype/tree/v1.27.0"
+ "source": "https://github.com/symfony/polyfill-ctype/tree/v1.29.0"
},
"funding": [
{
@@ -759,20 +755,20 @@
"type": "tidelift"
}
],
- "time": "2022-11-03T14:55:06+00:00"
+ "time": "2024-01-29T20:11:03+00:00"
},
{
"name": "symfony/polyfill-mbstring",
- "version": "v1.27.0",
+ "version": "v1.29.0",
"source": {
"type": "git",
"url": "https://github.com/symfony/polyfill-mbstring.git",
- "reference": "8ad114f6b39e2c98a8b0e3bd907732c207c2b534"
+ "reference": "9773676c8a1bb1f8d4340a62efe641cf76eda7ec"
},
"dist": {
"type": "zip",
- "url": "https://api.github.com/repos/symfony/polyfill-mbstring/zipball/8ad114f6b39e2c98a8b0e3bd907732c207c2b534",
- "reference": "8ad114f6b39e2c98a8b0e3bd907732c207c2b534",
+ "url": "https://api.github.com/repos/symfony/polyfill-mbstring/zipball/9773676c8a1bb1f8d4340a62efe641cf76eda7ec",
+ "reference": "9773676c8a1bb1f8d4340a62efe641cf76eda7ec",
"shasum": ""
},
"require": {
@@ -786,9 +782,6 @@
},
"type": "library",
"extra": {
- "branch-alias": {
- "dev-main": "1.27-dev"
- },
"thanks": {
"name": "symfony/polyfill",
"url": "https://github.com/symfony/polyfill"
@@ -826,7 +819,7 @@
"shim"
],
"support": {
- "source": "https://github.com/symfony/polyfill-mbstring/tree/v1.27.0"
+ "source": "https://github.com/symfony/polyfill-mbstring/tree/v1.29.0"
},
"funding": [
{
@@ -842,25 +835,25 @@
"type": "tidelift"
}
],
- "time": "2022-11-03T14:55:06+00:00"
+ "time": "2024-01-29T20:11:03+00:00"
},
{
"name": "symfony/service-contracts",
- "version": "v3.3.0",
+ "version": "v3.4.1",
"source": {
"type": "git",
"url": "https://github.com/symfony/service-contracts.git",
- "reference": "40da9cc13ec349d9e4966ce18b5fbcd724ab10a4"
+ "reference": "fe07cbc8d837f60caf7018068e350cc5163681a0"
},
"dist": {
"type": "zip",
- "url": "https://api.github.com/repos/symfony/service-contracts/zipball/40da9cc13ec349d9e4966ce18b5fbcd724ab10a4",
- "reference": "40da9cc13ec349d9e4966ce18b5fbcd724ab10a4",
+ "url": "https://api.github.com/repos/symfony/service-contracts/zipball/fe07cbc8d837f60caf7018068e350cc5163681a0",
+ "reference": "fe07cbc8d837f60caf7018068e350cc5163681a0",
"shasum": ""
},
"require": {
"php": ">=8.1",
- "psr/container": "^2.0"
+ "psr/container": "^1.1|^2.0"
},
"conflict": {
"ext-psr": "<1.1|>=2"
@@ -908,7 +901,7 @@
"standards"
],
"support": {
- "source": "https://github.com/symfony/service-contracts/tree/v3.3.0"
+ "source": "https://github.com/symfony/service-contracts/tree/v3.4.1"
},
"funding": [
{
@@ -924,27 +917,27 @@
"type": "tidelift"
}
],
- "time": "2023-05-23T14:45:45+00:00"
+ "time": "2023-12-26T14:02:43+00:00"
},
{
"name": "symfony/var-exporter",
- "version": "v6.3.0",
+ "version": "v7.0.4",
"source": {
"type": "git",
"url": "https://github.com/symfony/var-exporter.git",
- "reference": "db5416d04269f2827d8c54331ba4cfa42620d350"
+ "reference": "dfb0acb6803eb714f05d97dd4c5abe6d5fa9fe41"
},
"dist": {
"type": "zip",
- "url": "https://api.github.com/repos/symfony/var-exporter/zipball/db5416d04269f2827d8c54331ba4cfa42620d350",
- "reference": "db5416d04269f2827d8c54331ba4cfa42620d350",
+ "url": "https://api.github.com/repos/symfony/var-exporter/zipball/dfb0acb6803eb714f05d97dd4c5abe6d5fa9fe41",
+ "reference": "dfb0acb6803eb714f05d97dd4c5abe6d5fa9fe41",
"shasum": ""
},
"require": {
- "php": ">=8.1"
+ "php": ">=8.2"
},
"require-dev": {
- "symfony/var-dumper": "^5.4|^6.0"
+ "symfony/var-dumper": "^6.4|^7.0"
},
"type": "library",
"autoload": {
@@ -982,7 +975,7 @@
"serialize"
],
"support": {
- "source": "https://github.com/symfony/var-exporter/tree/v6.3.0"
+ "source": "https://github.com/symfony/var-exporter/tree/v7.0.4"
},
"funding": [
{
@@ -998,7 +991,7 @@
"type": "tidelift"
}
],
- "time": "2023-04-21T08:48:44+00:00"
+ "time": "2024-02-26T10:35:24+00:00"
}
],
"aliases": [],
@@ -1008,5 +1001,5 @@
"prefer-lowest": false,
"platform": [],
"platform-dev": [],
- "plugin-api-version": "2.3.0"
+ "plugin-api-version": "2.6.0"
}
diff --git a/.ci/phpmd/phpmd.xml b/.ci/phpmd/phpmd.xml
index 47c3f85687..e3b4cd3782 100644
--- a/.ci/phpmd/phpmd.xml
+++ b/.ci/phpmd/phpmd.xml
@@ -20,53 +20,75 @@
-->
- Bla bla
+ xmlns="http://pmd.sf.net/ruleset/1.0.0"
+ xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+ xsi:schemaLocation="http://pmd.sf.net/ruleset/1.0.0 http://pmd.sf.net/ruleset_xml_schema.xsd"
+ xsi:noNamespaceSchemaLocation="http://pmd.sf.net/ruleset_xml_schema.xsd">
+ Firefly III ruleset.
+
+
+
+
-
+
+
+
-
-
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
+
+
+
+
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
+
+
+
+
+
-
-
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/.ci/phpstan.neon b/.ci/phpstan.neon
index f846b62d11..7e804a9a43 100644
--- a/.ci/phpstan.neon
+++ b/.ci/phpstan.neon
@@ -1,42 +1,33 @@
-includes:
- - ../vendor/nunomaduro/larastan/extension.neon
- - ../vendor/ergebnis/phpstan-rules/rules.neon
- - ../vendor/phpstan/phpstan-deprecation-rules/rules.neon
- - ../vendor/thecodingmachine/phpstan-strict-rules/phpstan-strict-rules.neon
-
parameters:
+ universalObjectCratesClasses:
+ - Illuminate\Database\Eloquent\Model
+ # TODO: slowly remove these parameters and fix the issues found.
+ reportUnmatchedIgnoredErrors: false
+ checkGenericClassInNonGenericObjectType: false # remove this rule when all other issues are solved.
ignoreErrors:
+ # TODO: slowly remove these exceptions and fix the issues found.
+ - '#Dynamic call to static method#' # all the Laravel ORM things depend on this.
+ - '#Control structures using switch should not be used.#' # switch is fine in some cases.
+ - '#with no value type specified in iterable type array#' # remove this rule when all other issues are solved.
+ - '#has no value type specified in iterable type array#' # remove this rule when all other issues are solved.
- '#is not allowed to extend#'
+ - '#switch is forbidden to use#'
- '#is neither abstract nor final#'
- - '#has a nullable return type declaration#'
- - '#with a nullable type declaration#'
+ - '#on left side of \?\?\= always exists and is not nullable#'
+ - '#has a nullable return type declaration#' # perhaps throw errors instead?
+ - '#with a nullable type declaration#' # decide what action should be if param is null.
- '#with null as default value#'
- - '#is not covariant with PHPDoc type array#'
+ -
+ message: '#Constructor in [a-zA-Z0-9\\_]+ has parameter \$[a-zA-Z0-9\\_]+ with default value#'
+ paths:
+ - ../app/Exceptions/IntervalException.php
+ - ../app/Support/Navigation.php
-
message: '#but containers should not be injected#'
paths:
- ../app/Support/Authentication/RemoteUserGuard.php
-
- message: '#Control structures using switch should not be used.#'
- paths:
- - ../app/Api/V1/Controllers/Data/DestroyController.php
- - ../app/Console/Commands/Correction/FixAccountTypes.php
- - ../app/Console/Commands/Upgrade/OtherCurrenciesCorrections.php
- - ../app/Exceptions/GracefulNotFoundHandler.php
- - ../app/Generator/Webhook/StandardMessageGenerator.php
- - ../app/Support/Amount.php
- - ../app/Support/Navigation.php
- - ../app/Support/ParseDateString.php
- - ../app/Support/Search/AccountSearch.php
- - ../app/Support/Search/OperatorQuerySearch.php
- - ../app/Support/Twig/General.php
- - ../app/Transformers/RecurrenceTransformer.php
- - ../app/Validation/AccountValidator.php
- - ../app/Validation/RecurrenceValidation.php
- - ../app/Validation/TransactionValidation.php
-
- -
- message: '#Function compact\(\) should not be used#'
+ message: '#Function compact\(\) should not be used#' # too useful in template rendering.
paths:
- ../app/Generator/Report/Account/MonthReportGenerator.php
- ../app/Generator/Report/Audit/MonthReportGenerator.php
@@ -57,7 +48,6 @@ parameters:
message: '#Either catch a more specific exception#'
paths:
- ../app/Support/Form/FormSupport.php
-
paths:
- ../app
- ../database
@@ -66,5 +56,6 @@ parameters:
- ../bootstrap/app.php
# The level 8 is the highest level. original was 5
- level: 4
+ # 7 is more than enough, higher just leaves NULL things.
+ level: 7
diff --git a/.ci/phpstan.sh b/.ci/phpstan.sh
index 3b3beea910..84ff119226 100755
--- a/.ci/phpstan.sh
+++ b/.ci/phpstan.sh
@@ -29,7 +29,20 @@ SCRIPT_DIR="$( cd -- "$( dirname -- "${BASH_SOURCE[0]}" )" &> /dev/null && pwd )
# cp .ci/.env.ci .env
# Do static code analysis.
-# ./vendor/bin/phpstan analyse -c .ci/phpstan.neon --no-progress
-./vendor/bin/phpstan analyse -c .ci/phpstan.neon --xdebug --error-format=table > phpstan-report.txt
+if [[ $GITHUB_ACTIONS = "" ]]
+then
+ ./vendor/bin/phpstan analyse -c .ci/phpstan.neon --error-format=table > phpstan-report.txt
+ EXIT_CODE=$?
+ echo "The PHPstan report can be found in phpstan-report.txt. Exit code is $EXIT_CODE."
+fi
-echo 'The PHPstan report can be found in phpstan-report.txt'
+if [[ $GITHUB_ACTIONS = "true" ]]
+then
+ ./vendor/bin/phpstan analyse -c .ci/phpstan.neon --no-progress --error-format=github
+ EXIT_CODE=$?
+
+ # temporary exit code 0
+ # EXIT_CODE=0
+fi
+
+exit $EXIT_CODE
diff --git a/.ci/phpunit.sh b/.ci/phpunit.sh
deleted file mode 100755
index 58b307c329..0000000000
--- a/.ci/phpunit.sh
+++ /dev/null
@@ -1,63 +0,0 @@
-#!/usr/bin/env bash
-
-#
-# phpunit.sh
-# Copyright (c) 2021 james@firefly-iii.org
-#
-# This file is part of Firefly III (https://github.com/firefly-iii).
-#
-# This program is free software: you can redistribute it and/or modify
-# it under the terms of the GNU Affero General Public License as
-# published by the Free Software Foundation, either version 3 of the
-# License, or (at your option) any later version.
-#
-# This program 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 Affero General Public License for more details.
-#
-# You should have received a copy of the GNU Affero General Public License
-# along with this program. If not, see .
-#
-SCRIPT_DIR="$( cd -- "$( dirname -- "${BASH_SOURCE[0]}" )" &> /dev/null && pwd )"
-# enable test .env file.
-cp $SCRIPT_DIR/../.env $SCRIPT_DIR/../.env.backup
-cp $SCRIPT_DIR/.env.ci $SCRIPT_DIR/../.env
-
-COVERAGE=false
-RESET=false
-FILE=storage/database/database.sqlite
-
-while getopts "cr" o; do
- case "${o}" in
- c) COVERAGE=true;;
- r) RESET=true;;
- esac
-done
-
-# reset if necessary.
-if [ $RESET = "true" ] ; then
- rm -f $FILE
-fi
-
-# download test database
-if [ -f "$FILE" ]; then
- echo 'DB exists, will use it'
-else
- echo 'Download new DB'
- wget --quiet https://github.com/firefly-iii/test-fixtures/raw/main/test-database.sqlite -O $FILE
-fi
-
-# run phpunit
-if [ $COVERAGE = "true" ] ; then
- echo 'Run with coverage'
- XDEBUG_MODE=coverage ./vendor/bin/phpunit --configuration phpunit.xml --coverage-html $SCRIPT_DIR/coverage
-else
- echo 'Run without coverage'
- ./vendor/bin/phpunit --configuration phpunit.xml
-fi
-
-# restore .env file
-mv $SCRIPT_DIR/../.env.backup $SCRIPT_DIR/../.env
-
-cd $SCRIPT_DIR/..
diff --git a/.env.example b/.env.example
index ec2b4a8762..9bf6ec8409 100644
--- a/.env.example
+++ b/.env.example
@@ -1,6 +1,6 @@
# You can leave this on "local". If you change it to production most console commands will ask for extra confirmation.
# Never set it to "testing".
-APP_ENV=local
+APP_ENV=production
# Set to true if you want to see debug information in error screens.
APP_DEBUG=false
@@ -78,7 +78,7 @@ PAPERTRAIL_HOST=
PAPERTRAIL_PORT=
# Database credentials. Make sure the database exists. I recommend a dedicated user for Firefly III
-# For other database types, please see the FAQ: https://docs.firefly-iii.org/firefly-iii/faq/self-hosted/#i-want-to-use-sqlite
+# For other database types, please see the FAQ: https://docs.firefly-iii.org/references/faq/install/#i-want-to-use-sqlite
# If you use Docker or similar, you can set these variables from a file by appending them with _FILE
# Use "pgsql" for PostgreSQL
# Use "mysql" for MySQL and MariaDB.
@@ -122,7 +122,7 @@ SESSION_DRIVER=file
# If you use Docker or similar, you can set REDIS_HOST_FILE, REDIS_PASSWORD_FILE or
# REDIS_PORT_FILE to set the value from a file instead of from an environment variable
-# can be tcp, unix or http
+# can be tcp or unix. http is not supported
REDIS_SCHEME=tcp
# use only when using 'unix' for REDIS_SCHEME. Leave empty otherwise.
@@ -150,7 +150,7 @@ COOKIE_SECURE=false
COOKIE_SAMESITE=lax
# If you want Firefly III to email you, update these settings
-# For instructions, see: https://docs.firefly-iii.org/firefly-iii/advanced-installation/email/#email
+# For instructions, see: https://docs.firefly-iii.org/how-to/firefly-iii/advanced/notifications/#email
# If you use Docker or similar, you can set these variables from a file by appending them with _FILE
MAIL_MAILER=log
MAIL_HOST=null
@@ -195,6 +195,16 @@ MAP_DEFAULT_LAT=51.983333
MAP_DEFAULT_LONG=5.916667
MAP_DEFAULT_ZOOM=6
+#
+# Some objects have room for an URL, like transactions and webhooks.
+# By default, the following protocols are allowed:
+# http, https, ftp, ftps, mailto
+#
+# To change this, set your preferred comma separated set below.
+# Be sure to include http, https and other default ones if you need to.
+#
+VALID_URL_PROTOCOLS=
+
#
# Firefly III authentication settings
#
@@ -204,7 +214,7 @@ MAP_DEFAULT_ZOOM=6
# - 'web' (default, uses built in DB)
# - 'remote_user_guard' for Authelia etc
# Read more about these settings in the documentation.
-# https://docs.firefly-iii.org/firefly-iii/advanced-installation/authentication
+# https://docs.firefly-iii.org/how-to/firefly-iii/advanced/authentication/
#
# LDAP is no longer supported :(
#
@@ -259,7 +269,7 @@ ALLOW_WEBHOOKS=false
# 1. Set this token to any 32-character value (this is important!).
# 2. Use this token in the cron URL instead of a user's command line token that you can find in /profile
#
-# For more info: https://docs.firefly-iii.org/firefly-iii/advanced-installation/cron/
+# For more info: https://docs.firefly-iii.org/how-to/firefly-iii/advanced/cron/
#
# You can set this variable from a file by appending it with _FILE
#
@@ -314,18 +324,15 @@ PUSHER_SECRET=
PUSHER_ID=
DEMO_USERNAME=
DEMO_PASSWORD=
+
+#
+# The v2 layout is very experimental. If it breaks you get to keep both parts.
+# Be wary of data loss.
+#
FIREFLY_III_LAYOUT=v1
#
-# If you have trouble configuring your Firefly III installation, DON'T BOTHER setting this variable.
-# It won't work. It doesn't do ANYTHING. Don't believe the lies you read online. I'm not joking.
-# This configuration value WILL NOT HELP.
-#
-# Notable exception to this rule is Synology, which, according to some users, will use APP_URL to rewrite stuff.
-#
-# This variable is ONLY used in some of the emails Firefly III sends around. Nowhere else.
-# So when configuring anything WEB related this variable doesn't do anything. Nothing
-#
-# If you're stuck I understand you get desperate but look SOMEWHERE ELSE.
+# Please make sure this URL matches the external URL of your Firefly III installation.
+# It is used to validate specific requests and to generate URLs in emails.
#
APP_URL=http://localhost
diff --git a/.env.testing b/.env.testing
new file mode 100644
index 0000000000..2ca0859f2a
--- /dev/null
+++ b/.env.testing
@@ -0,0 +1,26 @@
+APP_ENV=testing
+APP_DEBUG=true
+SITE_OWNER=mail@example.com
+APP_KEY=TestTestTestTestTestTestTestTest
+DEFAULT_LANGUAGE=en_US
+DEFAULT_LOCALE=equal
+TZ=Europe/Amsterdam
+LOG_CHANNEL=stdout
+APP_LOG_LEVEL=debug
+AUDIT_LOG_LEVEL=info
+AUDIT_LOG_CHANNEL=audit_stdout
+DB_CONNECTION=sqlite
+CACHE_DRIVER=array
+SESSION_DRIVER=array
+MAIL_MAILER=log
+SEND_ERROR_MESSAGE=true
+ENABLE_EXTERNAL_MAP=false
+ENABLE_EXTERNAL_RATES=true
+AUTHENTICATION_GUARD=web
+ALLOW_WEBHOOKS=true
+APP_NAME=FireflyIII
+BROADCAST_DRIVER=log
+QUEUE_DRIVER=sync
+CACHE_PREFIX=firefly
+FIREFLY_III_LAYOUT=v1
+APP_URL=http://localhost
diff --git a/.github/ISSUE_TEMPLATE/fr.yml b/.github/ISSUE_TEMPLATE/fr.yml
index 679d35ae2a..d14c5249bd 100644
--- a/.github/ISSUE_TEMPLATE/fr.yml
+++ b/.github/ISSUE_TEMPLATE/fr.yml
@@ -8,7 +8,7 @@ body:
options:
- label: I've read the [support guidelines](https://github.com/firefly-iii/firefly-iii/blob/main/.github/support.md)
required: true
- - label: My request is not listed as [a very good idea, but unfortunately...](https://docs.firefly-iii.org/firefly-iii/more-information/what-its-not/)
+ - label: My request is not listed as [a very good idea, but unfortunately...](https://docs.firefly-iii.org/explanation/more-information/what-its-not/)
required: true
- label: I've used [the search](https://github.com/firefly-iii/firefly-iii/issues?q=is%3Aissue) and this has not been requested before.
required: true
diff --git a/.github/contributing.md b/.github/contributing.md
index 95080457fb..00df224461 100644
--- a/.github/contributing.md
+++ b/.github/contributing.md
@@ -1,3 +1,3 @@
-# [Contributing guidelines](https://docs.firefly-iii.org/firefly-iii/support/#contributing-code)
+# [Contributing guidelines](https://docs.firefly-iii.org/explanation/support/#contributing-code)
-[Contributing guidelines](https://docs.firefly-iii.org/firefly-iii/support/#contributing-code)
+[Contributing guidelines](https://docs.firefly-iii.org/explanation/support/#contributing-code)
diff --git a/.github/dependabot.yml b/.github/dependabot.yml
index 50269b374b..8d18a78293 100644
--- a/.github/dependabot.yml
+++ b/.github/dependabot.yml
@@ -1,11 +1,16 @@
version: 2
updates:
+ # Check for updates to GitHub Actions every week
+ - package-ecosystem: "github-actions"
+ directory: "/"
+ schedule:
+ interval: "weekly"
+
# composer updates
- package-ecosystem: "composer"
directory: "/" # Location of package manifests
target-branch: develop
- labels: [ "bug" ]
versioning-strategy: increase
schedule:
interval: "weekly"
@@ -14,15 +19,6 @@ updates:
- package-ecosystem: "npm"
directory: "/"
target-branch: develop
- labels: [ "bug" ]
- versioning-strategy: increase
- schedule:
- interval: "weekly"
-
- - package-ecosystem: "github-actions"
- directory: "/"
- target-branch: develop
- labels: [ "bug" ]
versioning-strategy: increase
schedule:
interval: "weekly"
diff --git a/.github/label-actions.yml b/.github/label-actions.yml
new file mode 100644
index 0000000000..6c9982d2cc
--- /dev/null
+++ b/.github/label-actions.yml
@@ -0,0 +1,111 @@
+# Configuration for Label Actions - https://github.com/dessant/label-actions
+
+# The `feature` label is added to issues
+feature:
+ issues:
+ # Post a comment, `{issue-author}` is an optional placeholder
+ comment: |
+ Hi there!
+
+ This is an automatic reply. `Share and enjoy`
+
+ This issue has been marked as a feature request. The requested (new) feature will become a part of Firefly III or the data importer in due course.
+
+ If you come across this issue, please be aware there is NO need to reply with "+1" or "me too" or "I need this too" or whatever. Such comments are not helpful, and do not influence [the roadmap](https://roadmap.firefly-iii.org/). Your comment may be :skull: deleted. You can subscribe to this issue to get updates.
+
+ Thank you for your contributions.
+
+epic:
+ issues:
+ # Post a comment, `{issue-author}` is an optional placeholder
+ comment: |
+ Hi there!
+
+ This is an automatic reply. `Share and enjoy`
+
+ This issue has been marked as an epic. In epics, large amounts of works are collected that will be part of a major new feature. If you have more ideas that could be a part of this epic, feel free to reply.
+
+ *However*, please be aware there is NO need to reply with "+1" or "me too" or "I need this too" or whatever. Such comments are not helpful, and do not influence [the roadmap](https://roadmap.firefly-iii.org/). Your comment may be :skull: deleted.
+
+ If you are merely interested in this epic's progress, you can subscribe to this issue to get updates.
+
+ Thank you for your contributions.
+
+enhancement:
+ issues:
+ # Post a comment, `{issue-author}` is an optional placeholder
+ comment: |
+ Hi there!
+
+ This is an automatic reply. `Share and enjoy`
+
+ This issue has been marked as an enhancement. The requested enhancement to an existing feature will become a part of Firefly III or the data importer in due course.
+
+ If you come across this issue, please be aware there is NO need to reply with "+1" or "me too" or "I need this too" or whatever. Such comments are not helpful, and do not influence [the roadmap](https://roadmap.firefly-iii.org/). Your comment may be :skull: deleted. You can subscribe to this issue to get updates.
+
+ Thank you for your contributions.
+
+triage:
+ issues:
+ # Post a comment, `{issue-author}` is an optional placeholder
+ comment: |
+ Hi there!
+
+ This is an automatic reply. `Share and enjoy`
+
+ This issue has been marked as being in triage. The root cause is not known yet, or the issue needs more investigation. You can help by sharing debug information (from `/debug`) if you also have this issue or when you haven't already done so.
+
+ Thank you for your contributions.
+
+needs-moar-debug:
+ issues:
+ comment: |
+ Hi there!
+
+ This is an automatic reply. `Share and enjoy`
+
+ To learn more about this issue, please make sure you share at least:
+
+ 1. The table you can find on the `/debug` page
+ 2. Firefly III version
+ 2. Docker, self-hosted, or hosted by a third party?
+ 3. Operating system and browser
+
+ Thank you for your contributions.
+ unlabel: needs-moar-debug
+
+
+needs-moar-logs:
+ issues:
+ comment: |
+ Hi there!
+
+ This is an automatic reply. `Share and enjoy`
+
+ To learn more about this issue, please share the relevant log files from your Firefly III or data importer installation.
+
+ The relevant instructions can be found in the documentation: [How to debug Firefly III?](https://docs.firefly-iii.org/how-to/general/debug/) Once debug mode is activated per these instructions, you can repeat your action and find the logs, depending on your method of installation. All is explained on the page.
+
+ Please share the relevant log lines in your issue, either inline or as an attachment. If you feel the logs contain sensitive information, you may also send them to [james@firefly-iii.org](mailto:james@firefly-iii.org). Without these logs, it may not be possible to properly investigate this issue.
+
+ Thank you for your contributions.
+ unlabel: needs-moar-logs
+
+v2-layout-issue:
+ issues:
+ comment: |
+ Hi there!
+
+ This is an automatic reply. `Share and enjoy`
+
+ It seems your issue is about the new v2-layout that is currently in development for Firefly III.
+
+ These issues are collected in [a GitHub discussion](https://github.com/firefly-iii/firefly-iii/issues/8361).
+
+ Please note that the v2 layout is still very much in development.
+
+ Thank you for your contributions.
+ close: true
+ close-reason: completed
+ lock: false
+ unlabel: v2-layout-issue
diff --git a/.github/support.md b/.github/support.md
index 80e4b99ad8..78cbed51e8 100644
--- a/.github/support.md
+++ b/.github/support.md
@@ -27,7 +27,7 @@ Only then [create a new issue](https://github.com/firefly-iii/firefly-iii/issues
- Issues can be converted into discussions if it's not a bug or feature request.
- Features that won't be implemented will be labelled "
- wontfix". [This isn't personal](https://docs.firefly-iii.org/firefly-iii/about-firefly-iii/what-its-not/).
+ wontfix". [This isn't personal](https://docs.firefly-iii.org/explanation/more-information/what-its-not/).
- Issues can be closed if they're duplicates of other issues.
- Issues can be closed if the answer is in the FAQ.
- Issues will be closed automatically after 14 days.
diff --git a/.github/workflows/cleanup.yml b/.github/workflows/cleanup.yml
index 5f820b0c40..0be8f1c3fc 100644
--- a/.github/workflows/cleanup.yml
+++ b/.github/workflows/cleanup.yml
@@ -1,6 +1,9 @@
# This workflow prunes old workflow runs for an entire repository.
-name: Prune old builds
+name: "Chore - Prune old builds"
+
+permissions:
+ actions: write
on:
schedule:
@@ -12,9 +15,9 @@ jobs:
timeout-minutes: 10
steps:
- name: Prune cancelled/skipped runs
- uses: actions/github-script@v6
+ uses: actions/github-script@v7
with:
- github-token: ${{ secrets.GH_ACTIONS_PERSONAL_ACCESS_TOKEN }}
+ github-token: ${{ secrets.GITHUB_TOKEN }}
script: |
const cancelled = await github.rest.actions.listWorkflowRunsForRepo({
owner: context.repo.owner,
@@ -22,14 +25,14 @@ jobs:
repo: context.repo.repo,
status: 'cancelled',
});
-
+
const skipped = await github.rest.actions.listWorkflowRunsForRepo({
owner: context.repo.owner,
per_page: 100,
repo: context.repo.repo,
status: 'skipped',
});
-
+
for (const response of [cancelled, skipped]) {
for (const run of response.data.workflow_runs) {
console.log(`Run id ${run.id} of '${run.name}' is a cancelled/skipped run. Deleting...`);
@@ -42,31 +45,33 @@ jobs:
}
- name: Prune runs older than 3 days
- uses: actions/github-script@v6
+ uses: actions/github-script@v7
with:
- github-token: ${{ secrets.GH_ACTIONS_PERSONAL_ACCESS_TOKEN }}
+ github-token: ${{ secrets.GITHUB_TOKEN }}
script: |
const days_to_expiration = 3;
const ms_in_day = 86400000;
const now = Date.now();
const pages = 5;
-
+
// we don't want to prune old runs from test.yml
// because we track the duration of runs over time
-
+
const workflows = [
'cleanup.yml',
+ 'close-duplicates.yml',
'closed-issues.yml',
- 'depsreview.yaml',
- 'laravel.yml',
+ 'debug-info-actions.yml',
+ 'depsreview.yml',
+ 'label-actions.yml',
'lock.yml',
- 'qodana.yml',
+ 'release.yml',
'sonarcloud.yml',
'stale.yml'
]
-
+
let runs_to_delete = [];
-
+
for (const workflow of workflows) {
for (let page = 0; page < pages; page += 1) {
let response = await github.rest.actions.listWorkflowRuns({
@@ -76,7 +81,7 @@ jobs:
repo: context.repo.repo,
workflow_id: workflow
});
-
+
if (response.data.workflow_runs.length > 0) {
for (const run of response.data.workflow_runs) {
if (now - Date.parse(run.created_at) > ms_in_day * days_to_expiration) {
@@ -86,7 +91,7 @@ jobs:
}
}
}
-
+
for (const run of runs_to_delete) {
console.log(`Run id ${run[0]} of '${run[1]}' is older than ${days_to_expiration} days. Deleting...`);
try {
diff --git a/.github/workflows/close-duplicates.yml b/.github/workflows/close-duplicates.yml
new file mode 100644
index 0000000000..493aaedf52
--- /dev/null
+++ b/.github/workflows/close-duplicates.yml
@@ -0,0 +1,39 @@
+name: "Issues - Command to close duplicate issues"
+
+# the workflow to execute on is comments that are newly created
+on:
+ issue_comment:
+ types: [created]
+
+permissions:
+ issues: write
+ checks: read
+
+jobs:
+ close_duplicates:
+ runs-on: ubuntu-latest
+ steps:
+ - uses: github/command@v1.1.0
+ id: command
+ with:
+ allowed_contexts: "issue"
+ command: ".duplicate"
+ - name: reply
+ if: ${{ steps.command.outputs.continue == 'true' }}
+ run: |
+
+ ISSUE_TITLE=$(gh issue view ${{ steps.command.outputs.params }} --json title --jq '.title')
+
+ gh issue comment "$NUMBER" --body "Hi there!
+
+ This is an automatic reply. \`Share and enjoy\`.
+
+ Your issue is probably a duplicate of issue #${{ steps.command.outputs.params }}: [$ISSUE_TITLE](https://github.com/firefly-iii/firefly-iii/issues/${{ steps.command.outputs.params }}). Please refer to issue #${{ steps.command.outputs.params }} for support.
+
+ You can close this issue now. If you believe this is not in fact a duplicate, please reply and let us know. Otherwise, this issue will be automatically closed in a few days time.
+
+ Thank you for your contributions."
+ env:
+ GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}
+ GH_REPO: ${{ github.repository }}
+ NUMBER: ${{ github.event.issue.number }}
diff --git a/.github/workflows/closed-issues.yml b/.github/workflows/closed-issues.yml
index 22a9c3438f..2681e20242 100644
--- a/.github/workflows/closed-issues.yml
+++ b/.github/workflows/closed-issues.yml
@@ -1,10 +1,11 @@
-name: "Reply to closed issue"
+---
+name: Issues - Reply to closed issue
on:
issues:
types:
- closed
jobs:
- auto_comment:
+ command_and_close:
runs-on: ubuntu-latest
steps:
- uses: aws-actions/closed-issue-message@v1
@@ -21,4 +22,4 @@ jobs:
If there is more to discuss, please open [a new issue](https://github.com/firefly-iii/firefly-iii/issues/new/choose) or [discussion](https://github.com/firefly-iii/firefly-iii/discussions/).
Thank you for your contributions.
- repo-token: "${{ secrets.GITHUB_TOKEN }}"
+ repo-token: ${{ secrets.GITHUB_TOKEN }}
diff --git a/.github/workflows/debug-info-actions.yml b/.github/workflows/debug-info-actions.yml
new file mode 100644
index 0000000000..be7b336eaf
--- /dev/null
+++ b/.github/workflows/debug-info-actions.yml
@@ -0,0 +1,32 @@
+name: 'Issues - Respond to hidden commands'
+
+# the workflow to execute on is comments that are newly created
+on:
+ issues:
+ types: [opened, edited]
+ issue_comment:
+ types: [created]
+
+# permissions needed for reacting to IssueOps commands on issues and PRs
+permissions:
+ contents: read
+ pull-requests: write
+ issues: write
+ checks: read
+
+jobs:
+ respond:
+ runs-on: ubuntu-latest
+ steps:
+ - run: |
+ ISSUE_BODY=$(gh issue view $NUMBER --json body)
+ if [[ $ISSUE_BODY == *".eOxNZAmyGz6CXMyf"* ]]; then
+ gh issue comment "$NUMBER" --body "$V2_ISSUE_REPLY_BODY"
+ gh issue close "$NUMBER" --reason completed
+ fi
+ env:
+ GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}
+ GH_REPO: ${{ github.repository }}
+ NUMBER: ${{ github.event.issue.number }}
+ V2_ISSUE_REPLY_BODY: ${{ secrets.V2_ISSUE_REPLY_BODY }}
+ LABELS: v2-layout-issue
diff --git a/.github/workflows/depsreview.yaml b/.github/workflows/depsreview.yaml
deleted file mode 100644
index d5ed859514..0000000000
--- a/.github/workflows/depsreview.yaml
+++ /dev/null
@@ -1,14 +0,0 @@
-name: 'Dependency Review'
-on: [ pull_request ]
-
-permissions:
- contents: read
-
-jobs:
- dependency-review:
- runs-on: ubuntu-latest
- steps:
- - name: 'Checkout Repository'
- uses: actions/checkout@v3
- - name: 'Dependency Review'
- uses: actions/dependency-review-action@v3
diff --git a/.github/workflows/depsreview.yml b/.github/workflows/depsreview.yml
new file mode 100644
index 0000000000..0be36de48c
--- /dev/null
+++ b/.github/workflows/depsreview.yml
@@ -0,0 +1,16 @@
+name: 'Code - Dependency review'
+on: [ pull_request ]
+
+permissions:
+ contents: read
+
+jobs:
+ dependency-review:
+ runs-on: ubuntu-latest
+ steps:
+ - name: 'Checkout repository'
+ uses: actions/checkout@v4
+ with:
+ fetch-depth: 0
+ - name: 'Dependency review'
+ uses: actions/dependency-review-action@v4
diff --git a/.github/workflows/label-actions.yml b/.github/workflows/label-actions.yml
new file mode 100644
index 0000000000..c80e42651e
--- /dev/null
+++ b/.github/workflows/label-actions.yml
@@ -0,0 +1,21 @@
+name: 'Issues - Reply to specific labels'
+
+on:
+ issues:
+ types: [labeled, unlabeled]
+ pull_request_target:
+ types: [labeled, unlabeled]
+ discussion:
+ types: [labeled, unlabeled]
+
+permissions:
+ contents: read
+ issues: write
+ pull-requests: write
+ discussions: write
+
+jobs:
+ action:
+ runs-on: ubuntu-latest
+ steps:
+ - uses: dessant/label-actions@v4
diff --git a/.github/workflows/laravel.yml b/.github/workflows/laravel.yml
deleted file mode 100644
index 75babbfe2d..0000000000
--- a/.github/workflows/laravel.yml
+++ /dev/null
@@ -1,146 +0,0 @@
-name: Firefly III
-
-on:
- push:
- branches-ignore:
- - '**'
-
-jobs:
- prepare:
-
- runs-on: ubuntu-latest
-
- steps:
- - uses: actions/checkout@v3
- - name: Copy .env
- run: test -f .env || cp .ci/.env.ci .env
- - name: Prepare dependencies
- run: |
- set -euxo pipefail
- export PATH=$PATH:$HOME/.composer/vendor/bin/
- composer global require hirak/prestissimo --no-plugins --no-scripts
- composer install --no-ansi --no-interaction --no-scripts --no-progress --prefer-dist --no-suggest
-
- touch ./storage/database/database.sqlite
- - name: Prepare Firefly III
- run: |
- chmod -R 777 storage bootstrap/cache
- php artisan migrate --seed
- php artisan firefly-iii:upgrade-database
- - name: Upload database
- uses: actions/upload-artifact@v2
- with:
- name: database
- path: storage/database/database.sqlite
- - name: Upload cache
- uses: actions/upload-artifact@v2
- with:
- name: cache
- path: bootstrap/cache/
- - name: Upload composer cache
- uses: actions/upload-artifact@v2
- with:
- name: composer
- path: ~/.composer
-
- laravel-tests:
-
- runs-on: ubuntu-latest
-
- needs:
- - prepare
-
- steps:
- - uses: actions/checkout@v3
- - name: Copy .env
- run: test -f .env || cp .ci/.env.ci .env
- - name: Download database
- uses: actions/download-artifact@v2
- with:
- name: database
- path: storage/database/database.sqlite
- - name: Download cache
- uses: actions/download-artifact@v2
- with:
- name: cache
- path: bootstrap/cache/
- - name: Download vendor
- uses: actions/download-artifact@v2
- with:
- name: composer
- path: ~/.composer
- - name: Install composer
- run: composer install --no-ansi --no-interaction --no-scripts --no-progress --prefer-dist --no-suggest
-
- - name: PHPUnit tests
- uses: php-actions/phpunit@v1
- with:
- config: phpunit.xml
- memory: 512M
-
- coding-standards:
-
- runs-on: ubuntu-latest
-
- needs:
- - prepare
-
- steps:
- - uses: actions/checkout@v3
- - name: Copy .env
- run: test -f .env || cp .ci/.env.ci .env
- - name: Download database
- uses: actions/download-artifact@v2
- with:
- name: database
- path: storage/database/database.sqlite
- - name: Download cache
- uses: actions/download-artifact@v2
- with:
- name: cache
- path: bootstrap/cache/
- - name: Download vendor
- uses: actions/download-artifact@v2
- with:
- name: composer
- path: ~/.composer
- - name: install depenencies
- run: |
- composer global require nette/coding-standard
- composer install --no-ansi --no-interaction --no-scripts --no-progress --prefer-dist --no-suggest
-
- - name: Execute code standard
- run: /home/runner/.composer/vendor/bin/ecs check app tests --config ./.ci/firefly-iii-standard.yml
-
- phpstan:
-
- runs-on: ubuntu-latest
-
- needs:
- - prepare
-
- steps:
- - uses: actions/checkout@v3
- - name: Copy .env
- run: test -f .env || cp .ci/.env.ci .env
- - name: Download database
- uses: actions/download-artifact@v2
- with:
- name: database
- path: storage/database/database.sqlite
- - name: Download cache
- uses: actions/download-artifact@v2
- with:
- name: cache
- path: bootstrap/cache/
- - name: Download vendor
- uses: actions/download-artifact@v2
- with:
- name: composer
- path: ~/.composer
- - name: Install depenencies
- run: |
- composer install --no-ansi --no-interaction --no-scripts --no-progress --prefer-dist --no-suggest
-
- - name: Execute PHPStan
- run: vendor/bin/phpstan analyse -c .ci/phpstan.neon
diff --git a/.github/workflows/lock.yml b/.github/workflows/lock.yml
index f01515c30d..d32b27d5ee 100644
--- a/.github/workflows/lock.yml
+++ b/.github/workflows/lock.yml
@@ -1,4 +1,4 @@
-name: Lock old issues
+name: 'Issues - Lock old issues'
on:
workflow_dispatch:
@@ -15,5 +15,5 @@ jobs:
- uses: JC5/lock-threads@main
with:
github-token: ${{ github.token }}
- issue-inactive-days: 90
- pr-inactive-days: 90
+ issue-inactive-days: 7
+ pr-inactive-days: 7
diff --git a/.github/workflows/qodana.yml b/.github/workflows/qodana.yml
deleted file mode 100644
index da78ebabe8..0000000000
--- a/.github/workflows/qodana.yml
+++ /dev/null
@@ -1,35 +0,0 @@
-name: Qodana
-on:
- workflow_dispatch:
- push:
- branches:
- - main
- - develop
-jobs:
- qodana:
- runs-on: ubuntu-latest
- name: 'Qodana Scan'
- steps:
- - name: Setup PHP with no coverage driver
- uses: shivammathur/setup-php@v2
- with:
- php-version: '8.2'
- coverage: none
- extensions: bcmath, intl
- env:
- update: true
- - uses: actions/checkout@v3
- with:
- fetch-depth: 0 # Shallow clones should be disabled for a better relevancy of analysis
- - name: Install dependencies
- run: |
- composer install --no-scripts
- cp .env.example .env
- php artisan key:generate
- php artisan clear-compiled
- php artisan ide-helper:generate;
-
- - name: 'Qodana Scan'
- uses: JetBrains/qodana-action@main
- env:
- QODANA_TOKEN: ${{ secrets.QODANA_TOKEN }}
diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml
new file mode 100644
index 0000000000..231ec6ee55
--- /dev/null
+++ b/.github/workflows/release.yml
@@ -0,0 +1,173 @@
+name: 'Code - Create new release'
+
+on:
+ workflow_dispatch:
+ inputs:
+ version:
+ description: 'Version to release'
+ required: true
+ default: 'develop'
+ schedule:
+ - cron: '15 0 * * MON,THU'
+
+jobs:
+ build:
+ runs-on: ubuntu-latest
+ steps:
+ - name: Checkout
+ uses: actions/checkout@v4
+ with:
+ fetch-depth: 0
+ - name: Switch branch
+ run: |
+ if [[ "develop" == "$version" ]]; then
+ git checkout --track origin/develop
+ git pull
+ else
+ git config user.name github-actions
+ git config user.email 41898282+github-actions[bot]@users.noreply.github.com
+ git checkout --track origin/develop
+ git pull
+ git checkout main
+ git merge develop
+ fi
+ env:
+ version: ${{ github.event_name == 'schedule' && 'develop' || github.event.inputs.version }}
+ - name: Setup PHP
+ uses: shivammathur/setup-php@v2
+ with:
+ php-version: '8.3'
+ extensions: mbstring, intl, zip, bcmath
+ - name: crowdin action
+ uses: crowdin/github-action@v1
+ with:
+ upload_sources: true
+ download_translations: true
+ push_translations: false
+ push_sources: false
+ env:
+ GITHUB_TOKEN: ${{ github.token }}
+ CROWDIN_PROJECT_NR: ${{ secrets.CROWDIN_PROJECT_NR }}
+ CROWDIN_TOKEN: ${{ secrets.CROWDIN_TOKEN }}
+ - name: Cleanup translations
+ id: cleanup-transactions
+ uses: JC5/firefly-iii-dev@v34
+ with:
+ action: 'ff3:crowdin-warning'
+ output: ''
+ env:
+ FIREFLY_III_ROOT: /github/workspace
+ GH_TOKEN: ''
+ - name: Cleanup changelog
+ id: cleanup-changelog
+ uses: JC5/firefly-iii-dev@v34
+ with:
+ action: 'ff3:changelog'
+ output: ''
+ env:
+ FIREFLY_III_ROOT: /github/workspace
+ GH_TOKEN: ${{ secrets.CHANGELOG_TOKEN }}
+ - name: Extract changelog
+ id: extract-changelog
+ uses: JC5/firefly-iii-dev@v34
+ with:
+ action: 'ff3:extract-changelog'
+ output: 'output'
+ env:
+ FIREFLY_III_ROOT: /github/workspace
+ GH_TOKEN: ""
+ - name: Replace version
+ id: replace-version
+ uses: JC5/firefly-iii-dev@v34
+ with:
+ action: 'ff3:version'
+ output: ''
+ env:
+ FIREFLY_III_ROOT: /github/workspace
+ GH_TOKEN: ""
+ FF_III_VERSION: ${{ github.event_name == 'schedule' && 'develop' || github.event.inputs.version }}
+ - name: Generate JSON v1
+ id: json-v1
+ uses: JC5/firefly-iii-dev@v34
+ with:
+ action: 'ff3:json-translations v1'
+ output: ''
+ env:
+ FIREFLY_III_ROOT: /github/workspace
+ GH_TOKEN: ''
+ - name: Generate JSON v2
+ id: json-v2
+ uses: JC5/firefly-iii-dev@v34
+ with:
+ action: 'ff3:json-translations v2'
+ output: ''
+ env:
+ FIREFLY_III_ROOT: /github/workspace
+ GH_TOKEN: ''
+ - name: Code cleanup
+ id: code-cleanup
+ uses: JC5/firefly-iii-dev@v34
+ with:
+ action: 'ff3:code'
+ output: ''
+ env:
+ FIREFLY_III_ROOT: /github/workspace
+ GH_TOKEN: ''
+ - name: Build new JS
+ run: |
+ npm upgrade
+ npm run build
+ - name: Build old JS
+ id: old-js
+ uses: JC5/firefly-iii-dev@v34
+ with:
+ action: 'ff3:old-js'
+ output: ''
+ env:
+ FIREFLY_III_ROOT: /github/workspace
+ GH_TOKEN: ''
+ - name: Run CI
+ run: |
+ rm -rf vendor composer.lock
+ composer validate --strict
+ composer update --no-dev --no-scripts --no-plugins -q
+ sudo chown -R runner:docker resources/lang
+ .ci/phpcs.sh
+ - name: Release
+ run: |
+ sudo timedatectl set-timezone Europe/Amsterdam
+ git config user.name github-actions
+ git config user.email 41898282+github-actions[bot]@users.noreply.github.com
+ git config advice.addIgnoredFile false
+
+ if [[ "develop" == "$version" ]]; then
+ [[ -z $(git status --untracked-files=normal --porcelain) ]] && echo "this branch is clean, no need to push..." && exit 0;
+ fi
+
+ git add -A
+ if test -f "output.txt"; then
+ git reset output.txt
+ fi
+ git commit -m "Auto commit for release '$version' on $(date +'%Y-%m-%d')" || true
+ git push
+
+ if [[ "develop" == "$version" ]]; then
+ echo "Create nightly release."
+ git tag -a $version-$(date +'%Y%m%d') -m "Nightly development release '$version' on $(date +'%Y-%m-%d')"
+ git push origin $version-$(date +'%Y%m%d')
+ gh release create $version-$(date +'%Y%m%d') -p --verify-tag \
+ -t "Development release for $(date +'%Y-%m-%d')" \
+ -n "Bi-weekly development release of Firefly III with the latest fixes, translations and features. This release was created on **$(date +'%Y-%m-%d')** and may contain bugs. Use at your own risk. Docker users can find this release under the \`develop\` tag."
+ else
+ echo "Create default release."
+ git tag -a $version -m "Here be changelog"
+ git push origin $version
+ gh release create $version -F output.txt -t "$version" --verify-tag
+ rm output.txt
+ git checkout develop
+ git merge main
+ git push
+ fi
+ env:
+ GH_TOKEN: ${{ github.token }}
+ version: ${{ github.event_name == 'schedule' && 'develop' || github.event.inputs.version }}
diff --git a/.github/workflows/sonarcloud.yml b/.github/workflows/sonarcloud.yml
index e9ba1b9b27..862d9d4dc7 100644
--- a/.github/workflows/sonarcloud.yml
+++ b/.github/workflows/sonarcloud.yml
@@ -1,38 +1,67 @@
-name: Sonarcloud
+name: 'Code - Run Sonarcloud'
on:
- pull_request:
+ pull_request:
+ workflow_dispatch:
push:
branches:
- main
- develop
+env:
+ DB_CONNECTION: sqlite
+ APP_KEY: UfpBqqeXx7zpNodsC6yjYQcRfDdm4Bxh
jobs:
sonarcloud:
name: SonarCloud
runs-on: ubuntu-latest
steps:
- - uses: actions/checkout@v3
- with:
- fetch-depth: 0 # Shallow clones should be disabled for a better relevancy of analysis
-
- name: Checkout
- uses: actions/checkout@v2
- with:
- fetch-depth: 0
-
+ uses: actions/checkout@v4
- name: Setup PHP with Xdebug
uses: shivammathur/setup-php@v2
with:
- php-version: '8.2'
+ php-version: '8.3'
coverage: xdebug
+ extensions: >-
+ bcmath
+ curl
+ fileinfo
+ iconv
+ intl
+ json
+ sqlite3
+ mbstring
+ openssl
+ pdo
+ session
+ simplexml
+ sodium
+ tokenizer
+ xml
+ xmlwriter
+
+ - name: Copy standard configuration
+ run: cp .env.testing .env
- name: Install Composer dependencies
run: composer install --prefer-dist --no-interaction --no-progress --no-scripts
- - name: Copy environment file
- run: cp .env.example .env
+ - name: PHPStan
+ run: .ci/phpstan.sh
- - name: Generate app key
- run: php artisan key:generate
+ - name: PHPMD
+ run: .ci/phpmd.sh
+
+ - name: PHP CS Fixer
+ run: .ci/phpcs.sh
+
+ - name: "Create database file"
+ run: touch storage/database/database.sqlite
+
+ - name: "Upgrades the database to the latest version"
+ run: php artisan firefly-iii:upgrade-database
+
+ - name: "Integrity Database Report"
+ run: php artisan firefly-iii:report-integrity
- name: "Run tests with coverage"
run: composer coverage
diff --git a/.github/workflows/stale.yml b/.github/workflows/stale.yml
index 817763ac59..e412dd4938 100644
--- a/.github/workflows/stale.yml
+++ b/.github/workflows/stale.yml
@@ -1,4 +1,4 @@
-name: "Close stale issues"
+name: "Issues - Mark and close stale issues"
on:
schedule:
- cron: "30 1 * * *"
@@ -14,21 +14,25 @@ jobs:
pull-requests: write # for actions/stale to close stale PRs
runs-on: ubuntu-latest
steps:
- - uses: actions/stale@v6
+ - uses: actions/stale@v9
with:
repo-token: ${{ secrets.GITHUB_TOKEN }}
stale-issue-message: >
- Hi there! This is an automatic reply. `Share and enjoy`
-
- This issue has been automatically marked as stale because it has not had recent activity. It will be closed if no further activity occurs.
+ Hi there!
+ This is an automatic reply. `Share and enjoy`
+
+ 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.
stale-pr-message: >
- Hi there! This is an automatic reply. `Share and enjoy`
+ Hi there!
+
+ This is an automatic reply. `Share and enjoy`
- This PR has been automatically marked as stale because it has not had recent activity. It will be closed if no further activity occurs.
+ This PR 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.
days-before-stale: 14
days-before-close: 7
- exempt-issue-labels: 'enhancement,feature,bug,announcement,epic'
+ exempt-issue-labels: 'enhancement,feature,bug,announcement,epic,triage'
diff --git a/.gitignore b/.gitignore
index ab681f4f44..7a00e55ffc 100644
--- a/.gitignore
+++ b/.gitignore
@@ -1,8 +1,7 @@
/node_modules
-/frontend/node_modules
/storage/*.key
/vendor
-/.vagrant
+public/hot
npm-debug.log
yarn-error.log
.env
diff --git a/app/Api/V1/Controllers/Autocomplete/AccountController.php b/app/Api/V1/Controllers/Autocomplete/AccountController.php
index ecbfba6e61..141412f486 100644
--- a/app/Api/V1/Controllers/Autocomplete/AccountController.php
+++ b/app/Api/V1/Controllers/Autocomplete/AccountController.php
@@ -32,7 +32,6 @@ use FireflyIII\Repositories\Account\AccountRepositoryInterface;
use FireflyIII\Support\Http\Api\AccountFilter;
use FireflyIII\User;
use Illuminate\Http\JsonResponse;
-use JsonException;
/**
* Class AccountController
@@ -41,6 +40,7 @@ class AccountController extends Controller
{
use AccountFilter;
+ /** @var array */
private array $balanceTypes;
private AccountRepositoryInterface $repository;
@@ -60,30 +60,25 @@ class AccountController extends Controller
return $next($request);
}
);
- $this->balanceTypes = [AccountType::ASSET, AccountType::LOAN, AccountType::DEBT, AccountType::MORTGAGE,];
+ $this->balanceTypes = [AccountType::ASSET, AccountType::LOAN, AccountType::DEBT, AccountType::MORTGAGE];
}
/**
* Documentation for this endpoint:
* https://api-docs.firefly-iii.org/?urls.primaryName=2.0.0%20(v1)#/autocomplete/getAccountsAC
*
- * @param AutocompleteRequest $request
- *
- * @return JsonResponse
- * @throws JsonException
* @throws FireflyException
* @throws FireflyException
*/
public function accounts(AutocompleteRequest $request): JsonResponse
{
- $data = $request->getData();
- $types = $data['types'];
- $query = $data['query'];
- $date = $data['date'] ?? today(config('app.timezone'));
+ $data = $request->getData();
+ $types = $data['types'];
+ $query = $data['query'];
+ $date = $data['date'] ?? today(config('app.timezone'));
+ $return = [];
+ $result = $this->repository->searchAccount((string)$query, $types, $this->parameters->get('limit'));
- $return = [];
-
- $result = $this->repository->searchAccount((string)$query, $types, $this->parameters->get('limit'));
// TODO this code is duplicated in the V2 Autocomplete controller, which means this code is due to be deprecated.
$defaultCurrency = app('amount')->getDefaultCurrency();
@@ -101,7 +96,7 @@ class AccountController extends Controller
);
}
- $return[] = [
+ $return[] = [
'id' => (string)$account->id,
'name' => $account->name,
'name_with_balance' => $nameWithBalance,
@@ -117,10 +112,10 @@ class AccountController extends Controller
// custom order.
usort(
$return,
- function ($a, $b) {
+ static function (array $left, array $right) {
$order = [AccountType::ASSET, AccountType::REVENUE, AccountType::EXPENSE];
- $posA = array_search($a['type'], $order, true);
- $posB = array_search($b['type'], $order, true);
+ $posA = (int)array_search($left['type'], $order, true);
+ $posB = (int)array_search($right['type'], $order, true);
return $posA - $posB;
}
diff --git a/app/Api/V1/Controllers/Autocomplete/BillController.php b/app/Api/V1/Controllers/Autocomplete/BillController.php
index 542fd4a25f..be64d6fd96 100644
--- a/app/Api/V1/Controllers/Autocomplete/BillController.php
+++ b/app/Api/V1/Controllers/Autocomplete/BillController.php
@@ -58,10 +58,6 @@ class BillController extends Controller
/**
* Documentation for this endpoint is at:
* https://api-docs.firefly-iii.org/?urls.primaryName=2.0.0%20(v1)#/autocomplete/getBillsAC
- *
- * @param AutocompleteRequest $request
- *
- * @return JsonResponse
*/
public function bills(AutocompleteRequest $request): JsonResponse
{
diff --git a/app/Api/V1/Controllers/Autocomplete/BudgetController.php b/app/Api/V1/Controllers/Autocomplete/BudgetController.php
index f3334df101..0674e2dd2e 100644
--- a/app/Api/V1/Controllers/Autocomplete/BudgetController.php
+++ b/app/Api/V1/Controllers/Autocomplete/BudgetController.php
@@ -58,10 +58,6 @@ class BudgetController extends Controller
/**
* Documentation for this endpoint is at:
* https://api-docs.firefly-iii.org/?urls.primaryName=2.0.0%20(v1)#/autocomplete/getBudgetsAC
- *
- * @param AutocompleteRequest $request
- *
- * @return JsonResponse
*/
public function budgets(AutocompleteRequest $request): JsonResponse
{
diff --git a/app/Api/V1/Controllers/Autocomplete/CategoryController.php b/app/Api/V1/Controllers/Autocomplete/CategoryController.php
index a35b7e11a6..6a1b104aae 100644
--- a/app/Api/V1/Controllers/Autocomplete/CategoryController.php
+++ b/app/Api/V1/Controllers/Autocomplete/CategoryController.php
@@ -58,10 +58,6 @@ class CategoryController extends Controller
/**
* Documentation for this endpoint is at:
* https://api-docs.firefly-iii.org/?urls.primaryName=2.0.0%20(v1)#/autocomplete/getCategoriesAC
- *
- * @param AutocompleteRequest $request
- *
- * @return JsonResponse
*/
public function categories(AutocompleteRequest $request): JsonResponse
{
diff --git a/app/Api/V1/Controllers/Autocomplete/CurrencyController.php b/app/Api/V1/Controllers/Autocomplete/CurrencyController.php
index 2250b32f33..abf6b7b468 100644
--- a/app/Api/V1/Controllers/Autocomplete/CurrencyController.php
+++ b/app/Api/V1/Controllers/Autocomplete/CurrencyController.php
@@ -26,7 +26,7 @@ namespace FireflyIII\Api\V1\Controllers\Autocomplete;
use FireflyIII\Api\V1\Controllers\Controller;
use FireflyIII\Api\V1\Requests\Autocomplete\AutocompleteRequest;
use FireflyIII\Models\TransactionCurrency;
-use FireflyIII\Repositories\Currency\CurrencyRepositoryInterface;
+use FireflyIII\Repositories\UserGroups\Currency\CurrencyRepositoryInterface;
use FireflyIII\User;
use Illuminate\Http\JsonResponse;
@@ -58,10 +58,6 @@ class CurrencyController extends Controller
/**
* Documentation for this endpoint is at:
* https://api-docs.firefly-iii.org/?urls.primaryName=2.0.0%20(v1)#/autocomplete/getCurrenciesAC
- *
- * @param AutocompleteRequest $request
- *
- * @return JsonResponse
*/
public function currencies(AutocompleteRequest $request): JsonResponse
{
@@ -87,9 +83,6 @@ class CurrencyController extends Controller
* Documentation for this endpoint is at:
* https://api-docs.firefly-iii.org/?urls.primaryName=2.0.0%20(v1)#/autocomplete/getCurrenciesCodeAC
*
- * @param AutocompleteRequest $request
- *
- * @return JsonResponse
* @deprecated
*/
public function currenciesWithCode(AutocompleteRequest $request): JsonResponse
diff --git a/app/Api/V1/Controllers/Autocomplete/ObjectGroupController.php b/app/Api/V1/Controllers/Autocomplete/ObjectGroupController.php
index 67cd318e38..e76794da2c 100644
--- a/app/Api/V1/Controllers/Autocomplete/ObjectGroupController.php
+++ b/app/Api/V1/Controllers/Autocomplete/ObjectGroupController.php
@@ -58,10 +58,6 @@ class ObjectGroupController extends Controller
/**
* Documentation for this endpoint is at:
* https://api-docs.firefly-iii.org/?urls.primaryName=2.0.0%20(v1)#/autocomplete/getObjectGroupsAC
- *
- * @param AutocompleteRequest $request
- *
- * @return JsonResponse
*/
public function objectGroups(AutocompleteRequest $request): JsonResponse
{
diff --git a/app/Api/V1/Controllers/Autocomplete/PiggyBankController.php b/app/Api/V1/Controllers/Autocomplete/PiggyBankController.php
index 74ac1c0498..3474edd3a1 100644
--- a/app/Api/V1/Controllers/Autocomplete/PiggyBankController.php
+++ b/app/Api/V1/Controllers/Autocomplete/PiggyBankController.php
@@ -62,10 +62,6 @@ class PiggyBankController extends Controller
/**
* This endpoint is documented at:
* https://api-docs.firefly-iii.org/?urls.primaryName=2.0.0%20(v1)#/autocomplete/getPiggiesAC
- *
- * @param AutocompleteRequest $request
- *
- * @return JsonResponse
*/
public function piggyBanks(AutocompleteRequest $request): JsonResponse
{
@@ -97,10 +93,6 @@ class PiggyBankController extends Controller
/**
* This endpoint is documented at:
* https://api-docs.firefly-iii.org/?urls.primaryName=2.0.0%20(v1)#/autocomplete/getPiggiesBalanceAC
- *
- * @param AutocompleteRequest $request
- *
- * @return JsonResponse
*/
public function piggyBanksWithBalance(AutocompleteRequest $request): JsonResponse
{
@@ -108,6 +100,7 @@ class PiggyBankController extends Controller
$piggies = $this->piggyRepository->searchPiggyBank($data['query'], $this->parameters->get('limit'));
$defaultCurrency = app('amount')->getDefaultCurrency();
$response = [];
+
/** @var PiggyBank $piggy */
foreach ($piggies as $piggy) {
$currency = $this->accountRepository->getAccountCurrency($piggy->account) ?? $defaultCurrency;
diff --git a/app/Api/V1/Controllers/Autocomplete/RecurrenceController.php b/app/Api/V1/Controllers/Autocomplete/RecurrenceController.php
index 74c1262ae4..cd60887127 100644
--- a/app/Api/V1/Controllers/Autocomplete/RecurrenceController.php
+++ b/app/Api/V1/Controllers/Autocomplete/RecurrenceController.php
@@ -56,10 +56,6 @@ class RecurrenceController extends Controller
/**
* This endpoint is documented at:
* * https://api-docs.firefly-iii.org/?urls.primaryName=2.0.0%20(v1)#/autocomplete/getRecurringAC
- *
- * @param AutocompleteRequest $request
- *
- * @return JsonResponse
*/
public function recurring(AutocompleteRequest $request): JsonResponse
{
diff --git a/app/Api/V1/Controllers/Autocomplete/RuleController.php b/app/Api/V1/Controllers/Autocomplete/RuleController.php
index 0f45c8fd44..a396fd4d4f 100644
--- a/app/Api/V1/Controllers/Autocomplete/RuleController.php
+++ b/app/Api/V1/Controllers/Autocomplete/RuleController.php
@@ -55,10 +55,6 @@ class RuleController extends Controller
/**
* This endpoint is documented at:
* * https://api-docs.firefly-iii.org/?urls.primaryName=2.0.0%20(v1)#/autocomplete/getRulesAC
- *
- * @param AutocompleteRequest $request
- *
- * @return JsonResponse
*/
public function rules(AutocompleteRequest $request): JsonResponse
{
diff --git a/app/Api/V1/Controllers/Autocomplete/RuleGroupController.php b/app/Api/V1/Controllers/Autocomplete/RuleGroupController.php
index c3c1af2503..7ea36c83dc 100644
--- a/app/Api/V1/Controllers/Autocomplete/RuleGroupController.php
+++ b/app/Api/V1/Controllers/Autocomplete/RuleGroupController.php
@@ -55,10 +55,6 @@ class RuleGroupController extends Controller
/**
* This endpoint is documented at:
* * https://api-docs.firefly-iii.org/?urls.primaryName=2.0.0%20(v1)#/autocomplete/getRuleGroupsAC
- *
- * @param AutocompleteRequest $request
- *
- * @return JsonResponse
*/
public function ruleGroups(AutocompleteRequest $request): JsonResponse
{
diff --git a/app/Api/V1/Controllers/Autocomplete/TagController.php b/app/Api/V1/Controllers/Autocomplete/TagController.php
index c0bf758e75..c79e4feb4e 100644
--- a/app/Api/V1/Controllers/Autocomplete/TagController.php
+++ b/app/Api/V1/Controllers/Autocomplete/TagController.php
@@ -58,17 +58,13 @@ class TagController extends Controller
/**
* This endpoint is documented at:
* * https://api-docs.firefly-iii.org/?urls.primaryName=2.0.0%20(v1)#/autocomplete/getTagAC
- *
- * @param AutocompleteRequest $request
- *
- * @return JsonResponse
*/
public function tags(AutocompleteRequest $request): JsonResponse
{
- $data = $request->getData();
-
+ $data = $request->getData();
$result = $this->repository->searchTags($data['query'], $this->parameters->get('limit'));
$array = [];
+
/** @var Tag $tag */
foreach ($result as $tag) {
$array[] = [
diff --git a/app/Api/V1/Controllers/Autocomplete/TransactionController.php b/app/Api/V1/Controllers/Autocomplete/TransactionController.php
index a8033ed624..0abe42e50d 100644
--- a/app/Api/V1/Controllers/Autocomplete/TransactionController.php
+++ b/app/Api/V1/Controllers/Autocomplete/TransactionController.php
@@ -63,15 +63,11 @@ class TransactionController extends Controller
/**
* This endpoint is documented at:
* * https://api-docs.firefly-iii.org/?urls.primaryName=2.0.0%20(v1)#/autocomplete/getTransactionsAC
- *
- * @param AutocompleteRequest $request
- *
- * @return JsonResponse
*/
public function transactions(AutocompleteRequest $request): JsonResponse
{
- $data = $request->getData();
- $result = $this->repository->searchJournalDescriptions($data['query'], $this->parameters->get('limit'));
+ $data = $request->getData();
+ $result = $this->repository->searchJournalDescriptions($data['query'], $this->parameters->get('limit'));
// limit and unique
$filtered = $result->unique('description');
@@ -93,10 +89,6 @@ class TransactionController extends Controller
/**
* This endpoint is documented at:
* * https://api-docs.firefly-iii.org/?urls.primaryName=2.0.0%20(v1)#/autocomplete/getTransactionsIDAC
- *
- * @param AutocompleteRequest $request
- *
- * @return JsonResponse
*/
public function transactionsWithID(AutocompleteRequest $request): JsonResponse
{
@@ -117,7 +109,7 @@ class TransactionController extends Controller
}
// limit and unique
- $array = [];
+ $array = [];
/** @var TransactionJournal $journal */
foreach ($result as $journal) {
diff --git a/app/Api/V1/Controllers/Autocomplete/TransactionTypeController.php b/app/Api/V1/Controllers/Autocomplete/TransactionTypeController.php
index 66f1f23a8f..272a23afa2 100644
--- a/app/Api/V1/Controllers/Autocomplete/TransactionTypeController.php
+++ b/app/Api/V1/Controllers/Autocomplete/TransactionTypeController.php
@@ -54,10 +54,6 @@ class TransactionTypeController extends Controller
/**
* This endpoint is documented at
* * https://api-docs.firefly-iii.org/?urls.primaryName=2.0.0%20(v1)#/autocomplete/getTransactionTypesAC
- *
- * @param AutocompleteRequest $request
- *
- * @return JsonResponse
*/
public function transactionTypes(AutocompleteRequest $request): JsonResponse
{
diff --git a/app/Api/V1/Controllers/Chart/AccountController.php b/app/Api/V1/Controllers/Chart/AccountController.php
index 5c554c17f2..de628ffcfb 100644
--- a/app/Api/V1/Controllers/Chart/AccountController.php
+++ b/app/Api/V1/Controllers/Chart/AccountController.php
@@ -30,14 +30,11 @@ use FireflyIII\Api\V1\Requests\Data\DateRequest;
use FireflyIII\Exceptions\FireflyException;
use FireflyIII\Models\Account;
use FireflyIII\Models\AccountType;
+use FireflyIII\Models\Preference;
use FireflyIII\Repositories\Account\AccountRepositoryInterface;
-use FireflyIII\Repositories\Currency\CurrencyRepositoryInterface;
use FireflyIII\Support\Http\Api\ApiSupport;
use FireflyIII\User;
use Illuminate\Http\JsonResponse;
-use JsonException;
-use Psr\Container\ContainerExceptionInterface;
-use Psr\Container\NotFoundExceptionInterface;
/**
* Class AccountController
@@ -46,13 +43,10 @@ class AccountController extends Controller
{
use ApiSupport;
- private CurrencyRepositoryInterface $currencyRepository;
- private AccountRepositoryInterface $repository;
+ private AccountRepositoryInterface $repository;
/**
* AccountController constructor.
- *
-
*/
public function __construct()
{
@@ -64,9 +58,6 @@ class AccountController extends Controller
$this->repository = app(AccountRepositoryInterface::class);
$this->repository->setUser($user);
- $this->currencyRepository = app(CurrencyRepositoryInterface::class);
- $this->currencyRepository->setUser($user);
-
return $next($request);
}
);
@@ -76,25 +67,23 @@ class AccountController extends Controller
* This endpoint is documented at:
* https://api-docs.firefly-iii.org/?urls.primaryName=2.0.0%20(v1)#/charts/getChartAccountOverview
*
- * @param DateRequest $request
- *
- * @return JsonResponse
* @throws FireflyException
- * @throws JsonException
- * @throws ContainerExceptionInterface
- * @throws NotFoundExceptionInterface
*/
public function overview(DateRequest $request): JsonResponse
{
// parameters for chart:
- $dates = $request->getAll();
+ $dates = $request->getAll();
+
/** @var Carbon $start */
- $start = $dates['start'];
+ $start = $dates['start'];
+
/** @var Carbon $end */
- $end = $dates['end'];
+ $end = $dates['end'];
// user's preferences
$defaultSet = $this->repository->getAccountsByType([AccountType::ASSET])->pluck('id')->toArray();
+
+ /** @var Preference $frontPage */
$frontPage = app('preferences')->get('frontPageAccounts', $defaultSet);
$default = app('amount')->getDefaultCurrency();
@@ -103,17 +92,17 @@ class AccountController extends Controller
$frontPage->save();
}
-
// get accounts:
- $accounts = $this->repository->getAccountsById($frontPage->data);
- $chartData = [];
+ $accounts = $this->repository->getAccountsById($frontPage->data);
+ $chartData = [];
+
/** @var Account $account */
foreach ($accounts as $account) {
- $currency = $this->repository->getAccountCurrency($account);
+ $currency = $this->repository->getAccountCurrency($account);
if (null === $currency) {
$currency = $default;
}
- $currentSet = [
+ $currentSet = [
'label' => $account->name,
'currency_id' => (string)$currency->id,
'currency_code' => $currency->code,
@@ -129,16 +118,16 @@ class AccountController extends Controller
$currentStart = clone $start;
$range = app('steam')->balanceInRange($account, $start, clone $end);
// 2022-10-11 this method no longer converts to float.
- $previous = array_values($range)[0];
+ $previous = array_values($range)[0];
while ($currentStart <= $end) {
- $format = $currentStart->format('Y-m-d');
- $label = $currentStart->toAtomString();
- $balance = array_key_exists($format, $range) ? $range[$format] : $previous;
- $previous = $balance;
+ $format = $currentStart->format('Y-m-d');
+ $label = $currentStart->toAtomString();
+ $balance = array_key_exists($format, $range) ? $range[$format] : $previous;
+ $previous = $balance;
$currentStart->addDay();
$currentSet['entries'][$label] = $balance;
}
- $chartData[] = $currentSet;
+ $chartData[] = $currentSet;
}
return response()->json($chartData);
diff --git a/app/Api/V1/Controllers/Controller.php b/app/Api/V1/Controllers/Controller.php
index 1e2b2b45d7..74160af153 100644
--- a/app/Api/V1/Controllers/Controller.php
+++ b/app/Api/V1/Controllers/Controller.php
@@ -27,22 +27,22 @@ namespace FireflyIII\Api\V1\Controllers;
use Carbon\Carbon;
use Carbon\Exceptions\InvalidDateException;
use Carbon\Exceptions\InvalidFormatException;
+use FireflyIII\Models\Preference;
+use FireflyIII\User;
use Illuminate\Foundation\Auth\Access\AuthorizesRequests;
use Illuminate\Foundation\Bus\DispatchesJobs;
use Illuminate\Foundation\Validation\ValidatesRequests;
use Illuminate\Routing\Controller as BaseController;
-use Illuminate\Support\Facades\Log;
use League\Fractal\Manager;
use League\Fractal\Serializer\JsonApiSerializer;
-use Psr\Container\ContainerExceptionInterface;
-use Psr\Container\NotFoundExceptionInterface;
use Symfony\Component\HttpFoundation\Exception\BadRequestException;
use Symfony\Component\HttpFoundation\ParameterBag;
/**
* Class Controller.
*
-
+ * @SuppressWarnings(PHPMD.CouplingBetweenObjects)
+ * @SuppressWarnings(PHPMD.NumberOfChildren)
*/
abstract class Controller extends BaseController
{
@@ -50,7 +50,9 @@ abstract class Controller extends BaseController
use DispatchesJobs;
use ValidatesRequests;
- protected const CONTENT_TYPE = 'application/vnd.api+json';
+ protected const string CONTENT_TYPE = 'application/vnd.api+json';
+
+ /** @var array */
protected array $allowedSort;
protected ParameterBag $parameters;
@@ -76,45 +78,42 @@ abstract class Controller extends BaseController
/**
* Method to grab all parameters from the URL.
- *
- * @return ParameterBag
- * @throws ContainerExceptionInterface
- * @throws NotFoundExceptionInterface
*/
private function getParameters(): ParameterBag
{
- $bag = new ParameterBag();
- $page = (int)request()->get('page');
+ $bag = new ParameterBag();
+ $page = (int)request()->get('page');
if ($page < 1) {
$page = 1;
}
- if ($page > pow(2, 16)) {
- $page = pow(2, 16);
+ if ($page > 2 ** 16) {
+ $page = 2 ** 16;
}
$bag->set('page', $page);
// some date fields:
- $dates = ['start', 'end', 'date'];
+ $dates = ['start', 'end', 'date'];
foreach ($dates as $field) {
$date = null;
+
try {
$date = request()->query->get($field);
} catch (BadRequestException $e) {
- Log::error(sprintf('Request field "%s" contains a non-scalar value. Value set to NULL.', $field));
- Log::error($e->getMessage());
- Log::error($e->getTraceAsString());
+ app('log')->error(sprintf('Request field "%s" contains a non-scalar value. Value set to NULL.', $field));
+ app('log')->error($e->getMessage());
+ app('log')->error($e->getTraceAsString());
$value = null;
}
- $obj = null;
+ $obj = null;
if (null !== $date) {
try {
- $obj = Carbon::parse($date);
- } catch (InvalidDateException | InvalidFormatException $e) {
+ $obj = Carbon::parse((string)$date);
+ } catch (InvalidDateException|InvalidFormatException $e) {
// don't care
app('log')->warning(
sprintf(
'Ignored invalid date "%s" in API controller parameter check: %s',
- substr($date, 0, 20),
+ substr((string)$date, 0, 20),
$e->getMessage()
)
);
@@ -129,17 +128,23 @@ abstract class Controller extends BaseController
try {
$value = request()->query->get($integer);
} catch (BadRequestException $e) {
- Log::error(sprintf('Request field "%s" contains a non-scalar value. Value set to NULL.', $integer));
- Log::error($e->getMessage());
- Log::error($e->getTraceAsString());
+ app('log')->error(sprintf('Request field "%s" contains a non-scalar value. Value set to NULL.', $integer));
+ app('log')->error($e->getMessage());
+ app('log')->error($e->getTraceAsString());
$value = null;
}
if (null !== $value) {
$bag->set($integer, (int)$value);
}
- if (null === $value && 'limit' === $integer && auth()->check()) {
+ if (null === $value
+ && 'limit' === $integer // @phpstan-ignore-line
+ && auth()->check()) {
// set default for user:
- $pageSize = (int)app('preferences')->getForUser(auth()->user(), 'listPageSize', 50)->data;
+ /** @var User $user */
+ $user = auth()->user();
+
+ /** @var Preference $pageSize */
+ $pageSize = (int)app('preferences')->getForUser($user, 'listPageSize', 50)->data;
$bag->set($integer, $pageSize);
}
}
@@ -148,26 +153,22 @@ abstract class Controller extends BaseController
return $this->getSortParameters($bag);
}
- /**
- * @param ParameterBag $bag
- *
- * @return ParameterBag
- */
private function getSortParameters(ParameterBag $bag): ParameterBag
{
$sortParameters = [];
+
try {
$param = (string)request()->query->get('sort');
} catch (BadRequestException $e) {
- Log::error('Request field "sort" contains a non-scalar value. Value set to NULL.');
- Log::error($e->getMessage());
- Log::error($e->getTraceAsString());
+ app('log')->error('Request field "sort" contains a non-scalar value. Value set to NULL.');
+ app('log')->error($e->getMessage());
+ app('log')->error($e->getTraceAsString());
$param = '';
}
if ('' === $param) {
return $bag;
}
- $parts = explode(',', $param);
+ $parts = explode(',', $param);
foreach ($parts as $part) {
$part = trim($part);
$direction = 'asc';
@@ -186,8 +187,6 @@ abstract class Controller extends BaseController
/**
* Method to help build URL's.
- *
- * @return string
*/
final protected function buildParams(): string
{
@@ -199,22 +198,20 @@ abstract class Controller extends BaseController
}
if ($value instanceof Carbon) {
$params[$key] = $value->format('Y-m-d');
+
continue;
}
$params[$key] = $value;
}
- return $return . http_build_query($params);
+ return $return.http_build_query($params);
}
- /**
- * @return Manager
- */
final protected function getManager(): Manager
{
// create some objects:
$manager = new Manager();
- $baseUrl = request()->getSchemeAndHttpHost() . '/api/v1';
+ $baseUrl = request()->getSchemeAndHttpHost().'/api/v1';
$manager->setSerializer(new JsonApiSerializer($baseUrl));
return $manager;
diff --git a/app/Api/V1/Controllers/Data/Bulk/TransactionController.php b/app/Api/V1/Controllers/Data/Bulk/TransactionController.php
index 56afbde1cd..869c17ae87 100644
--- a/app/Api/V1/Controllers/Data/Bulk/TransactionController.php
+++ b/app/Api/V1/Controllers/Data/Bulk/TransactionController.php
@@ -44,9 +44,6 @@ class TransactionController extends Controller
{
private AccountRepositoryInterface $repository;
- /**
- *
- */
public function __construct()
{
parent::__construct();
@@ -63,10 +60,6 @@ class TransactionController extends Controller
/**
* This endpoint is documented at:
* https://api-docs.firefly-iii.org/?urls.primaryName=2.0.0%20(v1)#/data/bulkUpdateTransactions
- *
- * @param TransactionRequest $request
- *
- * @return JsonResponse
*/
public function update(TransactionRequest $request): JsonResponse
{
@@ -76,12 +69,12 @@ class TransactionController extends Controller
// this deserves better code, but for now a loop of basic if-statements
// to respond to what is in the $query.
// this is OK because only one thing can be in the query at the moment.
- if ($this->updatesTransactionAccount($params)) {
+ if ($this->isUpdateTransactionAccount($params)) {
$original = $this->repository->find((int)$params['where']['account_id']);
$destination = $this->repository->find((int)$params['update']['account_id']);
/** @var AccountDestroyService $service */
- $service = app(AccountDestroyService::class);
+ $service = app(AccountDestroyService::class);
$service->moveTransactions($original, $destination);
}
@@ -89,11 +82,9 @@ class TransactionController extends Controller
}
/**
- * @param array $params
- *
- * @return bool
+ * @param array> $params
*/
- private function updatesTransactionAccount(array $params): bool
+ private function isUpdateTransactionAccount(array $params): bool
{
return array_key_exists('account_id', $params['where']) && array_key_exists('account_id', $params['update']);
}
diff --git a/app/Api/V1/Controllers/Data/DestroyController.php b/app/Api/V1/Controllers/Data/DestroyController.php
index 8b22e7c673..f0f044b768 100644
--- a/app/Api/V1/Controllers/Data/DestroyController.php
+++ b/app/Api/V1/Controllers/Data/DestroyController.php
@@ -58,160 +58,53 @@ class DestroyController extends Controller
* This endpoint is documented at:
* https://api-docs.firefly-iii.org/?urls.primaryName=2.0.0%20(v1)#/data/destroyData
*
- * @param DestroyRequest $request
- *
- * @return JsonResponse
* @throws FireflyException
*/
public function destroy(DestroyRequest $request): JsonResponse
{
- $objects = $request->getObjects();
- $this->unused = $request->boolean('unused', false);
- switch ($objects) {
- default:
- throw new FireflyException(sprintf('200033: This endpoint can\'t handle object "%s"', $objects));
- case 'budgets':
- $this->destroyBudgets();
- break;
- case 'bills':
- $this->destroyBills();
- break;
- case 'piggy_banks':
- $this->destroyPiggyBanks();
- break;
- case 'rules':
- $this->destroyRules();
- break;
- case 'recurring':
- $this->destroyRecurringTransactions();
- break;
- case 'categories':
- $this->destroyCategories();
- break;
- case 'tags':
- $this->destroyTags();
- break;
- case 'object_groups':
- $this->destroyObjectGroups();
- break;
- case 'not_assets_liabilities':
- $this->destroyAccounts(
- [
- AccountType::BENEFICIARY,
- AccountType::CASH,
- AccountType::CREDITCARD,
- AccountType::DEFAULT,
- AccountType::EXPENSE,
- AccountType::IMPORT,
- AccountType::INITIAL_BALANCE,
- AccountType::LIABILITY_CREDIT,
- AccountType::RECONCILIATION,
- AccountType::REVENUE,
- ]
- );
- break;
- case 'accounts':
- $this->destroyAccounts(
- [
- AccountType::ASSET,
- AccountType::BENEFICIARY,
- AccountType::CASH,
- AccountType::CREDITCARD,
- AccountType::DEBT,
- AccountType::DEFAULT,
- AccountType::EXPENSE,
- AccountType::IMPORT,
- AccountType::INITIAL_BALANCE,
- AccountType::LIABILITY_CREDIT,
- AccountType::LOAN,
- AccountType::MORTGAGE,
- AccountType::RECONCILIATION,
- AccountType::REVENUE,
- ]
- );
- break;
- case 'asset_accounts':
- $this->destroyAccounts(
- [
- AccountType::ASSET,
- AccountType::DEFAULT,
- ]
- );
- break;
- case 'expense_accounts':
- $this->destroyAccounts(
- [
- AccountType::BENEFICIARY,
- AccountType::EXPENSE,
- ]
- );
- break;
- case 'revenue_accounts':
- $this->destroyAccounts(
- [
- AccountType::REVENUE,
- ]
- );
- break;
- case 'liabilities':
- $this->destroyAccounts(
- [
- AccountType::DEBT,
- AccountType::LOAN,
- AccountType::MORTGAGE,
- AccountType::CREDITCARD,
- ]
- );
- break;
- case 'transactions':
- $this->destroyTransactions(
- [
- TransactionType::WITHDRAWAL,
- TransactionType::DEPOSIT,
- TransactionType::TRANSFER,
- TransactionType::RECONCILIATION,
- TransactionType::OPENING_BALANCE,
- ]
- );
- break;
- case 'withdrawals':
- $this->destroyTransactions(
- [
- TransactionType::WITHDRAWAL,
- ]
- );
- break;
- case 'deposits':
- $this->destroyTransactions(
- [
- TransactionType::DEPOSIT,
- ]
- );
- break;
- case 'transfers':
- $this->destroyTransactions(
- [
- TransactionType::TRANSFER,
- ]
- );
- break;
- }
+ $objects = $request->getObjects();
+ $this->unused = $request->boolean('unused', false);
+
+ $allExceptAssets = [AccountType::BENEFICIARY, AccountType::CASH, AccountType::CREDITCARD, AccountType::DEFAULT, AccountType::EXPENSE, AccountType::IMPORT, AccountType::INITIAL_BALANCE, AccountType::LIABILITY_CREDIT, AccountType::RECONCILIATION, AccountType::REVENUE];
+ $all = [AccountType::ASSET, AccountType::BENEFICIARY, AccountType::CASH, AccountType::CREDITCARD, AccountType::DEBT, AccountType::DEFAULT, AccountType::EXPENSE, AccountType::IMPORT, AccountType::INITIAL_BALANCE, AccountType::LIABILITY_CREDIT, AccountType::LOAN, AccountType::MORTGAGE, AccountType::RECONCILIATION];
+ $liabilities = [AccountType::DEBT, AccountType::LOAN, AccountType::MORTGAGE, AccountType::CREDITCARD];
+ $transactions = [TransactionType::WITHDRAWAL, TransactionType::DEPOSIT, TransactionType::TRANSFER, TransactionType::RECONCILIATION];
+
+ match ($objects) {
+ 'budgets' => $this->destroyBudgets(),
+ 'bills' => $this->destroyBills(),
+ 'piggy_banks' => $this->destroyPiggyBanks(),
+ 'rules' => $this->destroyRules(),
+ 'recurring' => $this->destroyRecurringTransactions(),
+ 'categories' => $this->destroyCategories(),
+ 'tags' => $this->destroyTags(),
+ 'object_groups' => $this->destroyObjectGroups(),
+ 'not_assets_liabilities' => $this->destroyAccounts($allExceptAssets),
+ 'accounts' => $this->destroyAccounts($all),
+ 'asset_accounts' => $this->destroyAccounts([AccountType::ASSET, AccountType::DEFAULT]),
+ 'expense_accounts' => $this->destroyAccounts([AccountType::BENEFICIARY, AccountType::EXPENSE]),
+ 'revenue_accounts' => $this->destroyAccounts([AccountType::REVENUE]),
+ 'liabilities' => $this->destroyAccounts($liabilities),
+ 'transactions' => $this->destroyTransactions($transactions),
+ 'withdrawals' => $this->destroyTransactions([TransactionType::WITHDRAWAL]),
+ 'deposits' => $this->destroyTransactions([TransactionType::DEPOSIT]),
+ 'transfers' => $this->destroyTransactions([TransactionType::TRANSFER]),
+ default => throw new FireflyException(sprintf('200033: This endpoint can\'t handle object "%s"', $objects)),
+ };
+
app('preferences')->mark();
return response()->json([], 204);
}
- /**
- *
- */
private function destroyBudgets(): void
{
/** @var AvailableBudgetRepositoryInterface $abRepository */
- $abRepository = app(AvailableBudgetRepositoryInterface::class);
+ $abRepository = app(AvailableBudgetRepositoryInterface::class);
$abRepository->destroyAll();
/** @var BudgetLimitRepositoryInterface $blRepository */
- $blRepository = app(BudgetLimitRepositoryInterface::class);
+ $blRepository = app(BudgetLimitRepositoryInterface::class);
$blRepository->destroyAll();
/** @var BudgetRepositoryInterface $budgetRepository */
@@ -219,9 +112,6 @@ class DestroyController extends Controller
$budgetRepository->destroyAll();
}
- /**
- *
- */
private function destroyBills(): void
{
/** @var BillRepositoryInterface $repository */
@@ -229,9 +119,6 @@ class DestroyController extends Controller
$repository->destroyAll();
}
- /**
- *
- */
private function destroyPiggyBanks(): void
{
/** @var PiggyBankRepositoryInterface $repository */
@@ -239,9 +126,6 @@ class DestroyController extends Controller
$repository->destroyAll();
}
- /**
- *
- */
private function destroyRules(): void
{
/** @var RuleGroupRepositoryInterface $repository */
@@ -249,9 +133,6 @@ class DestroyController extends Controller
$repository->destroyAll();
}
- /**
- *
- */
private function destroyRecurringTransactions(): void
{
/** @var RecurringRepositoryInterface $repository */
@@ -259,9 +140,6 @@ class DestroyController extends Controller
$repository->destroyAll();
}
- /**
- *
- */
private function destroyCategories(): void
{
/** @var CategoryRepositoryInterface $categoryRepos */
@@ -269,9 +147,6 @@ class DestroyController extends Controller
$categoryRepos->destroyAll();
}
- /**
- *
- */
private function destroyTags(): void
{
/** @var TagRepositoryInterface $tagRepository */
@@ -279,9 +154,6 @@ class DestroyController extends Controller
$tagRepository->destroyAll();
}
- /**
- * @return void
- */
private function destroyObjectGroups(): void
{
/** @var ObjectGroupRepositoryInterface $repository */
@@ -290,7 +162,7 @@ class DestroyController extends Controller
}
/**
- * @param array $types
+ * @param array $types
*/
private function destroyAccounts(array $types): void
{
@@ -303,19 +175,22 @@ class DestroyController extends Controller
foreach ($collection as $account) {
$count = $account->transactions()->count();
if (true === $this->unused && 0 === $count) {
- Log::info(sprintf('Deleted unused account #%d "%s"', $account->id, $account->name));
+ app('log')->info(sprintf('Deleted unused account #%d "%s"', $account->id, $account->name));
+ Log::channel('audit')->info(sprintf('Deleted unused account #%d "%s"', $account->id, $account->name));
$service->destroy($account, null);
+
continue;
}
if (false === $this->unused) {
- Log::info(sprintf('Deleting account #%d "%s"', $account->id, $account->name));
+ app('log')->info(sprintf('Deleting account #%d "%s"', $account->id, $account->name));
+ Log::channel('audit')->warning(sprintf('Deleted account #%d "%s"', $account->id, $account->name));
$service->destroy($account, null);
}
}
}
/**
- * @param array $types
+ * @param array $types
*/
private function destroyTransactions(array $types): void
{
@@ -323,6 +198,7 @@ class DestroyController extends Controller
$repository = app(JournalRepositoryInterface::class);
$journals = $repository->findByType($types);
$service = app(JournalDestroyService::class);
+
/** @var TransactionJournal $journal */
foreach ($journals as $journal) {
$service->destroy($journal);
diff --git a/app/Api/V1/Controllers/Data/Export/ExportController.php b/app/Api/V1/Controllers/Data/Export/ExportController.php
index c722088a2e..8eda16cf8f 100644
--- a/app/Api/V1/Controllers/Data/Export/ExportController.php
+++ b/app/Api/V1/Controllers/Data/Export/ExportController.php
@@ -29,8 +29,6 @@ use FireflyIII\Api\V1\Requests\Data\Export\ExportRequest;
use FireflyIII\Exceptions\FireflyException;
use FireflyIII\Support\Export\ExportDataGenerator;
use Illuminate\Http\Response as LaravelResponse;
-use Psr\Container\ContainerExceptionInterface;
-use Psr\Container\NotFoundExceptionInterface;
/**
* Class ExportController
@@ -59,10 +57,9 @@ class ExportController extends Controller
* This endpoint is documented at:
* https://api-docs.firefly-iii.org/?urls.primaryName=2.0.0%20(v1)#/data/exportAccounts
*
- * @param ExportRequest $request
- *
- * @return LaravelResponse
* @throws FireflyException
+ *
+ * @SuppressWarnings(PHPMD.UnusedFormalParameter)
*/
public function accounts(ExportRequest $request): LaravelResponse
{
@@ -72,12 +69,7 @@ class ExportController extends Controller
}
/**
- * @param string $key
- *
- * @return LaravelResponse
* @throws FireflyException
- * @throws ContainerExceptionInterface
- * @throws NotFoundExceptionInterface
*/
private function returnExport(string $key): LaravelResponse
{
@@ -90,13 +82,14 @@ class ExportController extends Controller
$response
->header('Content-Description', 'File Transfer')
->header('Content-Type', 'application/octet-stream')
- ->header('Content-Disposition', 'attachment; filename=' . $fileName)
+ ->header('Content-Disposition', 'attachment; filename='.$fileName)
->header('Content-Transfer-Encoding', 'binary')
->header('Connection', 'Keep-Alive')
->header('Expires', '0')
->header('Cache-Control', 'must-revalidate, post-check=0, pre-check=0')
->header('Pragma', 'public')
- ->header('Content-Length', (string)strlen($data[$key]));
+ ->header('Content-Length', (string)strlen($data[$key]))
+ ;
return $response;
}
@@ -105,10 +98,9 @@ class ExportController extends Controller
* This endpoint is documented at:
* https://api-docs.firefly-iii.org/?urls.primaryName=2.0.0%20(v1)#/data/exportBills
*
- * @param ExportRequest $request
- *
- * @return LaravelResponse
* @throws FireflyException
+ *
+ * @SuppressWarnings(PHPMD.UnusedFormalParameter)
*/
public function bills(ExportRequest $request): LaravelResponse
{
@@ -121,10 +113,9 @@ class ExportController extends Controller
* This endpoint is documented at:
* https://api-docs.firefly-iii.org/?urls.primaryName=2.0.0%20(v1)#/data/exportBudgets
*
- * @param ExportRequest $request
- *
- * @return LaravelResponse
* @throws FireflyException
+ *
+ * @SuppressWarnings(PHPMD.UnusedFormalParameter)
*/
public function budgets(ExportRequest $request): LaravelResponse
{
@@ -137,10 +128,9 @@ class ExportController extends Controller
* This endpoint is documented at:
* https://api-docs.firefly-iii.org/?urls.primaryName=2.0.0%20(v1)#/data/exportCategories
*
- * @param ExportRequest $request
- *
- * @return LaravelResponse
* @throws FireflyException
+ *
+ * @SuppressWarnings(PHPMD.UnusedFormalParameter)
*/
public function categories(ExportRequest $request): LaravelResponse
{
@@ -153,10 +143,9 @@ class ExportController extends Controller
* This endpoint is documented at:
* https://api-docs.firefly-iii.org/?urls.primaryName=2.0.0%20(v1)#/data/exportPiggies
*
- * @param ExportRequest $request
- *
- * @return LaravelResponse
* @throws FireflyException
+ *
+ * @SuppressWarnings(PHPMD.UnusedFormalParameter)
*/
public function piggyBanks(ExportRequest $request): LaravelResponse
{
@@ -169,10 +158,9 @@ class ExportController extends Controller
* This endpoint is documented at:
* https://api-docs.firefly-iii.org/?urls.primaryName=2.0.0%20(v1)#/data/exportRecurring
*
- * @param ExportRequest $request
- *
- * @return LaravelResponse
* @throws FireflyException
+ *
+ * @SuppressWarnings(PHPMD.UnusedFormalParameter)
*/
public function recurring(ExportRequest $request): LaravelResponse
{
@@ -185,10 +173,9 @@ class ExportController extends Controller
* This endpoint is documented at:
* https://api-docs.firefly-iii.org/?urls.primaryName=2.0.0%20(v1)#/data/exportRules
*
- * @param ExportRequest $request
- *
- * @return LaravelResponse
* @throws FireflyException
+ *
+ * @SuppressWarnings(PHPMD.UnusedFormalParameter)
*/
public function rules(ExportRequest $request): LaravelResponse
{
@@ -201,10 +188,9 @@ class ExportController extends Controller
* This endpoint is documented at:
* https://api-docs.firefly-iii.org/?urls.primaryName=2.0.0%20(v1)#/data/exportTags
*
- * @param ExportRequest $request
- *
- * @return LaravelResponse
* @throws FireflyException
+ *
+ * @SuppressWarnings(PHPMD.UnusedFormalParameter)
*/
public function tags(ExportRequest $request): LaravelResponse
{
@@ -217,9 +203,6 @@ class ExportController extends Controller
* This endpoint is documented at:
* https://api-docs.firefly-iii.org/?urls.primaryName=2.0.0%20(v1)#/data/exportTransactions
*
- * @param ExportRequest $request
- *
- * @return LaravelResponse
* @throws FireflyException
*/
public function transactions(ExportRequest $request): LaravelResponse
diff --git a/app/Api/V1/Controllers/Data/PurgeController.php b/app/Api/V1/Controllers/Data/PurgeController.php
index b3af771d6d..593e60c623 100644
--- a/app/Api/V1/Controllers/Data/PurgeController.php
+++ b/app/Api/V1/Controllers/Data/PurgeController.php
@@ -35,6 +35,7 @@ use FireflyIII\Models\RuleGroup;
use FireflyIII\Models\Tag;
use FireflyIII\Models\TransactionGroup;
use FireflyIII\Models\TransactionJournal;
+use FireflyIII\User;
use Illuminate\Http\JsonResponse;
/**
@@ -46,11 +47,10 @@ class PurgeController extends Controller
* TODO cleanup and use repositories.
* This endpoint is documented at:
* https://api-docs.firefly-iii.org/?urls.primaryName=2.0.0%20(v1)#/data/purgeData
- *
- * @return JsonResponse
*/
public function purge(): JsonResponse
{
+ /** @var User $user */
$user = auth()->user();
// some manual code, too lazy to call all repositories.
@@ -62,8 +62,10 @@ class PurgeController extends Controller
Bill::whereUserId($user->id)->onlyTrashed()->forceDelete();
// piggies
- $set = PiggyBank::leftJoin('accounts', 'accounts.id', 'piggy_banks.account_id')
- ->where('accounts.user_id', $user->id)->onlyTrashed()->get(['piggy_banks.*']);
+ $set = PiggyBank::leftJoin('accounts', 'accounts.id', 'piggy_banks.account_id')
+ ->where('accounts.user_id', $user->id)->onlyTrashed()->get(['piggy_banks.*'])
+ ;
+
/** @var PiggyBank $piggy */
foreach ($set as $piggy) {
$piggy->forceDelete();
@@ -84,7 +86,6 @@ class PurgeController extends Controller
// tags
Tag::whereUserId($user->id)->onlyTrashed()->forceDelete();
-
// accounts
Account::whereUserId($user->id)->onlyTrashed()->forceDelete();
diff --git a/app/Api/V1/Controllers/Insight/Expense/AccountController.php b/app/Api/V1/Controllers/Insight/Expense/AccountController.php
index ad9d660d5e..6649561c78 100644
--- a/app/Api/V1/Controllers/Insight/Expense/AccountController.php
+++ b/app/Api/V1/Controllers/Insight/Expense/AccountController.php
@@ -28,12 +28,10 @@ use FireflyIII\Api\V1\Controllers\Controller;
use FireflyIII\Api\V1\Requests\Insight\GenericRequest;
use FireflyIII\Repositories\Account\AccountRepositoryInterface;
use FireflyIII\Repositories\Account\OperationsRepositoryInterface;
-use FireflyIII\Repositories\Currency\CurrencyRepositoryInterface;
use FireflyIII\Support\Http\Api\ApiSupport;
use Illuminate\Http\JsonResponse;
/**
- *
* Class AccountController
*
* Shows expense information grouped or limited by date.
@@ -43,27 +41,21 @@ class AccountController extends Controller
{
use ApiSupport;
- private CurrencyRepositoryInterface $currencyRepository;
private OperationsRepositoryInterface $opsRepository;
private AccountRepositoryInterface $repository;
/**
* AccountController constructor.
- *
-
*/
public function __construct()
{
parent::__construct();
$this->middleware(
function ($request, $next) {
- $user = auth()->user();
- $this->repository = app(AccountRepositoryInterface::class);
+ $user = auth()->user();
+ $this->repository = app(AccountRepositoryInterface::class);
$this->repository->setUser($user);
- $this->currencyRepository = app(CurrencyRepositoryInterface::class);
- $this->currencyRepository->setUser($user);
-
$this->opsRepository = app(OperationsRepositoryInterface::class);
$this->opsRepository->setUser($user);
@@ -75,10 +67,6 @@ class AccountController extends Controller
/**
* This endpoint is documented at:
* https://api-docs.firefly-iii.org/?urls.primaryName=2.0.0%20(v1)#/insight/insightExpenseAsset
- *
- * @param GenericRequest $request
- *
- * @return JsonResponse
*/
public function asset(GenericRequest $request): JsonResponse
{
@@ -106,10 +94,6 @@ class AccountController extends Controller
/**
* This endpoint is documented at:
* https://api-docs.firefly-iii.org/?urls.primaryName=2.0.0%20(v1)#/insight/insightExpenseExpense
- *
- * @param GenericRequest $request
- *
- * @return JsonResponse
*/
public function expense(GenericRequest $request): JsonResponse
{
diff --git a/app/Api/V1/Controllers/Insight/Expense/BillController.php b/app/Api/V1/Controllers/Insight/Expense/BillController.php
index a584c55913..bb88f850b1 100644
--- a/app/Api/V1/Controllers/Insight/Expense/BillController.php
+++ b/app/Api/V1/Controllers/Insight/Expense/BillController.php
@@ -60,18 +60,14 @@ class BillController extends Controller
* https://api-docs.firefly-iii.org/?urls.primaryName=2.0.0%20(v1)#/insight/insightExpenseBill
*
* Expenses per bill, possibly filtered by bill and account.
- *
- * @param GenericRequest $request
- *
- * @return JsonResponse
*/
public function bill(GenericRequest $request): JsonResponse
{
- $accounts = $request->getAssetAccounts();
- $bills = $request->getBills();
- $start = $request->getStart();
- $end = $request->getEnd();
- $response = [];
+ $accounts = $request->getAssetAccounts();
+ $bills = $request->getBills();
+ $start = $request->getStart();
+ $end = $request->getEnd();
+ $response = [];
// get all bills:
if (0 === $bills->count()) {
@@ -79,7 +75,7 @@ class BillController extends Controller
}
// collect all expenses in this period (regardless of type) by the given bills and accounts.
- $collector = app(GroupCollectorInterface::class);
+ $collector = app(GroupCollectorInterface::class);
$collector->setTypes([TransactionType::WITHDRAWAL])->setRange($start, $end)->setSourceAccounts($accounts);
$collector->setBills($bills);
@@ -92,7 +88,7 @@ class BillController extends Controller
$foreignKey = sprintf('%d-%d', $billId, $foreignCurrencyId);
if (0 !== $currencyId) {
- $response[$key] = $response[$key] ?? [
+ $response[$key] ??= [
'id' => (string)$billId,
'name' => $journal['bill_name'],
'difference' => '0',
@@ -104,7 +100,7 @@ class BillController extends Controller
$response[$key]['difference_float'] = (float)$response[$key]['difference']; // intentional float
}
if (0 !== $foreignCurrencyId) {
- $response[$foreignKey] = $response[$foreignKey] ?? [
+ $response[$foreignKey] ??= [
'difference' => '0',
'difference_float' => 0,
'currency_id' => (string)$foreignCurrencyId,
@@ -123,20 +119,16 @@ class BillController extends Controller
* https://api-docs.firefly-iii.org/?urls.primaryName=2.0.0%20(v1)#/insight/insightExpenseNoBill
*
* Expenses for no bill filtered by account.
- *
- * @param GenericRequest $request
- *
- * @return JsonResponse
*/
public function noBill(GenericRequest $request): JsonResponse
{
- $accounts = $request->getAssetAccounts();
- $start = $request->getStart();
- $end = $request->getEnd();
- $response = [];
+ $accounts = $request->getAssetAccounts();
+ $start = $request->getStart();
+ $end = $request->getEnd();
+ $response = [];
// collect all expenses in this period (regardless of type) by the given bills and accounts.
- $collector = app(GroupCollectorInterface::class);
+ $collector = app(GroupCollectorInterface::class);
$collector->setTypes([TransactionType::WITHDRAWAL])->setRange($start, $end)->setSourceAccounts($accounts);
$collector->withoutBill();
@@ -147,7 +139,7 @@ class BillController extends Controller
$foreignCurrencyId = (int)$journal['foreign_currency_id'];
if (0 !== $currencyId) {
- $response[$currencyId] = $response[$currencyId] ?? [
+ $response[$currencyId] ??= [
'difference' => '0',
'difference_float' => 0,
'currency_id' => (string)$currencyId,
@@ -157,7 +149,7 @@ class BillController extends Controller
$response[$currencyId]['difference_float'] = (float)$response[$currencyId]['difference']; // intentional float
}
if (0 !== $foreignCurrencyId) {
- $response[$foreignCurrencyId] = $response[$foreignCurrencyId] ?? [
+ $response[$foreignCurrencyId] ??= [
'difference' => '0',
'difference_float' => 0,
'currency_id' => (string)$foreignCurrencyId,
diff --git a/app/Api/V1/Controllers/Insight/Expense/BudgetController.php b/app/Api/V1/Controllers/Insight/Expense/BudgetController.php
index 27e600482b..475ea2f5fb 100644
--- a/app/Api/V1/Controllers/Insight/Expense/BudgetController.php
+++ b/app/Api/V1/Controllers/Insight/Expense/BudgetController.php
@@ -43,8 +43,6 @@ class BudgetController extends Controller
/**
* AccountController constructor.
- *
-
*/
public function __construct()
{
@@ -67,10 +65,6 @@ class BudgetController extends Controller
/**
* This endpoint is documented at:
* https://api-docs.firefly-iii.org/?urls.primaryName=2.0.0%20(v1)#/insight/insightExpenseBudget
- *
- * @param GenericRequest $request
- *
- * @return JsonResponse
*/
public function budget(GenericRequest $request): JsonResponse
{
@@ -82,9 +76,11 @@ class BudgetController extends Controller
if (0 === $budgets->count()) {
$budgets = $this->repository->getActiveBudgets();
}
+
/** @var Budget $budget */
foreach ($budgets as $budget) {
$expenses = $this->opsRepository->sumExpenses($start, $end, $assetAccounts, new Collection([$budget]));
+
/** @var array $expense */
foreach ($expenses as $expense) {
$result[] = [
@@ -104,10 +100,6 @@ class BudgetController extends Controller
/**
* This endpoint is documented at:
* https://api-docs.firefly-iii.org/?urls.primaryName=2.0.0%20(v1)#/insight/insightExpenseNoBudget
- *
- * @param GenericRequest $request
- *
- * @return JsonResponse
*/
public function noBudget(GenericRequest $request): JsonResponse
{
@@ -116,6 +108,7 @@ class BudgetController extends Controller
$assetAccounts = $request->getAssetAccounts();
$result = [];
$expenses = $this->noRepository->sumExpenses($start, $end, $assetAccounts);
+
/** @var array $expense */
foreach ($expenses as $expense) {
$result[] = [
diff --git a/app/Api/V1/Controllers/Insight/Expense/CategoryController.php b/app/Api/V1/Controllers/Insight/Expense/CategoryController.php
index b7972097f7..5ee6e77378 100644
--- a/app/Api/V1/Controllers/Insight/Expense/CategoryController.php
+++ b/app/Api/V1/Controllers/Insight/Expense/CategoryController.php
@@ -44,8 +44,6 @@ class CategoryController extends Controller
/**
* AccountController constructor.
- *
-
*/
public function __construct()
{
@@ -68,10 +66,6 @@ class CategoryController extends Controller
/**
* This endpoint is documented at:
* https://api-docs.firefly-iii.org/?urls.primaryName=2.0.0%20(v1)#/insight/insightTransferCategory
- *
- * @param GenericRequest $request
- *
- * @return JsonResponse
*/
public function category(GenericRequest $request): JsonResponse
{
@@ -83,9 +77,11 @@ class CategoryController extends Controller
if (0 === $categories->count()) {
$categories = $this->repository->getCategories();
}
+
/** @var Category $category */
foreach ($categories as $category) {
$expenses = $this->opsRepository->sumExpenses($start, $end, $assetAccounts, new Collection([$category]));
+
/** @var array $expense */
foreach ($expenses as $expense) {
$result[] = [
@@ -105,10 +101,6 @@ class CategoryController extends Controller
/**
* This endpoint is documented at:
* https://api-docs.firefly-iii.org/?urls.primaryName=2.0.0%20(v1)#/insight/insightTransferNoCategory
- *
- * @param GenericRequest $request
- *
- * @return JsonResponse
*/
public function noCategory(GenericRequest $request): JsonResponse
{
@@ -117,6 +109,7 @@ class CategoryController extends Controller
$assetAccounts = $request->getAssetAccounts();
$result = [];
$expenses = $this->noRepository->sumExpenses($start, $end, $assetAccounts);
+
/** @var array $expense */
foreach ($expenses as $expense) {
$result[] = [
diff --git a/app/Api/V1/Controllers/Insight/Expense/PeriodController.php b/app/Api/V1/Controllers/Insight/Expense/PeriodController.php
index eb583d0693..ad708ecd2d 100644
--- a/app/Api/V1/Controllers/Insight/Expense/PeriodController.php
+++ b/app/Api/V1/Controllers/Insight/Expense/PeriodController.php
@@ -37,20 +37,16 @@ class PeriodController extends Controller
/**
* This endpoint is documented at:
* https://api-docs.firefly-iii.org/?urls.primaryName=2.0.0%20(v1)#/insight/insightExpenseTotal
- *
- * @param GenericRequest $request
- *
- * @return JsonResponse
*/
public function total(GenericRequest $request): JsonResponse
{
- $accounts = $request->getAssetAccounts();
- $start = $request->getStart();
- $end = $request->getEnd();
- $response = [];
+ $accounts = $request->getAssetAccounts();
+ $start = $request->getStart();
+ $end = $request->getEnd();
+ $response = [];
// collect all expenses in this period (regardless of type)
- $collector = app(GroupCollectorInterface::class);
+ $collector = app(GroupCollectorInterface::class);
$collector->setTypes([TransactionType::WITHDRAWAL])->setRange($start, $end)->setSourceAccounts($accounts);
$genericSet = $collector->getExtractedJournals();
foreach ($genericSet as $journal) {
@@ -58,7 +54,7 @@ class PeriodController extends Controller
$foreignCurrencyId = (int)$journal['foreign_currency_id'];
if (0 !== $currencyId) {
- $response[$currencyId] = $response[$currencyId] ?? [
+ $response[$currencyId] ??= [
'difference' => '0',
'difference_float' => 0,
'currency_id' => (string)$currencyId,
@@ -68,7 +64,7 @@ class PeriodController extends Controller
$response[$currencyId]['difference_float'] = (float)$response[$currencyId]['difference']; // intentional float
}
if (0 !== $foreignCurrencyId) {
- $response[$foreignCurrencyId] = $response[$foreignCurrencyId] ?? [
+ $response[$foreignCurrencyId] ??= [
'difference' => '0',
'difference_float' => 0,
'currency_id' => (string)$foreignCurrencyId,
diff --git a/app/Api/V1/Controllers/Insight/Expense/TagController.php b/app/Api/V1/Controllers/Insight/Expense/TagController.php
index 9068f402f6..b2b2b6b4ea 100644
--- a/app/Api/V1/Controllers/Insight/Expense/TagController.php
+++ b/app/Api/V1/Controllers/Insight/Expense/TagController.php
@@ -59,20 +59,16 @@ class TagController extends Controller
* https://api-docs.firefly-iii.org/?urls.primaryName=2.0.0%20(v1)#/insight/insightExpenseNoTag
*
* Expenses for no tag filtered by account.
- *
- * @param GenericRequest $request
- *
- * @return JsonResponse
*/
public function noTag(GenericRequest $request): JsonResponse
{
- $accounts = $request->getAssetAccounts();
- $start = $request->getStart();
- $end = $request->getEnd();
- $response = [];
+ $accounts = $request->getAssetAccounts();
+ $start = $request->getStart();
+ $end = $request->getEnd();
+ $response = [];
// collect all expenses in this period (regardless of type) by the given bills and accounts.
- $collector = app(GroupCollectorInterface::class);
+ $collector = app(GroupCollectorInterface::class);
$collector->setTypes([TransactionType::WITHDRAWAL])->setRange($start, $end)->setSourceAccounts($accounts);
$collector->withoutTags();
@@ -83,7 +79,7 @@ class TagController extends Controller
$foreignCurrencyId = (int)$journal['foreign_currency_id'];
if (0 !== $currencyId) {
- $response[$currencyId] = $response[$currencyId] ?? [
+ $response[$currencyId] ??= [
'difference' => '0',
'difference_float' => 0,
'currency_id' => (string)$currencyId,
@@ -93,7 +89,7 @@ class TagController extends Controller
$response[$currencyId]['difference_float'] = (float)$response[$currencyId]['difference']; // float but on purpose.
}
if (0 !== $foreignCurrencyId) {
- $response[$foreignCurrencyId] = $response[$foreignCurrencyId] ?? [
+ $response[$foreignCurrencyId] ??= [
'difference' => '0',
'difference_float' => 0,
'currency_id' => (string)$foreignCurrencyId,
@@ -112,18 +108,14 @@ class TagController extends Controller
* https://api-docs.firefly-iii.org/?urls.primaryName=2.0.0%20(v1)#/insight/insightExpenseTag
*
* Expenses per tag, possibly filtered by tag and account.
- *
- * @param GenericRequest $request
- *
- * @return JsonResponse
*/
public function tag(GenericRequest $request): JsonResponse
{
- $accounts = $request->getAssetAccounts();
- $tags = $request->getTags();
- $start = $request->getStart();
- $end = $request->getEnd();
- $response = [];
+ $accounts = $request->getAssetAccounts();
+ $tags = $request->getTags();
+ $start = $request->getStart();
+ $end = $request->getEnd();
+ $response = [];
// get all tags:
if (0 === $tags->count()) {
@@ -131,10 +123,11 @@ class TagController extends Controller
}
// collect all expenses in this period (regardless of type) by the given bills and accounts.
- $collector = app(GroupCollectorInterface::class);
+ $collector = app(GroupCollectorInterface::class);
$collector->setTypes([TransactionType::WITHDRAWAL])->setRange($start, $end)->setSourceAccounts($accounts);
$collector->setTags($tags);
$genericSet = $collector->getExtractedJournals();
+
/** @var array $journal */
foreach ($genericSet as $journal) {
$currencyId = (int)$journal['currency_id'];
@@ -148,7 +141,7 @@ class TagController extends Controller
// on currency ID
if (0 !== $currencyId) {
- $response[$key] = $response[$key] ?? [
+ $response[$key] ??= [
'id' => (string)$tagId,
'name' => $tag['name'],
'difference' => '0',
diff --git a/app/Api/V1/Controllers/Insight/Income/AccountController.php b/app/Api/V1/Controllers/Insight/Income/AccountController.php
index 5d8aabc7f3..17e9d34205 100644
--- a/app/Api/V1/Controllers/Insight/Income/AccountController.php
+++ b/app/Api/V1/Controllers/Insight/Income/AccountController.php
@@ -28,12 +28,10 @@ use FireflyIII\Api\V1\Controllers\Controller;
use FireflyIII\Api\V1\Requests\Insight\GenericRequest;
use FireflyIII\Repositories\Account\AccountRepositoryInterface;
use FireflyIII\Repositories\Account\OperationsRepositoryInterface;
-use FireflyIII\Repositories\Currency\CurrencyRepositoryInterface;
use FireflyIII\Support\Http\Api\ApiSupport;
use Illuminate\Http\JsonResponse;
/**
- *
* Class AccountController
*
* Shows income information grouped or limited by date.
@@ -43,27 +41,21 @@ class AccountController extends Controller
{
use ApiSupport;
- private CurrencyRepositoryInterface $currencyRepository;
private OperationsRepositoryInterface $opsRepository;
private AccountRepositoryInterface $repository;
/**
* AccountController constructor.
- *
-
*/
public function __construct()
{
parent::__construct();
$this->middleware(
function ($request, $next) {
- $user = auth()->user();
- $this->repository = app(AccountRepositoryInterface::class);
+ $user = auth()->user();
+ $this->repository = app(AccountRepositoryInterface::class);
$this->repository->setUser($user);
- $this->currencyRepository = app(CurrencyRepositoryInterface::class);
- $this->currencyRepository->setUser($user);
-
$this->opsRepository = app(OperationsRepositoryInterface::class);
$this->opsRepository->setUser($user);
@@ -75,10 +67,6 @@ class AccountController extends Controller
/**
* This endpoint is documented at:
* https://api-docs.firefly-iii.org/?urls.primaryName=2.0.0%20(v1)#/insight/insightIncomeAsset
- *
- * @param GenericRequest $request
- *
- * @return JsonResponse
*/
public function asset(GenericRequest $request): JsonResponse
{
@@ -87,6 +75,7 @@ class AccountController extends Controller
$assetAccounts = $request->getAssetAccounts();
$income = $this->opsRepository->sumIncomeByDestination($start, $end, $assetAccounts);
$result = [];
+
/** @var array $entry */
foreach ($income as $entry) {
$result[] = [
@@ -105,10 +94,6 @@ class AccountController extends Controller
/**
* This endpoint is documented at:
* https://api-docs.firefly-iii.org/?urls.primaryName=2.0.0%20(v1)#/insight/insightIncomeRevenue
- *
- * @param GenericRequest $request
- *
- * @return JsonResponse
*/
public function revenue(GenericRequest $request): JsonResponse
{
diff --git a/app/Api/V1/Controllers/Insight/Income/CategoryController.php b/app/Api/V1/Controllers/Insight/Income/CategoryController.php
index f992540f1b..1f989dfe81 100644
--- a/app/Api/V1/Controllers/Insight/Income/CategoryController.php
+++ b/app/Api/V1/Controllers/Insight/Income/CategoryController.php
@@ -44,8 +44,6 @@ class CategoryController extends Controller
/**
* AccountController constructor.
- *
-
*/
public function __construct()
{
@@ -68,10 +66,6 @@ class CategoryController extends Controller
/**
* This endpoint is documented at:
* https://api-docs.firefly-iii.org/?urls.primaryName=2.0.0%20(v1)#/insight/insightIncomeCategory
- *
- * @param GenericRequest $request
- *
- * @return JsonResponse
*/
public function category(GenericRequest $request): JsonResponse
{
@@ -83,9 +77,11 @@ class CategoryController extends Controller
if (0 === $categories->count()) {
$categories = $this->repository->getCategories();
}
+
/** @var Category $category */
foreach ($categories as $category) {
$expenses = $this->opsRepository->sumIncome($start, $end, $assetAccounts, new Collection([$category]));
+
/** @var array $expense */
foreach ($expenses as $expense) {
$result[] = [
@@ -105,10 +101,6 @@ class CategoryController extends Controller
/**
* This endpoint is documented at:
* https://api-docs.firefly-iii.org/?urls.primaryName=2.0.0%20(v1)#/insight/insightIncomeNoCategory
- *
- * @param GenericRequest $request
- *
- * @return JsonResponse
*/
public function noCategory(GenericRequest $request): JsonResponse
{
@@ -117,6 +109,7 @@ class CategoryController extends Controller
$assetAccounts = $request->getAssetAccounts();
$result = [];
$expenses = $this->noRepository->sumIncome($start, $end, $assetAccounts);
+
/** @var array $expense */
foreach ($expenses as $expense) {
$result[] = [
diff --git a/app/Api/V1/Controllers/Insight/Income/PeriodController.php b/app/Api/V1/Controllers/Insight/Income/PeriodController.php
index cff22e7cbb..c207625407 100644
--- a/app/Api/V1/Controllers/Insight/Income/PeriodController.php
+++ b/app/Api/V1/Controllers/Insight/Income/PeriodController.php
@@ -37,20 +37,16 @@ class PeriodController extends Controller
/**
* This endpoint is documented at:
* https://api-docs.firefly-iii.org/?urls.primaryName=2.0.0%20(v1)#/insight/insightIncomeTotal
- *
- * @param GenericRequest $request
- *
- * @return JsonResponse
*/
public function total(GenericRequest $request): JsonResponse
{
- $accounts = $request->getAssetAccounts();
- $start = $request->getStart();
- $end = $request->getEnd();
- $response = [];
+ $accounts = $request->getAssetAccounts();
+ $start = $request->getStart();
+ $end = $request->getEnd();
+ $response = [];
// collect all expenses in this period (regardless of type)
- $collector = app(GroupCollectorInterface::class);
+ $collector = app(GroupCollectorInterface::class);
$collector->setTypes([TransactionType::DEPOSIT])->setRange($start, $end)->setDestinationAccounts($accounts);
$genericSet = $collector->getExtractedJournals();
foreach ($genericSet as $journal) {
@@ -58,7 +54,7 @@ class PeriodController extends Controller
$foreignCurrencyId = (int)$journal['foreign_currency_id'];
if (0 !== $currencyId) {
- $response[$currencyId] = $response[$currencyId] ?? [
+ $response[$currencyId] ??= [
'difference' => '0',
'difference_float' => 0,
'currency_id' => (string)$currencyId,
@@ -68,7 +64,7 @@ class PeriodController extends Controller
$response[$currencyId]['difference_float'] = (float)$response[$currencyId]['difference']; // float but on purpose.
}
if (0 !== $foreignCurrencyId) {
- $response[$foreignCurrencyId] = $response[$foreignCurrencyId] ?? [
+ $response[$foreignCurrencyId] ??= [
'difference' => '0',
'difference_float' => 0,
'currency_id' => (string)$foreignCurrencyId,
diff --git a/app/Api/V1/Controllers/Insight/Income/TagController.php b/app/Api/V1/Controllers/Insight/Income/TagController.php
index 87cb0bb4b3..ce35e5773c 100644
--- a/app/Api/V1/Controllers/Insight/Income/TagController.php
+++ b/app/Api/V1/Controllers/Insight/Income/TagController.php
@@ -60,20 +60,16 @@ class TagController extends Controller
* https://api-docs.firefly-iii.org/?urls.primaryName=2.0.0%20(v1)#/insight/insightIncomeTag
*
* Expenses for no tag filtered by account.
- *
- * @param GenericRequest $request
- *
- * @return JsonResponse
*/
public function noTag(GenericRequest $request): JsonResponse
{
- $accounts = $request->getAssetAccounts();
- $start = $request->getStart();
- $end = $request->getEnd();
- $response = [];
+ $accounts = $request->getAssetAccounts();
+ $start = $request->getStart();
+ $end = $request->getEnd();
+ $response = [];
// collect all expenses in this period (regardless of type) by the given bills and accounts.
- $collector = app(GroupCollectorInterface::class);
+ $collector = app(GroupCollectorInterface::class);
$collector->setTypes([TransactionType::DEPOSIT])->setRange($start, $end)->setDestinationAccounts($accounts);
$collector->withoutTags();
@@ -84,7 +80,7 @@ class TagController extends Controller
$foreignCurrencyId = (int)$journal['foreign_currency_id'];
if (0 !== $currencyId) {
- $response[$currencyId] = $response[$currencyId] ?? [
+ $response[$currencyId] ??= [
'difference' => '0',
'difference_float' => 0,
'currency_id' => (string)$currencyId,
@@ -94,7 +90,7 @@ class TagController extends Controller
$response[$currencyId]['difference_float'] = (float)$response[$currencyId]['difference'];
}
if (0 !== $foreignCurrencyId) {
- $response[$foreignCurrencyId] = $response[$foreignCurrencyId] ?? [
+ $response[$foreignCurrencyId] ??= [
'difference' => '0',
'difference_float' => 0,
'currency_id' => (string)$foreignCurrencyId,
@@ -116,18 +112,14 @@ class TagController extends Controller
* https://api-docs.firefly-iii.org/?urls.primaryName=2.0.0%20(v1)#/insight/insightIncomeNoTag
*
* Expenses per tag, possibly filtered by tag and account.
- *
- * @param GenericRequest $request
- *
- * @return JsonResponse
*/
public function tag(GenericRequest $request): JsonResponse
{
- $accounts = $request->getAssetAccounts();
- $tags = $request->getTags();
- $start = $request->getStart();
- $end = $request->getEnd();
- $response = [];
+ $accounts = $request->getAssetAccounts();
+ $tags = $request->getTags();
+ $start = $request->getStart();
+ $end = $request->getEnd();
+ $response = [];
// get all tags:
if (0 === $tags->count()) {
@@ -135,10 +127,11 @@ class TagController extends Controller
}
// collect all expenses in this period (regardless of type) by the given bills and accounts.
- $collector = app(GroupCollectorInterface::class);
+ $collector = app(GroupCollectorInterface::class);
$collector->setTypes([TransactionType::DEPOSIT])->setRange($start, $end)->setDestinationAccounts($accounts);
$collector->setTags($tags);
$genericSet = $collector->getExtractedJournals();
+
/** @var array $journal */
foreach ($genericSet as $journal) {
$currencyId = (int)$journal['currency_id'];
@@ -152,7 +145,7 @@ class TagController extends Controller
// on currency ID
if (0 !== $currencyId) {
- $response[$key] = $response[$key] ?? [
+ $response[$key] ??= [
'id' => (string)$tagId,
'name' => $tag['name'],
'difference' => '0',
diff --git a/app/Api/V1/Controllers/Insight/Transfer/AccountController.php b/app/Api/V1/Controllers/Insight/Transfer/AccountController.php
index 09d1fc2b8b..95fff5b468 100644
--- a/app/Api/V1/Controllers/Insight/Transfer/AccountController.php
+++ b/app/Api/V1/Controllers/Insight/Transfer/AccountController.php
@@ -40,8 +40,6 @@ class AccountController extends Controller
/**
* AccountController constructor.
- *
-
*/
public function __construct()
{
@@ -60,10 +58,6 @@ class AccountController extends Controller
/**
* This endpoint is documented at:
* https://api-docs.firefly-iii.org/?urls.primaryName=2.0.0%20(v1)#/insight/insightTransfers
- *
- * @param GenericRequest $request
- *
- * @return JsonResponse
*/
public function asset(GenericRequest $request): JsonResponse
{
diff --git a/app/Api/V1/Controllers/Insight/Transfer/CategoryController.php b/app/Api/V1/Controllers/Insight/Transfer/CategoryController.php
index f88bb8dd75..12c4f02f34 100644
--- a/app/Api/V1/Controllers/Insight/Transfer/CategoryController.php
+++ b/app/Api/V1/Controllers/Insight/Transfer/CategoryController.php
@@ -43,8 +43,6 @@ class CategoryController extends Controller
/**
* AccountController constructor.
- *
-
*/
public function __construct()
{
@@ -67,10 +65,6 @@ class CategoryController extends Controller
/**
* This endpoint is documented at:
* https://api-docs.firefly-iii.org/?urls.primaryName=2.0.0%20(v1)#/insight/insightTransferCategory
- *
- * @param GenericRequest $request
- *
- * @return JsonResponse
*/
public function category(GenericRequest $request): JsonResponse
{
@@ -82,9 +76,11 @@ class CategoryController extends Controller
if (0 === $categories->count()) {
$categories = $this->repository->getCategories();
}
+
/** @var Category $category */
foreach ($categories as $category) {
$expenses = $this->opsRepository->sumTransfers($start, $end, $assetAccounts, new Collection([$category]));
+
/** @var array $expense */
foreach ($expenses as $expense) {
$result[] = [
@@ -104,10 +100,6 @@ class CategoryController extends Controller
/**
* This endpoint is documented at:
* https://api-docs.firefly-iii.org/?urls.primaryName=2.0.0%20(v1)#/insight/insightTransferNoCategory
- *
- * @param GenericRequest $request
- *
- * @return JsonResponse
*/
public function noCategory(GenericRequest $request): JsonResponse
{
@@ -116,6 +108,7 @@ class CategoryController extends Controller
$assetAccounts = $request->getAssetAccounts();
$result = [];
$expenses = $this->noRepository->sumTransfers($start, $end, $assetAccounts);
+
/** @var array $expense */
foreach ($expenses as $expense) {
$result[] = [
diff --git a/app/Api/V1/Controllers/Insight/Transfer/PeriodController.php b/app/Api/V1/Controllers/Insight/Transfer/PeriodController.php
index fc4a35a196..6b011ec63d 100644
--- a/app/Api/V1/Controllers/Insight/Transfer/PeriodController.php
+++ b/app/Api/V1/Controllers/Insight/Transfer/PeriodController.php
@@ -37,20 +37,16 @@ class PeriodController extends Controller
/**
* This endpoint is documented at:
* https://api-docs.firefly-iii.org/?urls.primaryName=2.0.0%20(v1)#/insight/insightTransferTotal
- *
- * @param GenericRequest $request
- *
- * @return JsonResponse
*/
public function total(GenericRequest $request): JsonResponse
{
- $accounts = $request->getAssetAccounts();
- $start = $request->getStart();
- $end = $request->getEnd();
- $response = [];
+ $accounts = $request->getAssetAccounts();
+ $start = $request->getStart();
+ $end = $request->getEnd();
+ $response = [];
// collect all expenses in this period (regardless of type)
- $collector = app(GroupCollectorInterface::class);
+ $collector = app(GroupCollectorInterface::class);
$collector->setTypes([TransactionType::TRANSFER])->setRange($start, $end)->setDestinationAccounts($accounts);
$genericSet = $collector->getExtractedJournals();
foreach ($genericSet as $journal) {
@@ -58,7 +54,7 @@ class PeriodController extends Controller
$foreignCurrencyId = (int)$journal['foreign_currency_id'];
if (0 !== $currencyId) {
- $response[$currencyId] = $response[$currencyId] ?? [
+ $response[$currencyId] ??= [
'difference' => '0',
'difference_float' => 0,
'currency_id' => (string)$currencyId,
@@ -68,7 +64,7 @@ class PeriodController extends Controller
$response[$currencyId]['difference_float'] = (float)$response[$currencyId]['difference'];
}
if (0 !== $foreignCurrencyId) {
- $response[$foreignCurrencyId] = $response[$foreignCurrencyId] ?? [
+ $response[$foreignCurrencyId] ??= [
'difference' => '0',
'difference_float' => 0,
'currency_id' => (string)$foreignCurrencyId,
diff --git a/app/Api/V1/Controllers/Insight/Transfer/TagController.php b/app/Api/V1/Controllers/Insight/Transfer/TagController.php
index e880067197..4c79f40fb7 100644
--- a/app/Api/V1/Controllers/Insight/Transfer/TagController.php
+++ b/app/Api/V1/Controllers/Insight/Transfer/TagController.php
@@ -57,20 +57,16 @@ class TagController extends Controller
/**
* This endpoint is documented at:
* https://api-docs.firefly-iii.org/?urls.primaryName=2.0.0%20(v1)#/insight/insightTransferNoTag
- *
- * @param GenericRequest $request
- *
- * @return JsonResponse
*/
public function noTag(GenericRequest $request): JsonResponse
{
- $accounts = $request->getAssetAccounts();
- $start = $request->getStart();
- $end = $request->getEnd();
- $response = [];
+ $accounts = $request->getAssetAccounts();
+ $start = $request->getStart();
+ $end = $request->getEnd();
+ $response = [];
// collect all expenses in this period (regardless of type) by the given bills and accounts.
- $collector = app(GroupCollectorInterface::class);
+ $collector = app(GroupCollectorInterface::class);
$collector->setTypes([TransactionType::TRANSFER])->setRange($start, $end)->setDestinationAccounts($accounts);
$collector->withoutTags();
@@ -81,7 +77,7 @@ class TagController extends Controller
$foreignCurrencyId = (int)$journal['foreign_currency_id'];
if (0 !== $currencyId) {
- $response[$currencyId] = $response[$currencyId] ?? [
+ $response[$currencyId] ??= [
'difference' => '0',
'difference_float' => 0,
'currency_id' => (string)$currencyId,
@@ -91,7 +87,7 @@ class TagController extends Controller
$response[$currencyId]['difference_float'] = (float)$response[$currencyId]['difference'];
}
if (0 !== $foreignCurrencyId) {
- $response[$foreignCurrencyId] = $response[$foreignCurrencyId] ?? [
+ $response[$foreignCurrencyId] ??= [
'difference' => '0',
'difference_float' => 0,
'currency_id' => (string)$foreignCurrencyId,
@@ -113,18 +109,14 @@ class TagController extends Controller
* https://api-docs.firefly-iii.org/?urls.primaryName=2.0.0%20(v1)#/insight/insightTransferTag
*
* Transfers per tag, possibly filtered by tag and account.
- *
- * @param GenericRequest $request
- *
- * @return JsonResponse
*/
public function tag(GenericRequest $request): JsonResponse
{
- $accounts = $request->getAssetAccounts();
- $tags = $request->getTags();
- $start = $request->getStart();
- $end = $request->getEnd();
- $response = [];
+ $accounts = $request->getAssetAccounts();
+ $tags = $request->getTags();
+ $start = $request->getStart();
+ $end = $request->getEnd();
+ $response = [];
// get all tags:
if (0 === $tags->count()) {
@@ -132,10 +124,11 @@ class TagController extends Controller
}
// collect all expenses in this period (regardless of type) by the given bills and accounts.
- $collector = app(GroupCollectorInterface::class);
+ $collector = app(GroupCollectorInterface::class);
$collector->setTypes([TransactionType::TRANSFER])->setRange($start, $end)->setDestinationAccounts($accounts);
$collector->setTags($tags);
$genericSet = $collector->getExtractedJournals();
+
/** @var array $journal */
foreach ($genericSet as $journal) {
$currencyId = (int)$journal['currency_id'];
@@ -149,7 +142,7 @@ class TagController extends Controller
// on currency ID
if (0 !== $currencyId) {
- $response[$key] = $response[$key] ?? [
+ $response[$key] ??= [
'id' => (string)$tagId,
'name' => $tag['name'],
'difference' => '0',
diff --git a/app/Api/V1/Controllers/Models/Account/DestroyController.php b/app/Api/V1/Controllers/Models/Account/DestroyController.php
index b157b011fd..cebf3afc26 100644
--- a/app/Api/V1/Controllers/Models/Account/DestroyController.php
+++ b/app/Api/V1/Controllers/Models/Account/DestroyController.php
@@ -33,14 +33,12 @@ use Illuminate\Http\JsonResponse;
*/
class DestroyController extends Controller
{
- public const RESOURCE_KEY = 'accounts';
+ public const string RESOURCE_KEY = 'accounts';
private AccountRepositoryInterface $repository;
/**
* AccountController constructor.
- *
-
*/
public function __construct()
{
@@ -60,10 +58,6 @@ class DestroyController extends Controller
* https://api-docs.firefly-iii.org/?urls.primaryName=2.0.0%20(v1)#/accounts/deleteAccount
*
* Remove the specified resource from storage.
- *
- * @param Account $account
- *
- * @return JsonResponse
*/
public function destroy(Account $account): JsonResponse
{
diff --git a/app/Api/V1/Controllers/Models/Account/ListController.php b/app/Api/V1/Controllers/Models/Account/ListController.php
index 6e3660121c..edcdf2dfea 100644
--- a/app/Api/V1/Controllers/Models/Account/ListController.php
+++ b/app/Api/V1/Controllers/Models/Account/ListController.php
@@ -47,14 +47,12 @@ class ListController extends Controller
{
use TransactionFilter;
- public const RESOURCE_KEY = 'accounts';
+ public const string RESOURCE_KEY = 'accounts';
private AccountRepositoryInterface $repository;
/**
* AccountController constructor.
- *
-
*/
public function __construct()
{
@@ -73,29 +71,26 @@ class ListController extends Controller
* This endpoint is documented at:
* https://api-docs.firefly-iii.org/?urls.primaryName=2.0.0%20(v1)#/accounts/listAttachmentByAccount
*
- * @param Account $account
- *
- * @return JsonResponse
* @throws FireflyException
*/
public function attachments(Account $account): JsonResponse
{
- $manager = $this->getManager();
- $pageSize = $this->parameters->get('limit');
- $collection = $this->repository->getAttachments($account);
+ $manager = $this->getManager();
+ $pageSize = $this->parameters->get('limit');
+ $collection = $this->repository->getAttachments($account);
$count = $collection->count();
$attachments = $collection->slice(($this->parameters->get('page') - 1) * $pageSize, $pageSize);
// make paginator:
- $paginator = new LengthAwarePaginator($attachments, $count, $pageSize, $this->parameters->get('page'));
- $paginator->setPath(route('api.v1.accounts.attachments', [$account->id]) . $this->buildParams());
+ $paginator = new LengthAwarePaginator($attachments, $count, $pageSize, $this->parameters->get('page'));
+ $paginator->setPath(route('api.v1.accounts.attachments', [$account->id]).$this->buildParams());
/** @var AttachmentTransformer $transformer */
$transformer = app(AttachmentTransformer::class);
$transformer->setParameters($this->parameters);
- $resource = new FractalCollection($attachments, $transformer, 'attachments');
+ $resource = new FractalCollection($attachments, $transformer, 'attachments');
$resource->setPaginator(new IlluminatePaginatorAdapter($paginator));
return response()->json($manager->createData($resource)->toArray())->header('Content-Type', self::CONTENT_TYPE);
@@ -105,33 +100,30 @@ class ListController extends Controller
* This endpoint is documented at:
* https://api-docs.firefly-iii.org/?urls.primaryName=2.0.0%20(v1)#/accounts/listPiggyBankByAccount
*
- * @param Account $account
- *
- * @return JsonResponse
* @throws FireflyException
*/
public function piggyBanks(Account $account): JsonResponse
{
// create some objects:
- $manager = $this->getManager();
+ $manager = $this->getManager();
// types to get, page size:
- $pageSize = $this->parameters->get('limit');
+ $pageSize = $this->parameters->get('limit');
// get list of budgets. Count it and split it.
- $collection = $this->repository->getPiggyBanks($account);
- $count = $collection->count();
- $piggyBanks = $collection->slice(($this->parameters->get('page') - 1) * $pageSize, $pageSize);
+ $collection = $this->repository->getPiggyBanks($account);
+ $count = $collection->count();
+ $piggyBanks = $collection->slice(($this->parameters->get('page') - 1) * $pageSize, $pageSize);
// make paginator:
- $paginator = new LengthAwarePaginator($piggyBanks, $count, $pageSize, $this->parameters->get('page'));
- $paginator->setPath(route('api.v1.accounts.piggy-banks', [$account->id]) . $this->buildParams());
+ $paginator = new LengthAwarePaginator($piggyBanks, $count, $pageSize, $this->parameters->get('page'));
+ $paginator->setPath(route('api.v1.accounts.piggy-banks', [$account->id]).$this->buildParams());
/** @var PiggyBankTransformer $transformer */
$transformer = app(PiggyBankTransformer::class);
$transformer->setParameters($this->parameters);
- $resource = new FractalCollection($piggyBanks, $transformer, 'piggy_banks');
+ $resource = new FractalCollection($piggyBanks, $transformer, 'piggy_banks');
$resource->setPaginator(new IlluminatePaginatorAdapter($paginator));
return response()->json($manager->createData($resource)->toArray())->header('Content-Type', self::CONTENT_TYPE);
@@ -143,28 +135,25 @@ class ListController extends Controller
*
* Show all transaction groups related to the account.
*
- *
- * @param Request $request
- * @param Account $account
- *
- * @return JsonResponse
* @throws FireflyException
*/
public function transactions(Request $request, Account $account): JsonResponse
{
- $pageSize = $this->parameters->get('limit');
- $type = $request->get('type') ?? 'default';
+ $pageSize = $this->parameters->get('limit');
+ $type = $request->get('type') ?? 'default';
$this->parameters->set('type', $type);
- $types = $this->mapTransactionTypes($this->parameters->get('type'));
- $manager = $this->getManager();
+ $types = $this->mapTransactionTypes($this->parameters->get('type'));
+ $manager = $this->getManager();
+
/** @var User $admin */
- $admin = auth()->user();
+ $admin = auth()->user();
// use new group collector:
/** @var GroupCollectorInterface $collector */
- $collector = app(GroupCollectorInterface::class);
+ $collector = app(GroupCollectorInterface::class);
$collector->setUser($admin)->setAccounts(new Collection([$account]))
- ->withAPIInformation()->setLimit($pageSize)->setPage($this->parameters->get('page'))->setTypes($types);
+ ->withAPIInformation()->setLimit($pageSize)->setPage($this->parameters->get('page'))->setTypes($types)
+ ;
if (null !== $this->parameters->get('start')) {
$collector->setStart($this->parameters->get('start'));
@@ -173,15 +162,15 @@ class ListController extends Controller
$collector->setEnd($this->parameters->get('end'));
}
- $paginator = $collector->getPaginatedGroups();
- $paginator->setPath(route('api.v1.accounts.transactions', [$account->id]) . $this->buildParams());
- $groups = $paginator->getCollection();
+ $paginator = $collector->getPaginatedGroups();
+ $paginator->setPath(route('api.v1.accounts.transactions', [$account->id]).$this->buildParams());
+ $groups = $paginator->getCollection();
/** @var TransactionGroupTransformer $transformer */
$transformer = app(TransactionGroupTransformer::class);
$transformer->setParameters($this->parameters);
- $resource = new FractalCollection($groups, $transformer, 'transactions');
+ $resource = new FractalCollection($groups, $transformer, 'transactions');
$resource->setPaginator(new IlluminatePaginatorAdapter($paginator));
return response()->json($manager->createData($resource)->toArray())->header('Content-Type', self::CONTENT_TYPE);
diff --git a/app/Api/V1/Controllers/Models/Account/ShowController.php b/app/Api/V1/Controllers/Models/Account/ShowController.php
index 8decc0a0dd..e0aa98eb54 100644
--- a/app/Api/V1/Controllers/Models/Account/ShowController.php
+++ b/app/Api/V1/Controllers/Models/Account/ShowController.php
@@ -43,14 +43,12 @@ class ShowController extends Controller
{
use AccountFilter;
- public const RESOURCE_KEY = 'accounts';
+ public const string RESOURCE_KEY = 'accounts';
private AccountRepositoryInterface $repository;
/**
* AccountController constructor.
- *
-
*/
public function __construct()
{
@@ -71,40 +69,36 @@ class ShowController extends Controller
*
* Display a listing of the resource.
*
- * @param Request $request
- *
- * @return JsonResponse
* @throws FireflyException
*/
public function index(Request $request): JsonResponse
{
- $manager = $this->getManager();
- $type = $request->get('type') ?? 'all';
+ $manager = $this->getManager();
+ $type = $request->get('type') ?? 'all';
$this->parameters->set('type', $type);
// types to get, page size:
- $types = $this->mapAccountTypes($this->parameters->get('type'));
- $pageSize = $this->parameters->get('limit');
+ $types = $this->mapAccountTypes($this->parameters->get('type'));
+ $pageSize = $this->parameters->get('limit');
// get list of accounts. Count it and split it.
$this->repository->resetAccountOrder();
- $collection = $this->repository->getAccountsByType($types, $this->parameters->get('sort') ?? []);
- $count = $collection->count();
+ $collection = $this->repository->getAccountsByType($types, $this->parameters->get('sort') ?? []);
+ $count = $collection->count();
// continue sort:
-
- $accounts = $collection->slice(($this->parameters->get('page') - 1) * $pageSize, $pageSize);
+ $accounts = $collection->slice(($this->parameters->get('page') - 1) * $pageSize, $pageSize);
// make paginator:
- $paginator = new LengthAwarePaginator($accounts, $count, $pageSize, $this->parameters->get('page'));
- $paginator->setPath(route('api.v1.accounts.index') . $this->buildParams());
+ $paginator = new LengthAwarePaginator($accounts, $count, $pageSize, $this->parameters->get('page'));
+ $paginator->setPath(route('api.v1.accounts.index').$this->buildParams());
/** @var AccountTransformer $transformer */
$transformer = app(AccountTransformer::class);
$transformer->setParameters($this->parameters);
- $resource = new FractalCollection($accounts, $transformer, self::RESOURCE_KEY);
+ $resource = new FractalCollection($accounts, $transformer, self::RESOURCE_KEY);
$resource->setPaginator(new IlluminatePaginatorAdapter($paginator));
return response()->json($manager->createData($resource)->toArray())->header('Content-Type', self::CONTENT_TYPE);
@@ -115,22 +109,18 @@ class ShowController extends Controller
* https://api-docs.firefly-iii.org/?urls.primaryName=2.0.0%20(v1)#/accounts/getAccount
*
* Show single instance.
- *
- * @param Account $account
- *
- * @return JsonResponse
*/
public function show(Account $account): JsonResponse
{
// get list of accounts. Count it and split it.
$this->repository->resetAccountOrder();
$account->refresh();
- $manager = $this->getManager();
+ $manager = $this->getManager();
/** @var AccountTransformer $transformer */
$transformer = app(AccountTransformer::class);
$transformer->setParameters($this->parameters);
- $resource = new Item($account, $transformer, self::RESOURCE_KEY);
+ $resource = new Item($account, $transformer, self::RESOURCE_KEY);
return response()->json($manager->createData($resource)->toArray())->header('Content-Type', self::CONTENT_TYPE);
}
diff --git a/app/Api/V1/Controllers/Models/Account/StoreController.php b/app/Api/V1/Controllers/Models/Account/StoreController.php
index cb49ece28f..f5ed92468b 100644
--- a/app/Api/V1/Controllers/Models/Account/StoreController.php
+++ b/app/Api/V1/Controllers/Models/Account/StoreController.php
@@ -35,14 +35,12 @@ use League\Fractal\Resource\Item;
*/
class StoreController extends Controller
{
- public const RESOURCE_KEY = 'accounts';
+ public const string RESOURCE_KEY = 'accounts';
private AccountRepositoryInterface $repository;
/**
* AccountController constructor.
- *
-
*/
public function __construct()
{
@@ -62,23 +60,19 @@ class StoreController extends Controller
* https://api-docs.firefly-iii.org/?urls.primaryName=2.0.0%20(v1)#/accounts/storeAccount
*
* Store a new instance.
- *
- * @param StoreRequest $request
- *
- * @return JsonResponse
*/
public function store(StoreRequest $request): JsonResponse
{
- $data = $request->getAllAccountData();
+ $data = $request->getAllAccountData();
$this->repository->resetAccountOrder();
- $account = $this->repository->store($data);
- $manager = $this->getManager();
+ $account = $this->repository->store($data);
+ $manager = $this->getManager();
/** @var AccountTransformer $transformer */
$transformer = app(AccountTransformer::class);
$transformer->setParameters($this->parameters);
- $resource = new Item($account, $transformer, self::RESOURCE_KEY);
+ $resource = new Item($account, $transformer, self::RESOURCE_KEY);
return response()->json($manager->createData($resource)->toArray())->header('Content-Type', self::CONTENT_TYPE);
}
diff --git a/app/Api/V1/Controllers/Models/Account/UpdateController.php b/app/Api/V1/Controllers/Models/Account/UpdateController.php
index 1be3f42970..2031ba7005 100644
--- a/app/Api/V1/Controllers/Models/Account/UpdateController.php
+++ b/app/Api/V1/Controllers/Models/Account/UpdateController.php
@@ -29,23 +29,19 @@ use FireflyIII\Models\Account;
use FireflyIII\Repositories\Account\AccountRepositoryInterface;
use FireflyIII\Transformers\AccountTransformer;
use Illuminate\Http\JsonResponse;
-use Illuminate\Support\Facades\Log;
use League\Fractal\Resource\Item;
-use Preferences;
/**
* Class UpdateController
*/
class UpdateController extends Controller
{
- public const RESOURCE_KEY = 'accounts';
+ public const string RESOURCE_KEY = 'accounts';
private AccountRepositoryInterface $repository;
/**
* AccountController constructor.
- *
-
*/
public function __construct()
{
@@ -65,26 +61,21 @@ class UpdateController extends Controller
* https://api-docs.firefly-iii.org/?urls.primaryName=2.0.0%20(v1)#/accounts/updateAccount
*
* Update account.
- *
- * @param UpdateRequest $request
- * @param Account $account
- *
- * @return JsonResponse
*/
public function update(UpdateRequest $request, Account $account): JsonResponse
{
- Log::debug(sprintf('Now in %s', __METHOD__));
+ app('log')->debug(sprintf('Now in %s', __METHOD__));
$data = $request->getUpdateData();
- $data['type'] = config('firefly.shortNamesByFullName.' . $account->accountType->type);
+ $data['type'] = config('firefly.shortNamesByFullName.'.$account->accountType->type);
$account = $this->repository->update($account, $data);
$manager = $this->getManager();
$account->refresh();
- Preferences::mark();
+ app('preferences')->mark();
/** @var AccountTransformer $transformer */
- $transformer = app(AccountTransformer::class);
+ $transformer = app(AccountTransformer::class);
$transformer->setParameters($this->parameters);
- $resource = new Item($account, $transformer, self::RESOURCE_KEY);
+ $resource = new Item($account, $transformer, self::RESOURCE_KEY);
return response()->json($manager->createData($resource)->toArray())->header('Content-Type', self::CONTENT_TYPE);
}
diff --git a/app/Api/V1/Controllers/Models/Attachment/DestroyController.php b/app/Api/V1/Controllers/Models/Attachment/DestroyController.php
index ba81be4ecf..98d27ec070 100644
--- a/app/Api/V1/Controllers/Models/Attachment/DestroyController.php
+++ b/app/Api/V1/Controllers/Models/Attachment/DestroyController.php
@@ -29,6 +29,8 @@ use FireflyIII\Models\Attachment;
use FireflyIII\Repositories\Attachment\AttachmentRepositoryInterface;
use FireflyIII\User;
use Illuminate\Http\JsonResponse;
+use Illuminate\Support\Facades\Log;
+use Symfony\Component\HttpKernel\Exception\NotFoundHttpException;
/**
* Class DestroyController
@@ -39,8 +41,6 @@ class DestroyController extends Controller
/**
* DestroyController constructor.
- *
-
*/
public function __construct()
{
@@ -63,14 +63,15 @@ class DestroyController extends Controller
* https://api-docs.firefly-iii.org/?urls.primaryName=2.0.0%20(v1)#/attachments/deleteAttachment
*
* Remove the specified resource from storage.
- *
- *
- * @param Attachment $attachment
- *
- * @return JsonResponse
*/
public function destroy(Attachment $attachment): JsonResponse
{
+ if (true === auth()->user()->hasRole('demo')) {
+ Log::channel('audit')->warning(sprintf('Demo user tries to access attachment API in %s', __METHOD__));
+
+ throw new NotFoundHttpException();
+ }
+
$this->repository->destroy($attachment);
app('preferences')->mark();
diff --git a/app/Api/V1/Controllers/Models/Attachment/ShowController.php b/app/Api/V1/Controllers/Models/Attachment/ShowController.php
index 12e53d298c..0518aec90e 100644
--- a/app/Api/V1/Controllers/Models/Attachment/ShowController.php
+++ b/app/Api/V1/Controllers/Models/Attachment/ShowController.php
@@ -33,9 +33,11 @@ use FireflyIII\User;
use Illuminate\Http\JsonResponse;
use Illuminate\Http\Response as LaravelResponse;
use Illuminate\Pagination\LengthAwarePaginator;
+use Illuminate\Support\Facades\Log;
use League\Fractal\Pagination\IlluminatePaginatorAdapter;
use League\Fractal\Resource\Collection as FractalCollection;
use League\Fractal\Resource\Item;
+use Symfony\Component\HttpKernel\Exception\NotFoundHttpException;
/**
* Class ShowController
@@ -46,8 +48,6 @@ class ShowController extends Controller
/**
* ShowController constructor.
- *
-
*/
public function __construct()
{
@@ -71,13 +71,15 @@ class ShowController extends Controller
*
* Download an attachment.
*
- * @param Attachment $attachment
- *
- * @return LaravelResponse
- * @throws FireflyException
+ * @throws FireflyException
*/
public function download(Attachment $attachment): LaravelResponse
{
+ if (true === auth()->user()->hasRole('demo')) {
+ Log::channel('audit')->warning(sprintf('Demo user tries to access attachment API in %s', __METHOD__));
+
+ throw new NotFoundHttpException();
+ }
if (false === $attachment->uploaded) {
throw new FireflyException('200000: File has not been uploaded (yet).');
}
@@ -85,27 +87,29 @@ class ShowController extends Controller
throw new FireflyException('200000: File has not been uploaded (yet).');
}
if ($this->repository->exists($attachment)) {
- $content = $this->repository->getContent($attachment);
+ $content = $this->repository->getContent($attachment);
if ('' === $content) {
throw new FireflyException('200002: File is empty (zero bytes).');
}
- $quoted = sprintf('"%s"', addcslashes(basename($attachment->filename), '"\\'));
+ $quoted = sprintf('"%s"', addcslashes(basename($attachment->filename), '"\\'));
/** @var LaravelResponse $response */
$response = response($content);
$response
->header('Content-Description', 'File Transfer')
->header('Content-Type', 'application/octet-stream')
- ->header('Content-Disposition', 'attachment; filename=' . $quoted)
+ ->header('Content-Disposition', 'attachment; filename='.$quoted)
->header('Content-Transfer-Encoding', 'binary')
->header('Connection', 'Keep-Alive')
->header('Expires', '0')
->header('Cache-Control', 'must-revalidate, post-check=0, pre-check=0')
->header('Pragma', 'public')
- ->header('Content-Length', (string)strlen($content));
+ ->header('Content-Length', (string)strlen($content))
+ ;
return $response;
}
+
throw new FireflyException('200003: File does not exist.');
}
@@ -115,15 +119,20 @@ class ShowController extends Controller
*
* Display a listing of the resource.
*
- * @return JsonResponse
* @throws FireflyException
*/
public function index(): JsonResponse
{
- $manager = $this->getManager();
+ if (true === auth()->user()->hasRole('demo')) {
+ Log::channel('audit')->warning(sprintf('Demo user tries to access attachment API in %s', __METHOD__));
+
+ throw new NotFoundHttpException();
+ }
+
+ $manager = $this->getManager();
// types to get, page size:
- $pageSize = $this->parameters->get('limit');
+ $pageSize = $this->parameters->get('limit');
// get list of attachments. Count it and split it.
$collection = $this->repository->get();
@@ -131,14 +140,14 @@ class ShowController extends Controller
$attachments = $collection->slice(($this->parameters->get('page') - 1) * $pageSize, $pageSize);
// make paginator:
- $paginator = new LengthAwarePaginator($attachments, $count, $pageSize, $this->parameters->get('page'));
- $paginator->setPath(route('api.v1.attachments.index') . $this->buildParams());
+ $paginator = new LengthAwarePaginator($attachments, $count, $pageSize, $this->parameters->get('page'));
+ $paginator->setPath(route('api.v1.attachments.index').$this->buildParams());
/** @var AttachmentTransformer $transformer */
$transformer = app(AttachmentTransformer::class);
$transformer->setParameters($this->parameters);
- $resource = new FractalCollection($attachments, $transformer, 'attachments');
+ $resource = new FractalCollection($attachments, $transformer, 'attachments');
$resource->setPaginator(new IlluminatePaginatorAdapter($paginator));
return response()->json($manager->createData($resource)->toArray())->header('Content-Type', self::CONTENT_TYPE);
@@ -149,19 +158,21 @@ class ShowController extends Controller
* https://api-docs.firefly-iii.org/?urls.primaryName=2.0.0%20(v1)#/attachments/getAttachment
*
* Display the specified resource.
- *
- * @param Attachment $attachment
- *
- * @return JsonResponse
*/
public function show(Attachment $attachment): JsonResponse
{
- $manager = $this->getManager();
+ if (true === auth()->user()->hasRole('demo')) {
+ Log::channel('audit')->warning(sprintf('Demo user tries to access attachment API in %s', __METHOD__));
+
+ throw new NotFoundHttpException();
+ }
+ $manager = $this->getManager();
+
/** @var AttachmentTransformer $transformer */
$transformer = app(AttachmentTransformer::class);
$transformer->setParameters($this->parameters);
- $resource = new Item($attachment, $transformer, 'attachments');
+ $resource = new Item($attachment, $transformer, 'attachments');
return response()->json($manager->createData($resource)->toArray())->header('Content-Type', self::CONTENT_TYPE);
}
diff --git a/app/Api/V1/Controllers/Models/Attachment/StoreController.php b/app/Api/V1/Controllers/Models/Attachment/StoreController.php
index 6eeb9160c6..5c9edf7d3c 100644
--- a/app/Api/V1/Controllers/Models/Attachment/StoreController.php
+++ b/app/Api/V1/Controllers/Models/Attachment/StoreController.php
@@ -36,6 +36,7 @@ use Illuminate\Http\JsonResponse;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\Log;
use League\Fractal\Resource\Item;
+use Symfony\Component\HttpKernel\Exception\NotFoundHttpException;
/**
* Class StoreController
@@ -46,8 +47,6 @@ class StoreController extends Controller
/**
* StoreController constructor.
- *
-
*/
public function __construct()
{
@@ -71,43 +70,45 @@ class StoreController extends Controller
*
* Store a newly created resource in storage.
*
- * @param StoreRequest $request
- *
- * @return JsonResponse
* @throws FireflyException
*/
public function store(StoreRequest $request): JsonResponse
{
- Log::debug(sprintf('Now in %s', __METHOD__));
- $data = $request->getAll();
- $attachment = $this->repository->store($data);
- $manager = $this->getManager();
+ if (true === auth()->user()->hasRole('demo')) {
+ Log::channel('audit')->warning(sprintf('Demo user tries to access attachment API in %s', __METHOD__));
+
+ throw new NotFoundHttpException();
+ }
+ app('log')->debug(sprintf('Now in %s', __METHOD__));
+ $data = $request->getAll();
+ $attachment = $this->repository->store($data);
+ $manager = $this->getManager();
/** @var AttachmentTransformer $transformer */
$transformer = app(AttachmentTransformer::class);
$transformer->setParameters($this->parameters);
- $resource = new Item($attachment, $transformer, 'attachments');
+ $resource = new Item($attachment, $transformer, 'attachments');
return response()->json($manager->createData($resource)->toArray())->header('Content-Type', self::CONTENT_TYPE);
}
/**
* Upload an attachment.
- *
- *
- * @param Request $request
- * @param Attachment $attachment
- *
- * @return JsonResponse
*/
public function upload(Request $request, Attachment $attachment): JsonResponse
{
+ if (true === auth()->user()->hasRole('demo')) {
+ Log::channel('audit')->warning(sprintf('Demo user tries to access attachment API in %s', __METHOD__));
+
+ throw new NotFoundHttpException();
+ }
+
/** @var AttachmentHelperInterface $helper */
$helper = app(AttachmentHelperInterface::class);
$body = $request->getContent();
if ('' === $body) {
- Log::error('Body of attachment is empty.');
+ app('log')->error('Body of attachment is empty.');
return response()->json([], 422);
}
diff --git a/app/Api/V1/Controllers/Models/Attachment/UpdateController.php b/app/Api/V1/Controllers/Models/Attachment/UpdateController.php
index e50ce2cc80..6fcc11f472 100644
--- a/app/Api/V1/Controllers/Models/Attachment/UpdateController.php
+++ b/app/Api/V1/Controllers/Models/Attachment/UpdateController.php
@@ -31,7 +31,9 @@ use FireflyIII\Repositories\Attachment\AttachmentRepositoryInterface;
use FireflyIII\Transformers\AttachmentTransformer;
use FireflyIII\User;
use Illuminate\Http\JsonResponse;
+use Illuminate\Support\Facades\Log;
use League\Fractal\Resource\Item;
+use Symfony\Component\HttpKernel\Exception\NotFoundHttpException;
/**
* Class UpdateController
@@ -42,8 +44,6 @@ class UpdateController extends Controller
/**
* UpdateController constructor.
- *
-
*/
public function __construct()
{
@@ -66,23 +66,23 @@ class UpdateController extends Controller
* https://api-docs.firefly-iii.org/?urls.primaryName=2.0.0%20(v1)#/attachments/updateAttachment
*
* Update the specified resource in storage.
- *
- * @param UpdateRequest $request
- * @param Attachment $attachment
- *
- * @return JsonResponse
*/
public function update(UpdateRequest $request, Attachment $attachment): JsonResponse
{
- $data = $request->getAll();
+ if (true === auth()->user()->hasRole('demo')) {
+ Log::channel('audit')->warning(sprintf('Demo user tries to access attachment API in %s', __METHOD__));
+
+ throw new NotFoundHttpException();
+ }
+ $data = $request->getAll();
$this->repository->update($attachment, $data);
- $manager = $this->getManager();
+ $manager = $this->getManager();
/** @var AttachmentTransformer $transformer */
$transformer = app(AttachmentTransformer::class);
$transformer->setParameters($this->parameters);
- $resource = new Item($attachment, $transformer, 'attachments');
+ $resource = new Item($attachment, $transformer, 'attachments');
return response()->json($manager->createData($resource)->toArray())->header('Content-Type', self::CONTENT_TYPE);
}
diff --git a/app/Api/V1/Controllers/Models/AvailableBudget/ShowController.php b/app/Api/V1/Controllers/Models/AvailableBudget/ShowController.php
index 268fa4a317..165645d40f 100644
--- a/app/Api/V1/Controllers/Models/AvailableBudget/ShowController.php
+++ b/app/Api/V1/Controllers/Models/AvailableBudget/ShowController.php
@@ -44,8 +44,6 @@ class ShowController extends Controller
/**
* AvailableBudgetController constructor.
- *
-
*/
public function __construct()
{
@@ -68,18 +66,17 @@ class ShowController extends Controller
*
* Display a listing of the resource.
*
- * @return JsonResponse
* @throws FireflyException
*/
public function index(): JsonResponse
{
- $manager = $this->getManager();
+ $manager = $this->getManager();
// types to get, page size:
- $pageSize = $this->parameters->get('limit');
+ $pageSize = $this->parameters->get('limit');
- $start = $this->parameters->get('start');
- $end = $this->parameters->get('end');
+ $start = $this->parameters->get('start');
+ $end = $this->parameters->get('end');
// get list of available budgets. Count it and split it.
$collection = $this->abRepository->getAvailableBudgetsByDate($start, $end);
@@ -87,14 +84,14 @@ class ShowController extends Controller
$availableBudgets = $collection->slice(($this->parameters->get('page') - 1) * $pageSize, $pageSize);
// make paginator:
- $paginator = new LengthAwarePaginator($availableBudgets, $count, $pageSize, $this->parameters->get('page'));
- $paginator->setPath(route('api.v1.available-budgets.index') . $this->buildParams());
+ $paginator = new LengthAwarePaginator($availableBudgets, $count, $pageSize, $this->parameters->get('page'));
+ $paginator->setPath(route('api.v1.available-budgets.index').$this->buildParams());
/** @var AvailableBudgetTransformer $transformer */
- $transformer = app(AvailableBudgetTransformer::class);
+ $transformer = app(AvailableBudgetTransformer::class);
$transformer->setParameters($this->parameters);
- $resource = new FractalCollection($availableBudgets, $transformer, 'available_budgets');
+ $resource = new FractalCollection($availableBudgets, $transformer, 'available_budgets');
$resource->setPaginator(new IlluminatePaginatorAdapter($paginator));
return response()->json($manager->createData($resource)->toArray())->header('Content-Type', self::CONTENT_TYPE);
@@ -105,20 +102,16 @@ class ShowController extends Controller
* https://api-docs.firefly-iii.org/?urls.primaryName=2.0.0%20(v1)#/available_budgets/getAvailableBudget
*
* Display the specified resource.
- *
- * @param AvailableBudget $availableBudget
- *
- * @return JsonResponse
*/
public function show(AvailableBudget $availableBudget): JsonResponse
{
- $manager = $this->getManager();
+ $manager = $this->getManager();
/** @var AvailableBudgetTransformer $transformer */
$transformer = app(AvailableBudgetTransformer::class);
$transformer->setParameters($this->parameters);
- $resource = new Item($availableBudget, $transformer, 'available_budgets');
+ $resource = new Item($availableBudget, $transformer, 'available_budgets');
return response()->json($manager->createData($resource)->toArray())->header('Content-Type', self::CONTENT_TYPE);
}
diff --git a/app/Api/V1/Controllers/Models/Bill/DestroyController.php b/app/Api/V1/Controllers/Models/Bill/DestroyController.php
index befa62ddc1..d589a1c218 100644
--- a/app/Api/V1/Controllers/Models/Bill/DestroyController.php
+++ b/app/Api/V1/Controllers/Models/Bill/DestroyController.php
@@ -37,8 +37,6 @@ class DestroyController extends Controller
/**
* BillController constructor.
- *
-
*/
public function __construct()
{
@@ -58,10 +56,6 @@ class DestroyController extends Controller
* https://api-docs.firefly-iii.org/?urls.primaryName=2.0.0%20(v1)#/bills/deleteBill
*
* Remove the specified resource from storage.
- *
- * @param Bill $bill
- *
- * @return JsonResponse
*/
public function destroy(Bill $bill): JsonResponse
{
diff --git a/app/Api/V1/Controllers/Models/Bill/ListController.php b/app/Api/V1/Controllers/Models/Bill/ListController.php
index df2535bb49..24985d9e08 100644
--- a/app/Api/V1/Controllers/Models/Bill/ListController.php
+++ b/app/Api/V1/Controllers/Models/Bill/ListController.php
@@ -50,8 +50,6 @@ class ListController extends Controller
/**
* BillController constructor.
- *
-
*/
public function __construct()
{
@@ -72,29 +70,26 @@ class ListController extends Controller
*
* Display a listing of the resource.
*
- * @param Bill $bill
- *
- * @return JsonResponse
* @throws FireflyException
*/
public function attachments(Bill $bill): JsonResponse
{
- $manager = $this->getManager();
- $pageSize = $this->parameters->get('limit');
- $collection = $this->repository->getAttachments($bill);
+ $manager = $this->getManager();
+ $pageSize = $this->parameters->get('limit');
+ $collection = $this->repository->getAttachments($bill);
$count = $collection->count();
$attachments = $collection->slice(($this->parameters->get('page') - 1) * $pageSize, $pageSize);
// make paginator:
- $paginator = new LengthAwarePaginator($attachments, $count, $pageSize, $this->parameters->get('page'));
- $paginator->setPath(route('api.v1.bills.attachments', [$bill->id]) . $this->buildParams());
+ $paginator = new LengthAwarePaginator($attachments, $count, $pageSize, $this->parameters->get('page'));
+ $paginator->setPath(route('api.v1.bills.attachments', [$bill->id]).$this->buildParams());
/** @var AttachmentTransformer $transformer */
$transformer = app(AttachmentTransformer::class);
$transformer->setParameters($this->parameters);
- $resource = new FractalCollection($attachments, $transformer, 'attachments');
+ $resource = new FractalCollection($attachments, $transformer, 'attachments');
$resource->setPaginator(new IlluminatePaginatorAdapter($paginator));
return response()->json($manager->createData($resource)->toArray())->header('Content-Type', self::CONTENT_TYPE);
@@ -106,31 +101,28 @@ class ListController extends Controller
*
* List all of them.
*
- * @param Bill $bill
- *
- * @return JsonResponse
* @throws FireflyException
*/
public function rules(Bill $bill): JsonResponse
{
- $manager = $this->getManager();
+ $manager = $this->getManager();
// types to get, page size:
- $pageSize = $this->parameters->get('limit');
+ $pageSize = $this->parameters->get('limit');
// get list of budgets. Count it and split it.
- $collection = $this->repository->getRulesForBill($bill);
- $count = $collection->count();
- $rules = $collection->slice(($this->parameters->get('page') - 1) * $pageSize, $pageSize);
+ $collection = $this->repository->getRulesForBill($bill);
+ $count = $collection->count();
+ $rules = $collection->slice(($this->parameters->get('page') - 1) * $pageSize, $pageSize);
// make paginator:
- $paginator = new LengthAwarePaginator($rules, $count, $pageSize, $this->parameters->get('page'));
- $paginator->setPath(route('api.v1.bills.rules', [$bill->id]) . $this->buildParams());
+ $paginator = new LengthAwarePaginator($rules, $count, $pageSize, $this->parameters->get('page'));
+ $paginator->setPath(route('api.v1.bills.rules', [$bill->id]).$this->buildParams());
/** @var RuleTransformer $transformer */
$transformer = app(RuleTransformer::class);
$transformer->setParameters($this->parameters);
- $resource = new FractalCollection($rules, $transformer, 'rules');
+ $resource = new FractalCollection($rules, $transformer, 'rules');
$resource->setPaginator(new IlluminatePaginatorAdapter($paginator));
return response()->json($manager->createData($resource)->toArray())->header('Content-Type', self::CONTENT_TYPE);
@@ -142,28 +134,23 @@ class ListController extends Controller
*
* Show all transactions.
*
- * @param Request $request
- *
- * @param Bill $bill
- *
- * @return JsonResponse
* @throws FireflyException
*/
public function transactions(Request $request, Bill $bill): JsonResponse
{
- $pageSize = $this->parameters->get('limit');
- $type = $request->get('type') ?? 'default';
+ $pageSize = $this->parameters->get('limit');
+ $type = $request->get('type') ?? 'default';
$this->parameters->set('type', $type);
- $types = $this->mapTransactionTypes($this->parameters->get('type'));
- $manager = $this->getManager();
+ $types = $this->mapTransactionTypes($this->parameters->get('type'));
+ $manager = $this->getManager();
/** @var User $admin */
- $admin = auth()->user();
+ $admin = auth()->user();
// use new group collector:
/** @var GroupCollectorInterface $collector */
- $collector = app(GroupCollectorInterface::class);
+ $collector = app(GroupCollectorInterface::class);
$collector
->setUser($admin)
// include source + destination account name and type.
@@ -175,7 +162,8 @@ class ListController extends Controller
// set page to retrieve
->setPage($this->parameters->get('page'))
// set types of transactions to return.
- ->setTypes($types);
+ ->setTypes($types)
+ ;
if (null !== $this->parameters->get('start')) {
$collector->setStart($this->parameters->get('start'));
@@ -185,15 +173,15 @@ class ListController extends Controller
}
// get paginator.
- $paginator = $collector->getPaginatedGroups();
- $paginator->setPath(route('api.v1.bills.transactions', [$bill->id]) . $this->buildParams());
+ $paginator = $collector->getPaginatedGroups();
+ $paginator->setPath(route('api.v1.bills.transactions', [$bill->id]).$this->buildParams());
$transactions = $paginator->getCollection();
/** @var TransactionGroupTransformer $transformer */
- $transformer = app(TransactionGroupTransformer::class);
+ $transformer = app(TransactionGroupTransformer::class);
$transformer->setParameters($this->parameters);
- $resource = new FractalCollection($transactions, $transformer, 'transactions');
+ $resource = new FractalCollection($transactions, $transformer, 'transactions');
$resource->setPaginator(new IlluminatePaginatorAdapter($paginator));
return response()->json($manager->createData($resource)->toArray())->header('Content-Type', self::CONTENT_TYPE);
diff --git a/app/Api/V1/Controllers/Models/Bill/ShowController.php b/app/Api/V1/Controllers/Models/Bill/ShowController.php
index 7848ce9cc9..b18abdddd0 100644
--- a/app/Api/V1/Controllers/Models/Bill/ShowController.php
+++ b/app/Api/V1/Controllers/Models/Bill/ShowController.php
@@ -43,8 +43,6 @@ class ShowController extends Controller
/**
* BillController constructor.
- *
-
*/
public function __construct()
{
@@ -65,24 +63,23 @@ class ShowController extends Controller
*
* Display a listing of the resource.
*
- * @return JsonResponse
* @throws FireflyException
*/
public function index(): JsonResponse
{
$this->repository->correctOrder();
- $bills = $this->repository->getBills();
- $manager = $this->getManager();
- $pageSize = $this->parameters->get('limit');
- $count = $bills->count();
- $bills = $bills->slice(($this->parameters->get('page') - 1) * $pageSize, $pageSize);
- $paginator = new LengthAwarePaginator($bills, $count, $pageSize, $this->parameters->get('page'));
+ $bills = $this->repository->getBills();
+ $manager = $this->getManager();
+ $pageSize = $this->parameters->get('limit');
+ $count = $bills->count();
+ $bills = $bills->slice(($this->parameters->get('page') - 1) * $pageSize, $pageSize);
+ $paginator = new LengthAwarePaginator($bills, $count, $pageSize, $this->parameters->get('page'));
/** @var BillTransformer $transformer */
$transformer = app(BillTransformer::class);
$transformer->setParameters($this->parameters);
- $resource = new FractalCollection($bills, $transformer, 'bills');
+ $resource = new FractalCollection($bills, $transformer, 'bills');
$resource->setPaginator(new IlluminatePaginatorAdapter($paginator));
return response()->json($manager->createData($resource)->toArray())->header('Content-Type', self::CONTENT_TYPE);
@@ -93,19 +90,16 @@ class ShowController extends Controller
* https://api-docs.firefly-iii.org/?urls.primaryName=2.0.0%20(v1)#/bills/getBill
*
* Show the specified bill.
- *
- * @param Bill $bill
- *
- * @return JsonResponse
*/
public function show(Bill $bill): JsonResponse
{
- $manager = $this->getManager();
+ $manager = $this->getManager();
+
/** @var BillTransformer $transformer */
$transformer = app(BillTransformer::class);
$transformer->setParameters($this->parameters);
- $resource = new Item($bill, $transformer, 'bills');
+ $resource = new Item($bill, $transformer, 'bills');
return response()->json($manager->createData($resource)->toArray())->header('Content-Type', self::CONTENT_TYPE);
}
diff --git a/app/Api/V1/Controllers/Models/Bill/StoreController.php b/app/Api/V1/Controllers/Models/Bill/StoreController.php
index 2a819f8912..d5c08063d5 100644
--- a/app/Api/V1/Controllers/Models/Bill/StoreController.php
+++ b/app/Api/V1/Controllers/Models/Bill/StoreController.php
@@ -43,8 +43,6 @@ class StoreController extends Controller
/**
* BillController constructor.
- *
-
*/
public function __construct()
{
@@ -65,22 +63,19 @@ class StoreController extends Controller
*
* Store a bill.
*
- * @param StoreRequest $request
- *
- * @return JsonResponse
* @throws FireflyException
*/
public function store(StoreRequest $request): JsonResponse
{
- $data = $request->getAll();
- $bill = $this->repository->store($data);
- $manager = $this->getManager();
+ $data = $request->getAll();
+ $bill = $this->repository->store($data);
+ $manager = $this->getManager();
/** @var BillTransformer $transformer */
$transformer = app(BillTransformer::class);
$transformer->setParameters($this->parameters);
- $resource = new Item($bill, $transformer, 'bills');
+ $resource = new Item($bill, $transformer, 'bills');
return response()->json($manager->createData($resource)->toArray())->header('Content-Type', self::CONTENT_TYPE);
}
diff --git a/app/Api/V1/Controllers/Models/Bill/UpdateController.php b/app/Api/V1/Controllers/Models/Bill/UpdateController.php
index e17e2945f9..3c8c81bd76 100644
--- a/app/Api/V1/Controllers/Models/Bill/UpdateController.php
+++ b/app/Api/V1/Controllers/Models/Bill/UpdateController.php
@@ -40,8 +40,6 @@ class UpdateController extends Controller
/**
* BillController constructor.
- *
-
*/
public function __construct()
{
@@ -61,23 +59,18 @@ class UpdateController extends Controller
* https://api-docs.firefly-iii.org/?urls.primaryName=2.0.0%20(v1)#/bills/updateBill
*
* Update a bill.
- *
- * @param UpdateRequest $request
- * @param Bill $bill
- *
- * @return JsonResponse
*/
public function update(UpdateRequest $request, Bill $bill): JsonResponse
{
- $data = $request->getAll();
- $bill = $this->repository->update($bill, $data);
- $manager = $this->getManager();
+ $data = $request->getAll();
+ $bill = $this->repository->update($bill, $data);
+ $manager = $this->getManager();
/** @var BillTransformer $transformer */
$transformer = app(BillTransformer::class);
$transformer->setParameters($this->parameters);
- $resource = new Item($bill, $transformer, 'bills');
+ $resource = new Item($bill, $transformer, 'bills');
return response()->json($manager->createData($resource)->toArray())->header('Content-Type', self::CONTENT_TYPE);
}
diff --git a/app/Api/V1/Controllers/Models/Budget/DestroyController.php b/app/Api/V1/Controllers/Models/Budget/DestroyController.php
index 8f6847aee9..d7a473e7de 100644
--- a/app/Api/V1/Controllers/Models/Budget/DestroyController.php
+++ b/app/Api/V1/Controllers/Models/Budget/DestroyController.php
@@ -37,8 +37,6 @@ class DestroyController extends Controller
/**
* DestroyController constructor.
- *
-
*/
public function __construct()
{
@@ -58,10 +56,6 @@ class DestroyController extends Controller
* https://api-docs.firefly-iii.org/?urls.primaryName=2.0.0%20(v1)#/budgets/deleteBudget
*
* Remove the specified resource from storage.
- *
- * @param Budget $budget
- *
- * @return JsonResponse
*/
public function destroy(Budget $budget): JsonResponse
{
diff --git a/app/Api/V1/Controllers/Models/Budget/ListController.php b/app/Api/V1/Controllers/Models/Budget/ListController.php
index 88bf49569c..c7892fb394 100644
--- a/app/Api/V1/Controllers/Models/Budget/ListController.php
+++ b/app/Api/V1/Controllers/Models/Budget/ListController.php
@@ -40,9 +40,7 @@ use Illuminate\Pagination\LengthAwarePaginator;
use League\Fractal\Pagination\IlluminatePaginatorAdapter;
use League\Fractal\Resource\Collection as FractalCollection;
-/***
- * Class ListController
- */
+// Class ListController
class ListController extends Controller
{
use TransactionFilter;
@@ -52,8 +50,6 @@ class ListController extends Controller
/**
* ListController constructor.
- *
-
*/
public function __construct()
{
@@ -74,29 +70,26 @@ class ListController extends Controller
* This endpoint is documented at:
* https://api-docs.firefly-iii.org/?urls.primaryName=2.0.0%20(v1)#/budgets/listAttachmentByBudget
*
- * @param Budget $budget
- *
- * @return JsonResponse
* @throws FireflyException
*/
public function attachments(Budget $budget): JsonResponse
{
- $manager = $this->getManager();
- $pageSize = $this->parameters->get('limit');
- $collection = $this->repository->getAttachments($budget);
+ $manager = $this->getManager();
+ $pageSize = $this->parameters->get('limit');
+ $collection = $this->repository->getAttachments($budget);
$count = $collection->count();
$attachments = $collection->slice(($this->parameters->get('page') - 1) * $pageSize, $pageSize);
// make paginator:
- $paginator = new LengthAwarePaginator($attachments, $count, $pageSize, $this->parameters->get('page'));
- $paginator->setPath(route('api.v1.budgets.attachments', [$budget->id]) . $this->buildParams());
+ $paginator = new LengthAwarePaginator($attachments, $count, $pageSize, $this->parameters->get('page'));
+ $paginator->setPath(route('api.v1.budgets.attachments', [$budget->id]).$this->buildParams());
/** @var AttachmentTransformer $transformer */
$transformer = app(AttachmentTransformer::class);
$transformer->setParameters($this->parameters);
- $resource = new FractalCollection($attachments, $transformer, 'attachments');
+ $resource = new FractalCollection($attachments, $transformer, 'attachments');
$resource->setPaginator(new IlluminatePaginatorAdapter($paginator));
return response()->json($manager->createData($resource)->toArray())->header('Content-Type', self::CONTENT_TYPE);
@@ -108,26 +101,23 @@ class ListController extends Controller
*
* Display a listing of the resource.
*
- * @param Budget $budget
- *
- * @return JsonResponse
* @throws FireflyException
*/
public function budgetLimits(Budget $budget): JsonResponse
{
- $manager = $this->getManager();
- $pageSize = $this->parameters->get('limit');
+ $manager = $this->getManager();
+ $pageSize = $this->parameters->get('limit');
$this->parameters->set('budget_id', $budget->id);
$collection = $this->blRepository->getBudgetLimits($budget, $this->parameters->get('start'), $this->parameters->get('end'));
$count = $collection->count();
$budgetLimits = $collection->slice(($this->parameters->get('page') - 1) * $pageSize, $pageSize);
$paginator = new LengthAwarePaginator($budgetLimits, $count, $pageSize, $this->parameters->get('page'));
- $paginator->setPath(route('api.v1.budgets.budget-limits', [$budget->id]) . $this->buildParams());
+ $paginator->setPath(route('api.v1.budgets.budget-limits', [$budget->id]).$this->buildParams());
/** @var BudgetLimitTransformer $transformer */
- $transformer = app(BudgetLimitTransformer::class);
+ $transformer = app(BudgetLimitTransformer::class);
$transformer->setParameters($this->parameters);
- $resource = new FractalCollection($budgetLimits, $transformer, 'budget_limits');
+ $resource = new FractalCollection($budgetLimits, $transformer, 'budget_limits');
$resource->setPaginator(new IlluminatePaginatorAdapter($paginator));
return response()->json($manager->createData($resource)->toArray())->header('Content-Type', self::CONTENT_TYPE);
@@ -139,29 +129,24 @@ class ListController extends Controller
*
* Show all transactions.
*
- * @param Request $request
- *
- * @param Budget $budget
- *
- * @return JsonResponse
* @throws FireflyException
*/
public function transactions(Request $request, Budget $budget): JsonResponse
{
- $pageSize = $this->parameters->get('limit');
+ $pageSize = $this->parameters->get('limit');
- $type = $request->get('type') ?? 'default';
+ $type = $request->get('type') ?? 'default';
$this->parameters->set('type', $type);
- $types = $this->mapTransactionTypes($this->parameters->get('type'));
- $manager = $this->getManager();
+ $types = $this->mapTransactionTypes($this->parameters->get('type'));
+ $manager = $this->getManager();
/** @var User $admin */
- $admin = auth()->user();
+ $admin = auth()->user();
// use new group collector:
/** @var GroupCollectorInterface $collector */
- $collector = app(GroupCollectorInterface::class);
+ $collector = app(GroupCollectorInterface::class);
$collector
->setUser($admin)
// filter on budget.
@@ -173,7 +158,8 @@ class ListController extends Controller
// set page to retrieve
->setPage($this->parameters->get('page'))
// set types of transactions to return.
- ->setTypes($types);
+ ->setTypes($types)
+ ;
if (null !== $this->parameters->get('start')) {
$collector->setStart($this->parameters->get('start'));
@@ -182,14 +168,14 @@ class ListController extends Controller
$collector->setEnd($this->parameters->get('end'));
}
- $paginator = $collector->getPaginatedGroups();
- $paginator->setPath(route('api.v1.budgets.transactions', [$budget->id]) . $this->buildParams());
+ $paginator = $collector->getPaginatedGroups();
+ $paginator->setPath(route('api.v1.budgets.transactions', [$budget->id]).$this->buildParams());
$transactions = $paginator->getCollection();
/** @var TransactionGroupTransformer $transformer */
- $transformer = app(TransactionGroupTransformer::class);
+ $transformer = app(TransactionGroupTransformer::class);
$transformer->setParameters($this->parameters);
- $resource = new FractalCollection($transactions, $transformer, 'transactions');
+ $resource = new FractalCollection($transactions, $transformer, 'transactions');
$resource->setPaginator(new IlluminatePaginatorAdapter($paginator));
return response()->json($manager->createData($resource)->toArray())->header('Content-Type', self::CONTENT_TYPE);
@@ -201,27 +187,24 @@ class ListController extends Controller
*
* Show all transactions.
*
- * @param Request $request
- *
- * @return JsonResponse
* @throws FireflyException
*/
public function withoutBudget(Request $request): JsonResponse
{
- $pageSize = $this->parameters->get('limit');
+ $pageSize = $this->parameters->get('limit');
- $type = $request->get('type') ?? 'default';
+ $type = $request->get('type') ?? 'default';
$this->parameters->set('type', $type);
- $types = $this->mapTransactionTypes($this->parameters->get('type'));
- $manager = $this->getManager();
+ $types = $this->mapTransactionTypes($this->parameters->get('type'));
+ $manager = $this->getManager();
/** @var User $admin */
- $admin = auth()->user();
+ $admin = auth()->user();
// use new group collector:
/** @var GroupCollectorInterface $collector */
- $collector = app(GroupCollectorInterface::class);
+ $collector = app(GroupCollectorInterface::class);
$collector
->setUser($admin)
// filter on budget.
@@ -233,7 +216,8 @@ class ListController extends Controller
// set page to retrieve
->setPage($this->parameters->get('page'))
// set types of transactions to return.
- ->setTypes($types);
+ ->setTypes($types)
+ ;
if (null !== $this->parameters->get('start')) {
$collector->setStart($this->parameters->get('start'));
@@ -242,14 +226,14 @@ class ListController extends Controller
$collector->setEnd($this->parameters->get('end'));
}
- $paginator = $collector->getPaginatedGroups();
- $paginator->setPath(route('api.v1.budgets.without-budget') . $this->buildParams());
+ $paginator = $collector->getPaginatedGroups();
+ $paginator->setPath(route('api.v1.budgets.without-budget').$this->buildParams());
$transactions = $paginator->getCollection();
/** @var TransactionGroupTransformer $transformer */
- $transformer = app(TransactionGroupTransformer::class);
+ $transformer = app(TransactionGroupTransformer::class);
$transformer->setParameters($this->parameters);
- $resource = new FractalCollection($transactions, $transformer, 'transactions');
+ $resource = new FractalCollection($transactions, $transformer, 'transactions');
$resource->setPaginator(new IlluminatePaginatorAdapter($paginator));
return response()->json($manager->createData($resource)->toArray())->header('Content-Type', self::CONTENT_TYPE);
diff --git a/app/Api/V1/Controllers/Models/Budget/ShowController.php b/app/Api/V1/Controllers/Models/Budget/ShowController.php
index 8f36f0fbfb..5c266ed4e8 100644
--- a/app/Api/V1/Controllers/Models/Budget/ShowController.php
+++ b/app/Api/V1/Controllers/Models/Budget/ShowController.php
@@ -45,8 +45,6 @@ class ShowController extends Controller
/**
* ListController constructor.
- *
-
*/
public function __construct()
{
@@ -69,30 +67,29 @@ class ShowController extends Controller
*
* Display a listing of the resource.
*
- * @return JsonResponse
* @throws FireflyException
*/
public function index(): JsonResponse
{
- $manager = $this->getManager();
+ $manager = $this->getManager();
// types to get, page size:
- $pageSize = $this->parameters->get('limit');
+ $pageSize = $this->parameters->get('limit');
// get list of budgets. Count it and split it.
- $collection = $this->repository->getBudgets();
- $count = $collection->count();
- $budgets = $collection->slice(($this->parameters->get('page') - 1) * $pageSize, $pageSize);
+ $collection = $this->repository->getBudgets();
+ $count = $collection->count();
+ $budgets = $collection->slice(($this->parameters->get('page') - 1) * $pageSize, $pageSize);
// make paginator:
- $paginator = new LengthAwarePaginator($budgets, $count, $pageSize, $this->parameters->get('page'));
- $paginator->setPath(route('api.v1.budgets.index') . $this->buildParams());
+ $paginator = new LengthAwarePaginator($budgets, $count, $pageSize, $this->parameters->get('page'));
+ $paginator->setPath(route('api.v1.budgets.index').$this->buildParams());
/** @var BudgetTransformer $transformer */
$transformer = app(BudgetTransformer::class);
$transformer->setParameters($this->parameters);
- $resource = new FractalCollection($budgets, $transformer, 'budgets');
+ $resource = new FractalCollection($budgets, $transformer, 'budgets');
$resource->setPaginator(new IlluminatePaginatorAdapter($paginator));
return response()->json($manager->createData($resource)->toArray())->header('Content-Type', self::CONTENT_TYPE);
@@ -100,20 +97,16 @@ class ShowController extends Controller
/**
* Show a budget.
- *
- * @param Budget $budget
- *
- * @return JsonResponse
*/
public function show(Budget $budget): JsonResponse
{
- $manager = $this->getManager();
+ $manager = $this->getManager();
/** @var BudgetTransformer $transformer */
$transformer = app(BudgetTransformer::class);
$transformer->setParameters($this->parameters);
- $resource = new Item($budget, $transformer, 'budgets');
+ $resource = new Item($budget, $transformer, 'budgets');
return response()->json($manager->createData($resource)->toArray())->header('Content-Type', self::CONTENT_TYPE);
}
diff --git a/app/Api/V1/Controllers/Models/Budget/StoreController.php b/app/Api/V1/Controllers/Models/Budget/StoreController.php
index a70f823a9b..3bc7df5f3c 100644
--- a/app/Api/V1/Controllers/Models/Budget/StoreController.php
+++ b/app/Api/V1/Controllers/Models/Budget/StoreController.php
@@ -40,8 +40,6 @@ class StoreController extends Controller
/**
* StoreController constructor.
- *
-
*/
public function __construct()
{
@@ -62,23 +60,19 @@ class StoreController extends Controller
*
* Store a budget.
*
- * @param StoreRequest $request
- *
- * @return JsonResponse
* @throws FireflyException
- *
*/
public function store(StoreRequest $request): JsonResponse
{
- $budget = $this->repository->store($request->getAll());
+ $budget = $this->repository->store($request->getAll());
$budget->refresh();
- $manager = $this->getManager();
+ $manager = $this->getManager();
/** @var BudgetTransformer $transformer */
$transformer = app(BudgetTransformer::class);
$transformer->setParameters($this->parameters);
- $resource = new Item($budget, $transformer, 'budgets');
+ $resource = new Item($budget, $transformer, 'budgets');
return response()->json($manager->createData($resource)->toArray())->header('Content-Type', self::CONTENT_TYPE);
}
diff --git a/app/Api/V1/Controllers/Models/Budget/UpdateController.php b/app/Api/V1/Controllers/Models/Budget/UpdateController.php
index 5836be33f1..e6e6405255 100644
--- a/app/Api/V1/Controllers/Models/Budget/UpdateController.php
+++ b/app/Api/V1/Controllers/Models/Budget/UpdateController.php
@@ -40,8 +40,6 @@ class UpdateController extends Controller
/**
* UpdateController constructor.
- *
-
*/
public function __construct()
{
@@ -61,23 +59,18 @@ class UpdateController extends Controller
* https://api-docs.firefly-iii.org/?urls.primaryName=2.0.0%20(v1)#/budgets/updateBudget
*
* Update a budget.
- *
- * @param UpdateRequest $request
- * @param Budget $budget
- *
- * @return JsonResponse
*/
public function update(UpdateRequest $request, Budget $budget): JsonResponse
{
- $data = $request->getAll();
- $budget = $this->repository->update($budget, $data);
- $manager = $this->getManager();
+ $data = $request->getAll();
+ $budget = $this->repository->update($budget, $data);
+ $manager = $this->getManager();
/** @var BudgetTransformer $transformer */
$transformer = app(BudgetTransformer::class);
$transformer->setParameters($this->parameters);
- $resource = new Item($budget, $transformer, 'budgets');
+ $resource = new Item($budget, $transformer, 'budgets');
return response()->json($manager->createData($resource)->toArray())->header('Content-Type', self::CONTENT_TYPE);
}
diff --git a/app/Api/V1/Controllers/Models/BudgetLimit/DestroyController.php b/app/Api/V1/Controllers/Models/BudgetLimit/DestroyController.php
index c459b1cee3..968ad1434d 100644
--- a/app/Api/V1/Controllers/Models/BudgetLimit/DestroyController.php
+++ b/app/Api/V1/Controllers/Models/BudgetLimit/DestroyController.php
@@ -40,8 +40,6 @@ class DestroyController extends Controller
/**
* BudgetLimitController constructor.
- *
-
*/
public function __construct()
{
@@ -64,10 +62,6 @@ class DestroyController extends Controller
*
* Remove the specified resource from storage.
*
- * @param Budget $budget
- * @param BudgetLimit $budgetLimit
- *
- * @return JsonResponse
* @throws FireflyException
*/
public function destroy(Budget $budget, BudgetLimit $budgetLimit): JsonResponse
diff --git a/app/Api/V1/Controllers/Models/BudgetLimit/ListController.php b/app/Api/V1/Controllers/Models/BudgetLimit/ListController.php
index adc69dc9a0..5dac95e7bd 100644
--- a/app/Api/V1/Controllers/Models/BudgetLimit/ListController.php
+++ b/app/Api/V1/Controllers/Models/BudgetLimit/ListController.php
@@ -28,7 +28,6 @@ use FireflyIII\Exceptions\FireflyException;
use FireflyIII\Helpers\Collector\GroupCollectorInterface;
use FireflyIII\Models\Budget;
use FireflyIII\Models\BudgetLimit;
-use FireflyIII\Repositories\Budget\BudgetLimitRepositoryInterface;
use FireflyIII\Support\Http\Api\TransactionFilter;
use FireflyIII\Transformers\TransactionGroupTransformer;
use FireflyIII\User;
@@ -44,55 +43,28 @@ class ListController extends Controller
{
use TransactionFilter;
- private BudgetLimitRepositoryInterface $blRepository;
-
- /**
- * BudgetLimitController constructor.
- *
-
- */
- public function __construct()
- {
- parent::__construct();
- $this->middleware(
- function ($request, $next) {
- /** @var User $user */
- $user = auth()->user();
- $this->blRepository = app(BudgetLimitRepositoryInterface::class);
- $this->blRepository->setUser($user);
-
- return $next($request);
- }
- );
- }
-
/**
* This endpoint is documented at:
* https://api-docs.firefly-iii.org/?urls.primaryName=2.0.0%20(v1)#/budgets/listTransactionByBudgetLimit
* Show all transactions.
*
- * @param Request $request
- * @param Budget $budget
- * @param BudgetLimit $budgetLimit
- *
- * @return JsonResponse
* @throws FireflyException
*/
public function transactions(Request $request, Budget $budget, BudgetLimit $budgetLimit): JsonResponse
{
- $pageSize = $this->parameters->get('limit');
- $type = $request->get('type') ?? 'default';
+ $pageSize = $this->parameters->get('limit');
+ $type = $request->get('type') ?? 'default';
$this->parameters->set('type', $type);
- $types = $this->mapTransactionTypes($this->parameters->get('type'));
- $manager = $this->getManager();
+ $types = $this->mapTransactionTypes($this->parameters->get('type'));
+ $manager = $this->getManager();
/** @var User $admin */
- $admin = auth()->user();
+ $admin = auth()->user();
// use new group collector:
/** @var GroupCollectorInterface $collector */
- $collector = app(GroupCollectorInterface::class);
+ $collector = app(GroupCollectorInterface::class);
$collector
->setUser($admin)
// filter on budget.
@@ -104,19 +76,20 @@ class ListController extends Controller
// set page to retrieve
->setPage($this->parameters->get('page'))
// set types of transactions to return.
- ->setTypes($types);
+ ->setTypes($types)
+ ;
$collector->setRange($budgetLimit->start_date, $budgetLimit->end_date);
$collector->setTypes($types);
- $paginator = $collector->getPaginatedGroups();
- $paginator->setPath(route('api.v1.budgets.limits.transactions', [$budget->id, $budgetLimit->id]) . $this->buildParams());
+ $paginator = $collector->getPaginatedGroups();
+ $paginator->setPath(route('api.v1.budgets.limits.transactions', [$budget->id, $budgetLimit->id]).$this->buildParams());
$transactions = $paginator->getCollection();
/** @var TransactionGroupTransformer $transformer */
- $transformer = app(TransactionGroupTransformer::class);
+ $transformer = app(TransactionGroupTransformer::class);
$transformer->setParameters($this->parameters);
- $resource = new FractalCollection($transactions, $transformer, 'transactions');
+ $resource = new FractalCollection($transactions, $transformer, 'transactions');
$resource->setPaginator(new IlluminatePaginatorAdapter($paginator));
return response()->json($manager->createData($resource)->toArray())->header('Content-Type', self::CONTENT_TYPE);
diff --git a/app/Api/V1/Controllers/Models/BudgetLimit/ShowController.php b/app/Api/V1/Controllers/Models/BudgetLimit/ShowController.php
index 1a4c4e6302..c26cddcd19 100644
--- a/app/Api/V1/Controllers/Models/BudgetLimit/ShowController.php
+++ b/app/Api/V1/Controllers/Models/BudgetLimit/ShowController.php
@@ -33,7 +33,6 @@ use FireflyIII\Repositories\Budget\BudgetRepositoryInterface;
use FireflyIII\Transformers\BudgetLimitTransformer;
use FireflyIII\User;
use Illuminate\Http\JsonResponse;
-use Illuminate\Http\Request;
use Illuminate\Pagination\LengthAwarePaginator;
use League\Fractal\Pagination\IlluminatePaginatorAdapter;
use League\Fractal\Resource\Collection as FractalCollection;
@@ -49,8 +48,6 @@ class ShowController extends Controller
/**
* BudgetLimitController constructor.
- *
-
*/
public function __construct()
{
@@ -74,29 +71,23 @@ class ShowController extends Controller
* https://api-docs.firefly-iii.org/?urls.primaryName=2.0.0%20(v1)#/budgets/listBudgetLimitByBudget
*
* Display a listing of the budget limits for this budget.
- *
- * @param Request $request
- * @param Budget $budget
- *
- * @return JsonResponse
- * @throws FireflyException
*/
- public function index(Request $request, Budget $budget): JsonResponse
+ public function index(Budget $budget): JsonResponse
{
- $manager = $this->getManager();
+ $manager = $this->getManager();
$manager->parseIncludes('budget');
$pageSize = $this->parameters->get('limit');
$collection = $this->blRepository->getBudgetLimits($budget, $this->parameters->get('start'), $this->parameters->get('end'));
$count = $collection->count();
$budgetLimits = $collection->slice(($this->parameters->get('page') - 1) * $pageSize, $pageSize);
$paginator = new LengthAwarePaginator($budgetLimits, $count, $pageSize, $this->parameters->get('page'));
- $paginator->setPath(route('api.v1.budgets.limits.index', [$budget->id]) . $this->buildParams());
+ $paginator->setPath(route('api.v1.budgets.limits.index', [$budget->id]).$this->buildParams());
/** @var BudgetLimitTransformer $transformer */
- $transformer = app(BudgetLimitTransformer::class);
+ $transformer = app(BudgetLimitTransformer::class);
$transformer->setParameters($this->parameters);
- $resource = new FractalCollection($budgetLimits, $transformer, 'budget_limits');
+ $resource = new FractalCollection($budgetLimits, $transformer, 'budget_limits');
$resource->setPaginator(new IlluminatePaginatorAdapter($paginator));
return response()->json($manager->createData($resource)->toArray())->header('Content-Type', self::CONTENT_TYPE);
@@ -108,27 +99,24 @@ class ShowController extends Controller
*
* Display a listing of the budget limits for this budget.
*
- * @param SameDateRequest $request
- *
- * @return JsonResponse
- * @throws FireflyException
+ * @SuppressWarnings(PHPMD.UnusedFormalParameter)
*/
public function indexAll(SameDateRequest $request): JsonResponse
{
- $manager = $this->getManager();
+ $manager = $this->getManager();
$manager->parseIncludes('budget');
$pageSize = $this->parameters->get('limit');
$collection = $this->blRepository->getAllBudgetLimits($this->parameters->get('start'), $this->parameters->get('end'));
$count = $collection->count();
$budgetLimits = $collection->slice(($this->parameters->get('page') - 1) * $pageSize, $pageSize);
$paginator = new LengthAwarePaginator($budgetLimits, $count, $pageSize, $this->parameters->get('page'));
- $paginator->setPath(route('api.v1.budget-limits.index') . $this->buildParams());
+ $paginator->setPath(route('api.v1.budget-limits.index').$this->buildParams());
/** @var BudgetLimitTransformer $transformer */
- $transformer = app(BudgetLimitTransformer::class);
+ $transformer = app(BudgetLimitTransformer::class);
$transformer->setParameters($this->parameters);
- $resource = new FractalCollection($budgetLimits, $transformer, 'budget_limits');
+ $resource = new FractalCollection($budgetLimits, $transformer, 'budget_limits');
$resource->setPaginator(new IlluminatePaginatorAdapter($paginator));
return response()->json($manager->createData($resource)->toArray())->header('Content-Type', self::CONTENT_TYPE);
@@ -138,26 +126,21 @@ class ShowController extends Controller
* This endpoint is documented at:
* https://api-docs.firefly-iii.org/?urls.primaryName=2.0.0%20(v1)#/budgets/getBudgetLimit
*
- * @param Request $request
- * @param Budget $budget
- * @param BudgetLimit $budgetLimit
- *
- * @return JsonResponse
* @throws FireflyException
*/
- public function show(Request $request, Budget $budget, BudgetLimit $budgetLimit): JsonResponse
+ public function show(Budget $budget, BudgetLimit $budgetLimit): JsonResponse
{
- if ((int)$budget->id !== (int)$budgetLimit->budget_id) {
+ if ($budget->id !== $budgetLimit->budget_id) {
throw new FireflyException('20028: The budget limit does not belong to the budget.');
}
// continue!
- $manager = $this->getManager();
+ $manager = $this->getManager();
/** @var BudgetLimitTransformer $transformer */
$transformer = app(BudgetLimitTransformer::class);
$transformer->setParameters($this->parameters);
- $resource = new Item($budgetLimit, $transformer, 'budget_limits');
+ $resource = new Item($budgetLimit, $transformer, 'budget_limits');
return response()->json($manager->createData($resource)->toArray())->header('Content-Type', self::CONTENT_TYPE);
}
diff --git a/app/Api/V1/Controllers/Models/BudgetLimit/StoreController.php b/app/Api/V1/Controllers/Models/BudgetLimit/StoreController.php
index 3cb8d1858b..32913dc1d3 100644
--- a/app/Api/V1/Controllers/Models/BudgetLimit/StoreController.php
+++ b/app/Api/V1/Controllers/Models/BudgetLimit/StoreController.php
@@ -41,8 +41,6 @@ class StoreController extends Controller
/**
* BudgetLimitController constructor.
- *
-
*/
public function __construct()
{
@@ -64,11 +62,6 @@ class StoreController extends Controller
* https://api-docs.firefly-iii.org/?urls.primaryName=2.0.0%20(v1)#/budgets/storeBudgetLimit
*
* Store a newly created resource in storage.
- *
- * @param StoreRequest $request
- * @param Budget $budget
- *
- * @return JsonResponse
*/
public function store(StoreRequest $request, Budget $budget): JsonResponse
{
@@ -77,13 +70,14 @@ class StoreController extends Controller
$data['end_date'] = $data['end'];
$data['budget_id'] = $budget->id;
- $budgetLimit = $this->blRepository->store($data);
- $manager = $this->getManager();
+ $budgetLimit = $this->blRepository->store($data);
+ $manager = $this->getManager();
+
/** @var BudgetLimitTransformer $transformer */
- $transformer = app(BudgetLimitTransformer::class);
+ $transformer = app(BudgetLimitTransformer::class);
$transformer->setParameters($this->parameters);
- $resource = new Item($budgetLimit, $transformer, 'budget_limits');
+ $resource = new Item($budgetLimit, $transformer, 'budget_limits');
return response()->json($manager->createData($resource)->toArray())->header('Content-Type', self::CONTENT_TYPE);
}
diff --git a/app/Api/V1/Controllers/Models/BudgetLimit/UpdateController.php b/app/Api/V1/Controllers/Models/BudgetLimit/UpdateController.php
index 8cf724245d..31a9e81244 100644
--- a/app/Api/V1/Controllers/Models/BudgetLimit/UpdateController.php
+++ b/app/Api/V1/Controllers/Models/BudgetLimit/UpdateController.php
@@ -46,8 +46,6 @@ class UpdateController extends Controller
* https://api-docs.firefly-iii.org/?urls.primaryName=2.0.0%20(v1)#/budgets/updateBudgetLimit
*
* BudgetLimitController constructor.
- *
-
*/
public function __construct()
{
@@ -69,16 +67,11 @@ class UpdateController extends Controller
* This endpoint is documented at:
* https://api-docs.firefly-iii.org/?urls.primaryName=2.0.0%20(v1)#/budgets/updateBudgetLimit
*
- * @param UpdateRequest $request
- * @param Budget $budget
- * @param BudgetLimit $budgetLimit
- *
- * @return JsonResponse
* @throws FireflyException
*/
public function update(UpdateRequest $request, Budget $budget, BudgetLimit $budgetLimit): JsonResponse
{
- if ((int)$budget->id !== (int)$budgetLimit->budget_id) {
+ if ($budget->id !== $budgetLimit->budget_id) {
throw new FireflyException('20028: The budget limit does not belong to the budget.');
}
$data = $request->getAll();
@@ -87,10 +80,10 @@ class UpdateController extends Controller
$manager = $this->getManager();
/** @var BudgetLimitTransformer $transformer */
- $transformer = app(BudgetLimitTransformer::class);
+ $transformer = app(BudgetLimitTransformer::class);
$transformer->setParameters($this->parameters);
- $resource = new Item($budgetLimit, $transformer, 'budget_limits');
+ $resource = new Item($budgetLimit, $transformer, 'budget_limits');
return response()->json($manager->createData($resource)->toArray())->header('Content-Type', self::CONTENT_TYPE);
}
diff --git a/app/Api/V1/Controllers/Models/Category/DestroyController.php b/app/Api/V1/Controllers/Models/Category/DestroyController.php
index 3e977e948d..10d6b8ebe6 100644
--- a/app/Api/V1/Controllers/Models/Category/DestroyController.php
+++ b/app/Api/V1/Controllers/Models/Category/DestroyController.php
@@ -37,8 +37,6 @@ class DestroyController extends Controller
/**
* CategoryController constructor.
- *
-
*/
public function __construct()
{
@@ -58,10 +56,6 @@ class DestroyController extends Controller
* https://api-docs.firefly-iii.org/?urls.primaryName=2.0.0%20(v1)#/categories/deleteCategory
*
* Remove the specified resource from storage.
- *
- * @param Category $category
- *
- * @return JsonResponse
*/
public function destroy(Category $category): JsonResponse
{
diff --git a/app/Api/V1/Controllers/Models/Category/ListController.php b/app/Api/V1/Controllers/Models/Category/ListController.php
index ffc37839e1..4377a47b80 100644
--- a/app/Api/V1/Controllers/Models/Category/ListController.php
+++ b/app/Api/V1/Controllers/Models/Category/ListController.php
@@ -49,8 +49,6 @@ class ListController extends Controller
/**
* CategoryController constructor.
- *
-
*/
public function __construct()
{
@@ -69,29 +67,26 @@ class ListController extends Controller
* This endpoint is documented at:
* https://api-docs.firefly-iii.org/?urls.primaryName=2.0.0%20(v1)#/categories/listAttachmentByCategory
*
- * @param Category $category
- *
- * @return JsonResponse
* @throws FireflyException
*/
public function attachments(Category $category): JsonResponse
{
- $manager = $this->getManager();
- $pageSize = $this->parameters->get('limit');
- $collection = $this->repository->getAttachments($category);
+ $manager = $this->getManager();
+ $pageSize = $this->parameters->get('limit');
+ $collection = $this->repository->getAttachments($category);
$count = $collection->count();
$attachments = $collection->slice(($this->parameters->get('page') - 1) * $pageSize, $pageSize);
// make paginator:
- $paginator = new LengthAwarePaginator($attachments, $count, $pageSize, $this->parameters->get('page'));
- $paginator->setPath(route('api.v1.categories.attachments', [$category->id]) . $this->buildParams());
+ $paginator = new LengthAwarePaginator($attachments, $count, $pageSize, $this->parameters->get('page'));
+ $paginator->setPath(route('api.v1.categories.attachments', [$category->id]).$this->buildParams());
/** @var AttachmentTransformer $transformer */
$transformer = app(AttachmentTransformer::class);
$transformer->setParameters($this->parameters);
- $resource = new FractalCollection($attachments, $transformer, 'attachments');
+ $resource = new FractalCollection($attachments, $transformer, 'attachments');
$resource->setPaginator(new IlluminatePaginatorAdapter($paginator));
return response()->json($manager->createData($resource)->toArray())->header('Content-Type', self::CONTENT_TYPE);
@@ -103,28 +98,23 @@ class ListController extends Controller
*
* Show all transactions.
*
- * @param Request $request
- *
- * @param Category $category
- *
- * @return JsonResponse
* @throws FireflyException
*/
public function transactions(Request $request, Category $category): JsonResponse
{
- $pageSize = $this->parameters->get('limit');
- $type = $request->get('type') ?? 'default';
+ $pageSize = $this->parameters->get('limit');
+ $type = $request->get('type') ?? 'default';
$this->parameters->set('type', $type);
- $types = $this->mapTransactionTypes($this->parameters->get('type'));
- $manager = $this->getManager();
+ $types = $this->mapTransactionTypes($this->parameters->get('type'));
+ $manager = $this->getManager();
/** @var User $admin */
- $admin = auth()->user();
+ $admin = auth()->user();
// use new group collector:
/** @var GroupCollectorInterface $collector */
- $collector = app(GroupCollectorInterface::class);
+ $collector = app(GroupCollectorInterface::class);
$collector
->setUser($admin)
// filter on category.
@@ -136,7 +126,8 @@ class ListController extends Controller
// set page to retrieve
->setPage($this->parameters->get('page'))
// set types of transactions to return.
- ->setTypes($types);
+ ->setTypes($types)
+ ;
if (null !== $this->parameters->get('start')) {
$collector->setStart($this->parameters->get('start'));
@@ -145,15 +136,15 @@ class ListController extends Controller
$collector->setEnd($this->parameters->get('end'));
}
- $paginator = $collector->getPaginatedGroups();
- $paginator->setPath(route('api.v1.categories.transactions', [$category->id]) . $this->buildParams());
+ $paginator = $collector->getPaginatedGroups();
+ $paginator->setPath(route('api.v1.categories.transactions', [$category->id]).$this->buildParams());
$transactions = $paginator->getCollection();
/** @var TransactionGroupTransformer $transformer */
- $transformer = app(TransactionGroupTransformer::class);
+ $transformer = app(TransactionGroupTransformer::class);
$transformer->setParameters($this->parameters);
- $resource = new FractalCollection($transactions, $transformer, 'transactions');
+ $resource = new FractalCollection($transactions, $transformer, 'transactions');
$resource->setPaginator(new IlluminatePaginatorAdapter($paginator));
return response()->json($manager->createData($resource)->toArray())->header('Content-Type', self::CONTENT_TYPE);
diff --git a/app/Api/V1/Controllers/Models/Category/ShowController.php b/app/Api/V1/Controllers/Models/Category/ShowController.php
index 5a772647a1..8ff9c81972 100644
--- a/app/Api/V1/Controllers/Models/Category/ShowController.php
+++ b/app/Api/V1/Controllers/Models/Category/ShowController.php
@@ -43,8 +43,6 @@ class ShowController extends Controller
/**
* CategoryController constructor.
- *
-
*/
public function __construct()
{
@@ -65,29 +63,28 @@ class ShowController extends Controller
*
* Display a listing of the resource.
*
- * @return JsonResponse
* @throws FireflyException
*/
public function index(): JsonResponse
{
- $manager = $this->getManager();
+ $manager = $this->getManager();
// types to get, page size:
- $pageSize = $this->parameters->get('limit');
+ $pageSize = $this->parameters->get('limit');
// get list of budgets. Count it and split it.
- $collection = $this->repository->getCategories();
- $count = $collection->count();
- $categories = $collection->slice(($this->parameters->get('page') - 1) * $pageSize, $pageSize);
+ $collection = $this->repository->getCategories();
+ $count = $collection->count();
+ $categories = $collection->slice(($this->parameters->get('page') - 1) * $pageSize, $pageSize);
// make paginator:
- $paginator = new LengthAwarePaginator($categories, $count, $pageSize, $this->parameters->get('page'));
- $paginator->setPath(route('api.v1.categories.index') . $this->buildParams());
+ $paginator = new LengthAwarePaginator($categories, $count, $pageSize, $this->parameters->get('page'));
+ $paginator->setPath(route('api.v1.categories.index').$this->buildParams());
/** @var CategoryTransformer $transformer */
$transformer = app(CategoryTransformer::class);
$transformer->setParameters($this->parameters);
- $resource = new FractalCollection($categories, $transformer, 'categories');
+ $resource = new FractalCollection($categories, $transformer, 'categories');
$resource->setPaginator(new IlluminatePaginatorAdapter($paginator));
return response()->json($manager->createData($resource)->toArray())->header('Content-Type', self::CONTENT_TYPE);
@@ -98,20 +95,16 @@ class ShowController extends Controller
* https://api-docs.firefly-iii.org/?urls.primaryName=2.0.0%20(v1)#/categories/getCategory
*
* Show the category.
- *
- * @param Category $category
- *
- * @return JsonResponse
*/
public function show(Category $category): JsonResponse
{
- $manager = $this->getManager();
+ $manager = $this->getManager();
/** @var CategoryTransformer $transformer */
$transformer = app(CategoryTransformer::class);
$transformer->setParameters($this->parameters);
- $resource = new Item($category, $transformer, 'categories');
+ $resource = new Item($category, $transformer, 'categories');
return response()->json($manager->createData($resource)->toArray())->header('Content-Type', self::CONTENT_TYPE);
}
diff --git a/app/Api/V1/Controllers/Models/Category/StoreController.php b/app/Api/V1/Controllers/Models/Category/StoreController.php
index 9ae15f6382..12ccc9517b 100644
--- a/app/Api/V1/Controllers/Models/Category/StoreController.php
+++ b/app/Api/V1/Controllers/Models/Category/StoreController.php
@@ -40,8 +40,6 @@ class StoreController extends Controller
/**
* CategoryController constructor.
- *
-
*/
public function __construct()
{
@@ -62,21 +60,18 @@ class StoreController extends Controller
*
* Store new category.
*
- * @param StoreRequest $request
- *
- * @return JsonResponse
* @throws FireflyException
*/
public function store(StoreRequest $request): JsonResponse
{
- $category = $this->repository->store($request->getAll());
- $manager = $this->getManager();
+ $category = $this->repository->store($request->getAll());
+ $manager = $this->getManager();
/** @var CategoryTransformer $transformer */
$transformer = app(CategoryTransformer::class);
$transformer->setParameters($this->parameters);
- $resource = new Item($category, $transformer, 'categories');
+ $resource = new Item($category, $transformer, 'categories');
return response()->json($manager->createData($resource)->toArray())->header('Content-Type', self::CONTENT_TYPE);
}
diff --git a/app/Api/V1/Controllers/Models/Category/UpdateController.php b/app/Api/V1/Controllers/Models/Category/UpdateController.php
index c5bf2f04f4..9efa912e72 100644
--- a/app/Api/V1/Controllers/Models/Category/UpdateController.php
+++ b/app/Api/V1/Controllers/Models/Category/UpdateController.php
@@ -40,8 +40,6 @@ class UpdateController extends Controller
/**
* CategoryController constructor.
- *
-
*/
public function __construct()
{
@@ -61,23 +59,18 @@ class UpdateController extends Controller
* https://api-docs.firefly-iii.org/?urls.primaryName=2.0.0%20(v1)#/categories/updateCategory
*
* Update the category.
- *
- * @param UpdateRequest $request
- * @param Category $category
- *
- * @return JsonResponse
*/
public function update(UpdateRequest $request, Category $category): JsonResponse
{
- $data = $request->getAll();
- $category = $this->repository->update($category, $data);
- $manager = $this->getManager();
+ $data = $request->getAll();
+ $category = $this->repository->update($category, $data);
+ $manager = $this->getManager();
/** @var CategoryTransformer $transformer */
$transformer = app(CategoryTransformer::class);
$transformer->setParameters($this->parameters);
- $resource = new Item($category, $transformer, 'categories');
+ $resource = new Item($category, $transformer, 'categories');
return response()->json($manager->createData($resource)->toArray())->header('Content-Type', self::CONTENT_TYPE);
}
diff --git a/app/Api/V1/Controllers/Models/ObjectGroup/DestroyController.php b/app/Api/V1/Controllers/Models/ObjectGroup/DestroyController.php
index d9da7ec3e9..f253d9a956 100644
--- a/app/Api/V1/Controllers/Models/ObjectGroup/DestroyController.php
+++ b/app/Api/V1/Controllers/Models/ObjectGroup/DestroyController.php
@@ -38,8 +38,6 @@ class DestroyController extends Controller
/**
* ObjectGroupController constructor.
- *
-
*/
public function __construct()
{
@@ -61,10 +59,6 @@ class DestroyController extends Controller
* https://api-docs.firefly-iii.org/?urls.primaryName=2.0.0%20(v1)#/object_groups/deleteObjectGroup
*
* Remove the specified resource from storage.
- *
- * @param ObjectGroup $objectGroup
- *
- * @return JsonResponse
*/
public function destroy(ObjectGroup $objectGroup): JsonResponse
{
diff --git a/app/Api/V1/Controllers/Models/ObjectGroup/ListController.php b/app/Api/V1/Controllers/Models/ObjectGroup/ListController.php
index 33dc0d4e5b..97cc5d794f 100644
--- a/app/Api/V1/Controllers/Models/ObjectGroup/ListController.php
+++ b/app/Api/V1/Controllers/Models/ObjectGroup/ListController.php
@@ -44,8 +44,6 @@ class ListController extends Controller
/**
* ObjectGroupController constructor.
- *
-
*/
public function __construct()
{
@@ -68,30 +66,27 @@ class ListController extends Controller
*
* List all bills in this object group
*
- * @param ObjectGroup $objectGroup
- *
- * @return JsonResponse
* @throws FireflyException
*/
public function bills(ObjectGroup $objectGroup): JsonResponse
{
- $manager = $this->getManager();
+ $manager = $this->getManager();
- $pageSize = $this->parameters->get('limit');
+ $pageSize = $this->parameters->get('limit');
// get list of piggy banks. Count it and split it.
- $collection = $this->repository->getBills($objectGroup);
- $count = $collection->count();
- $bills = $collection->slice(($this->parameters->get('page') - 1) * $pageSize, $pageSize);
+ $collection = $this->repository->getBills($objectGroup);
+ $count = $collection->count();
+ $bills = $collection->slice(($this->parameters->get('page') - 1) * $pageSize, $pageSize);
// make paginator:
- $paginator = new LengthAwarePaginator($bills, $count, $pageSize, $this->parameters->get('page'));
- $paginator->setPath(route('api.v1.currencies.bills', [$objectGroup->id]) . $this->buildParams());
+ $paginator = new LengthAwarePaginator($bills, $count, $pageSize, $this->parameters->get('page'));
+ $paginator->setPath(route('api.v1.currencies.bills', [$objectGroup->id]).$this->buildParams());
/** @var BillTransformer $transformer */
$transformer = app(BillTransformer::class);
$transformer->setParameters($this->parameters);
- $resource = new FractalCollection($bills, $transformer, 'bills');
+ $resource = new FractalCollection($bills, $transformer, 'bills');
$resource->setPaginator(new IlluminatePaginatorAdapter($paginator));
return response()->json($manager->createData($resource)->toArray())->header('Content-Type', self::CONTENT_TYPE);
@@ -103,33 +98,30 @@ class ListController extends Controller
*
* List all piggies under the object group.
*
- * @param ObjectGroup $objectGroup
- *
- * @return JsonResponse
* @throws FireflyException
*/
public function piggyBanks(ObjectGroup $objectGroup): JsonResponse
{
// create some objects:
- $manager = $this->getManager();
+ $manager = $this->getManager();
// types to get, page size:
- $pageSize = $this->parameters->get('limit');
+ $pageSize = $this->parameters->get('limit');
// get list of piggy banks. Count it and split it.
- $collection = $this->repository->getPiggyBanks($objectGroup);
- $count = $collection->count();
- $piggyBanks = $collection->slice(($this->parameters->get('page') - 1) * $pageSize, $pageSize);
+ $collection = $this->repository->getPiggyBanks($objectGroup);
+ $count = $collection->count();
+ $piggyBanks = $collection->slice(($this->parameters->get('page') - 1) * $pageSize, $pageSize);
// make paginator:
- $paginator = new LengthAwarePaginator($piggyBanks, $count, $pageSize, $this->parameters->get('page'));
- $paginator->setPath(route('api.v1.object-groups.piggy-banks', [$objectGroup->id]) . $this->buildParams());
+ $paginator = new LengthAwarePaginator($piggyBanks, $count, $pageSize, $this->parameters->get('page'));
+ $paginator->setPath(route('api.v1.object-groups.piggy-banks', [$objectGroup->id]).$this->buildParams());
/** @var PiggyBankTransformer $transformer */
$transformer = app(PiggyBankTransformer::class);
$transformer->setParameters($this->parameters);
- $resource = new FractalCollection($piggyBanks, $transformer, 'piggy_banks');
+ $resource = new FractalCollection($piggyBanks, $transformer, 'piggy_banks');
$resource->setPaginator(new IlluminatePaginatorAdapter($paginator));
return response()->json($manager->createData($resource)->toArray())->header('Content-Type', self::CONTENT_TYPE);
diff --git a/app/Api/V1/Controllers/Models/ObjectGroup/ShowController.php b/app/Api/V1/Controllers/Models/ObjectGroup/ShowController.php
index ae8e202aa3..c7452c3d5b 100644
--- a/app/Api/V1/Controllers/Models/ObjectGroup/ShowController.php
+++ b/app/Api/V1/Controllers/Models/ObjectGroup/ShowController.php
@@ -24,13 +24,11 @@ declare(strict_types=1);
namespace FireflyIII\Api\V1\Controllers\Models\ObjectGroup;
use FireflyIII\Api\V1\Controllers\Controller;
-use FireflyIII\Exceptions\FireflyException;
use FireflyIII\Models\ObjectGroup;
use FireflyIII\Repositories\ObjectGroup\ObjectGroupRepositoryInterface;
use FireflyIII\Transformers\ObjectGroupTransformer;
use FireflyIII\User;
use Illuminate\Http\JsonResponse;
-use Illuminate\Http\Request;
use Illuminate\Pagination\LengthAwarePaginator;
use League\Fractal\Pagination\IlluminatePaginatorAdapter;
use League\Fractal\Resource\Collection as FractalCollection;
@@ -45,8 +43,6 @@ class ShowController extends Controller
/**
* ObjectGroupController constructor.
- *
-
*/
public function __construct()
{
@@ -68,18 +64,13 @@ class ShowController extends Controller
* https://api-docs.firefly-iii.org/?urls.primaryName=2.0.0%20(v1)#/object_groups/listObjectGroups
*
* Display a listing of the resource.
- *
- * @param Request $request
- *
- * @return JsonResponse
- * @throws FireflyException
*/
- public function index(Request $request): JsonResponse
+ public function index(): JsonResponse
{
- $manager = $this->getManager();
+ $manager = $this->getManager();
// types to get, page size:
- $pageSize = $this->parameters->get('limit');
+ $pageSize = $this->parameters->get('limit');
$this->repository->resetOrder();
$collection = $this->repository->get();
@@ -87,14 +78,14 @@ class ShowController extends Controller
$objectGroups = $collection->slice(($this->parameters->get('page') - 1) * $pageSize, $pageSize);
// make paginator:
- $paginator = new LengthAwarePaginator($objectGroups, $count, $pageSize, $this->parameters->get('page'));
- $paginator->setPath(route('api.v1.object-groups.index') . $this->buildParams());
+ $paginator = new LengthAwarePaginator($objectGroups, $count, $pageSize, $this->parameters->get('page'));
+ $paginator->setPath(route('api.v1.object-groups.index').$this->buildParams());
/** @var ObjectGroupTransformer $transformer */
- $transformer = app(ObjectGroupTransformer::class);
+ $transformer = app(ObjectGroupTransformer::class);
$transformer->setParameters($this->parameters);
- $resource = new FractalCollection($objectGroups, $transformer, 'object_groups');
+ $resource = new FractalCollection($objectGroups, $transformer, 'object_groups');
$resource->setPaginator(new IlluminatePaginatorAdapter($paginator));
return response()->json($manager->createData($resource)->toArray())->header('Content-Type', self::CONTENT_TYPE);
@@ -105,21 +96,17 @@ class ShowController extends Controller
* https://api-docs.firefly-iii.org/?urls.primaryName=2.0.0%20(v1)#/object_groups/getObjectGroup
*
* Show single instance.
- *
- * @param ObjectGroup $objectGroup
- *
- * @return JsonResponse
*/
public function show(ObjectGroup $objectGroup): JsonResponse
{
- $manager = $this->getManager();
+ $manager = $this->getManager();
$this->repository->resetOrder();
$objectGroup->refresh();
/** @var ObjectGroupTransformer $transformer */
$transformer = app(ObjectGroupTransformer::class);
$transformer->setParameters($this->parameters);
- $resource = new Item($objectGroup, $transformer, 'object_groups');
+ $resource = new Item($objectGroup, $transformer, 'object_groups');
return response()->json($manager->createData($resource)->toArray())->header('Content-Type', self::CONTENT_TYPE);
}
diff --git a/app/Api/V1/Controllers/Models/ObjectGroup/UpdateController.php b/app/Api/V1/Controllers/Models/ObjectGroup/UpdateController.php
index 21ebcbf6fc..02b6d0f6ac 100644
--- a/app/Api/V1/Controllers/Models/ObjectGroup/UpdateController.php
+++ b/app/Api/V1/Controllers/Models/ObjectGroup/UpdateController.php
@@ -41,8 +41,6 @@ class UpdateController extends Controller
/**
* ObjectGroupController constructor.
- *
-
*/
public function __construct()
{
@@ -62,23 +60,18 @@ class UpdateController extends Controller
/**
* This endpoint is documented at:
* https://api-docs.firefly-iii.org/?urls.primaryName=2.0.0%20(v1)#/object_groups/updateObjectGroup
- *
- * @param UpdateRequest $request
- * @param ObjectGroup $objectGroup
- *
- * @return JsonResponse
*/
public function update(UpdateRequest $request, ObjectGroup $objectGroup): JsonResponse
{
- $data = $request->getUpdateData();
+ $data = $request->getUpdateData();
$this->repository->update($objectGroup, $data);
$this->repository->resetOrder();
- $manager = $this->getManager();
+ $manager = $this->getManager();
/** @var ObjectGroupTransformer $transformer */
$transformer = app(ObjectGroupTransformer::class);
$transformer->setParameters($this->parameters);
- $resource = new Item($objectGroup, $transformer, 'object_groups');
+ $resource = new Item($objectGroup, $transformer, 'object_groups');
return response()->json($manager->createData($resource)->toArray())->header('Content-Type', self::CONTENT_TYPE);
}
diff --git a/app/Api/V1/Controllers/Models/PiggyBank/DestroyController.php b/app/Api/V1/Controllers/Models/PiggyBank/DestroyController.php
index 6c1c4fd021..69dfa0485b 100644
--- a/app/Api/V1/Controllers/Models/PiggyBank/DestroyController.php
+++ b/app/Api/V1/Controllers/Models/PiggyBank/DestroyController.php
@@ -37,8 +37,6 @@ class DestroyController extends Controller
/**
* Constructor.
- *
-
*/
public function __construct()
{
@@ -58,10 +56,6 @@ class DestroyController extends Controller
* https://api-docs.firefly-iii.org/?urls.primaryName=2.0.0%20(v1)#/piggy_banks/deletePiggyBank
*
* Delete the resource.
- *
- * @param PiggyBank $piggyBank
- *
- * @return JsonResponse
*/
public function destroy(PiggyBank $piggyBank): JsonResponse
{
diff --git a/app/Api/V1/Controllers/Models/PiggyBank/ListController.php b/app/Api/V1/Controllers/Models/PiggyBank/ListController.php
index 96a62a4940..4b48b6335a 100644
--- a/app/Api/V1/Controllers/Models/PiggyBank/ListController.php
+++ b/app/Api/V1/Controllers/Models/PiggyBank/ListController.php
@@ -43,8 +43,6 @@ class ListController extends Controller
/**
* Constructor.
- *
-
*/
public function __construct()
{
@@ -63,29 +61,26 @@ class ListController extends Controller
* This endpoint is documented at:
* https://api-docs.firefly-iii.org/?urls.primaryName=2.0.0%20(v1)#/piggy_banks/listAttachmentByPiggyBank
*
- * @param PiggyBank $piggyBank
- *
- * @return JsonResponse
* @throws FireflyException
*/
public function attachments(PiggyBank $piggyBank): JsonResponse
{
- $manager = $this->getManager();
- $pageSize = $this->parameters->get('limit');
- $collection = $this->repository->getAttachments($piggyBank);
+ $manager = $this->getManager();
+ $pageSize = $this->parameters->get('limit');
+ $collection = $this->repository->getAttachments($piggyBank);
$count = $collection->count();
$attachments = $collection->slice(($this->parameters->get('page') - 1) * $pageSize, $pageSize);
// make paginator:
- $paginator = new LengthAwarePaginator($attachments, $count, $pageSize, $this->parameters->get('page'));
- $paginator->setPath(route('api.v1.piggy-banks.attachments', [$piggyBank->id]) . $this->buildParams());
+ $paginator = new LengthAwarePaginator($attachments, $count, $pageSize, $this->parameters->get('page'));
+ $paginator->setPath(route('api.v1.piggy-banks.attachments', [$piggyBank->id]).$this->buildParams());
/** @var AttachmentTransformer $transformer */
$transformer = app(AttachmentTransformer::class);
$transformer->setParameters($this->parameters);
- $resource = new FractalCollection($attachments, $transformer, 'attachments');
+ $resource = new FractalCollection($attachments, $transformer, 'attachments');
$resource->setPaginator(new IlluminatePaginatorAdapter($paginator));
return response()->json($manager->createData($resource)->toArray())->header('Content-Type', self::CONTENT_TYPE);
@@ -97,30 +92,27 @@ class ListController extends Controller
*
* List single resource.
*
- * @param PiggyBank $piggyBank
- *
- * @return JsonResponse
* @throws FireflyException
*/
public function piggyBankEvents(PiggyBank $piggyBank): JsonResponse
{
// types to get, page size:
- $pageSize = $this->parameters->get('limit');
- $manager = $this->getManager();
+ $pageSize = $this->parameters->get('limit');
+ $manager = $this->getManager();
- $collection = $this->repository->getEvents($piggyBank);
- $count = $collection->count();
- $events = $collection->slice(($this->parameters->get('page') - 1) * $pageSize, $pageSize);
+ $collection = $this->repository->getEvents($piggyBank);
+ $count = $collection->count();
+ $events = $collection->slice(($this->parameters->get('page') - 1) * $pageSize, $pageSize);
// make paginator:
- $paginator = new LengthAwarePaginator($events, $count, $pageSize, $this->parameters->get('page'));
- $paginator->setPath(route('api.v1.piggy-banks.events', [$piggyBank->id]) . $this->buildParams());
+ $paginator = new LengthAwarePaginator($events, $count, $pageSize, $this->parameters->get('page'));
+ $paginator->setPath(route('api.v1.piggy-banks.events', [$piggyBank->id]).$this->buildParams());
/** @var PiggyBankEventTransformer $transformer */
$transformer = app(PiggyBankEventTransformer::class);
$transformer->setParameters($this->parameters);
- $resource = new FractalCollection($events, $transformer, 'piggy_bank_events');
+ $resource = new FractalCollection($events, $transformer, 'piggy_bank_events');
$resource->setPaginator(new IlluminatePaginatorAdapter($paginator));
return response()->json($manager->createData($resource)->toArray())->header('Content-Type', self::CONTENT_TYPE);
diff --git a/app/Api/V1/Controllers/Models/PiggyBank/ShowController.php b/app/Api/V1/Controllers/Models/PiggyBank/ShowController.php
index 22bb4f3624..12fcc88eb1 100644
--- a/app/Api/V1/Controllers/Models/PiggyBank/ShowController.php
+++ b/app/Api/V1/Controllers/Models/PiggyBank/ShowController.php
@@ -43,8 +43,6 @@ class ShowController extends Controller
/**
* Constructor.
- *
-
*/
public function __construct()
{
@@ -65,29 +63,28 @@ class ShowController extends Controller
*
* List all of them.
*
- * @return JsonResponse
* @throws FireflyException
*/
public function index(): JsonResponse
{
- $manager = $this->getManager();
+ $manager = $this->getManager();
// types to get, page size:
- $pageSize = $this->parameters->get('limit');
+ $pageSize = $this->parameters->get('limit');
// get list of budgets. Count it and split it.
- $collection = $this->repository->getPiggyBanks();
- $count = $collection->count();
- $piggyBanks = $collection->slice(($this->parameters->get('page') - 1) * $pageSize, $pageSize);
+ $collection = $this->repository->getPiggyBanks();
+ $count = $collection->count();
+ $piggyBanks = $collection->slice(($this->parameters->get('page') - 1) * $pageSize, $pageSize);
// make paginator:
- $paginator = new LengthAwarePaginator($piggyBanks, $count, $pageSize, $this->parameters->get('page'));
- $paginator->setPath(route('api.v1.piggy-banks.index') . $this->buildParams());
+ $paginator = new LengthAwarePaginator($piggyBanks, $count, $pageSize, $this->parameters->get('page'));
+ $paginator->setPath(route('api.v1.piggy-banks.index').$this->buildParams());
/** @var PiggyBankTransformer $transformer */
$transformer = app(PiggyBankTransformer::class);
$transformer->setParameters($this->parameters);
- $resource = new FractalCollection($piggyBanks, $transformer, 'piggy_banks');
+ $resource = new FractalCollection($piggyBanks, $transformer, 'piggy_banks');
$resource->setPaginator(new IlluminatePaginatorAdapter($paginator));
return response()->json($manager->createData($resource)->toArray())->header('Content-Type', self::CONTENT_TYPE);
@@ -98,20 +95,16 @@ class ShowController extends Controller
* https://api-docs.firefly-iii.org/?urls.primaryName=2.0.0%20(v1)#/piggy_banks/getPiggyBank
*
* List single resource.
- *
- * @param PiggyBank $piggyBank
- *
- * @return JsonResponse
*/
public function show(PiggyBank $piggyBank): JsonResponse
{
- $manager = $this->getManager();
+ $manager = $this->getManager();
/** @var PiggyBankTransformer $transformer */
$transformer = app(PiggyBankTransformer::class);
$transformer->setParameters($this->parameters);
- $resource = new Item($piggyBank, $transformer, 'piggy_banks');
+ $resource = new Item($piggyBank, $transformer, 'piggy_banks');
return response()->json($manager->createData($resource)->toArray())->header('Content-Type', self::CONTENT_TYPE);
}
diff --git a/app/Api/V1/Controllers/Models/PiggyBank/StoreController.php b/app/Api/V1/Controllers/Models/PiggyBank/StoreController.php
index a29e0b03d8..ecc97d6662 100644
--- a/app/Api/V1/Controllers/Models/PiggyBank/StoreController.php
+++ b/app/Api/V1/Controllers/Models/PiggyBank/StoreController.php
@@ -40,8 +40,6 @@ class StoreController extends Controller
/**
* Constructor.
- *
-
*/
public function __construct()
{
@@ -62,21 +60,18 @@ class StoreController extends Controller
*
* Store new object.
*
- * @param StoreRequest $request
- *
- * @return JsonResponse
* @throws FireflyException
*/
public function store(StoreRequest $request): JsonResponse
{
- $piggyBank = $this->repository->store($request->getAll());
- $manager = $this->getManager();
+ $piggyBank = $this->repository->store($request->getAll());
+ $manager = $this->getManager();
/** @var PiggyBankTransformer $transformer */
$transformer = app(PiggyBankTransformer::class);
$transformer->setParameters($this->parameters);
- $resource = new Item($piggyBank, $transformer, 'piggy_banks');
+ $resource = new Item($piggyBank, $transformer, 'piggy_banks');
return response()->json($manager->createData($resource)->toArray())->header('Content-Type', self::CONTENT_TYPE);
}
diff --git a/app/Api/V1/Controllers/Models/PiggyBank/UpdateController.php b/app/Api/V1/Controllers/Models/PiggyBank/UpdateController.php
index 9e7e841ee9..06e0a29b04 100644
--- a/app/Api/V1/Controllers/Models/PiggyBank/UpdateController.php
+++ b/app/Api/V1/Controllers/Models/PiggyBank/UpdateController.php
@@ -40,8 +40,6 @@ class UpdateController extends Controller
/**
* Constructor.
- *
-
*/
public function __construct()
{
@@ -61,27 +59,23 @@ class UpdateController extends Controller
* https://api-docs.firefly-iii.org/?urls.primaryName=2.0.0%20(v1)#/piggy_banks/updatePiggyBank
*
* Update piggy bank.
- *
- * @param UpdateRequest $request
- * @param PiggyBank $piggyBank
- *
- * @return JsonResponse
*/
public function update(UpdateRequest $request, PiggyBank $piggyBank): JsonResponse
{
- $data = $request->getAll();
- $piggyBank = $this->repository->update($piggyBank, $data);
+ $data = $request->getAll();
+ $piggyBank = $this->repository->update($piggyBank, $data);
if (array_key_exists('current_amount', $data) && '' !== $data['current_amount']) {
$this->repository->setCurrentAmount($piggyBank, $data['current_amount']);
}
- $manager = $this->getManager();
+ $manager = $this->getManager();
+
/** @var PiggyBankTransformer $transformer */
$transformer = app(PiggyBankTransformer::class);
$transformer->setParameters($this->parameters);
- $resource = new Item($piggyBank, $transformer, 'piggy_banks');
+ $resource = new Item($piggyBank, $transformer, 'piggy_banks');
return response()->json($manager->createData($resource)->toArray())->header('Content-Type', self::CONTENT_TYPE);
}
diff --git a/app/Api/V1/Controllers/Models/Recurrence/DestroyController.php b/app/Api/V1/Controllers/Models/Recurrence/DestroyController.php
index 41018c5403..9985c6e826 100644
--- a/app/Api/V1/Controllers/Models/Recurrence/DestroyController.php
+++ b/app/Api/V1/Controllers/Models/Recurrence/DestroyController.php
@@ -37,8 +37,6 @@ class DestroyController extends Controller
/**
* RecurrenceController constructor.
- *
-
*/
public function __construct()
{
@@ -58,10 +56,6 @@ class DestroyController extends Controller
* https://api-docs.firefly-iii.org/?urls.primaryName=2.0.0%20(v1)#/recurrences/deleteRecurrence
*
* Delete the resource.
- *
- * @param Recurrence $recurrence
- *
- * @return JsonResponse
*/
public function destroy(Recurrence $recurrence): JsonResponse
{
diff --git a/app/Api/V1/Controllers/Models/Recurrence/ListController.php b/app/Api/V1/Controllers/Models/Recurrence/ListController.php
index 9d81586362..162ef9f84b 100644
--- a/app/Api/V1/Controllers/Models/Recurrence/ListController.php
+++ b/app/Api/V1/Controllers/Models/Recurrence/ListController.php
@@ -47,8 +47,6 @@ class ListController extends Controller
/**
* RecurrenceController constructor.
- *
-
*/
public function __construct()
{
@@ -69,29 +67,25 @@ class ListController extends Controller
*
* Show transactions for this recurrence.
*
- * @param Request $request
- * @param Recurrence $recurrence
- *
- * @return JsonResponse
* @throws FireflyException
*/
public function transactions(Request $request, Recurrence $recurrence): JsonResponse
{
- $pageSize = $this->parameters->get('limit');
- $type = $request->get('type') ?? 'default';
+ $pageSize = $this->parameters->get('limit');
+ $type = $request->get('type') ?? 'default';
$this->parameters->set('type', $type);
- $types = $this->mapTransactionTypes($this->parameters->get('type'));
- $manager = $this->getManager();
+ $types = $this->mapTransactionTypes($this->parameters->get('type'));
+ $manager = $this->getManager();
// whatever is returned by the query, it must be part of these journals:
- $journalIds = $this->repository->getJournalIds($recurrence);
+ $journalIds = $this->repository->getJournalIds($recurrence);
/** @var User $admin */
- $admin = auth()->user();
+ $admin = auth()->user();
// use new group collector:
/** @var GroupCollectorInterface $collector */
- $collector = app(GroupCollectorInterface::class);
+ $collector = app(GroupCollectorInterface::class);
$collector
->setUser($admin)
// filter on journal IDs.
@@ -103,7 +97,8 @@ class ListController extends Controller
// set page to retrieve
->setPage($this->parameters->get('page'))
// set types of transactions to return.
- ->setTypes($types);
+ ->setTypes($types)
+ ;
if (null !== $this->parameters->get('start')) {
$collector->setStart($this->parameters->get('start'));
@@ -112,15 +107,15 @@ class ListController extends Controller
$collector->setEnd($this->parameters->get('end'));
}
- $paginator = $collector->getPaginatedGroups();
- $paginator->setPath(route('api.v1.transactions.index') . $this->buildParams());
+ $paginator = $collector->getPaginatedGroups();
+ $paginator->setPath(route('api.v1.transactions.index').$this->buildParams());
$transactions = $paginator->getCollection();
/** @var TransactionGroupTransformer $transformer */
- $transformer = app(TransactionGroupTransformer::class);
+ $transformer = app(TransactionGroupTransformer::class);
$transformer->setParameters($this->parameters);
- $resource = new FractalCollection($transactions, $transformer, 'transactions');
+ $resource = new FractalCollection($transactions, $transformer, 'transactions');
$resource->setPaginator(new IlluminatePaginatorAdapter($paginator));
return response()->json($manager->createData($resource)->toArray())->header('Content-Type', self::CONTENT_TYPE);
diff --git a/app/Api/V1/Controllers/Models/Recurrence/ShowController.php b/app/Api/V1/Controllers/Models/Recurrence/ShowController.php
index 54d1f86c30..83b8fc2b13 100644
--- a/app/Api/V1/Controllers/Models/Recurrence/ShowController.php
+++ b/app/Api/V1/Controllers/Models/Recurrence/ShowController.php
@@ -43,8 +43,6 @@ class ShowController extends Controller
/**
* RecurrenceController constructor.
- *
-
*/
public function __construct()
{
@@ -65,30 +63,29 @@ class ShowController extends Controller
*
* List all of them.
*
- * @return JsonResponse
* @throws FireflyException
*/
public function index(): JsonResponse
{
- $manager = $this->getManager();
+ $manager = $this->getManager();
// types to get, page size:
- $pageSize = $this->parameters->get('limit');
+ $pageSize = $this->parameters->get('limit');
// get list of budgets. Count it and split it.
- $collection = $this->repository->get();
- $count = $collection->count();
- $piggyBanks = $collection->slice(($this->parameters->get('page') - 1) * $pageSize, $pageSize);
+ $collection = $this->repository->get();
+ $count = $collection->count();
+ $piggyBanks = $collection->slice(($this->parameters->get('page') - 1) * $pageSize, $pageSize);
// make paginator:
- $paginator = new LengthAwarePaginator($piggyBanks, $count, $pageSize, $this->parameters->get('page'));
- $paginator->setPath(route('api.v1.recurrences.index') . $this->buildParams());
+ $paginator = new LengthAwarePaginator($piggyBanks, $count, $pageSize, $this->parameters->get('page'));
+ $paginator->setPath(route('api.v1.recurrences.index').$this->buildParams());
/** @var RecurrenceTransformer $transformer */
$transformer = app(RecurrenceTransformer::class);
$transformer->setParameters($this->parameters);
- $resource = new FractalCollection($piggyBanks, $transformer, 'recurrences');
+ $resource = new FractalCollection($piggyBanks, $transformer, 'recurrences');
$resource->setPaginator(new IlluminatePaginatorAdapter($paginator));
return response()->json($manager->createData($resource)->toArray())->header('Content-Type', self::CONTENT_TYPE);
@@ -99,20 +96,16 @@ class ShowController extends Controller
* https://api-docs.firefly-iii.org/?urls.primaryName=2.0.0%20(v1)#/recurrences/getRecurrence
*
* List single resource.
- *
- * @param Recurrence $recurrence
- *
- * @return JsonResponse
*/
public function show(Recurrence $recurrence): JsonResponse
{
- $manager = $this->getManager();
+ $manager = $this->getManager();
/** @var RecurrenceTransformer $transformer */
$transformer = app(RecurrenceTransformer::class);
$transformer->setParameters($this->parameters);
- $resource = new Item($recurrence, $transformer, 'recurrences');
+ $resource = new Item($recurrence, $transformer, 'recurrences');
return response()->json($manager->createData($resource)->toArray())->header('Content-Type', self::CONTENT_TYPE);
}
diff --git a/app/Api/V1/Controllers/Models/Recurrence/StoreController.php b/app/Api/V1/Controllers/Models/Recurrence/StoreController.php
index e213ce03ea..617a509817 100644
--- a/app/Api/V1/Controllers/Models/Recurrence/StoreController.php
+++ b/app/Api/V1/Controllers/Models/Recurrence/StoreController.php
@@ -40,8 +40,6 @@ class StoreController extends Controller
/**
* RecurrenceController constructor.
- *
-
*/
public function __construct()
{
@@ -62,22 +60,19 @@ class StoreController extends Controller
*
* Store new object.
*
- * @param StoreRequest $request
- *
- * @return JsonResponse
* @throws FireflyException
*/
public function store(StoreRequest $request): JsonResponse
{
- $data = $request->getAll();
- $recurrence = $this->repository->store($data);
- $manager = $this->getManager();
+ $data = $request->getAll();
+ $recurrence = $this->repository->store($data);
+ $manager = $this->getManager();
/** @var RecurrenceTransformer $transformer */
$transformer = app(RecurrenceTransformer::class);
$transformer->setParameters($this->parameters);
- $resource = new Item($recurrence, $transformer, 'recurrences');
+ $resource = new Item($recurrence, $transformer, 'recurrences');
return response()->json($manager->createData($resource)->toArray())->header('Content-Type', self::CONTENT_TYPE);
}
diff --git a/app/Api/V1/Controllers/Models/Recurrence/UpdateController.php b/app/Api/V1/Controllers/Models/Recurrence/UpdateController.php
index 04a1a92a19..d56c98efb5 100644
--- a/app/Api/V1/Controllers/Models/Recurrence/UpdateController.php
+++ b/app/Api/V1/Controllers/Models/Recurrence/UpdateController.php
@@ -40,8 +40,6 @@ class UpdateController extends Controller
/**
* RecurrenceController constructor.
- *
-
*/
public function __construct()
{
@@ -61,23 +59,18 @@ class UpdateController extends Controller
* https://api-docs.firefly-iii.org/?urls.primaryName=2.0.0%20(v1)#/recurrences/updateRecurrence
*
* Update single recurrence.
- *
- * @param UpdateRequest $request
- * @param Recurrence $recurrence
- *
- * @return JsonResponse
*/
public function update(UpdateRequest $request, Recurrence $recurrence): JsonResponse
{
- $data = $request->getAll();
- $recurrence = $this->repository->update($recurrence, $data);
- $manager = $this->getManager();
+ $data = $request->getAll();
+ $recurrence = $this->repository->update($recurrence, $data);
+ $manager = $this->getManager();
/** @var RecurrenceTransformer $transformer */
$transformer = app(RecurrenceTransformer::class);
$transformer->setParameters($this->parameters);
- $resource = new Item($recurrence, $transformer, 'recurrences');
+ $resource = new Item($recurrence, $transformer, 'recurrences');
return response()->json($manager->createData($resource)->toArray())->header('Content-Type', self::CONTENT_TYPE);
}
diff --git a/app/Api/V1/Controllers/Models/Rule/DestroyController.php b/app/Api/V1/Controllers/Models/Rule/DestroyController.php
index 20e035f882..ad0b52e9ad 100644
--- a/app/Api/V1/Controllers/Models/Rule/DestroyController.php
+++ b/app/Api/V1/Controllers/Models/Rule/DestroyController.php
@@ -38,8 +38,6 @@ class DestroyController extends Controller
/**
* RuleController constructor.
- *
-
*/
public function __construct()
{
@@ -47,7 +45,7 @@ class DestroyController extends Controller
$this->middleware(
function ($request, $next) {
/** @var User $user */
- $user = auth()->user();
+ $user = auth()->user();
$this->ruleRepository = app(RuleRepositoryInterface::class);
$this->ruleRepository->setUser($user);
@@ -62,10 +60,6 @@ class DestroyController extends Controller
* https://api-docs.firefly-iii.org/?urls.primaryName=2.0.0%20(v1)#/rules/deleteRule
*
* Delete the resource.
- *
- * @param Rule $rule
- *
- * @return JsonResponse
*/
public function destroy(Rule $rule): JsonResponse
{
diff --git a/app/Api/V1/Controllers/Models/Rule/ShowController.php b/app/Api/V1/Controllers/Models/Rule/ShowController.php
index b4b93c7767..a075a0e8be 100644
--- a/app/Api/V1/Controllers/Models/Rule/ShowController.php
+++ b/app/Api/V1/Controllers/Models/Rule/ShowController.php
@@ -44,8 +44,6 @@ class ShowController extends Controller
/**
* RuleController constructor.
- *
-
*/
public function __construct()
{
@@ -53,7 +51,7 @@ class ShowController extends Controller
$this->middleware(
function ($request, $next) {
/** @var User $user */
- $user = auth()->user();
+ $user = auth()->user();
$this->ruleRepository = app(RuleRepositoryInterface::class);
$this->ruleRepository->setUser($user);
@@ -69,30 +67,29 @@ class ShowController extends Controller
*
* List all of them.
*
- * @return JsonResponse
* @throws FireflyException
*/
public function index(): JsonResponse
{
- $manager = $this->getManager();
+ $manager = $this->getManager();
// types to get, page size:
- $pageSize = $this->parameters->get('limit');
+ $pageSize = $this->parameters->get('limit');
// get list of budgets. Count it and split it.
- $collection = $this->ruleRepository->getAll();
- $count = $collection->count();
- $rules = $collection->slice(($this->parameters->get('page') - 1) * $pageSize, $pageSize);
+ $collection = $this->ruleRepository->getAll();
+ $count = $collection->count();
+ $rules = $collection->slice(($this->parameters->get('page') - 1) * $pageSize, $pageSize);
// make paginator:
- $paginator = new LengthAwarePaginator($rules, $count, $pageSize, $this->parameters->get('page'));
- $paginator->setPath(route('api.v1.rules.index') . $this->buildParams());
+ $paginator = new LengthAwarePaginator($rules, $count, $pageSize, $this->parameters->get('page'));
+ $paginator->setPath(route('api.v1.rules.index').$this->buildParams());
/** @var RuleTransformer $transformer */
$transformer = app(RuleTransformer::class);
$transformer->setParameters($this->parameters);
- $resource = new FractalCollection($rules, $transformer, 'rules');
+ $resource = new FractalCollection($rules, $transformer, 'rules');
$resource->setPaginator(new IlluminatePaginatorAdapter($paginator));
return response()->json($manager->createData($resource)->toArray())->header('Content-Type', self::CONTENT_TYPE);
@@ -103,19 +100,16 @@ class ShowController extends Controller
* https://api-docs.firefly-iii.org/?urls.primaryName=2.0.0%20(v1)#/rules/getRule
*
* List single resource.
- *
- * @param Rule $rule
- *
- * @return JsonResponse
*/
public function show(Rule $rule): JsonResponse
{
- $manager = $this->getManager();
+ $manager = $this->getManager();
+
/** @var RuleTransformer $transformer */
$transformer = app(RuleTransformer::class);
$transformer->setParameters($this->parameters);
- $resource = new Item($rule, $transformer, 'rules');
+ $resource = new Item($rule, $transformer, 'rules');
return response()->json($manager->createData($resource)->toArray())->header('Content-Type', self::CONTENT_TYPE);
}
diff --git a/app/Api/V1/Controllers/Models/Rule/StoreController.php b/app/Api/V1/Controllers/Models/Rule/StoreController.php
index 1d5e7ac89c..fab9191954 100644
--- a/app/Api/V1/Controllers/Models/Rule/StoreController.php
+++ b/app/Api/V1/Controllers/Models/Rule/StoreController.php
@@ -40,8 +40,6 @@ class StoreController extends Controller
/**
* RuleController constructor.
- *
-
*/
public function __construct()
{
@@ -49,7 +47,7 @@ class StoreController extends Controller
$this->middleware(
function ($request, $next) {
/** @var User $user */
- $user = auth()->user();
+ $user = auth()->user();
$this->ruleRepository = app(RuleRepositoryInterface::class);
$this->ruleRepository->setUser($user);
@@ -64,20 +62,17 @@ class StoreController extends Controller
* https://api-docs.firefly-iii.org/?urls.primaryName=2.0.0%20(v1)#/rules/storeRule
*
* Store new object.
- *
- * @param StoreRequest $request
- *
- * @return JsonResponse
*/
public function store(StoreRequest $request): JsonResponse
{
- $rule = $this->ruleRepository->store($request->getAll());
- $manager = $this->getManager();
+ $rule = $this->ruleRepository->store($request->getAll());
+ $manager = $this->getManager();
+
/** @var RuleTransformer $transformer */
$transformer = app(RuleTransformer::class);
$transformer->setParameters($this->parameters);
- $resource = new Item($rule, $transformer, 'rules');
+ $resource = new Item($rule, $transformer, 'rules');
return response()->json($manager->createData($resource)->toArray())->header('Content-Type', self::CONTENT_TYPE);
}
diff --git a/app/Api/V1/Controllers/Models/Rule/TriggerController.php b/app/Api/V1/Controllers/Models/Rule/TriggerController.php
index 1f409a592d..fdc855ba53 100644
--- a/app/Api/V1/Controllers/Models/Rule/TriggerController.php
+++ b/app/Api/V1/Controllers/Models/Rule/TriggerController.php
@@ -46,8 +46,6 @@ class TriggerController extends Controller
/**
* RuleController constructor.
- *
-
*/
public function __construct()
{
@@ -55,7 +53,7 @@ class TriggerController extends Controller
$this->middleware(
function ($request, $next) {
/** @var User $user */
- $user = auth()->user();
+ $user = auth()->user();
$this->ruleRepository = app(RuleRepositoryInterface::class);
$this->ruleRepository->setUser($user);
@@ -68,18 +66,13 @@ class TriggerController extends Controller
/**
* This endpoint is documented at:
* https://api-docs.firefly-iii.org/?urls.primaryName=2.0.0%20(v1)#/rules/testRule
- *
- * @param TestRequest $request
- * @param Rule $rule
- *
- * @return JsonResponse
*/
public function testRule(TestRequest $request, Rule $rule): JsonResponse
{
- $parameters = $request->getTestParameters();
+ $parameters = $request->getTestParameters();
/** @var RuleEngineInterface $ruleEngine */
- $ruleEngine = app(RuleEngineInterface::class);
+ $ruleEngine = app(RuleEngineInterface::class);
$ruleEngine->setRules(new Collection([$rule]));
// overrule the rule(s) if necessary.
@@ -96,21 +89,21 @@ class TriggerController extends Controller
$ruleEngine->addOperator(['type' => 'account_id', 'value' => implode(',', $parameters['accounts'])]);
}
-
// file the rule(s)
$transactions = $ruleEngine->find();
$count = $transactions->count();
- $paginator = new LengthAwarePaginator($transactions, $count, 31337, $this->parameters->get('page'));
- $paginator->setPath(route('api.v1.rules.test', [$rule->id]) . $this->buildParams());
+ $paginator = new LengthAwarePaginator($transactions, $count, 31337, $this->parameters->get('page'));
+ $paginator->setPath(route('api.v1.rules.test', [$rule->id]).$this->buildParams());
// resulting list is presented as JSON thing.
- $manager = $this->getManager();
+ $manager = $this->getManager();
+
/** @var TransactionGroupTransformer $transformer */
- $transformer = app(TransactionGroupTransformer::class);
+ $transformer = app(TransactionGroupTransformer::class);
$transformer->setParameters($this->parameters);
- $resource = new FractalCollection($transactions, $transformer, 'transactions');
+ $resource = new FractalCollection($transactions, $transformer, 'transactions');
$resource->setPaginator(new IlluminatePaginatorAdapter($paginator));
return response()->json($manager->createData($resource)->toArray())->header('Content-Type', self::CONTENT_TYPE);
@@ -121,11 +114,6 @@ class TriggerController extends Controller
* https://api-docs.firefly-iii.org/?urls.primaryName=2.0.0%20(v1)#/rules/fireRule
*
* Execute the given rule group on a set of existing transactions.
- *
- * @param TriggerRequest $request
- * @param Rule $rule
- *
- * @return JsonResponse
*/
public function triggerRule(TriggerRequest $request, Rule $rule): JsonResponse
{
@@ -150,7 +138,6 @@ class TriggerController extends Controller
$ruleEngine->addOperator(['type' => 'account_id', 'value' => implode(',', $parameters['accounts'])]);
}
-
// fire the rule(s)
$ruleEngine->fire();
diff --git a/app/Api/V1/Controllers/Models/Rule/UpdateController.php b/app/Api/V1/Controllers/Models/Rule/UpdateController.php
index f4b1f1a8a5..16efffe784 100644
--- a/app/Api/V1/Controllers/Models/Rule/UpdateController.php
+++ b/app/Api/V1/Controllers/Models/Rule/UpdateController.php
@@ -41,8 +41,6 @@ class UpdateController extends Controller
/**
* RuleController constructor.
- *
-
*/
public function __construct()
{
@@ -50,7 +48,7 @@ class UpdateController extends Controller
$this->middleware(
function ($request, $next) {
/** @var User $user */
- $user = auth()->user();
+ $user = auth()->user();
$this->ruleRepository = app(RuleRepositoryInterface::class);
$this->ruleRepository->setUser($user);
@@ -65,23 +63,18 @@ class UpdateController extends Controller
* https://api-docs.firefly-iii.org/?urls.primaryName=2.0.0%20(v1)#/rules/updateRule
*
* Update a rule.
- *
- * @param UpdateRequest $request
- * @param Rule $rule
- *
- * @return JsonResponse
*/
public function update(UpdateRequest $request, Rule $rule): JsonResponse
{
- $data = $request->getAll();
- $rule = $this->ruleRepository->update($rule, $data);
- $manager = $this->getManager();
+ $data = $request->getAll();
+ $rule = $this->ruleRepository->update($rule, $data);
+ $manager = $this->getManager();
/** @var RuleTransformer $transformer */
$transformer = app(RuleTransformer::class);
$transformer->setParameters($this->parameters);
- $resource = new Item($rule, $transformer, 'rules');
+ $resource = new Item($rule, $transformer, 'rules');
return response()->json($manager->createData($resource)->toArray())->header('Content-Type', self::CONTENT_TYPE);
}
diff --git a/app/Api/V1/Controllers/Models/RuleGroup/DestroyController.php b/app/Api/V1/Controllers/Models/RuleGroup/DestroyController.php
index 62f390aef4..67ad164cda 100644
--- a/app/Api/V1/Controllers/Models/RuleGroup/DestroyController.php
+++ b/app/Api/V1/Controllers/Models/RuleGroup/DestroyController.php
@@ -38,8 +38,6 @@ class DestroyController extends Controller
/**
* RuleGroupController constructor.
- *
-
*/
public function __construct()
{
@@ -47,7 +45,7 @@ class DestroyController extends Controller
$this->middleware(
function ($request, $next) {
/** @var User $user */
- $user = auth()->user();
+ $user = auth()->user();
$this->ruleGroupRepository = app(RuleGroupRepositoryInterface::class);
$this->ruleGroupRepository->setUser($user);
@@ -62,10 +60,6 @@ class DestroyController extends Controller
* https://api-docs.firefly-iii.org/?urls.primaryName=2.0.0%20(v1)#/rule_groups/deleteRuleGroup
*
* Delete the resource.
- *
- * @param RuleGroup $ruleGroup
- *
- * @return JsonResponse
*/
public function destroy(RuleGroup $ruleGroup): JsonResponse
{
diff --git a/app/Api/V1/Controllers/Models/RuleGroup/ListController.php b/app/Api/V1/Controllers/Models/RuleGroup/ListController.php
index 5c197da60d..ac881f47c3 100644
--- a/app/Api/V1/Controllers/Models/RuleGroup/ListController.php
+++ b/app/Api/V1/Controllers/Models/RuleGroup/ListController.php
@@ -43,8 +43,6 @@ class ListController extends Controller
/**
* RuleGroupController constructor.
- *
-
*/
public function __construct()
{
@@ -52,7 +50,7 @@ class ListController extends Controller
$this->middleware(
function ($request, $next) {
/** @var User $user */
- $user = auth()->user();
+ $user = auth()->user();
$this->ruleGroupRepository = app(RuleGroupRepositoryInterface::class);
$this->ruleGroupRepository->setUser($user);
@@ -66,31 +64,28 @@ class ListController extends Controller
* This endpoint is documented at:
* https://api-docs.firefly-iii.org/?urls.primaryName=2.0.0%20(v1)#/rule_groups/listRuleByGroup
*
- * @param RuleGroup $group
- *
- * @return JsonResponse
* @throws FireflyException
*/
public function rules(RuleGroup $group): JsonResponse
{
- $manager = $this->getManager();
+ $manager = $this->getManager();
// types to get, page size:
- $pageSize = $this->parameters->get('limit');
+ $pageSize = $this->parameters->get('limit');
// get list of budgets. Count it and split it.
- $collection = $this->ruleGroupRepository->getRules($group);
- $count = $collection->count();
- $rules = $collection->slice(($this->parameters->get('page') - 1) * $pageSize, $pageSize);
+ $collection = $this->ruleGroupRepository->getRules($group);
+ $count = $collection->count();
+ $rules = $collection->slice(($this->parameters->get('page') - 1) * $pageSize, $pageSize);
// make paginator:
- $paginator = new LengthAwarePaginator($rules, $count, $pageSize, $this->parameters->get('page'));
- $paginator->setPath(route('api.v1.rule-groups.rules', [$group->id]) . $this->buildParams());
+ $paginator = new LengthAwarePaginator($rules, $count, $pageSize, $this->parameters->get('page'));
+ $paginator->setPath(route('api.v1.rule-groups.rules', [$group->id]).$this->buildParams());
/** @var RuleTransformer $transformer */
$transformer = app(RuleTransformer::class);
$transformer->setParameters($this->parameters);
- $resource = new FractalCollection($rules, $transformer, 'rules');
+ $resource = new FractalCollection($rules, $transformer, 'rules');
$resource->setPaginator(new IlluminatePaginatorAdapter($paginator));
return response()->json($manager->createData($resource)->toArray())->header('Content-Type', self::CONTENT_TYPE);
diff --git a/app/Api/V1/Controllers/Models/RuleGroup/ShowController.php b/app/Api/V1/Controllers/Models/RuleGroup/ShowController.php
index cfe41894c4..bda98d5f41 100644
--- a/app/Api/V1/Controllers/Models/RuleGroup/ShowController.php
+++ b/app/Api/V1/Controllers/Models/RuleGroup/ShowController.php
@@ -44,8 +44,6 @@ class ShowController extends Controller
/**
* RuleGroupController constructor.
- *
-
*/
public function __construct()
{
@@ -53,7 +51,7 @@ class ShowController extends Controller
$this->middleware(
function ($request, $next) {
/** @var User $user */
- $user = auth()->user();
+ $user = auth()->user();
$this->ruleGroupRepository = app(RuleGroupRepositoryInterface::class);
$this->ruleGroupRepository->setUser($user);
@@ -68,29 +66,28 @@ class ShowController extends Controller
* https://api-docs.firefly-iii.org/?urls.primaryName=2.0.0%20(v1)#/rule_groups/listRuleGroup
* List all of them.
*
- * @return JsonResponse
* @throws FireflyException
*/
public function index(): JsonResponse
{
- $manager = $this->getManager();
+ $manager = $this->getManager();
// types to get, page size:
- $pageSize = $this->parameters->get('limit');
+ $pageSize = $this->parameters->get('limit');
// get list of rule groups. Count it and split it.
- $collection = $this->ruleGroupRepository->get();
- $count = $collection->count();
- $ruleGroups = $collection->slice(($this->parameters->get('page') - 1) * $pageSize, $pageSize);
+ $collection = $this->ruleGroupRepository->get();
+ $count = $collection->count();
+ $ruleGroups = $collection->slice(($this->parameters->get('page') - 1) * $pageSize, $pageSize);
// make paginator:
- $paginator = new LengthAwarePaginator($ruleGroups, $count, $pageSize, $this->parameters->get('page'));
- $paginator->setPath(route('api.v1.rule-groups.index') . $this->buildParams());
+ $paginator = new LengthAwarePaginator($ruleGroups, $count, $pageSize, $this->parameters->get('page'));
+ $paginator->setPath(route('api.v1.rule-groups.index').$this->buildParams());
/** @var RuleGroupTransformer $transformer */
$transformer = app(RuleGroupTransformer::class);
$transformer->setParameters($this->parameters);
- $resource = new FractalCollection($ruleGroups, $transformer, 'rule_groups');
+ $resource = new FractalCollection($ruleGroups, $transformer, 'rule_groups');
$resource->setPaginator(new IlluminatePaginatorAdapter($paginator));
return response()->json($manager->createData($resource)->toArray())->header('Content-Type', self::CONTENT_TYPE);
@@ -101,19 +98,16 @@ class ShowController extends Controller
* https://api-docs.firefly-iii.org/?urls.primaryName=2.0.0%20(v1)#/rule_groups/getRuleGroup
*
* List single resource.
- *
- * @param RuleGroup $ruleGroup
- *
- * @return JsonResponse
*/
public function show(RuleGroup $ruleGroup): JsonResponse
{
- $manager = $this->getManager();
+ $manager = $this->getManager();
+
/** @var RuleGroupTransformer $transformer */
$transformer = app(RuleGroupTransformer::class);
$transformer->setParameters($this->parameters);
- $resource = new Item($ruleGroup, $transformer, 'rule_groups');
+ $resource = new Item($ruleGroup, $transformer, 'rule_groups');
return response()->json($manager->createData($resource)->toArray())->header('Content-Type', self::CONTENT_TYPE);
}
diff --git a/app/Api/V1/Controllers/Models/RuleGroup/StoreController.php b/app/Api/V1/Controllers/Models/RuleGroup/StoreController.php
index 02e1433a6b..746cb7a4d6 100644
--- a/app/Api/V1/Controllers/Models/RuleGroup/StoreController.php
+++ b/app/Api/V1/Controllers/Models/RuleGroup/StoreController.php
@@ -42,8 +42,6 @@ class StoreController extends Controller
/**
* RuleGroupController constructor.
- *
-
*/
public function __construct()
{
@@ -51,12 +49,12 @@ class StoreController extends Controller
$this->middleware(
function ($request, $next) {
/** @var User $user */
- $user = auth()->user();
+ $user = auth()->user();
$this->ruleGroupRepository = app(RuleGroupRepositoryInterface::class);
$this->ruleGroupRepository->setUser($user);
- $this->accountRepository = app(AccountRepositoryInterface::class);
+ $this->accountRepository = app(AccountRepositoryInterface::class);
$this->accountRepository->setUser($user);
return $next($request);
@@ -69,21 +67,17 @@ class StoreController extends Controller
* https://api-docs.firefly-iii.org/?urls.primaryName=2.0.0%20(v1)#/rule_groups/storeRuleGroup
*
* Store new object.
- *
- * @param StoreRequest $request
- *
- * @return JsonResponse
*/
public function store(StoreRequest $request): JsonResponse
{
- $ruleGroup = $this->ruleGroupRepository->store($request->getAll());
- $manager = $this->getManager();
+ $ruleGroup = $this->ruleGroupRepository->store($request->getAll());
+ $manager = $this->getManager();
/** @var RuleGroupTransformer $transformer */
$transformer = app(RuleGroupTransformer::class);
$transformer->setParameters($this->parameters);
- $resource = new Item($ruleGroup, $transformer, 'rule_groups');
+ $resource = new Item($ruleGroup, $transformer, 'rule_groups');
return response()->json($manager->createData($resource)->toArray())->header('Content-Type', self::CONTENT_TYPE);
}
diff --git a/app/Api/V1/Controllers/Models/RuleGroup/TriggerController.php b/app/Api/V1/Controllers/Models/RuleGroup/TriggerController.php
index cda13829b7..7eceb14721 100644
--- a/app/Api/V1/Controllers/Models/RuleGroup/TriggerController.php
+++ b/app/Api/V1/Controllers/Models/RuleGroup/TriggerController.php
@@ -23,7 +23,6 @@ declare(strict_types=1);
namespace FireflyIII\Api\V1\Controllers\Models\RuleGroup;
-use Exception;
use FireflyIII\Api\V1\Controllers\Controller;
use FireflyIII\Api\V1\Requests\Models\RuleGroup\TestRequest;
use FireflyIII\Api\V1\Requests\Models\RuleGroup\TriggerRequest;
@@ -47,8 +46,6 @@ class TriggerController extends Controller
/**
* RuleGroupController constructor.
- *
-
*/
public function __construct()
{
@@ -56,7 +53,7 @@ class TriggerController extends Controller
$this->middleware(
function ($request, $next) {
/** @var User $user */
- $user = auth()->user();
+ $user = auth()->user();
$this->ruleGroupRepository = app(RuleGroupRepositoryInterface::class);
$this->ruleGroupRepository->setUser($user);
@@ -70,23 +67,18 @@ class TriggerController extends Controller
* This endpoint is documented at:
* https://api-docs.firefly-iii.org/?urls.primaryName=2.0.0%20(v1)#/rule_groups/testRuleGroup
*
- * @param TestRequest $request
- * @param RuleGroup $group
- *
- * @return JsonResponse
* @throws FireflyException
- *
*/
public function testGroup(TestRequest $request, RuleGroup $group): JsonResponse
{
- $rules = $this->ruleGroupRepository->getActiveRules($group);
+ $rules = $this->ruleGroupRepository->getActiveRules($group);
if (0 === $rules->count()) {
throw new FireflyException('200023: No rules in this rule group.');
}
- $parameters = $request->getTestParameters();
+ $parameters = $request->getTestParameters();
/** @var RuleEngineInterface $ruleEngine */
- $ruleEngine = app(RuleEngineInterface::class);
+ $ruleEngine = app(RuleEngineInterface::class);
$ruleEngine->setRules($rules);
// overrule the rule(s) if necessary.
@@ -107,16 +99,17 @@ class TriggerController extends Controller
$transactions = $ruleEngine->find();
$count = $transactions->count();
- $paginator = new LengthAwarePaginator($transactions, $count, 31337, $this->parameters->get('page'));
- $paginator->setPath(route('api.v1.rule-groups.test', [$group->id]) . $this->buildParams());
+ $paginator = new LengthAwarePaginator($transactions, $count, 31337, $this->parameters->get('page'));
+ $paginator->setPath(route('api.v1.rule-groups.test', [$group->id]).$this->buildParams());
// resulting list is presented as JSON thing.
- $manager = $this->getManager();
+ $manager = $this->getManager();
+
/** @var TransactionGroupTransformer $transformer */
- $transformer = app(TransactionGroupTransformer::class);
+ $transformer = app(TransactionGroupTransformer::class);
$transformer->setParameters($this->parameters);
- $resource = new FractalCollection($transactions, $transformer, 'transactions');
+ $resource = new FractalCollection($transactions, $transformer, 'transactions');
$resource->setPaginator(new IlluminatePaginatorAdapter($paginator));
return response()->json($manager->createData($resource)->toArray())->header('Content-Type', self::CONTENT_TYPE);
@@ -128,15 +121,11 @@ class TriggerController extends Controller
*
* Execute the given rule group on a set of existing transactions.
*
- * @param TriggerRequest $request
- * @param RuleGroup $group
- *
- * @return JsonResponse
- * @throws Exception
+ * @throws \Exception
*/
public function triggerGroup(TriggerRequest $request, RuleGroup $group): JsonResponse
{
- $rules = $this->ruleGroupRepository->getActiveRules($group);
+ $rules = $this->ruleGroupRepository->getActiveRules($group);
if (0 === $rules->count()) {
throw new FireflyException('200023: No rules in this rule group.');
}
@@ -158,7 +147,7 @@ class TriggerController extends Controller
// add a range:
$ruleEngine->addOperator(['type' => 'date_before', 'value' => $parameters['end']->format('Y-m-d')]);
}
- if (array_key_exists('accounts', $parameters) && '' !== $parameters['accounts']) {
+ if (array_key_exists('accounts', $parameters) && is_array($parameters['accounts']) && count($parameters['accounts']) > 0) {
$ruleEngine->addOperator(['type' => 'account_id', 'value' => implode(',', $parameters['accounts'])]);
}
diff --git a/app/Api/V1/Controllers/Models/RuleGroup/UpdateController.php b/app/Api/V1/Controllers/Models/RuleGroup/UpdateController.php
index 1d2b19b6ac..e65a7de47d 100644
--- a/app/Api/V1/Controllers/Models/RuleGroup/UpdateController.php
+++ b/app/Api/V1/Controllers/Models/RuleGroup/UpdateController.php
@@ -41,8 +41,6 @@ class UpdateController extends Controller
/**
* RuleGroupController constructor.
- *
-
*/
public function __construct()
{
@@ -50,7 +48,7 @@ class UpdateController extends Controller
$this->middleware(
function ($request, $next) {
/** @var User $user */
- $user = auth()->user();
+ $user = auth()->user();
$this->ruleGroupRepository = app(RuleGroupRepositoryInterface::class);
$this->ruleGroupRepository->setUser($user);
@@ -65,22 +63,17 @@ class UpdateController extends Controller
* https://api-docs.firefly-iii.org/?urls.primaryName=2.0.0%20(v1)#/rule_groups/updateRuleGroup
*
* Update a rule group.
- *
- * @param UpdateRequest $request
- * @param RuleGroup $ruleGroup
- *
- * @return JsonResponse
*/
public function update(UpdateRequest $request, RuleGroup $ruleGroup): JsonResponse
{
- $ruleGroup = $this->ruleGroupRepository->update($ruleGroup, $request->getAll());
- $manager = $this->getManager();
+ $ruleGroup = $this->ruleGroupRepository->update($ruleGroup, $request->getAll());
+ $manager = $this->getManager();
/** @var RuleGroupTransformer $transformer */
$transformer = app(RuleGroupTransformer::class);
$transformer->setParameters($this->parameters);
- $resource = new Item($ruleGroup, $transformer, 'rule_groups');
+ $resource = new Item($ruleGroup, $transformer, 'rule_groups');
return response()->json($manager->createData($resource)->toArray())->header('Content-Type', self::CONTENT_TYPE);
}
diff --git a/app/Api/V1/Controllers/Models/Tag/DestroyController.php b/app/Api/V1/Controllers/Models/Tag/DestroyController.php
index a0b7f2c3b9..ffe999a4fe 100644
--- a/app/Api/V1/Controllers/Models/Tag/DestroyController.php
+++ b/app/Api/V1/Controllers/Models/Tag/DestroyController.php
@@ -38,8 +38,6 @@ class DestroyController extends Controller
/**
* TagController constructor.
- *
-
*/
public function __construct()
{
@@ -47,7 +45,7 @@ class DestroyController extends Controller
$this->middleware(
function ($request, $next) {
/** @var User $user */
- $user = auth()->user();
+ $user = auth()->user();
$this->repository = app(TagRepositoryInterface::class);
$this->repository->setUser($user);
@@ -62,10 +60,6 @@ class DestroyController extends Controller
* https://api-docs.firefly-iii.org/?urls.primaryName=2.0.0%20(v1)#/tags/deleteTag
*
* Delete the resource.
- *
- * @param Tag $tag
- *
- * @return JsonResponse
*/
public function destroy(Tag $tag): JsonResponse
{
diff --git a/app/Api/V1/Controllers/Models/Tag/ListController.php b/app/Api/V1/Controllers/Models/Tag/ListController.php
index 864c01385c..4bf4156661 100644
--- a/app/Api/V1/Controllers/Models/Tag/ListController.php
+++ b/app/Api/V1/Controllers/Models/Tag/ListController.php
@@ -49,8 +49,6 @@ class ListController extends Controller
/**
* TagController constructor.
- *
-
*/
public function __construct()
{
@@ -58,7 +56,7 @@ class ListController extends Controller
$this->middleware(
function ($request, $next) {
/** @var User $user */
- $user = auth()->user();
+ $user = auth()->user();
$this->repository = app(TagRepositoryInterface::class);
$this->repository->setUser($user);
@@ -72,29 +70,26 @@ class ListController extends Controller
* This endpoint is documented at:
* https://api-docs.firefly-iii.org/?urls.primaryName=2.0.0%20(v1)#/tags/listAttachmentByTag
*
- * @param Tag $tag
- *
- * @return JsonResponse
* @throws FireflyException
*/
public function attachments(Tag $tag): JsonResponse
{
- $manager = $this->getManager();
- $pageSize = $this->parameters->get('limit');
- $collection = $this->repository->getAttachments($tag);
+ $manager = $this->getManager();
+ $pageSize = $this->parameters->get('limit');
+ $collection = $this->repository->getAttachments($tag);
$count = $collection->count();
$attachments = $collection->slice(($this->parameters->get('page') - 1) * $pageSize, $pageSize);
// make paginator:
- $paginator = new LengthAwarePaginator($attachments, $count, $pageSize, $this->parameters->get('page'));
- $paginator->setPath(route('api.v1.tags.attachments', [$tag->id]) . $this->buildParams());
+ $paginator = new LengthAwarePaginator($attachments, $count, $pageSize, $this->parameters->get('page'));
+ $paginator->setPath(route('api.v1.tags.attachments', [$tag->id]).$this->buildParams());
/** @var AttachmentTransformer $transformer */
$transformer = app(AttachmentTransformer::class);
$transformer->setParameters($this->parameters);
- $resource = new FractalCollection($attachments, $transformer, 'attachments');
+ $resource = new FractalCollection($attachments, $transformer, 'attachments');
$resource->setPaginator(new IlluminatePaginatorAdapter($paginator));
return response()->json($manager->createData($resource)->toArray())->header('Content-Type', self::CONTENT_TYPE);
@@ -106,26 +101,23 @@ class ListController extends Controller
*
* Show all transactions.
*
- * @param Request $request
- * @param Tag $tag
- *
- * @return JsonResponse
* @throws FireflyException
*/
public function transactions(Request $request, Tag $tag): JsonResponse
{
- $pageSize = $this->parameters->get('limit');
- $type = $request->get('type') ?? 'default';
+ $pageSize = $this->parameters->get('limit');
+ $type = $request->get('type') ?? 'default';
$this->parameters->set('type', $type);
- $types = $this->mapTransactionTypes($this->parameters->get('type'));
- $manager = $this->getManager();
+ $types = $this->mapTransactionTypes($this->parameters->get('type'));
+ $manager = $this->getManager();
+
/** @var User $admin */
- $admin = auth()->user();
+ $admin = auth()->user();
// use new group collector:
/** @var GroupCollectorInterface $collector */
- $collector = app(GroupCollectorInterface::class);
+ $collector = app(GroupCollectorInterface::class);
$collector
->setUser($admin)
// filter on tag.
@@ -137,7 +129,8 @@ class ListController extends Controller
// set page to retrieve
->setPage($this->parameters->get('page'))
// set types of transactions to return.
- ->setTypes($types);
+ ->setTypes($types)
+ ;
if (null !== $this->parameters->get('start')) {
$collector->setStart($this->parameters->get('start'));
@@ -145,15 +138,15 @@ class ListController extends Controller
if (null !== $this->parameters->get('end')) {
$collector->setEnd($this->parameters->get('end'));
}
- $paginator = $collector->getPaginatedGroups();
- $paginator->setPath(route('api.v1.tags.transactions', [$tag->id]) . $this->buildParams());
+ $paginator = $collector->getPaginatedGroups();
+ $paginator->setPath(route('api.v1.tags.transactions', [$tag->id]).$this->buildParams());
$transactions = $paginator->getCollection();
/** @var TransactionGroupTransformer $transformer */
- $transformer = app(TransactionGroupTransformer::class);
+ $transformer = app(TransactionGroupTransformer::class);
$transformer->setParameters($this->parameters);
- $resource = new FractalCollection($transactions, $transformer, 'transactions');
+ $resource = new FractalCollection($transactions, $transformer, 'transactions');
$resource->setPaginator(new IlluminatePaginatorAdapter($paginator));
return response()->json($manager->createData($resource)->toArray())->header('Content-Type', self::CONTENT_TYPE);
diff --git a/app/Api/V1/Controllers/Models/Tag/ShowController.php b/app/Api/V1/Controllers/Models/Tag/ShowController.php
index 9c50ddf6c1..8d62cc28e8 100644
--- a/app/Api/V1/Controllers/Models/Tag/ShowController.php
+++ b/app/Api/V1/Controllers/Models/Tag/ShowController.php
@@ -44,8 +44,6 @@ class ShowController extends Controller
/**
* TagController constructor.
- *
-
*/
public function __construct()
{
@@ -53,7 +51,7 @@ class ShowController extends Controller
$this->middleware(
function ($request, $next) {
/** @var User $user */
- $user = auth()->user();
+ $user = auth()->user();
$this->repository = app(TagRepositoryInterface::class);
$this->repository->setUser($user);
@@ -69,29 +67,28 @@ class ShowController extends Controller
*
* List all of them.
*
- * @return JsonResponse
* @throws FireflyException
*/
public function index(): JsonResponse
{
- $manager = $this->getManager();
+ $manager = $this->getManager();
// types to get, page size:
- $pageSize = $this->parameters->get('limit');
+ $pageSize = $this->parameters->get('limit');
// get list of budgets. Count it and split it.
- $collection = $this->repository->get();
- $count = $collection->count();
- $rules = $collection->slice(($this->parameters->get('page') - 1) * $pageSize, $pageSize);
+ $collection = $this->repository->get();
+ $count = $collection->count();
+ $rules = $collection->slice(($this->parameters->get('page') - 1) * $pageSize, $pageSize);
// make paginator:
- $paginator = new LengthAwarePaginator($rules, $count, $pageSize, $this->parameters->get('page'));
- $paginator->setPath(route('api.v1.tags.index') . $this->buildParams());
+ $paginator = new LengthAwarePaginator($rules, $count, $pageSize, $this->parameters->get('page'));
+ $paginator->setPath(route('api.v1.tags.index').$this->buildParams());
/** @var TagTransformer $transformer */
$transformer = app(TagTransformer::class);
$transformer->setParameters($this->parameters);
- $resource = new FractalCollection($rules, $transformer, 'tags');
+ $resource = new FractalCollection($rules, $transformer, 'tags');
$resource->setPaginator(new IlluminatePaginatorAdapter($paginator));
return response()->json($manager->createData($resource)->toArray())->header('Content-Type', self::CONTENT_TYPE);
@@ -102,19 +99,16 @@ class ShowController extends Controller
* https://api-docs.firefly-iii.org/?urls.primaryName=2.0.0%20(v1)#/tags/getTag
*
* List single resource.
- *
- * @param Tag $tag
- *
- * @return JsonResponse
*/
public function show(Tag $tag): JsonResponse
{
- $manager = $this->getManager();
+ $manager = $this->getManager();
+
/** @var TagTransformer $transformer */
$transformer = app(TagTransformer::class);
$transformer->setParameters($this->parameters);
- $resource = new Item($tag, $transformer, 'tags');
+ $resource = new Item($tag, $transformer, 'tags');
return response()->json($manager->createData($resource)->toArray())->header('Content-Type', self::CONTENT_TYPE);
}
diff --git a/app/Api/V1/Controllers/Models/Tag/StoreController.php b/app/Api/V1/Controllers/Models/Tag/StoreController.php
index 309ee7a14b..a66fbbd231 100644
--- a/app/Api/V1/Controllers/Models/Tag/StoreController.php
+++ b/app/Api/V1/Controllers/Models/Tag/StoreController.php
@@ -40,8 +40,6 @@ class StoreController extends Controller
/**
* TagController constructor.
- *
-
*/
public function __construct()
{
@@ -49,7 +47,7 @@ class StoreController extends Controller
$this->middleware(
function ($request, $next) {
/** @var User $user */
- $user = auth()->user();
+ $user = auth()->user();
$this->repository = app(TagRepositoryInterface::class);
$this->repository->setUser($user);
@@ -64,20 +62,17 @@ class StoreController extends Controller
* https://api-docs.firefly-iii.org/?urls.primaryName=2.0.0%20(v1)#/tags/storeTag
*
* Store new object.
- *
- * @param StoreRequest $request
- *
- * @return JsonResponse
*/
public function store(StoreRequest $request): JsonResponse
{
- $rule = $this->repository->store($request->getAll());
- $manager = $this->getManager();
+ $rule = $this->repository->store($request->getAll());
+ $manager = $this->getManager();
+
/** @var TagTransformer $transformer */
$transformer = app(TagTransformer::class);
$transformer->setParameters($this->parameters);
- $resource = new Item($rule, $transformer, 'tags');
+ $resource = new Item($rule, $transformer, 'tags');
return response()->json($manager->createData($resource)->toArray())->header('Content-Type', self::CONTENT_TYPE);
}
diff --git a/app/Api/V1/Controllers/Models/Tag/UpdateController.php b/app/Api/V1/Controllers/Models/Tag/UpdateController.php
index 89c9eafa22..f4cda86433 100644
--- a/app/Api/V1/Controllers/Models/Tag/UpdateController.php
+++ b/app/Api/V1/Controllers/Models/Tag/UpdateController.php
@@ -41,8 +41,6 @@ class UpdateController extends Controller
/**
* TagController constructor.
- *
-
*/
public function __construct()
{
@@ -50,7 +48,7 @@ class UpdateController extends Controller
$this->middleware(
function ($request, $next) {
/** @var User $user */
- $user = auth()->user();
+ $user = auth()->user();
$this->repository = app(TagRepositoryInterface::class);
$this->repository->setUser($user);
@@ -65,21 +63,17 @@ class UpdateController extends Controller
* https://api-docs.firefly-iii.org/?urls.primaryName=2.0.0%20(v1)#/tags/updateTag
*
* Update a rule.
- *
- * @param UpdateRequest $request
- * @param Tag $tag
- *
- * @return JsonResponse
*/
public function update(UpdateRequest $request, Tag $tag): JsonResponse
{
- $rule = $this->repository->update($tag, $request->getAll());
- $manager = $this->getManager();
+ $rule = $this->repository->update($tag, $request->getAll());
+ $manager = $this->getManager();
+
/** @var TagTransformer $transformer */
$transformer = app(TagTransformer::class);
$transformer->setParameters($this->parameters);
- $resource = new Item($rule, $transformer, 'tags');
+ $resource = new Item($rule, $transformer, 'tags');
return response()->json($manager->createData($resource)->toArray())->header('Content-Type', self::CONTENT_TYPE);
}
diff --git a/app/Api/V1/Controllers/Models/Transaction/DestroyController.php b/app/Api/V1/Controllers/Models/Transaction/DestroyController.php
index a15a24ff33..a1780773f1 100644
--- a/app/Api/V1/Controllers/Models/Transaction/DestroyController.php
+++ b/app/Api/V1/Controllers/Models/Transaction/DestroyController.php
@@ -33,7 +33,6 @@ use FireflyIII\Repositories\Journal\JournalRepositoryInterface;
use FireflyIII\Repositories\TransactionGroup\TransactionGroupRepository;
use FireflyIII\User;
use Illuminate\Http\JsonResponse;
-use Illuminate\Support\Facades\Log;
/**
* Class DestroyController
@@ -45,8 +44,6 @@ class DestroyController extends Controller
/**
* TransactionController constructor.
- *
-
*/
public function __construct()
{
@@ -54,9 +51,9 @@ class DestroyController extends Controller
$this->middleware(
function ($request, $next) {
/** @var User $admin */
- $admin = auth()->user();
+ $admin = auth()->user();
- $this->repository = app(JournalRepositoryInterface::class);
+ $this->repository = app(JournalRepositoryInterface::class);
$this->repository->setUser($admin);
$this->groupRepository = app(TransactionGroupRepository::class);
@@ -72,16 +69,13 @@ class DestroyController extends Controller
* https://api-docs.firefly-iii.org/?urls.primaryName=2.0.0%20(v1)#/transactions/deleteTransaction
*
* Remove the specified resource from storage.
- *
- * @param TransactionGroup $transactionGroup
- *
- * @return JsonResponse
*/
public function destroy(TransactionGroup $transactionGroup): JsonResponse
{
- Log::debug(sprintf('Now in %s', __METHOD__));
+ app('log')->debug(sprintf('Now in %s', __METHOD__));
// grab asset account(s) from group:
$accounts = [];
+
/** @var TransactionJournal $journal */
foreach ($transactionGroup->transactionJournals as $journal) {
/** @var Transaction $transaction */
@@ -100,7 +94,7 @@ class DestroyController extends Controller
/** @var Account $account */
foreach ($accounts as $account) {
- Log::debug(sprintf('Now going to trigger updated account event for account #%d', $account->id));
+ app('log')->debug(sprintf('Now going to trigger updated account event for account #%d', $account->id));
event(new UpdatedAccount($account));
}
@@ -112,10 +106,6 @@ class DestroyController extends Controller
* https://api-docs.firefly-iii.org/?urls.primaryName=2.0.0%20(v1)#/transactions/deleteTransactionJournal
*
* Remove the specified resource from storage.
- *
- * @param TransactionJournal $transactionJournal
- *
- * @return JsonResponse
*/
public function destroyJournal(TransactionJournal $transactionJournal): JsonResponse
{
diff --git a/app/Api/V1/Controllers/Models/Transaction/ListController.php b/app/Api/V1/Controllers/Models/Transaction/ListController.php
index 25d9d098d0..cbc9c153b8 100644
--- a/app/Api/V1/Controllers/Models/Transaction/ListController.php
+++ b/app/Api/V1/Controllers/Models/Transaction/ListController.php
@@ -47,8 +47,6 @@ class ListController extends Controller
/**
* TransactionController constructor.
- *
-
*/
public function __construct()
{
@@ -56,7 +54,7 @@ class ListController extends Controller
$this->middleware(
function ($request, $next) {
/** @var User $admin */
- $admin = auth()->user();
+ $admin = auth()->user();
$this->journalAPIRepository = app(JournalAPIRepositoryInterface::class);
$this->journalAPIRepository->setUser($admin);
@@ -70,16 +68,13 @@ class ListController extends Controller
* This endpoint is documented at:
* https://api-docs.firefly-iii.org/?urls.primaryName=2.0.0%20(v1)#/transactions/listAttachmentByTransaction
*
- * @param TransactionGroup $transactionGroup
- *
- * @return JsonResponse
* @throws FireflyException
*/
public function attachments(TransactionGroup $transactionGroup): JsonResponse
{
- $manager = $this->getManager();
- $pageSize = $this->parameters->get('limit');
- $collection = new Collection();
+ $manager = $this->getManager();
+ $pageSize = $this->parameters->get('limit');
+ $collection = new Collection();
foreach ($transactionGroup->transactionJournals as $transactionJournal) {
$collection = $this->journalAPIRepository->getAttachments($transactionJournal)->merge($collection);
}
@@ -88,14 +83,14 @@ class ListController extends Controller
$attachments = $collection->slice(($this->parameters->get('page') - 1) * $pageSize, $pageSize);
// make paginator:
- $paginator = new LengthAwarePaginator($attachments, $count, $pageSize, $this->parameters->get('page'));
- $paginator->setPath(route('api.v1.transactions.attachments', [$transactionGroup->id]) . $this->buildParams());
+ $paginator = new LengthAwarePaginator($attachments, $count, $pageSize, $this->parameters->get('page'));
+ $paginator->setPath(route('api.v1.transactions.attachments', [$transactionGroup->id]).$this->buildParams());
/** @var AttachmentTransformer $transformer */
$transformer = app(AttachmentTransformer::class);
$transformer->setParameters($this->parameters);
- $resource = new FractalCollection($attachments, $transformer, 'attachments');
+ $resource = new FractalCollection($attachments, $transformer, 'attachments');
$resource->setPaginator(new IlluminatePaginatorAdapter($paginator));
return response()->json($manager->createData($resource)->toArray())->header('Content-Type', self::CONTENT_TYPE);
@@ -105,30 +100,27 @@ class ListController extends Controller
* This endpoint is documented at:
* https://api-docs.firefly-iii.org/?urls.primaryName=2.0.0%20(v1)#/transactions/listEventByTransaction
*
- * @param TransactionGroup $transactionGroup
- *
- * @return JsonResponse
* @throws FireflyException
*/
public function piggyBankEvents(TransactionGroup $transactionGroup): JsonResponse
{
- $manager = $this->getManager();
- $collection = new Collection();
- $pageSize = $this->parameters->get('limit');
+ $manager = $this->getManager();
+ $collection = new Collection();
+ $pageSize = $this->parameters->get('limit');
foreach ($transactionGroup->transactionJournals as $transactionJournal) {
$collection = $this->journalAPIRepository->getPiggyBankEvents($transactionJournal)->merge($collection);
}
- $count = $collection->count();
- $events = $collection->slice(($this->parameters->get('page') - 1) * $pageSize, $pageSize);
+ $count = $collection->count();
+ $events = $collection->slice(($this->parameters->get('page') - 1) * $pageSize, $pageSize);
// make paginator:
- $paginator = new LengthAwarePaginator($events, $count, $pageSize, $this->parameters->get('page'));
- $paginator->setPath(route('api.v1.transactions.piggy-bank-events', [$transactionGroup->id]) . $this->buildParams());
+ $paginator = new LengthAwarePaginator($events, $count, $pageSize, $this->parameters->get('page'));
+ $paginator->setPath(route('api.v1.transactions.piggy-bank-events', [$transactionGroup->id]).$this->buildParams());
/** @var PiggyBankEventTransformer $transformer */
$transformer = app(PiggyBankEventTransformer::class);
$transformer->setParameters($this->parameters);
- $resource = new FractalCollection($events, $transformer, 'piggy_bank_events');
+ $resource = new FractalCollection($events, $transformer, 'piggy_bank_events');
$resource->setPaginator(new IlluminatePaginatorAdapter($paginator));
// /** @var PiggyBankEventTransformer $transformer */
// $transformer = app(PiggyBankEventTransformer::class);
@@ -143,9 +135,6 @@ class ListController extends Controller
* This endpoint is documented at:
* https://api-docs.firefly-iii.org/?urls.primaryName=2.0.0%20(v1)#/transactions/listLinksByJournal
*
- * @param TransactionJournal $transactionJournal
- *
- * @return JsonResponse
* @throws FireflyException
*/
public function transactionLinks(TransactionJournal $transactionJournal): JsonResponse
@@ -157,14 +146,14 @@ class ListController extends Controller
$journalLinks = $collection->slice(($this->parameters->get('page') - 1) * $pageSize, $pageSize);
// make paginator:
- $paginator = new LengthAwarePaginator($journalLinks, $count, $pageSize, $this->parameters->get('page'));
- $paginator->setPath(route('api.v1.transaction-journals.transaction-links', [$transactionJournal->id]) . $this->buildParams());
+ $paginator = new LengthAwarePaginator($journalLinks, $count, $pageSize, $this->parameters->get('page'));
+ $paginator->setPath(route('api.v1.transaction-journals.transaction-links', [$transactionJournal->id]).$this->buildParams());
/** @var TransactionLinkTransformer $transformer */
- $transformer = app(TransactionLinkTransformer::class);
+ $transformer = app(TransactionLinkTransformer::class);
$transformer->setParameters($this->parameters);
- $resource = new FractalCollection($journalLinks, $transformer, 'transaction_links');
+ $resource = new FractalCollection($journalLinks, $transformer, 'transaction_links');
$resource->setPaginator(new IlluminatePaginatorAdapter($paginator));
return response()->json($manager->createData($resource)->toArray())->header('Content-Type', self::CONTENT_TYPE);
diff --git a/app/Api/V1/Controllers/Models/Transaction/ShowController.php b/app/Api/V1/Controllers/Models/Transaction/ShowController.php
index 2819c50fb2..7140254beb 100644
--- a/app/Api/V1/Controllers/Models/Transaction/ShowController.php
+++ b/app/Api/V1/Controllers/Models/Transaction/ShowController.php
@@ -51,25 +51,23 @@ class ShowController extends Controller
*
* Show all transactions.
*
- * @param Request $request
- *
- * @return JsonResponse
* @throws FireflyException
*/
public function index(Request $request): JsonResponse
{
- $pageSize = $this->parameters->get('limit');
- $type = $request->get('type') ?? 'default';
+ $pageSize = $this->parameters->get('limit');
+ $type = $request->get('type') ?? 'default';
$this->parameters->set('type', $type);
- $types = $this->mapTransactionTypes($this->parameters->get('type'));
- $manager = $this->getManager();
+ $types = $this->mapTransactionTypes($this->parameters->get('type'));
+ $manager = $this->getManager();
+
/** @var User $admin */
- $admin = auth()->user();
+ $admin = auth()->user();
// use new group collector:
/** @var GroupCollectorInterface $collector */
- $collector = app(GroupCollectorInterface::class);
+ $collector = app(GroupCollectorInterface::class);
$collector
->setUser($admin)
// all info needed for the API:
@@ -79,19 +77,20 @@ class ShowController extends Controller
// set page to retrieve
->setPage($this->parameters->get('page'))
// set types of transactions to return.
- ->setTypes($types);
+ ->setTypes($types)
+ ;
if (null !== $this->parameters->get('start') || null !== $this->parameters->get('end')) {
$collector->setRange($this->parameters->get('start'), $this->parameters->get('end'));
}
- $paginator = $collector->getPaginatedGroups();
- $paginator->setPath(route('api.v1.transactions.index') . $this->buildParams());
+ $paginator = $collector->getPaginatedGroups();
+ $paginator->setPath(route('api.v1.transactions.index').$this->buildParams());
$transactions = $paginator->getCollection();
/** @var TransactionGroupTransformer $transformer */
- $transformer = app(TransactionGroupTransformer::class);
+ $transformer = app(TransactionGroupTransformer::class);
$transformer->setParameters($this->parameters);
- $resource = new FractalCollection($transactions, $transformer, 'transactions');
+ $resource = new FractalCollection($transactions, $transformer, 'transactions');
$resource->setPaginator(new IlluminatePaginatorAdapter($paginator));
return response()->json($manager->createData($resource)->toArray())->header('Content-Type', self::CONTENT_TYPE);
@@ -102,10 +101,6 @@ class ShowController extends Controller
* https://api-docs.firefly-iii.org/?urls.primaryName=2.0.0%20(v1)#/transactions/getTransactionByJournal
*
* Show a single transaction, by transaction journal.
- *
- * @param TransactionJournal $transactionJournal
- *
- * @return JsonResponse
*/
public function showJournal(TransactionJournal $transactionJournal): JsonResponse
{
@@ -117,34 +112,34 @@ class ShowController extends Controller
* https://api-docs.firefly-iii.org/?urls.primaryName=2.0.0%20(v1)#/transactions/getTransaction
*
* Show a single transaction.
- *
- * @param TransactionGroup $transactionGroup
- *
- * @return JsonResponse
*/
public function show(TransactionGroup $transactionGroup): JsonResponse
{
- $manager = $this->getManager();
+ $manager = $this->getManager();
+
/** @var User $admin */
- $admin = auth()->user();
+ $admin = auth()->user();
+
// use new group collector:
/** @var GroupCollectorInterface $collector */
- $collector = app(GroupCollectorInterface::class);
+ $collector = app(GroupCollectorInterface::class);
$collector
->setUser($admin)
// filter on transaction group.
->setTransactionGroup($transactionGroup)
// all info needed for the API:
- ->withAPIInformation();
+ ->withAPIInformation()
+ ;
$selectedGroup = $collector->getGroups()->first();
if (null === $selectedGroup) {
throw new NotFoundHttpException();
}
+
/** @var TransactionGroupTransformer $transformer */
- $transformer = app(TransactionGroupTransformer::class);
+ $transformer = app(TransactionGroupTransformer::class);
$transformer->setParameters($this->parameters);
- $resource = new Item($selectedGroup, $transformer, 'transactions');
+ $resource = new Item($selectedGroup, $transformer, 'transactions');
return response()->json($manager->createData($resource)->toArray())->header('Content-Type', self::CONTENT_TYPE);
}
diff --git a/app/Api/V1/Controllers/Models/Transaction/StoreController.php b/app/Api/V1/Controllers/Models/Transaction/StoreController.php
index 29c4a262e8..716fa898e3 100644
--- a/app/Api/V1/Controllers/Models/Transaction/StoreController.php
+++ b/app/Api/V1/Controllers/Models/Transaction/StoreController.php
@@ -38,7 +38,6 @@ use Illuminate\Http\JsonResponse;
use Illuminate\Support\Facades\Log;
use Illuminate\Validation\ValidationException;
use League\Fractal\Resource\Item;
-use Validator;
/**
* Class StoreController
@@ -51,8 +50,6 @@ class StoreController extends Controller
/**
* TransactionController constructor.
- *
-
*/
public function __construct()
{
@@ -60,7 +57,7 @@ class StoreController extends Controller
$this->middleware(
function ($request, $next) {
/** @var User $admin */
- $admin = auth()->user();
+ $admin = auth()->user();
$this->groupRepository = app(TransactionGroupRepositoryInterface::class);
$this->groupRepository->setUser($admin);
@@ -76,62 +73,66 @@ class StoreController extends Controller
*
* Store a new transaction.
*
- * @param StoreRequest $request
- *
- * @return JsonResponse
* @throws FireflyException|ValidationException
*/
public function store(StoreRequest $request): JsonResponse
{
- Log::debug('Now in API StoreController::store()');
- $data = $request->getAll();
- $data['user'] = auth()->user()->id;
+ app('log')->debug('Now in API StoreController::store()');
+ $data = $request->getAll();
+ $data['user'] = auth()->user()->id;
Log::channel('audit')
- ->info('Store new transaction over API.', $data);
+ ->info('Store new transaction over API.', $data)
+ ;
try {
$transactionGroup = $this->groupRepository->store($data);
- } catch (DuplicateTransactionException $e) {
+ } catch (DuplicateTransactionException $e) { // @phpstan-ignore-line
app('log')->warning('Caught a duplicate transaction. Return error message.');
- $validator = Validator::make(
+ $validator = \Validator::make(
['transactions' => [['description' => $e->getMessage()]]],
['transactions.0.description' => new IsDuplicateTransaction()]
);
- throw new ValidationException($validator, 0, $e);
- } catch (FireflyException $e) {
+
+ throw new ValidationException($validator); // @phpstan-ignore-line
+ } catch (FireflyException $e) { // @phpstan-ignore-line
app('log')->warning('Caught an exception. Return error message.');
- Log::error($e->getMessage());
+ app('log')->error($e->getMessage());
$message = sprintf('Internal exception: %s', $e->getMessage());
- $validator = Validator::make(['transactions' => [['description' => $message]]], ['transactions.0.description' => new IsDuplicateTransaction()]);
- throw new ValidationException($validator, 0, $e);
+ $validator = \Validator::make(['transactions' => [['description' => $message]]], ['transactions.0.description' => new IsDuplicateTransaction()]);
+
+ throw new ValidationException($validator); // @phpstan-ignore-line
}
app('preferences')->mark();
- $applyRules = $data['apply_rules'] ?? true;
- $fireWebhooks = $data['fire_webhooks'] ?? true;
+ $applyRules = $data['apply_rules'] ?? true;
+ $fireWebhooks = $data['fire_webhooks'] ?? true;
event(new StoredTransactionGroup($transactionGroup, $applyRules, $fireWebhooks));
- $manager = $this->getManager();
+ $manager = $this->getManager();
+
/** @var User $admin */
- $admin = auth()->user();
+ $admin = auth()->user();
+
// use new group collector:
/** @var GroupCollectorInterface $collector */
- $collector = app(GroupCollectorInterface::class);
+ $collector = app(GroupCollectorInterface::class);
$collector
->setUser($admin)
// filter on transaction group.
->setTransactionGroup($transactionGroup)
// all info needed for the API:
- ->withAPIInformation();
+ ->withAPIInformation()
+ ;
$selectedGroup = $collector->getGroups()->first();
if (null === $selectedGroup) {
throw new FireflyException('200032: Cannot find transaction. Possibly, a rule deleted this transaction after its creation.');
}
+
/** @var TransactionGroupTransformer $transformer */
- $transformer = app(TransactionGroupTransformer::class);
+ $transformer = app(TransactionGroupTransformer::class);
$transformer->setParameters($this->parameters);
- $resource = new Item($selectedGroup, $transformer, 'transactions');
+ $resource = new Item($selectedGroup, $transformer, 'transactions');
return response()->json($manager->createData($resource)->toArray())->header('Content-Type', self::CONTENT_TYPE);
}
diff --git a/app/Api/V1/Controllers/Models/Transaction/UpdateController.php b/app/Api/V1/Controllers/Models/Transaction/UpdateController.php
index 8da2d15204..5f9946b44a 100644
--- a/app/Api/V1/Controllers/Models/Transaction/UpdateController.php
+++ b/app/Api/V1/Controllers/Models/Transaction/UpdateController.php
@@ -32,7 +32,6 @@ use FireflyIII\Repositories\TransactionGroup\TransactionGroupRepositoryInterface
use FireflyIII\Transformers\TransactionGroupTransformer;
use FireflyIII\User;
use Illuminate\Http\JsonResponse;
-use Illuminate\Support\Facades\Log;
use League\Fractal\Resource\Item;
use Symfony\Component\HttpKernel\Exception\NotFoundHttpException;
@@ -45,8 +44,6 @@ class UpdateController extends Controller
/**
* TransactionController constructor.
- *
-
*/
public function __construct()
{
@@ -54,7 +51,7 @@ class UpdateController extends Controller
$this->middleware(
function ($request, $next) {
/** @var User $admin */
- $admin = auth()->user();
+ $admin = auth()->user();
$this->groupRepository = app(TransactionGroupRepositoryInterface::class);
$this->groupRepository->setUser($admin);
@@ -69,45 +66,43 @@ class UpdateController extends Controller
* https://api-docs.firefly-iii.org/?urls.primaryName=2.0.0%20(v1)#/transactions/updateTransaction
*
* Update a transaction.
- *
- * @param UpdateRequest $request
- * @param TransactionGroup $transactionGroup
- *
- * @return JsonResponse
*/
public function update(UpdateRequest $request, TransactionGroup $transactionGroup): JsonResponse
{
- Log::debug('Now in update routine for transaction group!');
- $data = $request->getAll();
+ app('log')->debug('Now in update routine for transaction group!');
+ $data = $request->getAll();
$transactionGroup = $this->groupRepository->update($transactionGroup, $data);
$manager = $this->getManager();
app('preferences')->mark();
- $applyRules = $data['apply_rules'] ?? true;
- $fireWebhooks = $data['fire_webhooks'] ?? true;
+ $applyRules = $data['apply_rules'] ?? true;
+ $fireWebhooks = $data['fire_webhooks'] ?? true;
event(new UpdatedTransactionGroup($transactionGroup, $applyRules, $fireWebhooks));
/** @var User $admin */
- $admin = auth()->user();
+ $admin = auth()->user();
+
// use new group collector:
/** @var GroupCollectorInterface $collector */
- $collector = app(GroupCollectorInterface::class);
+ $collector = app(GroupCollectorInterface::class);
$collector
->setUser($admin)
// filter on transaction group.
->setTransactionGroup($transactionGroup)
// all info needed for the API:
- ->withAPIInformation();
+ ->withAPIInformation()
+ ;
- $selectedGroup = $collector->getGroups()->first();
+ $selectedGroup = $collector->getGroups()->first();
if (null === $selectedGroup) {
throw new NotFoundHttpException();
}
+
/** @var TransactionGroupTransformer $transformer */
- $transformer = app(TransactionGroupTransformer::class);
+ $transformer = app(TransactionGroupTransformer::class);
$transformer->setParameters($this->parameters);
- $resource = new Item($selectedGroup, $transformer, 'transactions');
+ $resource = new Item($selectedGroup, $transformer, 'transactions');
return response()->json($manager->createData($resource)->toArray())->header('Content-Type', self::CONTENT_TYPE);
}
diff --git a/app/Api/V1/Controllers/Models/TransactionCurrency/DestroyController.php b/app/Api/V1/Controllers/Models/TransactionCurrency/DestroyController.php
index 1cfb07d391..e2512cf47c 100644
--- a/app/Api/V1/Controllers/Models/TransactionCurrency/DestroyController.php
+++ b/app/Api/V1/Controllers/Models/TransactionCurrency/DestroyController.php
@@ -27,11 +27,10 @@ namespace FireflyIII\Api\V1\Controllers\Models\TransactionCurrency;
use FireflyIII\Api\V1\Controllers\Controller;
use FireflyIII\Exceptions\FireflyException;
use FireflyIII\Models\TransactionCurrency;
-use FireflyIII\Repositories\Currency\CurrencyRepositoryInterface;
use FireflyIII\Repositories\User\UserRepositoryInterface;
+use FireflyIII\Repositories\UserGroups\Currency\CurrencyRepositoryInterface;
use FireflyIII\User;
use Illuminate\Http\JsonResponse;
-use Validator;
/**
* Class DestroyController
@@ -43,8 +42,6 @@ class DestroyController extends Controller
/**
* CurrencyRepository constructor.
- *
-
*/
public function __construct()
{
@@ -66,9 +63,6 @@ class DestroyController extends Controller
*
* Remove the specified resource from storage.
*
- * @param TransactionCurrency $currency
- *
- * @return JsonResponse
* @throws FireflyException
*/
public function destroy(TransactionCurrency $currency): JsonResponse
@@ -80,15 +74,15 @@ class DestroyController extends Controller
if (!$this->userRepository->hasRole($admin, 'owner')) {
// access denied:
$messages = ['currency_code' => '200005: You need the "owner" role to do this.'];
- Validator::make([], $rules, $messages)->validate();
+ \Validator::make([], $rules, $messages)->validate();
}
if ($this->repository->currencyInUse($currency)) {
$messages = ['currency_code' => '200006: Currency in use.'];
- Validator::make([], $rules, $messages)->validate();
+ \Validator::make([], $rules, $messages)->validate();
}
if ($this->repository->isFallbackCurrency($currency)) {
$messages = ['currency_code' => '200026: Currency is fallback.'];
- Validator::make([], $rules, $messages)->validate();
+ \Validator::make([], $rules, $messages)->validate();
}
$this->repository->destroy($currency);
diff --git a/app/Api/V1/Controllers/Models/TransactionCurrency/ListController.php b/app/Api/V1/Controllers/Models/TransactionCurrency/ListController.php
index cd52b0060b..2607c280de 100644
--- a/app/Api/V1/Controllers/Models/TransactionCurrency/ListController.php
+++ b/app/Api/V1/Controllers/Models/TransactionCurrency/ListController.php
@@ -38,7 +38,6 @@ use FireflyIII\Repositories\Account\AccountRepositoryInterface;
use FireflyIII\Repositories\Bill\BillRepositoryInterface;
use FireflyIII\Repositories\Budget\AvailableBudgetRepositoryInterface;
use FireflyIII\Repositories\Budget\BudgetLimitRepositoryInterface;
-use FireflyIII\Repositories\Currency\CurrencyRepositoryInterface;
use FireflyIII\Repositories\Recurring\RecurringRepositoryInterface;
use FireflyIII\Repositories\Rule\RuleRepositoryInterface;
use FireflyIII\Support\Http\Api\AccountFilter;
@@ -65,48 +64,24 @@ class ListController extends Controller
use AccountFilter;
use TransactionFilter;
- private CurrencyRepositoryInterface $repository;
-
- /**
- * CurrencyRepository constructor.
- *
-
- */
- public function __construct()
- {
- parent::__construct();
- $this->middleware(
- function ($request, $next) {
- $this->repository = app(CurrencyRepositoryInterface::class);
- $this->repository->setUser(auth()->user());
-
- return $next($request);
- }
- );
- }
-
/**
* This endpoint is documented at:
* https://api-docs.firefly-iii.org/?urls.primaryName=2.0.0%20(v1)#/currencies/listAccountByCurrency
* Display a list of accounts.
*
- * @param Request $request
- * @param TransactionCurrency $currency
- *
- * @return JsonResponse
* @throws FireflyException
*/
public function accounts(Request $request, TransactionCurrency $currency): JsonResponse
{
- $manager = $this->getManager();
+ $manager = $this->getManager();
// read type from URL
- $type = $request->get('type') ?? 'all';
+ $type = $request->get('type') ?? 'all';
$this->parameters->set('type', $type);
// types to get, page size:
- $types = $this->mapAccountTypes($this->parameters->get('type'));
- $pageSize = $this->parameters->get('limit');
+ $types = $this->mapAccountTypes($this->parameters->get('type'));
+ $pageSize = $this->parameters->get('limit');
// get list of accounts. Count it and split it.
/** @var AccountRepositoryInterface $accountRepository */
@@ -114,7 +89,7 @@ class ListController extends Controller
$unfiltered = $accountRepository->getAccountsByType($types);
// filter list on currency preference:
- $collection = $unfiltered->filter(
+ $collection = $unfiltered->filter(
static function (Account $account) use ($currency, $accountRepository) {
$currencyId = (int)$accountRepository->getMetaValue($account, 'currency_id');
@@ -122,17 +97,17 @@ class ListController extends Controller
}
);
- $count = $collection->count();
- $accounts = $collection->slice(($this->parameters->get('page') - 1) * $pageSize, $pageSize);
+ $count = $collection->count();
+ $accounts = $collection->slice(($this->parameters->get('page') - 1) * $pageSize, $pageSize);
// make paginator:
- $paginator = new LengthAwarePaginator($accounts, $count, $pageSize, $this->parameters->get('page'));
- $paginator->setPath(route('api.v1.currencies.accounts', [$currency->code]) . $this->buildParams());
+ $paginator = new LengthAwarePaginator($accounts, $count, $pageSize, $this->parameters->get('page'));
+ $paginator->setPath(route('api.v1.currencies.accounts', [$currency->code]).$this->buildParams());
/** @var AccountTransformer $transformer */
- $transformer = app(AccountTransformer::class);
+ $transformer = app(AccountTransformer::class);
$transformer->setParameters($this->parameters);
- $resource = new FractalCollection($accounts, $transformer, 'accounts');
+ $resource = new FractalCollection($accounts, $transformer, 'accounts');
$resource->setPaginator(new IlluminatePaginatorAdapter($paginator));
return response()->json($manager->createData($resource)->toArray())->header('Content-Type', self::CONTENT_TYPE);
@@ -144,33 +119,30 @@ class ListController extends Controller
*
* Display a listing of the resource.
*
- * @param TransactionCurrency $currency
- *
- * @return JsonResponse
* @throws FireflyException
*/
public function availableBudgets(TransactionCurrency $currency): JsonResponse
{
- $manager = $this->getManager();
+ $manager = $this->getManager();
// types to get, page size:
- $pageSize = $this->parameters->get('limit');
+ $pageSize = $this->parameters->get('limit');
// get list of available budgets. Count it and split it.
/** @var AvailableBudgetRepositoryInterface $abRepository */
- $abRepository = app(AvailableBudgetRepositoryInterface::class);
+ $abRepository = app(AvailableBudgetRepositoryInterface::class);
$collection = $abRepository->getAvailableBudgetsByCurrency($currency);
$count = $collection->count();
$availableBudgets = $collection->slice(($this->parameters->get('page') - 1) * $pageSize, $pageSize);
// make paginator:
- $paginator = new LengthAwarePaginator($availableBudgets, $count, $pageSize, $this->parameters->get('page'));
- $paginator->setPath(route('api.v1.currencies.available-budgets', [$currency->code]) . $this->buildParams());
+ $paginator = new LengthAwarePaginator($availableBudgets, $count, $pageSize, $this->parameters->get('page'));
+ $paginator->setPath(route('api.v1.currencies.available-budgets', [$currency->code]).$this->buildParams());
/** @var AvailableBudgetTransformer $transformer */
- $transformer = app(AvailableBudgetTransformer::class);
+ $transformer = app(AvailableBudgetTransformer::class);
$transformer->setParameters($this->parameters);
- $resource = new FractalCollection($availableBudgets, $transformer, 'available_budgets');
+ $resource = new FractalCollection($availableBudgets, $transformer, 'available_budgets');
$resource->setPaginator(new IlluminatePaginatorAdapter($paginator));
return response()->json($manager->createData($resource)->toArray())->header('Content-Type', self::CONTENT_TYPE);
@@ -182,38 +154,35 @@ class ListController extends Controller
*
* List all bills
*
- * @param TransactionCurrency $currency
- *
- * @return JsonResponse
* @throws FireflyException
*/
public function bills(TransactionCurrency $currency): JsonResponse
{
- $manager = $this->getManager();
+ $manager = $this->getManager();
/** @var BillRepositoryInterface $billRepos */
- $billRepos = app(BillRepositoryInterface::class);
- $pageSize = $this->parameters->get('limit');
- $unfiltered = $billRepos->getBills();
+ $billRepos = app(BillRepositoryInterface::class);
+ $pageSize = $this->parameters->get('limit');
+ $unfiltered = $billRepos->getBills();
// filter and paginate list:
- $collection = $unfiltered->filter(
+ $collection = $unfiltered->filter(
static function (Bill $bill) use ($currency) {
return $bill->transaction_currency_id === $currency->id;
}
);
- $count = $collection->count();
- $bills = $collection->slice(($this->parameters->get('page') - 1) * $pageSize, $pageSize);
+ $count = $collection->count();
+ $bills = $collection->slice(($this->parameters->get('page') - 1) * $pageSize, $pageSize);
// make paginator:
- $paginator = new LengthAwarePaginator($bills, $count, $pageSize, $this->parameters->get('page'));
- $paginator->setPath(route('api.v1.currencies.bills', [$currency->code]) . $this->buildParams());
+ $paginator = new LengthAwarePaginator($bills, $count, $pageSize, $this->parameters->get('page'));
+ $paginator->setPath(route('api.v1.currencies.bills', [$currency->code]).$this->buildParams());
/** @var BillTransformer $transformer */
$transformer = app(BillTransformer::class);
$transformer->setParameters($this->parameters);
- $resource = new FractalCollection($bills, $transformer, 'bills');
+ $resource = new FractalCollection($bills, $transformer, 'bills');
$resource->setPaginator(new IlluminatePaginatorAdapter($paginator));
return response()->json($manager->createData($resource)->toArray())->header('Content-Type', self::CONTENT_TYPE);
@@ -225,9 +194,6 @@ class ListController extends Controller
*
* List all budget limits
*
- * @param TransactionCurrency $currency
- *
- * @return JsonResponse
* @throws FireflyException
*/
public function budgetLimits(TransactionCurrency $currency): JsonResponse
@@ -241,13 +207,13 @@ class ListController extends Controller
$count = $collection->count();
$budgetLimits = $collection->slice(($this->parameters->get('page') - 1) * $pageSize, $pageSize);
$paginator = new LengthAwarePaginator($budgetLimits, $count, $pageSize, $this->parameters->get('page'));
- $paginator->setPath(route('api.v1.currencies.budget-limits', [$currency->code]) . $this->buildParams());
+ $paginator->setPath(route('api.v1.currencies.budget-limits', [$currency->code]).$this->buildParams());
/** @var BudgetLimitTransformer $transformer */
- $transformer = app(BudgetLimitTransformer::class);
+ $transformer = app(BudgetLimitTransformer::class);
$transformer->setParameters($this->parameters);
- $resource = new FractalCollection($budgetLimits, $transformer, 'budget_limits');
+ $resource = new FractalCollection($budgetLimits, $transformer, 'budget_limits');
$resource->setPaginator(new IlluminatePaginatorAdapter($paginator));
return response()->json($manager->createData($resource)->toArray())->header('Content-Type', self::CONTENT_TYPE);
@@ -259,16 +225,13 @@ class ListController extends Controller
*
* List all recurring transactions.
*
- * @param TransactionCurrency $currency
- *
- * @return JsonResponse
* @throws FireflyException
*/
public function recurrences(TransactionCurrency $currency): JsonResponse
{
- $manager = $this->getManager();
+ $manager = $this->getManager();
// types to get, page size:
- $pageSize = $this->parameters->get('limit');
+ $pageSize = $this->parameters->get('limit');
// get list of budgets. Count it and split it.
/** @var RecurringRepositoryInterface $recurringRepos */
@@ -276,8 +239,8 @@ class ListController extends Controller
$unfiltered = $recurringRepos->getAll();
// filter selection
- $collection = $unfiltered->filter(
- static function (Recurrence $recurrence) use ($currency) {
+ $collection = $unfiltered->filter( // @phpstan-ignore-line
+ static function (Recurrence $recurrence) use ($currency) { // @phpstan-ignore-line
/** @var RecurrenceTransaction $transaction */
foreach ($recurrence->recurrenceTransactions as $transaction) {
if ($transaction->transaction_currency_id === $currency->id || $transaction->foreign_currency_id === $currency->id) {
@@ -288,18 +251,18 @@ class ListController extends Controller
return null;
}
);
- $count = $collection->count();
- $piggyBanks = $collection->slice(($this->parameters->get('page') - 1) * $pageSize, $pageSize);
+ $count = $collection->count();
+ $piggyBanks = $collection->slice(($this->parameters->get('page') - 1) * $pageSize, $pageSize);
// make paginator:
- $paginator = new LengthAwarePaginator($piggyBanks, $count, $pageSize, $this->parameters->get('page'));
- $paginator->setPath(route('api.v1.currencies.recurrences', [$currency->code]) . $this->buildParams());
+ $paginator = new LengthAwarePaginator($piggyBanks, $count, $pageSize, $this->parameters->get('page'));
+ $paginator->setPath(route('api.v1.currencies.recurrences', [$currency->code]).$this->buildParams());
/** @var RecurrenceTransformer $transformer */
- $transformer = app(RecurrenceTransformer::class);
+ $transformer = app(RecurrenceTransformer::class);
$transformer->setParameters($this->parameters);
- $resource = new FractalCollection($piggyBanks, $transformer, 'recurrences');
+ $resource = new FractalCollection($piggyBanks, $transformer, 'recurrences');
$resource->setPaginator(new IlluminatePaginatorAdapter($paginator));
return response()->json($manager->createData($resource)->toArray())->header('Content-Type', self::CONTENT_TYPE);
@@ -311,23 +274,20 @@ class ListController extends Controller
*
* List all of them.
*
- * @param TransactionCurrency $currency
- *
- * @return JsonResponse
* @throws FireflyException
*/
public function rules(TransactionCurrency $currency): JsonResponse
{
- $manager = $this->getManager();
- $pageSize = $this->parameters->get('limit');
+ $manager = $this->getManager();
+ $pageSize = $this->parameters->get('limit');
// get list of budgets. Count it and split it.
/** @var RuleRepositoryInterface $ruleRepos */
- $ruleRepos = app(RuleRepositoryInterface::class);
- $unfiltered = $ruleRepos->getAll();
+ $ruleRepos = app(RuleRepositoryInterface::class);
+ $unfiltered = $ruleRepos->getAll();
- $collection = $unfiltered->filter(
- static function (Rule $rule) use ($currency) {
+ $collection = $unfiltered->filter( // @phpstan-ignore-line
+ static function (Rule $rule) use ($currency) { // @phpstan-ignore-line
/** @var RuleTrigger $trigger */
foreach ($rule->ruleTriggers as $trigger) {
if ('currency_is' === $trigger->trigger_type && $currency->name === $trigger->trigger_value) {
@@ -339,18 +299,18 @@ class ListController extends Controller
}
);
- $count = $collection->count();
- $rules = $collection->slice(($this->parameters->get('page') - 1) * $pageSize, $pageSize);
+ $count = $collection->count();
+ $rules = $collection->slice(($this->parameters->get('page') - 1) * $pageSize, $pageSize);
// make paginator:
- $paginator = new LengthAwarePaginator($rules, $count, $pageSize, $this->parameters->get('page'));
- $paginator->setPath(route('api.v1.rules.index') . $this->buildParams());
+ $paginator = new LengthAwarePaginator($rules, $count, $pageSize, $this->parameters->get('page'));
+ $paginator->setPath(route('api.v1.rules.index').$this->buildParams());
/** @var RuleTransformer $transformer */
$transformer = app(RuleTransformer::class);
$transformer->setParameters($this->parameters);
- $resource = new FractalCollection($rules, $transformer, 'rules');
+ $resource = new FractalCollection($rules, $transformer, 'rules');
$resource->setPaginator(new IlluminatePaginatorAdapter($paginator));
return response()->json($manager->createData($resource)->toArray())->header('Content-Type', self::CONTENT_TYPE);
@@ -362,28 +322,23 @@ class ListController extends Controller
*
* Show all transactions.
*
- * @param Request $request
- *
- * @param TransactionCurrency $currency
- *
- * @return JsonResponse
* @throws FireflyException
*/
public function transactions(Request $request, TransactionCurrency $currency): JsonResponse
{
- $pageSize = $this->parameters->get('limit');
- $type = $request->get('type') ?? 'default';
+ $pageSize = $this->parameters->get('limit');
+ $type = $request->get('type') ?? 'default';
$this->parameters->set('type', $type);
- $types = $this->mapTransactionTypes($this->parameters->get('type'));
- $manager = $this->getManager();
+ $types = $this->mapTransactionTypes($this->parameters->get('type'));
+ $manager = $this->getManager();
/** @var User $admin */
- $admin = auth()->user();
+ $admin = auth()->user();
// use new group collector:
/** @var GroupCollectorInterface $collector */
- $collector = app(GroupCollectorInterface::class);
+ $collector = app(GroupCollectorInterface::class);
$collector
->setUser($admin)
// filter on currency.
@@ -395,22 +350,23 @@ class ListController extends Controller
// set page to retrieve
->setPage($this->parameters->get('page'))
// set types of transactions to return.
- ->setTypes($types);
+ ->setTypes($types)
+ ;
if (null !== $this->parameters->get('start')) {
$collector->setStart($this->parameters->get('start'));
}
if (null !== $this->parameters->get('end')) {
$collector->setEnd($this->parameters->get('end'));
}
- $paginator = $collector->getPaginatedGroups();
- $paginator->setPath(route('api.v1.currencies.transactions', [$currency->code]) . $this->buildParams());
+ $paginator = $collector->getPaginatedGroups();
+ $paginator->setPath(route('api.v1.currencies.transactions', [$currency->code]).$this->buildParams());
$transactions = $paginator->getCollection();
/** @var TransactionGroupTransformer $transformer */
- $transformer = app(TransactionGroupTransformer::class);
+ $transformer = app(TransactionGroupTransformer::class);
$transformer->setParameters($this->parameters);
- $resource = new FractalCollection($transactions, $transformer, 'transactions');
+ $resource = new FractalCollection($transactions, $transformer, 'transactions');
$resource->setPaginator(new IlluminatePaginatorAdapter($paginator));
return response()->json($manager->createData($resource)->toArray())->header('Content-Type', self::CONTENT_TYPE);
diff --git a/app/Api/V1/Controllers/Models/TransactionCurrency/ShowController.php b/app/Api/V1/Controllers/Models/TransactionCurrency/ShowController.php
index 3c5b7c65c0..363d599869 100644
--- a/app/Api/V1/Controllers/Models/TransactionCurrency/ShowController.php
+++ b/app/Api/V1/Controllers/Models/TransactionCurrency/ShowController.php
@@ -27,13 +27,13 @@ namespace FireflyIII\Api\V1\Controllers\Models\TransactionCurrency;
use FireflyIII\Api\V1\Controllers\Controller;
use FireflyIII\Exceptions\FireflyException;
use FireflyIII\Models\TransactionCurrency;
-use FireflyIII\Repositories\Currency\CurrencyRepositoryInterface;
+use FireflyIII\Repositories\UserGroups\Currency\CurrencyRepositoryInterface;
use FireflyIII\Support\Http\Api\AccountFilter;
use FireflyIII\Support\Http\Api\TransactionFilter;
use FireflyIII\Transformers\CurrencyTransformer;
+use FireflyIII\User;
use Illuminate\Http\JsonResponse;
use Illuminate\Pagination\LengthAwarePaginator;
-use JsonException;
use League\Fractal\Pagination\IlluminatePaginatorAdapter;
use League\Fractal\Resource\Collection as FractalCollection;
use League\Fractal\Resource\Item;
@@ -50,8 +50,6 @@ class ShowController extends Controller
/**
* CurrencyRepository constructor.
- *
-
*/
public function __construct()
{
@@ -72,28 +70,25 @@ class ShowController extends Controller
*
* Display a listing of the resource.
*
- * @return JsonResponse
* @throws FireflyException
- * @throws JsonException
*/
public function index(): JsonResponse
{
- $pageSize = $this->parameters->get('limit');
- $collection = $this->repository->getAll();
- $count = $collection->count();
+ $pageSize = $this->parameters->get('limit');
+ $collection = $this->repository->getAll();
+ $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 = $this->getManager();
- $defaultCurrency = app('amount')->getDefaultCurrencyByUser(auth()->user());
- $this->parameters->set('defaultCurrency', $defaultCurrency);
+ $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 = $this->getManager();
/** @var CurrencyTransformer $transformer */
$transformer = app(CurrencyTransformer::class);
$transformer->setParameters($this->parameters);
- $resource = new FractalCollection($currencies, $transformer, 'currencies');
+ $resource = new FractalCollection($currencies, $transformer, 'currencies');
$resource->setPaginator(new IlluminatePaginatorAdapter($paginator));
return response()->json($manager->createData($resource)->toArray())->header('Content-Type', self::CONTENT_TYPE);
@@ -105,23 +100,24 @@ class ShowController extends Controller
*
* Show a currency.
*
- * @param TransactionCurrency $currency
- *
- * @return JsonResponse
* @throws FireflyException
- * @throws JsonException
*/
public function show(TransactionCurrency $currency): JsonResponse
{
+ /** @var User $user */
+ $user = auth()->user();
$manager = $this->getManager();
- $defaultCurrency = app('amount')->getDefaultCurrencyByUser(auth()->user());
+ $defaultCurrency = app('amount')->getDefaultCurrencyByUserGroup($user->userGroup);
$this->parameters->set('defaultCurrency', $defaultCurrency);
+ // update fields with user info.
+ $currency->refreshForUser($user);
+
/** @var CurrencyTransformer $transformer */
- $transformer = app(CurrencyTransformer::class);
+ $transformer = app(CurrencyTransformer::class);
$transformer->setParameters($this->parameters);
- $resource = new Item($currency, $transformer, 'currencies');
+ $resource = new Item($currency, $transformer, 'currencies');
return response()->json($manager->createData($resource)->toArray())->header('Content-Type', self::CONTENT_TYPE);
}
@@ -132,21 +128,23 @@ class ShowController extends Controller
*
* Show a currency.
*
- * @return JsonResponse
* @throws FireflyException
- * @throws JsonException
*/
public function showDefault(): JsonResponse
{
- $manager = $this->getManager();
- $currency = app('amount')->getDefaultCurrencyByUser(auth()->user());
- $this->parameters->set('defaultCurrency', $currency);
+ /** @var User $user */
+ $user = auth()->user();
+ $manager = $this->getManager();
+ $currency = app('amount')->getDefaultCurrencyByUserGroup($user->userGroup);
+
+ // update fields with user info.
+ $currency->refreshForUser($user);
/** @var CurrencyTransformer $transformer */
$transformer = app(CurrencyTransformer::class);
$transformer->setParameters($this->parameters);
- $resource = new Item($currency, $transformer, 'currencies');
+ $resource = new Item($currency, $transformer, 'currencies');
return response()->json($manager->createData($resource)->toArray())->header('Content-Type', self::CONTENT_TYPE);
}
diff --git a/app/Api/V1/Controllers/Models/TransactionCurrency/StoreController.php b/app/Api/V1/Controllers/Models/TransactionCurrency/StoreController.php
index 61a4c63d22..fd041a704e 100644
--- a/app/Api/V1/Controllers/Models/TransactionCurrency/StoreController.php
+++ b/app/Api/V1/Controllers/Models/TransactionCurrency/StoreController.php
@@ -27,12 +27,12 @@ namespace FireflyIII\Api\V1\Controllers\Models\TransactionCurrency;
use FireflyIII\Api\V1\Controllers\Controller;
use FireflyIII\Api\V1\Requests\Models\TransactionCurrency\StoreRequest;
use FireflyIII\Exceptions\FireflyException;
-use FireflyIII\Repositories\Currency\CurrencyRepositoryInterface;
+use FireflyIII\Repositories\UserGroups\Currency\CurrencyRepositoryInterface;
use FireflyIII\Support\Http\Api\AccountFilter;
use FireflyIII\Support\Http\Api\TransactionFilter;
use FireflyIII\Transformers\CurrencyTransformer;
+use FireflyIII\User;
use Illuminate\Http\JsonResponse;
-use JsonException;
use League\Fractal\Resource\Item;
/**
@@ -47,8 +47,6 @@ class StoreController extends Controller
/**
* CurrencyRepository constructor.
- *
-
*/
public function __construct()
{
@@ -69,28 +67,26 @@ class StoreController extends Controller
*
* Store new currency.
*
- * @param StoreRequest $request
- *
- * @return JsonResponse
* @throws FireflyException
- * @throws JsonException
*/
public function store(StoreRequest $request): JsonResponse
{
- $currency = $this->repository->store($request->getAll());
+ $currency = $this->repository->store($request->getAll());
if (true === $request->boolean('default')) {
- app('preferences')->set('currencyPreference', $currency->code);
+ $this->repository->makeDefault($currency);
app('preferences')->mark();
}
- $manager = $this->getManager();
- $defaultCurrency = app('amount')->getDefaultCurrencyByUser(auth()->user());
- $this->parameters->set('defaultCurrency', $defaultCurrency);
+ $manager = $this->getManager();
+
+ /** @var User $user */
+ $user = auth()->user();
+ $currency->refreshForUser($user);
/** @var CurrencyTransformer $transformer */
$transformer = app(CurrencyTransformer::class);
$transformer->setParameters($this->parameters);
- $resource = new Item($currency, $transformer, 'currencies');
+ $resource = new Item($currency, $transformer, 'currencies');
return response()->json($manager->createData($resource)->toArray())->header('Content-Type', self::CONTENT_TYPE);
}
diff --git a/app/Api/V1/Controllers/Models/TransactionCurrency/UpdateController.php b/app/Api/V1/Controllers/Models/TransactionCurrency/UpdateController.php
index e0f978c048..d7d2288c9a 100644
--- a/app/Api/V1/Controllers/Models/TransactionCurrency/UpdateController.php
+++ b/app/Api/V1/Controllers/Models/TransactionCurrency/UpdateController.php
@@ -28,12 +28,12 @@ use FireflyIII\Api\V1\Controllers\Controller;
use FireflyIII\Api\V1\Requests\Models\TransactionCurrency\UpdateRequest;
use FireflyIII\Exceptions\FireflyException;
use FireflyIII\Models\TransactionCurrency;
-use FireflyIII\Repositories\Currency\CurrencyRepositoryInterface;
+use FireflyIII\Repositories\UserGroups\Currency\CurrencyRepositoryInterface;
use FireflyIII\Support\Http\Api\AccountFilter;
use FireflyIII\Support\Http\Api\TransactionFilter;
use FireflyIII\Transformers\CurrencyTransformer;
+use FireflyIII\User;
use Illuminate\Http\JsonResponse;
-use JsonException;
use League\Fractal\Resource\Item;
/**
@@ -48,8 +48,6 @@ class UpdateController extends Controller
/**
* CurrencyRepository constructor.
- *
-
*/
public function __construct()
{
@@ -70,11 +68,7 @@ class UpdateController extends Controller
*
* Disable a currency.
*
- * @param TransactionCurrency $currency
- *
- * @return JsonResponse
* @throws FireflyException
- * @throws JsonException
*/
public function disable(TransactionCurrency $currency): JsonResponse
{
@@ -82,17 +76,23 @@ class UpdateController extends Controller
if ($this->repository->currencyInUse($currency)) {
return response()->json([], 409);
}
- $this->repository->disable($currency);
- $manager = $this->getManager();
+ // must not be the only one in use:
+ if (1 === $this->repository->get()->count()) {
+ return response()->json([], 409);
+ }
- $defaultCurrency = app('amount')->getDefaultCurrencyByUser(auth()->user());
- $this->parameters->set('defaultCurrency', $defaultCurrency);
+ /** @var User $user */
+ $user = auth()->user();
+ $this->repository->disable($currency);
+ $manager = $this->getManager();
+
+ $currency->refreshForUser($user);
/** @var CurrencyTransformer $transformer */
$transformer = app(CurrencyTransformer::class);
$transformer->setParameters($this->parameters);
- $resource = new Item($currency, $transformer, 'currencies');
+ $resource = new Item($currency, $transformer, 'currencies');
return response()->json($manager->createData($resource)->toArray())->header('Content-Type', self::CONTENT_TYPE);
}
@@ -103,27 +103,25 @@ class UpdateController extends Controller
*
* Make the currency a default currency.
*
- * @param TransactionCurrency $currency
- *
- * @return JsonResponse
* @throws FireflyException
*/
public function makeDefault(TransactionCurrency $currency): JsonResponse
{
+ /** @var User $user */
+ $user = auth()->user();
$this->repository->enable($currency);
+ $this->repository->makeDefault($currency);
- app('preferences')->set('currencyPreference', $currency->code);
app('preferences')->mark();
- $manager = $this->getManager();
-
- $this->parameters->set('defaultCurrency', $currency);
+ $manager = $this->getManager();
+ $currency->refreshForUser($user);
/** @var CurrencyTransformer $transformer */
$transformer = app(CurrencyTransformer::class);
$transformer->setParameters($this->parameters);
- $resource = new Item($currency, $transformer, 'currencies');
+ $resource = new Item($currency, $transformer, 'currencies');
return response()->json($manager->createData($resource)->toArray())->header('Content-Type', self::CONTENT_TYPE);
}
@@ -134,25 +132,23 @@ class UpdateController extends Controller
*
* Enable a currency.
*
- * @param TransactionCurrency $currency
- *
- * @return JsonResponse
* @throws FireflyException
- * @throws JsonException
*/
public function enable(TransactionCurrency $currency): JsonResponse
{
$this->repository->enable($currency);
- $manager = $this->getManager();
+ $manager = $this->getManager();
- $defaultCurrency = app('amount')->getDefaultCurrencyByUser(auth()->user());
- $this->parameters->set('defaultCurrency', $defaultCurrency);
+ /** @var User $user */
+ $user = auth()->user();
+
+ $currency->refreshForUser($user);
/** @var CurrencyTransformer $transformer */
$transformer = app(CurrencyTransformer::class);
$transformer->setParameters($this->parameters);
- $resource = new Item($currency, $transformer, 'currencies');
+ $resource = new Item($currency, $transformer, 'currencies');
return response()->json($manager->createData($resource)->toArray())->header('Content-Type', self::CONTENT_TYPE);
}
@@ -163,33 +159,32 @@ class UpdateController extends Controller
*
* Update a currency.
*
- * @param UpdateRequest $request
- * @param TransactionCurrency $currency
- *
- * @return JsonResponse
* @throws FireflyException
- * @throws JsonException
*/
public function update(UpdateRequest $request, TransactionCurrency $currency): JsonResponse
{
- $data = $request->getAll();
- $currency = $this->repository->update($currency, $data);
+ $data = $request->getAll();
- if (true === $request->boolean('default')) {
- app('preferences')->set('currencyPreference', $currency->code);
- app('preferences')->mark();
+ /** @var User $user */
+ $user = auth()->user();
+
+ // safety catch on currency disablement.
+ $set = $this->repository->get();
+ if (array_key_exists('enabled', $data) && false === $data['enabled'] && 1 === count($set) && $set->first()->id === $currency->id) {
+ return response()->json([], 409);
}
+ $currency = $this->repository->update($currency, $data);
- $manager = $this->getManager();
+ app('preferences')->mark();
- $defaultCurrency = app('amount')->getDefaultCurrencyByUser(auth()->user());
- $this->parameters->set('defaultCurrency', $defaultCurrency);
+ $manager = $this->getManager();
+ $currency->refreshForUser($user);
/** @var CurrencyTransformer $transformer */
$transformer = app(CurrencyTransformer::class);
$transformer->setParameters($this->parameters);
- $resource = new Item($currency, $transformer, 'currencies');
+ $resource = new Item($currency, $transformer, 'currencies');
return response()->json($manager->createData($resource)->toArray())->header('Content-Type', self::CONTENT_TYPE);
}
diff --git a/app/Api/V1/Controllers/Models/TransactionLink/DestroyController.php b/app/Api/V1/Controllers/Models/TransactionLink/DestroyController.php
index 1c9b1fc9a7..e5c0b5ff46 100644
--- a/app/Api/V1/Controllers/Models/TransactionLink/DestroyController.php
+++ b/app/Api/V1/Controllers/Models/TransactionLink/DestroyController.php
@@ -39,8 +39,6 @@ class DestroyController extends Controller
/**
* TransactionLinkController constructor.
- *
-
*/
public function __construct()
{
@@ -48,7 +46,7 @@ class DestroyController extends Controller
$this->middleware(
function ($request, $next) {
/** @var User $user */
- $user = auth()->user();
+ $user = auth()->user();
$this->repository = app(LinkTypeRepositoryInterface::class);
@@ -64,10 +62,6 @@ class DestroyController extends Controller
* https://api-docs.firefly-iii.org/?urls.primaryName=2.0.0%20(v1)#/links/deleteTransactionLink
*
* Delete the resource.
- *
- * @param TransactionJournalLink $link
- *
- * @return JsonResponse
*/
public function destroy(TransactionJournalLink $link): JsonResponse
{
diff --git a/app/Api/V1/Controllers/Models/TransactionLink/ShowController.php b/app/Api/V1/Controllers/Models/TransactionLink/ShowController.php
index 485cbd51b2..f5874f90ae 100644
--- a/app/Api/V1/Controllers/Models/TransactionLink/ShowController.php
+++ b/app/Api/V1/Controllers/Models/TransactionLink/ShowController.php
@@ -46,8 +46,6 @@ class ShowController extends Controller
/**
* TransactionLinkController constructor.
- *
-
*/
public function __construct()
{
@@ -55,7 +53,7 @@ class ShowController extends Controller
$this->middleware(
function ($request, $next) {
/** @var User $user */
- $user = auth()->user();
+ $user = auth()->user();
$this->repository = app(LinkTypeRepositoryInterface::class);
@@ -72,21 +70,18 @@ class ShowController extends Controller
*
* List all transaction links there are.
*
- * @param Request $request
- *
- * @return JsonResponse
* @throws FireflyException
*/
public function index(Request $request): JsonResponse
{
// create some objects:
- $manager = $this->getManager();
+ $manager = $this->getManager();
// read type from URL
- $name = $request->get('name');
+ $name = $request->get('name');
// types to get, page size:
- $pageSize = $this->parameters->get('limit');
- $linkType = $this->repository->findByName($name);
+ $pageSize = $this->parameters->get('limit');
+ $linkType = $this->repository->findByName($name);
// get list of transaction links. Count it and split it.
$collection = $this->repository->getJournalLinks($linkType);
@@ -94,14 +89,14 @@ class ShowController extends Controller
$journalLinks = $collection->slice(($this->parameters->get('page') - 1) * $pageSize, $pageSize);
// make paginator:
- $paginator = new LengthAwarePaginator($journalLinks, $count, $pageSize, $this->parameters->get('page'));
- $paginator->setPath(route('api.v1.transaction-links.index') . $this->buildParams());
+ $paginator = new LengthAwarePaginator($journalLinks, $count, $pageSize, $this->parameters->get('page'));
+ $paginator->setPath(route('api.v1.transaction-links.index').$this->buildParams());
/** @var TransactionLinkTransformer $transformer */
- $transformer = app(TransactionLinkTransformer::class);
+ $transformer = app(TransactionLinkTransformer::class);
$transformer->setParameters($this->parameters);
- $resource = new FractalCollection($journalLinks, $transformer, 'transaction_links');
+ $resource = new FractalCollection($journalLinks, $transformer, 'transaction_links');
$resource->setPaginator(new IlluminatePaginatorAdapter($paginator));
return response()->json($manager->createData($resource)->toArray())->header('Content-Type', self::CONTENT_TYPE);
@@ -112,20 +107,16 @@ class ShowController extends Controller
* https://api-docs.firefly-iii.org/?urls.primaryName=2.0.0%20(v1)#/links/getTransactionLink
*
* List single resource.
- *
- * @param TransactionJournalLink $journalLink
- *
- * @return JsonResponse
*/
public function show(TransactionJournalLink $journalLink): JsonResponse
{
- $manager = $this->getManager();
+ $manager = $this->getManager();
/** @var TransactionLinkTransformer $transformer */
$transformer = app(TransactionLinkTransformer::class);
$transformer->setParameters($this->parameters);
- $resource = new Item($journalLink, $transformer, 'transaction_links');
+ $resource = new Item($journalLink, $transformer, 'transaction_links');
return response()->json($manager->createData($resource)->toArray())->header('Content-Type', self::CONTENT_TYPE);
}
diff --git a/app/Api/V1/Controllers/Models/TransactionLink/StoreController.php b/app/Api/V1/Controllers/Models/TransactionLink/StoreController.php
index 861dbbcc79..f3083cb7fe 100644
--- a/app/Api/V1/Controllers/Models/TransactionLink/StoreController.php
+++ b/app/Api/V1/Controllers/Models/TransactionLink/StoreController.php
@@ -47,8 +47,6 @@ class StoreController extends Controller
/**
* TransactionLinkController constructor.
- *
-
*/
public function __construct()
{
@@ -56,7 +54,7 @@ class StoreController extends Controller
$this->middleware(
function ($request, $next) {
/** @var User $user */
- $user = auth()->user();
+ $user = auth()->user();
$this->repository = app(LinkTypeRepositoryInterface::class);
$this->journalRepository = app(JournalRepositoryInterface::class);
@@ -75,29 +73,26 @@ class StoreController extends Controller
*
* Store new object.
*
- * @param StoreRequest $request
- *
- * @return JsonResponse
* @throws FireflyException
*/
public function store(StoreRequest $request): JsonResponse
{
- $manager = $this->getManager();
- $data = $request->getAll();
- $inward = $this->journalRepository->find($data['inward_id'] ?? 0);
- $outward = $this->journalRepository->find($data['outward_id'] ?? 0);
+ $manager = $this->getManager();
+ $data = $request->getAll();
+ $inward = $this->journalRepository->find($data['inward_id'] ?? 0);
+ $outward = $this->journalRepository->find($data['outward_id'] ?? 0);
if (null === $inward || null === $outward) {
throw new FireflyException('200024: Source or destination does not exist.');
}
$data['direction'] = 'inward';
- $journalLink = $this->repository->storeLink($data, $inward, $outward);
+ $journalLink = $this->repository->storeLink($data, $inward, $outward);
/** @var TransactionLinkTransformer $transformer */
- $transformer = app(TransactionLinkTransformer::class);
+ $transformer = app(TransactionLinkTransformer::class);
$transformer->setParameters($this->parameters);
- $resource = new Item($journalLink, $transformer, 'transaction_links');
+ $resource = new Item($journalLink, $transformer, 'transaction_links');
return response()->json($manager->createData($resource)->toArray())->header('Content-Type', self::CONTENT_TYPE);
}
diff --git a/app/Api/V1/Controllers/Models/TransactionLink/UpdateController.php b/app/Api/V1/Controllers/Models/TransactionLink/UpdateController.php
index f432b93c70..289774ad39 100644
--- a/app/Api/V1/Controllers/Models/TransactionLink/UpdateController.php
+++ b/app/Api/V1/Controllers/Models/TransactionLink/UpdateController.php
@@ -44,8 +44,6 @@ class UpdateController extends Controller
/**
* TransactionLinkController constructor.
- *
-
*/
public function __construct()
{
@@ -53,7 +51,7 @@ class UpdateController extends Controller
$this->middleware(
function ($request, $next) {
/** @var User $user */
- $user = auth()->user();
+ $user = auth()->user();
$this->repository = app(LinkTypeRepositoryInterface::class);
$this->journalRepository = app(JournalRepositoryInterface::class);
@@ -71,11 +69,6 @@ class UpdateController extends Controller
* https://api-docs.firefly-iii.org/?urls.primaryName=2.0.0%20(v1)#/links/updateTransactionLink
*
* Update object.
- *
- * @param UpdateRequest $request
- * @param TransactionJournalLink $journalLink
- *
- * @return JsonResponse
*/
public function update(UpdateRequest $request, TransactionJournalLink $journalLink): JsonResponse
{
@@ -87,7 +80,7 @@ class UpdateController extends Controller
$transformer = app(TransactionLinkTransformer::class);
$transformer->setParameters($this->parameters);
- $resource = new Item($journalLink, $transformer, 'transaction_links');
+ $resource = new Item($journalLink, $transformer, 'transaction_links');
return response()->json($manager->createData($resource)->toArray())->header('Content-Type', self::CONTENT_TYPE);
}
diff --git a/app/Api/V1/Controllers/Models/TransactionLinkType/DestroyController.php b/app/Api/V1/Controllers/Models/TransactionLinkType/DestroyController.php
index 4eca004d35..7abbff55d7 100644
--- a/app/Api/V1/Controllers/Models/TransactionLinkType/DestroyController.php
+++ b/app/Api/V1/Controllers/Models/TransactionLinkType/DestroyController.php
@@ -43,8 +43,6 @@ class DestroyController extends Controller
/**
* LinkTypeController constructor.
- *
-
*/
public function __construct()
{
@@ -67,9 +65,6 @@ class DestroyController extends Controller
*
* Delete the resource.
*
- * @param LinkType $linkType
- *
- * @return JsonResponse
* @throws FireflyException
*/
public function destroy(LinkType $linkType): JsonResponse
diff --git a/app/Api/V1/Controllers/Models/TransactionLinkType/ListController.php b/app/Api/V1/Controllers/Models/TransactionLinkType/ListController.php
index 3e18860ccb..a135a815bf 100644
--- a/app/Api/V1/Controllers/Models/TransactionLinkType/ListController.php
+++ b/app/Api/V1/Controllers/Models/TransactionLinkType/ListController.php
@@ -48,8 +48,6 @@ class ListController extends Controller
/**
* LinkTypeController constructor.
- *
-
*/
public function __construct()
{
@@ -70,30 +68,26 @@ class ListController extends Controller
* This endpoint is documented at:
* https://api-docs.firefly-iii.org/?urls.primaryName=2.0.0%20(v1)#/links/listTransactionByLinkType
*
- * @param Request $request
- * @param LinkType $linkType
- *
- * @return JsonResponse
* @throws FireflyException
*/
public function transactions(Request $request, LinkType $linkType): JsonResponse
{
- $pageSize = $this->parameters->get('limit');
- $type = $request->get('type') ?? 'default';
+ $pageSize = $this->parameters->get('limit');
+ $type = $request->get('type') ?? 'default';
$this->parameters->set('type', $type);
- $types = $this->mapTransactionTypes($this->parameters->get('type'));
- $manager = $this->getManager();
+ $types = $this->mapTransactionTypes($this->parameters->get('type'));
+ $manager = $this->getManager();
// whatever is returned by the query, it must be part of these journals:
- $journalIds = $this->repository->getJournalIds($linkType);
+ $journalIds = $this->repository->getJournalIds($linkType);
/** @var User $admin */
- $admin = auth()->user();
+ $admin = auth()->user();
// use new group collector:
/** @var GroupCollectorInterface $collector */
- $collector = app(GroupCollectorInterface::class);
+ $collector = app(GroupCollectorInterface::class);
$collector
->setUser($admin)
// filter on journal IDs.
@@ -105,22 +99,23 @@ class ListController extends Controller
// set page to retrieve
->setPage($this->parameters->get('page'))
// set types of transactions to return.
- ->setTypes($types);
+ ->setTypes($types)
+ ;
if (null !== $this->parameters->get('start')) {
$collector->setStart($this->parameters->get('start'));
}
if (null !== $this->parameters->get('end')) {
$collector->setEnd($this->parameters->get('end'));
}
- $paginator = $collector->getPaginatedGroups();
- $paginator->setPath(route('api.v1.transactions.index') . $this->buildParams());
+ $paginator = $collector->getPaginatedGroups();
+ $paginator->setPath(route('api.v1.transactions.index').$this->buildParams());
$transactions = $paginator->getCollection();
/** @var TransactionGroupTransformer $transformer */
- $transformer = app(TransactionGroupTransformer::class);
+ $transformer = app(TransactionGroupTransformer::class);
$transformer->setParameters($this->parameters);
- $resource = new FractalCollection($transactions, $transformer, 'transactions');
+ $resource = new FractalCollection($transactions, $transformer, 'transactions');
$resource->setPaginator(new IlluminatePaginatorAdapter($paginator));
return response()->json($manager->createData($resource)->toArray())->header('Content-Type', self::CONTENT_TYPE);
diff --git a/app/Api/V1/Controllers/Models/TransactionLinkType/ShowController.php b/app/Api/V1/Controllers/Models/TransactionLinkType/ShowController.php
index cc63966521..9fa5e2e497 100644
--- a/app/Api/V1/Controllers/Models/TransactionLinkType/ShowController.php
+++ b/app/Api/V1/Controllers/Models/TransactionLinkType/ShowController.php
@@ -48,8 +48,6 @@ class ShowController extends Controller
/**
* LinkTypeController constructor.
- *
-
*/
public function __construct()
{
@@ -70,30 +68,28 @@ class ShowController extends Controller
* This endpoint is documented at:
* https://api-docs.firefly-iii.org/?urls.primaryName=2.0.0%20(v1)#/links/listLinkType
*
- *
- * @return JsonResponse
* @throws FireflyException
*/
public function index(): JsonResponse
{
// create some objects:
- $manager = $this->getManager();
- $pageSize = $this->parameters->get('limit');
+ $manager = $this->getManager();
+ $pageSize = $this->parameters->get('limit');
// get list of accounts. Count it and split it.
- $collection = $this->repository->get();
- $count = $collection->count();
- $linkTypes = $collection->slice(($this->parameters->get('page') - 1) * $pageSize, $pageSize);
+ $collection = $this->repository->get();
+ $count = $collection->count();
+ $linkTypes = $collection->slice(($this->parameters->get('page') - 1) * $pageSize, $pageSize);
// make paginator:
- $paginator = new LengthAwarePaginator($linkTypes, $count, $pageSize, $this->parameters->get('page'));
- $paginator->setPath(route('api.v1.link-types.index') . $this->buildParams());
+ $paginator = new LengthAwarePaginator($linkTypes, $count, $pageSize, $this->parameters->get('page'));
+ $paginator->setPath(route('api.v1.link-types.index').$this->buildParams());
/** @var LinkTypeTransformer $transformer */
$transformer = app(LinkTypeTransformer::class);
$transformer->setParameters($this->parameters);
- $resource = new FractalCollection($linkTypes, $transformer, 'link_types');
+ $resource = new FractalCollection($linkTypes, $transformer, 'link_types');
$resource->setPaginator(new IlluminatePaginatorAdapter($paginator));
return response()->json($manager->createData($resource)->toArray())->header('Content-Type', self::CONTENT_TYPE);
@@ -104,19 +100,16 @@ class ShowController extends Controller
* https://api-docs.firefly-iii.org/?urls.primaryName=2.0.0%20(v1)#/links/getLinkType
*
* List single resource.
- *
- * @param LinkType $linkType
- *
- * @return JsonResponse
*/
public function show(LinkType $linkType): JsonResponse
{
- $manager = $this->getManager();
+ $manager = $this->getManager();
+
/** @var LinkTypeTransformer $transformer */
$transformer = app(LinkTypeTransformer::class);
$transformer->setParameters($this->parameters);
- $resource = new Item($linkType, $transformer, 'link_types');
+ $resource = new Item($linkType, $transformer, 'link_types');
return response()->json($manager->createData($resource)->toArray())->header('Content-Type', self::CONTENT_TYPE);
}
diff --git a/app/Api/V1/Controllers/Models/TransactionLinkType/StoreController.php b/app/Api/V1/Controllers/Models/TransactionLinkType/StoreController.php
index e42f5d74c2..c915dd6589 100644
--- a/app/Api/V1/Controllers/Models/TransactionLinkType/StoreController.php
+++ b/app/Api/V1/Controllers/Models/TransactionLinkType/StoreController.php
@@ -34,7 +34,6 @@ use FireflyIII\Transformers\LinkTypeTransformer;
use FireflyIII\User;
use Illuminate\Http\JsonResponse;
use League\Fractal\Resource\Item;
-use Validator;
/**
* Class StoreController
@@ -48,8 +47,6 @@ class StoreController extends Controller
/**
* LinkTypeController constructor.
- *
-
*/
public function __construct()
{
@@ -73,31 +70,28 @@ class StoreController extends Controller
*
* Store new object.
*
- * @param StoreRequest $request
- *
- * @return JsonResponse
* @throws FireflyException
*/
public function store(StoreRequest $request): JsonResponse
{
/** @var User $admin */
- $admin = auth()->user();
- $rules = ['name' => 'required'];
+ $admin = auth()->user();
+ $rules = ['name' => 'required'];
if (!$this->userRepository->hasRole($admin, 'owner')) {
// access denied:
$messages = ['name' => '200005: You need the "owner" role to do this.'];
- Validator::make([], $rules, $messages)->validate();
+ \Validator::make([], $rules, $messages)->validate();
}
- $data = $request->getAll();
+ $data = $request->getAll();
// if currency ID is 0, find the currency by the code:
- $linkType = $this->repository->store($data);
- $manager = $this->getManager();
+ $linkType = $this->repository->store($data);
+ $manager = $this->getManager();
/** @var LinkTypeTransformer $transformer */
$transformer = app(LinkTypeTransformer::class);
$transformer->setParameters($this->parameters);
- $resource = new Item($linkType, $transformer, 'link_types');
+ $resource = new Item($linkType, $transformer, 'link_types');
return response()->json($manager->createData($resource)->toArray())->header('Content-Type', self::CONTENT_TYPE);
}
diff --git a/app/Api/V1/Controllers/Models/TransactionLinkType/UpdateController.php b/app/Api/V1/Controllers/Models/TransactionLinkType/UpdateController.php
index 60bab00568..0b79bd30a1 100644
--- a/app/Api/V1/Controllers/Models/TransactionLinkType/UpdateController.php
+++ b/app/Api/V1/Controllers/Models/TransactionLinkType/UpdateController.php
@@ -35,7 +35,6 @@ use FireflyIII\Transformers\LinkTypeTransformer;
use FireflyIII\User;
use Illuminate\Http\JsonResponse;
use League\Fractal\Resource\Item;
-use Validator;
/**
* Class UpdateController
@@ -49,8 +48,6 @@ class UpdateController extends Controller
/**
* LinkTypeController constructor.
- *
-
*/
public function __construct()
{
@@ -74,10 +71,6 @@ class UpdateController extends Controller
*
* Update object.
*
- * @param UpdateRequest $request
- * @param LinkType $linkType
- *
- * @return JsonResponse
* @throws FireflyException
*/
public function update(UpdateRequest $request, LinkType $linkType): JsonResponse
@@ -87,22 +80,23 @@ class UpdateController extends Controller
}
/** @var User $admin */
- $admin = auth()->user();
- $rules = ['name' => 'required'];
+ $admin = auth()->user();
+ $rules = ['name' => 'required'];
if (!$this->userRepository->hasRole($admin, 'owner')) {
$messages = ['name' => '200005: You need the "owner" role to do this.'];
- Validator::make([], $rules, $messages)->validate();
+ \Validator::make([], $rules, $messages)->validate();
}
- $data = $request->getAll();
+ $data = $request->getAll();
$this->repository->update($linkType, $data);
- $manager = $this->getManager();
+ $manager = $this->getManager();
+
/** @var LinkTypeTransformer $transformer */
$transformer = app(LinkTypeTransformer::class);
$transformer->setParameters($this->parameters);
- $resource = new Item($linkType, $transformer, 'link_types');
+ $resource = new Item($linkType, $transformer, 'link_types');
return response()->json($manager->createData($resource)->toArray())->header('Content-Type', self::CONTENT_TYPE);
}
diff --git a/app/Api/V1/Controllers/Search/AccountController.php b/app/Api/V1/Controllers/Search/AccountController.php
index 2da3d3a254..98204fcef7 100644
--- a/app/Api/V1/Controllers/Search/AccountController.php
+++ b/app/Api/V1/Controllers/Search/AccountController.php
@@ -32,7 +32,6 @@ use Illuminate\Http\JsonResponse;
use Illuminate\Http\Request;
use Illuminate\Http\Response;
use Illuminate\Pagination\LengthAwarePaginator;
-use Illuminate\Support\Facades\Log;
use League\Fractal\Pagination\IlluminatePaginatorAdapter;
use League\Fractal\Resource\Collection as FractalCollection;
@@ -60,39 +59,36 @@ class AccountController extends Controller
/**
* This endpoint is documented at:
* https://api-docs.firefly-iii.org/?urls.primaryName=2.0.0%20(v1)#/search/searchAccounts
- *
- * @param Request $request
- *
- * @return JsonResponse|Response
*/
- public function search(Request $request): JsonResponse | Response
+ public function search(Request $request): JsonResponse|Response
{
- Log::debug('Now in account search()');
- $manager = $this->getManager();
- $query = trim((string)$request->get('query'));
- $field = trim((string)$request->get('field'));
- $type = $request->get('type') ?? 'all';
+ app('log')->debug('Now in account search()');
+ $manager = $this->getManager();
+ $query = trim((string)$request->get('query'));
+ $field = trim((string)$request->get('field'));
+ $type = $request->get('type') ?? 'all';
if ('' === $query || !in_array($field, $this->validFields, true)) {
return response(null, 422);
}
- $types = $this->mapAccountTypes($type);
+ $types = $this->mapAccountTypes($type);
/** @var AccountSearch $search */
- $search = app(AccountSearch::class);
+ $search = app(AccountSearch::class);
$search->setUser(auth()->user());
$search->setTypes($types);
$search->setField($field);
$search->setQuery($query);
- $accounts = $search->search();
+ $accounts = $search->search();
+
/** @var AccountTransformer $transformer */
$transformer = app(AccountTransformer::class);
$transformer->setParameters($this->parameters);
- $count = $accounts->count();
- $perPage = 0 === $count ? 1 : $count;
- $paginator = new LengthAwarePaginator($accounts, $count, $perPage, 1);
+ $count = $accounts->count();
+ $perPage = 0 === $count ? 1 : $count;
+ $paginator = new LengthAwarePaginator($accounts, $count, $perPage, 1);
- $resource = new FractalCollection($accounts, $transformer, 'accounts');
+ $resource = new FractalCollection($accounts, $transformer, 'accounts');
$resource->setPaginator(new IlluminatePaginatorAdapter($paginator));
return response()->json($manager->createData($resource)->toArray())->header('Content-Type', self::CONTENT_TYPE);
diff --git a/app/Api/V1/Controllers/Search/TransactionController.php b/app/Api/V1/Controllers/Search/TransactionController.php
index 2588d0520a..962a454253 100644
--- a/app/Api/V1/Controllers/Search/TransactionController.php
+++ b/app/Api/V1/Controllers/Search/TransactionController.php
@@ -42,35 +42,31 @@ class TransactionController extends Controller
* This endpoint is documented at:
* https://api-docs.firefly-iii.org/?urls.primaryName=2.0.0%20(v1)#/search/searchTransactions
*
- * @param Request $request
- * @param SearchInterface $searcher
- *
- * @return JsonResponse
* @throws FireflyException
*/
public function search(Request $request, SearchInterface $searcher): JsonResponse
{
- $manager = $this->getManager();
- $fullQuery = (string)$request->get('query');
- $page = 0 === (int)$request->get('page') ? 1 : (int)$request->get('page');
- $pageSize = $this->parameters->get('limit');
+ $manager = $this->getManager();
+ $fullQuery = (string)$request->get('query');
+ $page = 0 === (int)$request->get('page') ? 1 : (int)$request->get('page');
+ $pageSize = $this->parameters->get('limit');
$searcher->parseQuery($fullQuery);
$searcher->setPage($page);
$searcher->setLimit($pageSize);
- $groups = $searcher->searchTransactions();
- $parameters = ['search' => $fullQuery];
- $url = route('api.v1.search.transactions') . '?' . http_build_query($parameters);
+ $groups = $searcher->searchTransactions();
+ $parameters = ['search' => $fullQuery];
+ $url = route('api.v1.search.transactions').'?'.http_build_query($parameters);
$groups->setPath($url);
$transactions = $groups->getCollection();
/** @var TransactionGroupTransformer $transformer */
- $transformer = app(TransactionGroupTransformer::class);
+ $transformer = app(TransactionGroupTransformer::class);
$transformer->setParameters($this->parameters);
- $resource = new Collection($transactions, $transformer, 'transactions');
+ $resource = new Collection($transactions, $transformer, 'transactions');
$resource->setPaginator(new IlluminatePaginatorAdapter($groups));
- $array = $manager->createData($resource)->toArray();
+ $array = $manager->createData($resource)->toArray();
return response()->json($array)->header('Content-Type', self::CONTENT_TYPE);
}
diff --git a/app/Api/V1/Controllers/Summary/BasicController.php b/app/Api/V1/Controllers/Summary/BasicController.php
index 28ec3b227a..0ac913f809 100644
--- a/app/Api/V1/Controllers/Summary/BasicController.php
+++ b/app/Api/V1/Controllers/Summary/BasicController.php
@@ -25,21 +25,19 @@ declare(strict_types=1);
namespace FireflyIII\Api\V1\Controllers\Summary;
use Carbon\Carbon;
-use Exception;
use FireflyIII\Api\V1\Controllers\Controller;
use FireflyIII\Api\V1\Requests\Data\DateRequest;
use FireflyIII\Helpers\Collector\GroupCollectorInterface;
use FireflyIII\Helpers\Report\NetWorthInterface;
use FireflyIII\Models\Account;
use FireflyIII\Models\AccountType;
-use FireflyIII\Models\TransactionCurrency;
use FireflyIII\Models\TransactionType;
use FireflyIII\Repositories\Account\AccountRepositoryInterface;
use FireflyIII\Repositories\Bill\BillRepositoryInterface;
use FireflyIII\Repositories\Budget\AvailableBudgetRepositoryInterface;
use FireflyIII\Repositories\Budget\BudgetRepositoryInterface;
use FireflyIII\Repositories\Budget\OperationsRepositoryInterface;
-use FireflyIII\Repositories\Currency\CurrencyRepositoryInterface;
+use FireflyIII\Repositories\UserGroups\Currency\CurrencyRepositoryInterface;
use FireflyIII\User;
use Illuminate\Http\JsonResponse;
@@ -57,8 +55,6 @@ class BasicController extends Controller
/**
* BasicController constructor.
- *
-
*/
public function __construct()
{
@@ -90,28 +86,29 @@ class BasicController extends Controller
* This endpoint is documented at:
* https://api-docs.firefly-iii.org/?urls.primaryName=2.0.0%20(v1)#/summary/getBasicSummary
*
- * @param DateRequest $request
- *
- * @return JsonResponse
- * @throws Exception
+ * @throws \Exception
*/
public function basic(DateRequest $request): JsonResponse
{
// parameters for boxes:
- $dates = $request->getAll();
- $start = $dates['start'];
- $end = $dates['end'];
- $code = $request->get('currency_code');
+ $dates = $request->getAll();
+ $start = $dates['start'];
+ $end = $dates['end'];
+ $code = $request->get('currency_code');
// balance information:
$balanceData = $this->getBalanceInformation($start, $end);
$billData = $this->getBillInformation($start, $end);
$spentData = $this->getLeftToSpendInfo($start, $end);
- $networthData = $this->getNetWorthInfo($start, $end);
- $total = array_merge($balanceData, $billData, $spentData, $networthData);
+ $netWorthData = $this->getNetWorthInfo($start, $end);
+ // $balanceData = [];
+ // $billData = [];
+ // $spentData = [];
+ // $netWorthData = [];
+ $total = array_merge($balanceData, $billData, $spentData, $netWorthData);
// give new keys
- $return = [];
+ $return = [];
foreach ($total as $entry) {
if (null === $code || ($code === $entry['currency_code'])) {
$return[$entry['key']] = $entry;
@@ -121,65 +118,50 @@ class BasicController extends Controller
return response()->json($return);
}
- /**
- * @param Carbon $start
- * @param Carbon $end
- *
- * @return array
- */
private function getBalanceInformation(Carbon $start, Carbon $end): array
{
// prep some arrays:
- $incomes = [];
- $expenses = [];
- $sums = [];
- $return = [];
+ $incomes = [];
+ $expenses = [];
+ $sums = [];
+ $return = [];
// collect income of user using the new group collector.
/** @var GroupCollectorInterface $collector */
$collector = app(GroupCollectorInterface::class);
- $collector
- ->setRange($start, $end)
- // set page to retrieve
- ->setPage($this->parameters->get('page'))
- // set types of transactions to return.
- ->setTypes([TransactionType::DEPOSIT]);
+ $collector->setRange($start, $end)->setPage($this->parameters->get('page'))->setTypes([TransactionType::DEPOSIT]);
+
+ $set = $collector->getExtractedJournals();
- $set = $collector->getExtractedJournals();
/** @var array $transactionJournal */
foreach ($set as $transactionJournal) {
$currencyId = (int)$transactionJournal['currency_id'];
- $incomes[$currencyId] = $incomes[$currencyId] ?? '0';
+ $incomes[$currencyId] ??= '0';
$incomes[$currencyId] = bcadd(
$incomes[$currencyId],
bcmul($transactionJournal['amount'], '-1')
);
- $sums[$currencyId] = $sums[$currencyId] ?? '0';
+ $sums[$currencyId] ??= '0';
$sums[$currencyId] = bcadd($sums[$currencyId], bcmul($transactionJournal['amount'], '-1'));
}
// collect expenses of user using the new group collector.
/** @var GroupCollectorInterface $collector */
$collector = app(GroupCollectorInterface::class);
- $collector
- ->setRange($start, $end)
- // set page to retrieve
- ->setPage($this->parameters->get('page'))
- // set types of transactions to return.
- ->setTypes([TransactionType::WITHDRAWAL]);
- $set = $collector->getExtractedJournals();
+ $collector->setRange($start, $end)->setPage($this->parameters->get('page'))->setTypes([TransactionType::WITHDRAWAL]);
+ $set = $collector->getExtractedJournals();
/** @var array $transactionJournal */
foreach ($set as $transactionJournal) {
$currencyId = (int)$transactionJournal['currency_id'];
- $expenses[$currencyId] = $expenses[$currencyId] ?? '0';
+ $expenses[$currencyId] ??= '0';
$expenses[$currencyId] = bcadd($expenses[$currencyId], $transactionJournal['amount']);
- $sums[$currencyId] = $sums[$currencyId] ?? '0';
+ $sums[$currencyId] ??= '0';
$sums[$currencyId] = bcadd($sums[$currencyId], $transactionJournal['amount']);
}
// format amounts:
- $keys = array_keys($sums);
+ $keys = array_keys($sums);
foreach ($keys as $currencyId) {
$currency = $this->currencyRepos->find($currencyId);
if (null === $currency) {
@@ -196,8 +178,8 @@ class BasicController extends Controller
'currency_decimal_places' => $currency->decimal_places,
'value_parsed' => app('amount')->formatAnything($currency, $sums[$currencyId] ?? '0', false),
'local_icon' => 'balance-scale',
- 'sub_title' => app('amount')->formatAnything($currency, $expenses[$currencyId] ?? '0', false) .
- ' + ' . app('amount')->formatAnything($currency, $incomes[$currencyId] ?? '0', false),
+ 'sub_title' => app('amount')->formatAnything($currency, $expenses[$currencyId] ?? '0', false).
+ ' + '.app('amount')->formatAnything($currency, $incomes[$currencyId] ?? '0', false),
];
$return[] = [
'key' => sprintf('spent-in-%s', $currency->code),
@@ -228,12 +210,6 @@ class BasicController extends Controller
return $return;
}
- /**
- * @param Carbon $start
- * @param Carbon $end
- *
- * @return array
- */
private function getBillInformation(Carbon $start, Carbon $end): array
{
app('log')->debug(sprintf('Now in getBillInformation("%s", "%s")', $start->format('Y-m-d'), $end->format('Y-m-d-')));
@@ -244,7 +220,8 @@ class BasicController extends Controller
$paidAmount = $this->billRepository->sumPaidInRange($start, $end);
$unpaidAmount = $this->billRepository->sumUnpaidInRange($start, $end);
- $return = [];
+ $return = [];
+
/**
* @var array $info
*/
@@ -283,15 +260,12 @@ class BasicController extends Controller
];
}
app('log')->debug(sprintf('Done with getBillInformation("%s", "%s")', $start->format('Y-m-d'), $end->format('Y-m-d-')));
+
return $return;
}
/**
- * @param Carbon $start
- * @param Carbon $end
- *
- * @return array
- * @throws Exception
+ * @throws \Exception
*/
private function getLeftToSpendInfo(Carbon $start, Carbon $end): array
{
@@ -307,13 +281,13 @@ class BasicController extends Controller
$spentInCurrency = $row['sum'];
$leftToSpend = bcadd($amount, $spentInCurrency);
- $days = $today->diffInDays($end) + 1;
- $perDay = '0';
+ $days = $today->diffInDays($end) + 1;
+ $perDay = '0';
if (0 !== $days && bccomp($leftToSpend, '0') > -1) {
$perDay = bcdiv($leftToSpend, (string)$days);
}
- $return[] = [
+ $return[] = [
'key' => sprintf('left-to-spend-in-%s', $row['currency_code']),
'title' => trans('firefly.box_left_to_spend_in_currency', ['currency' => $row['currency_symbol']]),
'monetary_value' => $leftToSpend,
@@ -335,17 +309,11 @@ class BasicController extends Controller
return $return;
}
- /**
- * @param Carbon $start
- * @param Carbon $end
- *
- * @return array
- */
private function getNetWorthInfo(Carbon $start, Carbon $end): array
{
/** @var User $user */
- $user = auth()->user();
- $date = today(config('app.timezone'))->startOfDay();
+ $user = auth()->user();
+ $date = today(config('app.timezone'))->startOfDay();
// start and end in the future? use $end
if ($this->notInDateRange($date, $start, $end)) {
/** @var Carbon $date */
@@ -355,12 +323,12 @@ class BasicController extends Controller
/** @var NetWorthInterface $netWorthHelper */
$netWorthHelper = app(NetWorthInterface::class);
$netWorthHelper->setUser($user);
- $allAccounts = $this->accountRepository->getActiveAccountsByType(
+ $allAccounts = $this->accountRepository->getActiveAccountsByType(
[AccountType::ASSET, AccountType::DEFAULT, AccountType::LOAN, AccountType::MORTGAGE, AccountType::DEBT]
);
// filter list on preference of being included.
- $filtered = $allAccounts->filter(
+ $filtered = $allAccounts->filter(
function (Account $account) {
$includeNetWorth = $this->accountRepository->getMetaValue($account, 'include_net_worth');
@@ -368,25 +336,26 @@ class BasicController extends Controller
}
);
- $netWorthSet = $netWorthHelper->getNetWorthByCurrency($filtered, $date);
- $return = [];
- foreach ($netWorthSet as $data) {
- /** @var TransactionCurrency $currency */
- $currency = $data['currency'];
+ $netWorthSet = $netWorthHelper->byAccounts($filtered, $date);
+ $return = [];
+ foreach ($netWorthSet as $key => $data) {
+ if ('native' === $key) {
+ continue;
+ }
$amount = $data['balance'];
if (0 === bccomp($amount, '0')) {
continue;
}
// return stuff
$return[] = [
- 'key' => sprintf('net-worth-in-%s', $currency->code),
- 'title' => trans('firefly.box_net_worth_in_currency', ['currency' => $currency->symbol]),
+ 'key' => sprintf('net-worth-in-%s', $data['currency_code']),
+ 'title' => trans('firefly.box_net_worth_in_currency', ['currency' => $data['currency_symbol']]),
'monetary_value' => $amount,
- 'currency_id' => (string)$currency->id,
- 'currency_code' => $currency->code,
- 'currency_symbol' => $currency->symbol,
- 'currency_decimal_places' => $currency->decimal_places,
- 'value_parsed' => app('amount')->formatAnything($currency, $data['balance'], false),
+ 'currency_id' => (string)$data['currency_id'],
+ 'currency_code' => $data['currency_code'],
+ 'currency_symbol' => $data['currency_symbol'],
+ 'currency_decimal_places' => $data['currency_decimal_places'],
+ 'value_parsed' => app('amount')->formatFlat($data['currency_symbol'], $data['currency_decimal_places'], $data['balance'], false),
'local_icon' => 'line-chart',
'sub_title' => '',
];
@@ -397,13 +366,6 @@ class BasicController extends Controller
/**
* Check if date is outside session range.
- *
- * @param Carbon $date
- *
- * @param Carbon $start
- * @param Carbon $end
- *
- * @return bool
*/
protected function notInDateRange(Carbon $date, Carbon $start, Carbon $end): bool // Validate a preference
{
diff --git a/app/Api/V1/Controllers/System/AboutController.php b/app/Api/V1/Controllers/System/AboutController.php
index 390309d991..0b1bb117a9 100644
--- a/app/Api/V1/Controllers/System/AboutController.php
+++ b/app/Api/V1/Controllers/System/AboutController.php
@@ -24,7 +24,6 @@ declare(strict_types=1);
namespace FireflyIII\Api\V1\Controllers\System;
-use DB;
use FireflyIII\Api\V1\Controllers\Controller;
use FireflyIII\Transformers\UserTransformer;
use Illuminate\Http\JsonResponse;
@@ -42,8 +41,6 @@ class AboutController extends Controller
* https://api-docs.firefly-iii.org/?urls.primaryName=2.0.0%20(v1)#/about/getAbout
*
* Returns system information.
- *
- * @return JsonResponse
*/
public function about(): JsonResponse
{
@@ -51,15 +48,15 @@ class AboutController extends Controller
$replace = ['\~', '# '];
$phpVersion = str_replace($search, $replace, PHP_VERSION);
$phpOs = str_replace($search, $replace, PHP_OS);
- $currentDriver = DB::getDriverName();
+ $currentDriver = \DB::getDriverName();
$data
= [
- 'version' => config('firefly.version'),
- 'api_version' => config('firefly.api_version'),
- 'php_version' => $phpVersion,
- 'os' => $phpOs,
- 'driver' => $currentDriver,
- ];
+ 'version' => config('firefly.version'),
+ 'api_version' => config('firefly.api_version'),
+ 'php_version' => $phpVersion,
+ 'os' => $phpOs,
+ 'driver' => $currentDriver,
+ ];
return response()->api(['data' => $data])->header('Content-Type', self::CONTENT_TYPE);
}
@@ -69,18 +66,16 @@ class AboutController extends Controller
* https://api-docs.firefly-iii.org/?urls.primaryName=2.0.0%20(v1)#/about/getCurrentUser
*
* Returns information about the user.
- *
- * @return JsonResponse
*/
public function user(): JsonResponse
{
- $manager = $this->getManager();
+ $manager = $this->getManager();
/** @var UserTransformer $transformer */
$transformer = app(UserTransformer::class);
$transformer->setParameters($this->parameters);
- $resource = new Item(auth()->user(), $transformer, 'users');
+ $resource = new Item(auth()->user(), $transformer, 'users');
return response()->api($manager->createData($resource)->toArray())->header('Content-Type', self::CONTENT_TYPE);
}
diff --git a/app/Api/V1/Controllers/System/ConfigurationController.php b/app/Api/V1/Controllers/System/ConfigurationController.php
index b91efd9360..d1ae4de98d 100644
--- a/app/Api/V1/Controllers/System/ConfigurationController.php
+++ b/app/Api/V1/Controllers/System/ConfigurationController.php
@@ -29,10 +29,6 @@ use FireflyIII\Exceptions\FireflyException;
use FireflyIII\Repositories\User\UserRepositoryInterface;
use FireflyIII\Support\Binder\EitherConfigKey;
use Illuminate\Http\JsonResponse;
-use Illuminate\Support\Facades\Log;
-use Psr\Container\ContainerExceptionInterface;
-use Psr\Container\NotFoundExceptionInterface;
-use Validator;
/**
* Class ConfigurationController
@@ -60,18 +56,16 @@ class ConfigurationController extends Controller
* This endpoint is documented at:
* https://api-docs.firefly-iii.org/?urls.primaryName=2.0.0%20(v1)#/configuration/getConfiguration
*
- * @return JsonResponse
- * @throws ContainerExceptionInterface
* @throws FireflyException
- * @throws NotFoundExceptionInterface
*/
public function index(): JsonResponse
{
try {
$dynamicData = $this->getDynamicConfiguration();
} catch (FireflyException $e) {
- Log::error($e->getMessage());
- Log::error($e->getTraceAsString());
+ app('log')->error($e->getMessage());
+ app('log')->error($e->getTraceAsString());
+
throw new FireflyException('200030: Could not load config variables.', 0, $e);
}
$staticData = $this->getStaticConfiguration();
@@ -96,10 +90,6 @@ class ConfigurationController extends Controller
/**
* Get all config values.
- *
- * @return array
- * @throws ContainerExceptionInterface
- * @throws NotFoundExceptionInterface
*/
private function getDynamicConfiguration(): array
{
@@ -116,9 +106,6 @@ class ConfigurationController extends Controller
];
}
- /**
- * @return array
- */
private function getStaticConfiguration(): array
{
$list = EitherConfigKey::$static;
@@ -133,12 +120,6 @@ class ConfigurationController extends Controller
/**
* This endpoint is documented at:
* https://api-docs.firefly-iii.org/?urls.primaryName=2.0.0%20(v1)#/configuration/getSingleConfiguration
- *
- * @param string $configKey
- *
- * @return JsonResponse
- * @throws ContainerExceptionInterface
- * @throws NotFoundExceptionInterface
*/
public function show(string $configKey): JsonResponse
{
@@ -169,20 +150,14 @@ class ConfigurationController extends Controller
*
* Update the configuration.
*
- * @param UpdateRequest $request
- * @param string $name
- *
- * @return JsonResponse
- * @throws ContainerExceptionInterface
* @throws FireflyException
- * @throws NotFoundExceptionInterface
*/
public function update(UpdateRequest $request, string $name): JsonResponse
{
- $rules = ['value' => 'required'];
+ $rules = ['value' => 'required'];
if (!$this->repository->hasRole(auth()->user(), 'owner')) {
$messages = ['value' => '200005: You need the "owner" role to do this.'];
- Validator::make([], $rules, $messages)->validate();
+ \Validator::make([], $rules, $messages)->validate();
}
$data = $request->getAll();
$shortName = str_replace('configuration.', '', $name);
diff --git a/app/Api/V1/Controllers/System/CronController.php b/app/Api/V1/Controllers/System/CronController.php
index da110e13b8..397e579ecb 100644
--- a/app/Api/V1/Controllers/System/CronController.php
+++ b/app/Api/V1/Controllers/System/CronController.php
@@ -27,9 +27,6 @@ use FireflyIII\Api\V1\Controllers\Controller;
use FireflyIII\Api\V1\Requests\System\CronRequest;
use FireflyIII\Support\Http\Controllers\CronRunner;
use Illuminate\Http\JsonResponse;
-use Illuminate\Support\Facades\Log;
-use Psr\Container\ContainerExceptionInterface;
-use Psr\Container\NotFoundExceptionInterface;
/**
* Class CronController
@@ -41,27 +38,20 @@ class CronController extends Controller
/**
* This endpoint is documented at:
* https://api-docs.firefly-iii.org/?urls.primaryName=2.0.0%20(v1)#/about/getCron
- *
- * @param CronRequest $request
- * @param string $token
- *
- * @return JsonResponse
- * @throws ContainerExceptionInterface
- * @throws NotFoundExceptionInterface
*/
- public function cron(CronRequest $request, string $token): JsonResponse
+ public function cron(CronRequest $request): JsonResponse
{
- $config = $request->getAll();
+ $config = $request->getAll();
- Log::debug(sprintf('Now in %s', __METHOD__));
- Log::debug(sprintf('Date is %s', $config['date']->toIsoString()));
+ app('log')->debug(sprintf('Now in %s', __METHOD__));
+ app('log')->debug(sprintf('Date is %s', $config['date']->toIsoString()));
$return = [];
$return['recurring_transactions'] = $this->runRecurring($config['force'], $config['date']);
$return['auto_budgets'] = $this->runAutoBudget($config['force'], $config['date']);
if (true === config('cer.download_enabled')) {
$return['exchange_rates'] = $this->exchangeRatesCronJob($config['force'], $config['date']);
}
- $return['bill_warnings'] = $this->billWarningCronJob($config['force'], $config['date']);
+ $return['bill_warnings'] = $this->billWarningCronJob($config['force'], $config['date']);
return response()->json($return);
}
diff --git a/app/Api/V1/Controllers/System/UserController.php b/app/Api/V1/Controllers/System/UserController.php
index b0c6e519bc..b650b2d3c2 100644
--- a/app/Api/V1/Controllers/System/UserController.php
+++ b/app/Api/V1/Controllers/System/UserController.php
@@ -33,7 +33,6 @@ use FireflyIII\Transformers\UserTransformer;
use FireflyIII\User;
use Illuminate\Http\JsonResponse;
use Illuminate\Pagination\LengthAwarePaginator;
-use Illuminate\Support\Facades\Log;
use League\Fractal\Pagination\IlluminatePaginatorAdapter;
use League\Fractal\Resource\Collection as FractalCollection;
use League\Fractal\Resource\Item;
@@ -47,8 +46,6 @@ class UserController extends Controller
/**
* UserController constructor.
- *
-
*/
public function __construct()
{
@@ -68,9 +65,6 @@ class UserController extends Controller
*
* Remove the specified resource from storage.
*
- * @param User $user
- *
- * @return JsonResponse
* @throws FireflyException
*/
public function destroy(User $user): JsonResponse
@@ -86,6 +80,7 @@ class UserController extends Controller
return response()->json([], 204);
}
+
throw new FireflyException('200025: No access to function.');
}
@@ -95,30 +90,29 @@ class UserController extends Controller
*
* Display a listing of the resource.
*
- * @return JsonResponse
* @throws FireflyException
*/
public function index(): JsonResponse
{
// user preferences
- $pageSize = $this->parameters->get('limit');
- $manager = $this->getManager();
+ $pageSize = $this->parameters->get('limit');
+ $manager = $this->getManager();
// build collection
- $collection = $this->repository->all();
- $count = $collection->count();
- $users = $collection->slice(($this->parameters->get('page') - 1) * $pageSize, $pageSize);
+ $collection = $this->repository->all();
+ $count = $collection->count();
+ $users = $collection->slice(($this->parameters->get('page') - 1) * $pageSize, $pageSize);
// make paginator:
- $paginator = new LengthAwarePaginator($users, $count, $pageSize, $this->parameters->get('page'));
- $paginator->setPath(route('api.v1.users.index') . $this->buildParams());
+ $paginator = new LengthAwarePaginator($users, $count, $pageSize, $this->parameters->get('page'));
+ $paginator->setPath(route('api.v1.users.index').$this->buildParams());
// make resource
/** @var UserTransformer $transformer */
$transformer = app(UserTransformer::class);
$transformer->setParameters($this->parameters);
- $resource = new FractalCollection($users, $transformer, 'users');
+ $resource = new FractalCollection($users, $transformer, 'users');
$resource->setPaginator(new IlluminatePaginatorAdapter($paginator));
return response()->json($manager->createData($resource)->toArray())->header('Content-Type', self::CONTENT_TYPE);
@@ -129,21 +123,18 @@ class UserController extends Controller
* https://api-docs.firefly-iii.org/?urls.primaryName=2.0.0%20(v1)#/users/getUser
*
* Show a single user.
- *
- * @param User $user
- *
- * @return JsonResponse
*/
public function show(User $user): JsonResponse
{
// make manager
- $manager = $this->getManager();
+ $manager = $this->getManager();
+
// make resource
/** @var UserTransformer $transformer */
$transformer = app(UserTransformer::class);
$transformer->setParameters($this->parameters);
- $resource = new Item($user, $transformer, 'users');
+ $resource = new Item($user, $transformer, 'users');
return response()->json($manager->createData($resource)->toArray())->header('Content-Type', self::CONTENT_TYPE);
}
@@ -153,16 +144,12 @@ class UserController extends Controller
* https://api-docs.firefly-iii.org/?urls.primaryName=2.0.0%20(v1)#/users/storeUser
*
* Store a new user.
- *
- * @param UserStoreRequest $request
- *
- * @return JsonResponse
*/
public function store(UserStoreRequest $request): JsonResponse
{
- $data = $request->getAll();
- $user = $this->repository->store($data);
- $manager = $this->getManager();
+ $data = $request->getAll();
+ $user = $this->repository->store($data);
+ $manager = $this->getManager();
// make resource
@@ -170,7 +157,7 @@ class UserController extends Controller
$transformer = app(UserTransformer::class);
$transformer->setParameters($this->parameters);
- $resource = new Item($user, $transformer, 'users');
+ $resource = new Item($user, $transformer, 'users');
return response()->json($manager->createData($resource)->toArray())->header('Content-Type', self::CONTENT_TYPE);
}
@@ -180,30 +167,26 @@ class UserController extends Controller
* https://api-docs.firefly-iii.org/?urls.primaryName=2.0.0%20(v1)#/users/updateUser
*
* Update a user.
- *
- * @param UserUpdateRequest $request
- * @param User $user
- *
- * @return JsonResponse
*/
public function update(UserUpdateRequest $request, User $user): JsonResponse
{
- $data = $request->getAll();
+ $data = $request->getAll();
// can only update 'blocked' when user is admin.
if (!$this->repository->hasRole(auth()->user(), 'owner')) {
- Log::debug('Quietly drop fields "blocked" and "blocked_code" from request.');
+ app('log')->debug('Quietly drop fields "blocked" and "blocked_code" from request.');
unset($data['blocked'], $data['blocked_code']);
}
- $user = $this->repository->update($user, $data);
- $manager = $this->getManager();
+ $user = $this->repository->update($user, $data);
+ $manager = $this->getManager();
+
// make resource
/** @var UserTransformer $transformer */
$transformer = app(UserTransformer::class);
$transformer->setParameters($this->parameters);
- $resource = new Item($user, $transformer, 'users');
+ $resource = new Item($user, $transformer, 'users');
return response()->json($manager->createData($resource)->toArray())->header('Content-Type', self::CONTENT_TYPE);
}
diff --git a/app/Api/V1/Controllers/User/PreferencesController.php b/app/Api/V1/Controllers/User/PreferencesController.php
index 325e567814..ca61956772 100644
--- a/app/Api/V1/Controllers/User/PreferencesController.php
+++ b/app/Api/V1/Controllers/User/PreferencesController.php
@@ -41,8 +41,8 @@ use League\Fractal\Resource\Item;
*/
class PreferencesController extends Controller
{
- public const DATE_FORMAT = 'Y-m-d';
- public const RESOURCE_KEY = 'preferences';
+ public const string DATE_FORMAT = 'Y-m-d';
+ public const string RESOURCE_KEY = 'preferences';
/**
* This endpoint is documented at:
@@ -50,7 +50,6 @@ class PreferencesController extends Controller
*
* List all of them.
*
- * @return JsonResponse
* @throws FireflyException
*/
public function index(): JsonResponse
@@ -62,14 +61,14 @@ class PreferencesController extends Controller
$preferences = $collection->slice(($this->parameters->get('page') - 1) * $pageSize, $pageSize);
// make paginator:
- $paginator = new LengthAwarePaginator($preferences, $count, $pageSize, $this->parameters->get('page'));
- $paginator->setPath(route('api.v1.preferences.index') . $this->buildParams());
+ $paginator = new LengthAwarePaginator($preferences, $count, $pageSize, $this->parameters->get('page'));
+ $paginator->setPath(route('api.v1.preferences.index').$this->buildParams());
/** @var PreferenceTransformer $transformer */
$transformer = app(PreferenceTransformer::class);
$transformer->setParameters($this->parameters);
- $resource = new FractalCollection($preferences, $transformer, self::RESOURCE_KEY);
+ $resource = new FractalCollection($preferences, $transformer, self::RESOURCE_KEY);
$resource->setPaginator(new IlluminatePaginatorAdapter($paginator));
return response()->json($manager->createData($resource)->toArray())->header('Content-Type', self::CONTENT_TYPE);
@@ -80,19 +79,16 @@ class PreferencesController extends Controller
* https://api-docs.firefly-iii.org/?urls.primaryName=2.0.0%20(v1)#/preferences/getPreference
*
* Return a single preference by name.
- *
- * @param Preference $preference
- *
- * @return JsonResponse
*/
public function show(Preference $preference): JsonResponse
{
- $manager = $this->getManager();
+ $manager = $this->getManager();
+
/** @var PreferenceTransformer $transformer */
$transformer = app(PreferenceTransformer::class);
$transformer->setParameters($this->parameters);
- $resource = new Item($preference, $transformer, 'preferences');
+ $resource = new Item($preference, $transformer, 'preferences');
return response()->json($manager->createData($resource)->toArray())->header('Content-Type', self::CONTENT_TYPE);
}
@@ -101,22 +97,19 @@ class PreferencesController extends Controller
* This endpoint is documented at:
* https://api-docs.firefly-iii.org/?urls.primaryName=2.0.0%20(v1)#/preferences/storePreference
*
- * @param PreferenceStoreRequest $request
- *
- * @return JsonResponse
* @throws FireflyException
*/
public function store(PreferenceStoreRequest $request): JsonResponse
{
- $manager = $this->getManager();
- $data = $request->getAll();
- $pref = app('preferences')->set($data['name'], $data['data']);
+ $manager = $this->getManager();
+ $data = $request->getAll();
+ $pref = app('preferences')->set($data['name'], $data['data']);
/** @var PreferenceTransformer $transformer */
$transformer = app(PreferenceTransformer::class);
$transformer->setParameters($this->parameters);
- $resource = new Item($pref, $transformer, 'preferences');
+ $resource = new Item($pref, $transformer, 'preferences');
return response()->json($manager->createData($resource)->toArray())->header('Content-Type', self::CONTENT_TYPE);
}
@@ -125,23 +118,19 @@ class PreferencesController extends Controller
* This endpoint is documented at:
* https://api-docs.firefly-iii.org/?urls.primaryName=2.0.0%20(v1)#/preferences/updatePreference
*
- * @param PreferenceUpdateRequest $request
- * @param Preference $preference
- *
- * @return JsonResponse
* @throws FireflyException
*/
public function update(PreferenceUpdateRequest $request, Preference $preference): JsonResponse
{
- $manager = $this->getManager();
- $data = $request->getAll();
- $pref = app('preferences')->set($preference->name, $data['data']);
+ $manager = $this->getManager();
+ $data = $request->getAll();
+ $pref = app('preferences')->set($preference->name, $data['data']);
/** @var PreferenceTransformer $transformer */
$transformer = app(PreferenceTransformer::class);
$transformer->setParameters($this->parameters);
- $resource = new Item($pref, $transformer, 'preferences');
+ $resource = new Item($pref, $transformer, 'preferences');
return response()->json($manager->createData($resource)->toArray())->header('Content-Type', self::CONTENT_TYPE);
}
diff --git a/app/Api/V1/Controllers/Webhook/AttemptController.php b/app/Api/V1/Controllers/Webhook/AttemptController.php
index 901e22519e..222e25fc5e 100644
--- a/app/Api/V1/Controllers/Webhook/AttemptController.php
+++ b/app/Api/V1/Controllers/Webhook/AttemptController.php
@@ -32,20 +32,20 @@ use FireflyIII\Repositories\Webhook\WebhookRepositoryInterface;
use FireflyIII\Transformers\WebhookAttemptTransformer;
use Illuminate\Http\JsonResponse;
use Illuminate\Pagination\LengthAwarePaginator;
+use Illuminate\Support\Facades\Log;
use League\Fractal\Pagination\IlluminatePaginatorAdapter;
use League\Fractal\Resource\Collection as FractalCollection;
use League\Fractal\Resource\Item;
+use Symfony\Component\HttpKernel\Exception\NotFoundHttpException;
/**
* Class AttemptController
*/
class AttemptController extends Controller
{
- public const RESOURCE_KEY = 'webhook_attempts';
+ public const string RESOURCE_KEY = 'webhook_attempts';
private WebhookRepositoryInterface $repository;
- /**
- */
public function __construct()
{
parent::__construct();
@@ -63,10 +63,6 @@ class AttemptController extends Controller
* This endpoint is documented at:
* https://api-docs.firefly-iii.org/?urls.primaryName=2.0.0%20(v1)#/webhooks/getWebhookMessageAttempts
*
- * @param Webhook $webhook
- * @param WebhookMessage $message
- *
- * @return JsonResponse
* @throws FireflyException
*/
public function index(Webhook $webhook, WebhookMessage $message): JsonResponse
@@ -74,22 +70,28 @@ class AttemptController extends Controller
if ($message->webhook_id !== $webhook->id) {
throw new FireflyException('200040: Webhook and webhook message are no match');
}
+ if (false === config('firefly.allow_webhooks')) {
+ Log::channel('audit')->warning(sprintf('User lists webhook attempts of webhook #%d and message #%d, but webhooks are DISABLED.', $webhook->id, $message->id));
- $manager = $this->getManager();
- $pageSize = $this->parameters->get('limit');
- $collection = $this->repository->getAttempts($message);
- $count = $collection->count();
- $attempts = $collection->slice(($this->parameters->get('page') - 1) * $pageSize, $pageSize);
+ throw new NotFoundHttpException('Webhooks are not enabled.');
+ }
+ Log::channel('audit')->info(sprintf('User lists webhook attempts of webhook #%d and message #%d.', $webhook->id, $message->id));
+
+ $manager = $this->getManager();
+ $pageSize = $this->parameters->get('limit');
+ $collection = $this->repository->getAttempts($message);
+ $count = $collection->count();
+ $attempts = $collection->slice(($this->parameters->get('page') - 1) * $pageSize, $pageSize);
// make paginator:
- $paginator = new LengthAwarePaginator($attempts, $count, $pageSize, $this->parameters->get('page'));
- $paginator->setPath(route('api.v1.webhooks.attempts.index', [$webhook->id, $message->id]) . $this->buildParams());
+ $paginator = new LengthAwarePaginator($attempts, $count, $pageSize, $this->parameters->get('page'));
+ $paginator->setPath(route('api.v1.webhooks.attempts.index', [$webhook->id, $message->id]).$this->buildParams());
/** @var WebhookAttemptTransformer $transformer */
$transformer = app(WebhookAttemptTransformer::class);
$transformer->setParameters($this->parameters);
- $resource = new FractalCollection($attempts, $transformer, 'webhook_attempts');
+ $resource = new FractalCollection($attempts, $transformer, 'webhook_attempts');
$resource->setPaginator(new IlluminatePaginatorAdapter($paginator));
return response()->json($manager->createData($resource)->toArray())->header('Content-Type', self::CONTENT_TYPE);
@@ -101,11 +103,6 @@ class AttemptController extends Controller
*
* Show single instance.
*
- * @param Webhook $webhook
- * @param WebhookMessage $message
- * @param WebhookAttempt $attempt
- *
- * @return JsonResponse
* @throws FireflyException
*/
public function show(Webhook $webhook, WebhookMessage $message, WebhookAttempt $attempt): JsonResponse
@@ -117,12 +114,20 @@ class AttemptController extends Controller
throw new FireflyException('200041: Webhook message and webhook attempt are no match');
}
- $manager = $this->getManager();
+ if (false === config('firefly.allow_webhooks')) {
+ Log::channel('audit')->warning(sprintf('User views single webhook attempt #%d of webhook #%d and message #%d, but webhooks are DISABLED', $attempt->id, $webhook->id, $message->id));
+
+ throw new NotFoundHttpException('Webhooks are not enabled.');
+ }
+
+ Log::channel('audit')->info(sprintf('User views single webhook attempt #%d of webhook #%d and message #%d.', $attempt->id, $webhook->id, $message->id));
+
+ $manager = $this->getManager();
/** @var WebhookAttemptTransformer $transformer */
$transformer = app(WebhookAttemptTransformer::class);
$transformer->setParameters($this->parameters);
- $resource = new Item($attempt, $transformer, self::RESOURCE_KEY);
+ $resource = new Item($attempt, $transformer, self::RESOURCE_KEY);
return response()->json($manager->createData($resource)->toArray())->header('Content-Type', self::CONTENT_TYPE);
}
diff --git a/app/Api/V1/Controllers/Webhook/DestroyController.php b/app/Api/V1/Controllers/Webhook/DestroyController.php
index da914b57d4..4899c7be20 100644
--- a/app/Api/V1/Controllers/Webhook/DestroyController.php
+++ b/app/Api/V1/Controllers/Webhook/DestroyController.php
@@ -31,6 +31,8 @@ use FireflyIII\Models\WebhookAttempt;
use FireflyIII\Models\WebhookMessage;
use FireflyIII\Repositories\Webhook\WebhookRepositoryInterface;
use Illuminate\Http\JsonResponse;
+use Illuminate\Support\Facades\Log;
+use Symfony\Component\HttpKernel\Exception\NotFoundHttpException;
/**
* Class DestroyController
@@ -39,8 +41,6 @@ class DestroyController extends Controller
{
private WebhookRepositoryInterface $repository;
- /**
- */
public function __construct()
{
parent::__construct();
@@ -59,13 +59,16 @@ class DestroyController extends Controller
* https://api-docs.firefly-iii.org/?urls.primaryName=2.0.0%20(v1)#/webhooks/deleteWebhook
*
* Remove the specified resource from storage.
- *
- * @param Webhook $webhook
- *
- * @return JsonResponse
*/
public function destroy(Webhook $webhook): JsonResponse
{
+ if (false === config('firefly.allow_webhooks')) {
+ Log::channel('audit')->warning(sprintf('User tries to destroy webhook #%d. but webhooks are DISABLED.', $webhook->id));
+
+ throw new NotFoundHttpException('Webhooks are not enabled.');
+ }
+
+ Log::channel('audit')->info(sprintf('User destroys webhook #%d.', $webhook->id));
$this->repository->destroy($webhook);
app('preferences')->mark();
@@ -78,11 +81,6 @@ class DestroyController extends Controller
*
* Remove the specified resource from storage.
*
- * @param Webhook $webhook
- * @param WebhookMessage $message
- * @param WebhookAttempt $attempt
- *
- * @return JsonResponse
* @throws FireflyException
*/
public function destroyAttempt(Webhook $webhook, WebhookMessage $message, WebhookAttempt $attempt): JsonResponse
@@ -94,6 +92,14 @@ class DestroyController extends Controller
throw new FireflyException('200041: Webhook message and webhook attempt are no match');
}
+ if (false === config('firefly.allow_webhooks')) {
+ Log::channel('audit')->warning(sprintf('User tries to destroy webhook #%d, message #%d, attempt #%d, but webhooks are DISABLED.', $webhook->id, $message->id, $attempt->id));
+
+ throw new NotFoundHttpException('Webhooks are not enabled.');
+ }
+
+ Log::channel('audit')->info(sprintf('User destroys webhook #%d, message #%d, attempt #%d.', $webhook->id, $message->id, $attempt->id));
+
$this->repository->destroyAttempt($attempt);
app('preferences')->mark();
@@ -106,10 +112,6 @@ class DestroyController extends Controller
*
* Remove the specified resource from storage.
*
- * @param Webhook $webhook
- * @param WebhookMessage $message
- *
- * @return JsonResponse
* @throws FireflyException
*/
public function destroyMessage(Webhook $webhook, WebhookMessage $message): JsonResponse
@@ -117,6 +119,14 @@ class DestroyController extends Controller
if ($message->webhook_id !== $webhook->id) {
throw new FireflyException('200040: Webhook and webhook message are no match');
}
+
+ if (false === config('firefly.allow_webhooks')) {
+ Log::channel('audit')->warning(sprintf('User tries to destroy webhook #%d, message #%d, but webhooks are DISABLED.', $webhook->id, $message->id));
+
+ throw new NotFoundHttpException('Webhooks are not enabled.');
+ }
+ Log::channel('audit')->info(sprintf('User destroys webhook #%d, message #%d.', $webhook->id, $message->id));
+
$this->repository->destroyMessage($message);
app('preferences')->mark();
diff --git a/app/Api/V1/Controllers/Webhook/MessageController.php b/app/Api/V1/Controllers/Webhook/MessageController.php
index 53b427af0e..4bef15df7f 100644
--- a/app/Api/V1/Controllers/Webhook/MessageController.php
+++ b/app/Api/V1/Controllers/Webhook/MessageController.php
@@ -31,20 +31,20 @@ use FireflyIII\Repositories\Webhook\WebhookRepositoryInterface;
use FireflyIII\Transformers\WebhookMessageTransformer;
use Illuminate\Http\JsonResponse;
use Illuminate\Pagination\LengthAwarePaginator;
+use Illuminate\Support\Facades\Log;
use League\Fractal\Pagination\IlluminatePaginatorAdapter;
use League\Fractal\Resource\Collection as FractalCollection;
use League\Fractal\Resource\Item;
+use Symfony\Component\HttpKernel\Exception\NotFoundHttpException;
/**
* Class MessageController
*/
class MessageController extends Controller
{
- public const RESOURCE_KEY = 'webhook_messages';
+ public const string RESOURCE_KEY = 'webhook_messages';
private WebhookRepositoryInterface $repository;
- /**
- */
public function __construct()
{
parent::__construct();
@@ -62,29 +62,32 @@ class MessageController extends Controller
* This endpoint is documented at:
* https://api-docs.firefly-iii.org/?urls.primaryName=2.0.0%20(v1)#/webhooks/getWebhookMessages
*
- * @param Webhook $webhook
- *
- * @return JsonResponse
* @throws FireflyException
*/
public function index(Webhook $webhook): JsonResponse
{
- $manager = $this->getManager();
- $pageSize = $this->parameters->get('limit');
- $collection = $this->repository->getMessages($webhook);
+ if (false === config('firefly.allow_webhooks')) {
+ Log::channel('audit')->warning(sprintf('User tries to view messages of webhook #%d, but webhooks are DISABLED.', $webhook->id));
- $count = $collection->count();
- $messages = $collection->slice(($this->parameters->get('page') - 1) * $pageSize, $pageSize);
+ throw new NotFoundHttpException('Webhooks are not enabled.');
+ }
+ Log::channel('audit')->info(sprintf('User views messages of webhook #%d.', $webhook->id));
+ $manager = $this->getManager();
+ $pageSize = $this->parameters->get('limit');
+ $collection = $this->repository->getMessages($webhook);
+
+ $count = $collection->count();
+ $messages = $collection->slice(($this->parameters->get('page') - 1) * $pageSize, $pageSize);
// make paginator:
- $paginator = new LengthAwarePaginator($messages, $count, $pageSize, $this->parameters->get('page'));
- $paginator->setPath(route('api.v1.webhooks.messages.index', [$webhook->id]) . $this->buildParams());
+ $paginator = new LengthAwarePaginator($messages, $count, $pageSize, $this->parameters->get('page'));
+ $paginator->setPath(route('api.v1.webhooks.messages.index', [$webhook->id]).$this->buildParams());
/** @var WebhookMessageTransformer $transformer */
$transformer = app(WebhookMessageTransformer::class);
$transformer->setParameters($this->parameters);
- $resource = new FractalCollection($messages, $transformer, 'webhook_messages');
+ $resource = new FractalCollection($messages, $transformer, 'webhook_messages');
$resource->setPaginator(new IlluminatePaginatorAdapter($paginator));
return response()->json($manager->createData($resource)->toArray())->header('Content-Type', self::CONTENT_TYPE);
@@ -96,10 +99,6 @@ class MessageController extends Controller
*
* Show single instance.
*
- * @param Webhook $webhook
- * @param WebhookMessage $message
- *
- * @return JsonResponse
* @throws FireflyException
*/
public function show(Webhook $webhook, WebhookMessage $message): JsonResponse
@@ -107,13 +106,20 @@ class MessageController extends Controller
if ($message->webhook_id !== $webhook->id) {
throw new FireflyException('200040: Webhook and webhook message are no match');
}
+ if (false === config('firefly.allow_webhooks')) {
+ Log::channel('audit')->warning(sprintf('User tries to view message #%d of webhook #%d, but webhooks are DISABLED.', $message->id, $webhook->id));
- $manager = $this->getManager();
+ throw new NotFoundHttpException('Webhooks are not enabled.');
+ }
+
+ Log::channel('audit')->info(sprintf('User views message #%d of webhook #%d.', $message->id, $webhook->id));
+
+ $manager = $this->getManager();
/** @var WebhookMessageTransformer $transformer */
$transformer = app(WebhookMessageTransformer::class);
$transformer->setParameters($this->parameters);
- $resource = new Item($message, $transformer, self::RESOURCE_KEY);
+ $resource = new Item($message, $transformer, self::RESOURCE_KEY);
return response()->json($manager->createData($resource)->toArray())->header('Content-Type', self::CONTENT_TYPE);
}
diff --git a/app/Api/V1/Controllers/Webhook/ShowController.php b/app/Api/V1/Controllers/Webhook/ShowController.php
index 4ad46fdacc..039e5eb693 100644
--- a/app/Api/V1/Controllers/Webhook/ShowController.php
+++ b/app/Api/V1/Controllers/Webhook/ShowController.php
@@ -34,20 +34,20 @@ use FireflyIII\Transformers\WebhookTransformer;
use Illuminate\Http\JsonResponse;
use Illuminate\Pagination\LengthAwarePaginator;
use Illuminate\Support\Collection;
+use Illuminate\Support\Facades\Log;
use League\Fractal\Pagination\IlluminatePaginatorAdapter;
use League\Fractal\Resource\Collection as FractalCollection;
use League\Fractal\Resource\Item;
+use Symfony\Component\HttpKernel\Exception\NotFoundHttpException;
/**
* Class ShowController
*/
class ShowController extends Controller
{
- public const RESOURCE_KEY = 'webhooks';
+ public const string RESOURCE_KEY = 'webhooks';
private WebhookRepositoryInterface $repository;
- /**
- */
public function __construct()
{
parent::__construct();
@@ -67,26 +67,32 @@ class ShowController extends Controller
*
* Display a listing of the webhooks of the user.
*
- * @return JsonResponse
* @throws FireflyException
*/
public function index(): JsonResponse
{
- $manager = $this->getManager();
- $collection = $this->repository->all();
- $pageSize = $this->parameters->get('limit');
- $count = $collection->count();
- $webhooks = $collection->slice(($this->parameters->get('page') - 1) * $pageSize, $pageSize);
+ if (false === config('firefly.allow_webhooks')) {
+ Log::channel('audit')->info('User tries to view all webhooks, but webhooks are DISABLED.');
+
+ throw new NotFoundHttpException('Webhooks are not enabled.');
+ }
+
+ Log::channel('audit')->info('User views all webhooks.');
+ $manager = $this->getManager();
+ $collection = $this->repository->all();
+ $pageSize = $this->parameters->get('limit');
+ $count = $collection->count();
+ $webhooks = $collection->slice(($this->parameters->get('page') - 1) * $pageSize, $pageSize);
// make paginator:
- $paginator = new LengthAwarePaginator($webhooks, $count, $pageSize, $this->parameters->get('page'));
- $paginator->setPath(route('api.v1.webhooks.index') . $this->buildParams());
+ $paginator = new LengthAwarePaginator($webhooks, $count, $pageSize, $this->parameters->get('page'));
+ $paginator->setPath(route('api.v1.webhooks.index').$this->buildParams());
/** @var WebhookTransformer $transformer */
$transformer = app(WebhookTransformer::class);
$transformer->setParameters($this->parameters);
- $resource = new FractalCollection($webhooks, $transformer, self::RESOURCE_KEY);
+ $resource = new FractalCollection($webhooks, $transformer, self::RESOURCE_KEY);
$resource->setPaginator(new IlluminatePaginatorAdapter($paginator));
return response()->json($manager->createData($resource)->toArray())->header('Content-Type', self::CONTENT_TYPE);
@@ -97,19 +103,22 @@ class ShowController extends Controller
* https://api-docs.firefly-iii.org/?urls.primaryName=2.0.0%20(v1)#/webhooks/getWebhook
*
* Show single instance.
- *
- * @param Webhook $webhook
- *
- * @return JsonResponse
*/
public function show(Webhook $webhook): JsonResponse
{
- $manager = $this->getManager();
+ if (false === config('firefly.allow_webhooks')) {
+ Log::channel('audit')->info(sprintf('User tries to view webhook #%d, but webhooks are DISABLED.', $webhook->id));
+
+ throw new NotFoundHttpException('Webhooks are not enabled.');
+ }
+
+ Log::channel('audit')->info(sprintf('User views webhook #%d.', $webhook->id));
+ $manager = $this->getManager();
/** @var WebhookTransformer $transformer */
$transformer = app(WebhookTransformer::class);
$transformer->setParameters($this->parameters);
- $resource = new Item($webhook, $transformer, self::RESOURCE_KEY);
+ $resource = new Item($webhook, $transformer, self::RESOURCE_KEY);
return response()->json($manager->createData($resource)->toArray())->header('Content-Type', self::CONTENT_TYPE);
}
@@ -119,15 +128,18 @@ class ShowController extends Controller
* https://api-docs.firefly-iii.org/?urls.primaryName=2.0.0%20(v1)#/webhooks/triggerWebhookTransaction
*
* This method recycles part of the code of the StoredGroupEventHandler.
- *
- * @param Webhook $webhook
- * @param TransactionGroup $group
- *
- * @return JsonResponse
*/
public function triggerTransaction(Webhook $webhook, TransactionGroup $group): JsonResponse
{
+ if (false === config('firefly.allow_webhooks')) {
+ Log::channel('audit')->info(sprintf('User tries to trigger webhook #%d on transaction group #%d, but webhooks are DISABLED.', $webhook->id, $group->id));
+
+ throw new NotFoundHttpException('Webhooks are not enabled.');
+ }
+
app('log')->debug(sprintf('Now in triggerTransaction(%d, %d)', $webhook->id, $group->id));
+ Log::channel('audit')->info(sprintf('User triggers webhook #%d on transaction group #%d.', $webhook->id, $group->id));
+
/** @var MessageGeneratorInterface $engine */
$engine = app(MessageGeneratorInterface::class);
$engine->setUser(auth()->user());
diff --git a/app/Api/V1/Controllers/Webhook/StoreController.php b/app/Api/V1/Controllers/Webhook/StoreController.php
index 6c573a7929..e134feb34c 100644
--- a/app/Api/V1/Controllers/Webhook/StoreController.php
+++ b/app/Api/V1/Controllers/Webhook/StoreController.php
@@ -28,18 +28,18 @@ use FireflyIII\Api\V1\Requests\Models\Webhook\CreateRequest;
use FireflyIII\Repositories\Webhook\WebhookRepositoryInterface;
use FireflyIII\Transformers\WebhookTransformer;
use Illuminate\Http\JsonResponse;
+use Illuminate\Support\Facades\Log;
use League\Fractal\Resource\Item;
+use Symfony\Component\HttpKernel\Exception\NotFoundHttpException;
/**
* Class StoreController
*/
class StoreController extends Controller
{
- public const RESOURCE_KEY = 'webhooks';
+ public const string RESOURCE_KEY = 'webhooks';
private WebhookRepositoryInterface $repository;
- /**
- */
public function __construct()
{
parent::__construct();
@@ -56,21 +56,26 @@ class StoreController extends Controller
/**
* This endpoint is documented at:
* https://api-docs.firefly-iii.org/?urls.primaryName=2.0.0%20(v1)#/webhooks/storeWebhook
- *
- * @param CreateRequest $request
- *
- * @return JsonResponse
*/
public function store(CreateRequest $request): JsonResponse
{
- $data = $request->getData();
- $webhook = $this->repository->store($data);
- $manager = $this->getManager();
+ $data = $request->getData();
+ if (false === config('firefly.allow_webhooks')) {
+ Log::channel('audit')->info('User tries to store new webhook, but webhooks are DISABLED.', $data);
+
+ throw new NotFoundHttpException('Webhooks are not enabled.');
+ }
+
+ $webhook = $this->repository->store($data);
+ $manager = $this->getManager();
+
+ Log::channel('audit')->info('User stores new webhook', $data);
+
/** @var WebhookTransformer $transformer */
$transformer = app(WebhookTransformer::class);
$transformer->setParameters($this->parameters);
- $resource = new Item($webhook, $transformer, 'webhooks');
+ $resource = new Item($webhook, $transformer, 'webhooks');
return response()->json($manager->createData($resource)->toArray())->header('Content-Type', self::CONTENT_TYPE);
}
diff --git a/app/Api/V1/Controllers/Webhook/SubmitController.php b/app/Api/V1/Controllers/Webhook/SubmitController.php
index bf325fdbb4..50092296d5 100644
--- a/app/Api/V1/Controllers/Webhook/SubmitController.php
+++ b/app/Api/V1/Controllers/Webhook/SubmitController.php
@@ -28,6 +28,8 @@ use FireflyIII\Jobs\SendWebhookMessage;
use FireflyIII\Models\Webhook;
use FireflyIII\Repositories\Webhook\WebhookRepositoryInterface;
use Illuminate\Http\JsonResponse;
+use Illuminate\Support\Facades\Log;
+use Symfony\Component\HttpKernel\Exception\NotFoundHttpException;
/**
* Class SubmitController
@@ -36,8 +38,6 @@ class SubmitController extends Controller
{
private WebhookRepositoryInterface $repository;
- /**
- */
public function __construct()
{
parent::__construct();
@@ -54,13 +54,16 @@ class SubmitController extends Controller
/**
* This endpoint is documented at:
* https://api-docs.firefly-iii.org/?urls.primaryName=2.0.0%20(v1)#/webhooks/submitWebook
- *
- * @param Webhook $webhook
- *
- * @return JsonResponse
*/
public function submit(Webhook $webhook): JsonResponse
{
+ if (false === config('firefly.allow_webhooks')) {
+ Log::channel('audit')->info(sprintf('User tries to submit webhook #%d, but webhooks are DISABLED.', $webhook->id));
+
+ throw new NotFoundHttpException('Webhooks are not enabled.');
+ }
+
+ Log::channel('audit')->info(sprintf('User submits webhook #%d', $webhook->id));
// count messages that can be sent.
$messages = $this->repository->getReadyMessages($webhook);
if (0 === $messages->count()) {
diff --git a/app/Api/V1/Controllers/Webhook/UpdateController.php b/app/Api/V1/Controllers/Webhook/UpdateController.php
index 658412801b..680e423043 100644
--- a/app/Api/V1/Controllers/Webhook/UpdateController.php
+++ b/app/Api/V1/Controllers/Webhook/UpdateController.php
@@ -29,7 +29,9 @@ use FireflyIII\Models\Webhook;
use FireflyIII\Repositories\Webhook\WebhookRepositoryInterface;
use FireflyIII\Transformers\WebhookTransformer;
use Illuminate\Http\JsonResponse;
+use Illuminate\Support\Facades\Log;
use League\Fractal\Resource\Item;
+use Symfony\Component\HttpKernel\Exception\NotFoundHttpException;
/**
* Class UpdateController
@@ -38,8 +40,6 @@ class UpdateController extends Controller
{
private WebhookRepositoryInterface $repository;
- /**
- */
public function __construct()
{
parent::__construct();
@@ -56,22 +56,26 @@ class UpdateController extends Controller
/**
* This endpoint is documented at:
* https://api-docs.firefly-iii.org/?urls.primaryName=2.0.0%20(v1)#/webhooks/updateWebhook
- *
- * @param Webhook $webhook
- * @param UpdateRequest $request
- *
- * @return JsonResponse
*/
public function update(Webhook $webhook, UpdateRequest $request): JsonResponse
{
- $data = $request->getData();
- $webhook = $this->repository->update($webhook, $data);
- $manager = $this->getManager();
+ $data = $request->getData();
+ if (false === config('firefly.allow_webhooks')) {
+ Log::channel('audit')->info(sprintf('User tries to update webhook #%d, but webhooks are DISABLED.', $webhook->id), $data);
+
+ throw new NotFoundHttpException('Webhooks are not enabled.');
+ }
+
+ $webhook = $this->repository->update($webhook, $data);
+ $manager = $this->getManager();
+
+ Log::channel('audit')->info(sprintf('User updates webhook #%d', $webhook->id), $data);
+
/** @var WebhookTransformer $transformer */
$transformer = app(WebhookTransformer::class);
$transformer->setParameters($this->parameters);
- $resource = new Item($webhook, $transformer, 'webhooks');
+ $resource = new Item($webhook, $transformer, 'webhooks');
return response()->json($manager->createData($resource)->toArray())->header('Content-Type', self::CONTENT_TYPE);
}
diff --git a/app/Api/V1/Middleware/ApiDemoUser.php b/app/Api/V1/Middleware/ApiDemoUser.php
index 02553d67f0..e031bfa039 100644
--- a/app/Api/V1/Middleware/ApiDemoUser.php
+++ b/app/Api/V1/Middleware/ApiDemoUser.php
@@ -23,7 +23,6 @@ declare(strict_types=1);
namespace FireflyIII\Api\V1\Middleware;
-use Closure;
use FireflyIII\User;
use Illuminate\Http\Request;
@@ -35,14 +34,11 @@ class ApiDemoUser
/**
* Handle an incoming request.
*
- * @param Request $request
- * @param Closure $next
- *
* @return mixed
*/
- public function handle(Request $request, Closure $next)
+ public function handle(Request $request, \Closure $next)
{
- /** @var User|null $user */
+ /** @var null|User $user */
$user = $request->user();
if (null === $user) {
diff --git a/app/Api/V1/Requests/Autocomplete/AutocompleteRequest.php b/app/Api/V1/Requests/Autocomplete/AutocompleteRequest.php
index 875d1f7335..39bafac82c 100644
--- a/app/Api/V1/Requests/Autocomplete/AutocompleteRequest.php
+++ b/app/Api/V1/Requests/Autocomplete/AutocompleteRequest.php
@@ -33,12 +33,9 @@ use Illuminate\Foundation\Http\FormRequest;
*/
class AutocompleteRequest extends FormRequest
{
- use ConvertsDataTypes;
use ChecksLogin;
+ use ConvertsDataTypes;
- /**
- * @return array
- */
public function getData(): array
{
$types = $this->convertString('types');
@@ -57,9 +54,6 @@ class AutocompleteRequest extends FormRequest
];
}
- /**
- * @return array
- */
public function rules(): array
{
return [
diff --git a/app/Api/V1/Requests/Data/Bulk/MoveTransactionsRequest.php b/app/Api/V1/Requests/Data/Bulk/MoveTransactionsRequest.php
index 59df3d2678..4ec6250dd2 100644
--- a/app/Api/V1/Requests/Data/Bulk/MoveTransactionsRequest.php
+++ b/app/Api/V1/Requests/Data/Bulk/MoveTransactionsRequest.php
@@ -28,6 +28,7 @@ use FireflyIII\Repositories\Account\AccountRepositoryInterface;
use FireflyIII\Support\Request\ChecksLogin;
use FireflyIII\Support\Request\ConvertsDataTypes;
use Illuminate\Foundation\Http\FormRequest;
+use Illuminate\Support\Facades\Log;
use Illuminate\Validation\Validator;
/**
@@ -38,9 +39,6 @@ class MoveTransactionsRequest extends FormRequest
use ChecksLogin;
use ConvertsDataTypes;
- /**
- * @return array
- */
public function getAll(): array
{
return [
@@ -62,16 +60,12 @@ class MoveTransactionsRequest extends FormRequest
/**
* Configure the validator instance with special rules for after the basic validation rules.
- *
- * @param Validator $validator
* TODO this is duplicate.
- *
- * @return void
*/
public function withValidator(Validator $validator): void
{
$validator->after(
- function (Validator $validator) {
+ function (Validator $validator): void {
// validate start before end only if both are there.
$data = $validator->getData();
if (array_key_exists('original_account', $data) && array_key_exists('destination_account', $data)) {
@@ -79,20 +73,18 @@ class MoveTransactionsRequest extends FormRequest
}
}
);
+ if ($validator->fails()) {
+ Log::channel('audit')->error(sprintf('Validation errors in %s', __CLASS__), $validator->errors()->toArray());
+ }
}
- /**
- * @param Validator $validator
- *
- * @return void
- */
private function validateMove(Validator $validator): void
{
- $data = $validator->getData();
- $repository = app(AccountRepositoryInterface::class);
+ $data = $validator->getData();
+ $repository = app(AccountRepositoryInterface::class);
$repository->setUser(auth()->user());
- $original = $repository->find((int)$data['original_account']);
- $destination = $repository->find((int)$data['destination_account']);
+ $original = $repository->find((int)$data['original_account']);
+ $destination = $repository->find((int)$data['destination_account']);
// not the same type:
if ($original->accountType->type !== $destination->accountType->type) {
diff --git a/app/Api/V1/Requests/Data/Bulk/TransactionRequest.php b/app/Api/V1/Requests/Data/Bulk/TransactionRequest.php
index 07b29a7a60..fb8f302f76 100644
--- a/app/Api/V1/Requests/Data/Bulk/TransactionRequest.php
+++ b/app/Api/V1/Requests/Data/Bulk/TransactionRequest.php
@@ -32,7 +32,6 @@ use FireflyIII\Validation\Api\Data\Bulk\ValidatesBulkTransactionQuery;
use Illuminate\Foundation\Http\FormRequest;
use Illuminate\Support\Facades\Log;
use Illuminate\Validation\Validator;
-use JsonException;
/**
* Class TransactionRequest
@@ -43,27 +42,22 @@ class TransactionRequest extends FormRequest
use ConvertsDataTypes;
use ValidatesBulkTransactionQuery;
- /**
- * @return array
- */
public function getAll(): array
{
$data = [];
+
try {
$data = [
'query' => json_decode($this->get('query'), true, 8, JSON_THROW_ON_ERROR),
];
- } catch (JsonException $e) {
+ } catch (\JsonException $e) {
// dont really care. the validation should catch invalid json.
- Log::error($e->getMessage());
+ app('log')->error($e->getMessage());
}
return $data;
}
- /**
- * @return array
- */
public function rules(): array
{
return [
@@ -71,18 +65,16 @@ class TransactionRequest extends FormRequest
];
}
- /**
- * @param Validator $validator
- *
- * @return void
- */
public function withValidator(Validator $validator): void
{
$validator->after(
- function (Validator $validator) {
+ function (Validator $validator): void {
// validate transaction query data.
$this->validateTransactionQuery($validator);
}
);
+ if ($validator->fails()) {
+ Log::channel('audit')->error(sprintf('Validation errors in %s', __CLASS__), $validator->errors()->toArray());
+ }
}
}
diff --git a/app/Api/V1/Requests/Data/DateRequest.php b/app/Api/V1/Requests/Data/DateRequest.php
index a6e1cdf23b..416ee8793a 100644
--- a/app/Api/V1/Requests/Data/DateRequest.php
+++ b/app/Api/V1/Requests/Data/DateRequest.php
@@ -24,6 +24,7 @@ declare(strict_types=1);
namespace FireflyIII\Api\V1\Requests\Data;
+use FireflyIII\Exceptions\FireflyException;
use FireflyIII\Support\Request\ChecksLogin;
use FireflyIII\Support\Request\ConvertsDataTypes;
use Illuminate\Foundation\Http\FormRequest;
@@ -35,26 +36,28 @@ use Illuminate\Foundation\Http\FormRequest;
*/
class DateRequest extends FormRequest
{
- use ConvertsDataTypes;
use ChecksLogin;
+ use ConvertsDataTypes;
/**
* Get all data from the request.
- *
- * @return array
*/
public function getAll(): array
{
+ $start = $this->getCarbonDate('start');
+ $end = $this->getCarbonDate('end');
+ if ($start->diffInYears($end) > 5) {
+ throw new FireflyException('Date range out of range.');
+ }
+
return [
- 'start' => $this->getCarbonDate('start'),
- 'end' => $this->getCarbonDate('end'),
+ 'start' => $start,
+ 'end' => $end,
];
}
/**
* The rules that the incoming request must be matched against.
- *
- * @return array
*/
public function rules(): array
{
diff --git a/app/Api/V1/Requests/Data/DestroyRequest.php b/app/Api/V1/Requests/Data/DestroyRequest.php
index ea96e92c26..5296652d51 100644
--- a/app/Api/V1/Requests/Data/DestroyRequest.php
+++ b/app/Api/V1/Requests/Data/DestroyRequest.php
@@ -32,13 +32,11 @@ use Illuminate\Foundation\Http\FormRequest;
*/
class DestroyRequest extends FormRequest
{
- use ConvertsDataTypes;
use ChecksLogin;
+ use ConvertsDataTypes;
/**
* Get all data from the request.
- *
- * @return string
*/
public function getObjects(): string
{
@@ -47,13 +45,11 @@ class DestroyRequest extends FormRequest
/**
* The rules that the incoming request must be matched against.
- *
- * @return array
*/
public function rules(): array
{
- $valid = 'budgets,bills,piggy_banks,rules,recurring,categories,tags,object_groups' .
- ',accounts,asset_accounts,expense_accounts,revenue_accounts,liabilities,transactions,withdrawals,deposits,transfers' .
+ $valid = 'budgets,bills,piggy_banks,rules,recurring,categories,tags,object_groups'.
+ ',accounts,asset_accounts,expense_accounts,revenue_accounts,liabilities,transactions,withdrawals,deposits,transfers'.
',not_assets_liabilities';
return [
diff --git a/app/Api/V1/Requests/Data/Export/ExportRequest.php b/app/Api/V1/Requests/Data/Export/ExportRequest.php
index bb74c60cdb..3b858c60ff 100644
--- a/app/Api/V1/Requests/Data/Export/ExportRequest.php
+++ b/app/Api/V1/Requests/Data/Export/ExportRequest.php
@@ -38,21 +38,18 @@ class ExportRequest extends FormRequest
use ChecksLogin;
use ConvertsDataTypes;
- /**
- * @return array
- */
public function getAll(): array
{
- $result = [
+ $result = [
'start' => $this->getCarbonDate('start') ?? today(config('app.timezone'))->subYear(),
'end' => $this->getCarbonDate('end') ?? today(config('app.timezone')),
'type' => $this->convertString('type'),
];
- $parts = explode(',', $this->convertString('accounts'));
- $repository = app(AccountRepositoryInterface::class);
+ $parts = explode(',', $this->convertString('accounts'));
+ $repository = app(AccountRepositoryInterface::class);
$repository->setUser(auth()->user());
- $accounts = new Collection();
+ $accounts = new Collection();
foreach ($parts as $part) {
$accountId = (int)$part;
if (0 !== $accountId) {
@@ -69,14 +66,12 @@ class ExportRequest extends FormRequest
/**
* The rules that the incoming request must be matched against.
- *
- * @return array
*/
public function rules(): array
{
return [
'type' => 'in:csv',
- 'accounts' => 'min:1|max:65536',
+ 'accounts' => 'min:1|max:32768',
'start' => 'date|before:end',
'end' => 'date|after:start',
];
diff --git a/app/Api/V1/Requests/Data/SameDateRequest.php b/app/Api/V1/Requests/Data/SameDateRequest.php
index 549bf58563..9f419653f7 100644
--- a/app/Api/V1/Requests/Data/SameDateRequest.php
+++ b/app/Api/V1/Requests/Data/SameDateRequest.php
@@ -35,13 +35,11 @@ use Illuminate\Foundation\Http\FormRequest;
*/
class SameDateRequest extends FormRequest
{
- use ConvertsDataTypes;
use ChecksLogin;
+ use ConvertsDataTypes;
/**
* Get all data from the request.
- *
- * @return array
*/
public function getAll(): array
{
@@ -53,8 +51,6 @@ class SameDateRequest extends FormRequest
/**
* The rules that the incoming request must be matched against.
- *
- * @return array
*/
public function rules(): array
{
diff --git a/app/Api/V1/Requests/Insight/GenericRequest.php b/app/Api/V1/Requests/Insight/GenericRequest.php
index 0eb22bc584..1bde6efeb7 100644
--- a/app/Api/V1/Requests/Insight/GenericRequest.php
+++ b/app/Api/V1/Requests/Insight/GenericRequest.php
@@ -42,8 +42,8 @@ use Illuminate\Support\Collection;
*/
class GenericRequest extends FormRequest
{
- use ConvertsDataTypes;
use ChecksLogin;
+ use ConvertsDataTypes;
private Collection $accounts;
private Collection $bills;
@@ -53,8 +53,6 @@ class GenericRequest extends FormRequest
/**
* Get all data from the request.
- *
- * @return array
*/
public function getAll(): array
{
@@ -64,13 +62,11 @@ class GenericRequest extends FormRequest
];
}
- /**
- * @return Collection
- */
public function getAssetAccounts(): Collection
{
$this->parseAccounts();
$return = new Collection();
+
/** @var Account $account */
foreach ($this->accounts as $account) {
$type = $account->accountType->type;
@@ -82,9 +78,6 @@ class GenericRequest extends FormRequest
return $return;
}
- /**
- *
- */
private function parseAccounts(): void
{
if (0 !== $this->accounts->count()) {
@@ -92,7 +85,7 @@ class GenericRequest extends FormRequest
}
$repository = app(AccountRepositoryInterface::class);
$repository->setUser(auth()->user());
- $array = $this->get('accounts');
+ $array = $this->get('accounts');
if (is_array($array)) {
foreach ($array as $accountId) {
$accountId = (int)$accountId;
@@ -104,9 +97,6 @@ class GenericRequest extends FormRequest
}
}
- /**
- * @return Collection
- */
public function getBills(): Collection
{
$this->parseBills();
@@ -114,9 +104,6 @@ class GenericRequest extends FormRequest
return $this->bills;
}
- /**
- *
- */
private function parseBills(): void
{
if (0 !== $this->bills->count()) {
@@ -124,7 +111,7 @@ class GenericRequest extends FormRequest
}
$repository = app(BillRepositoryInterface::class);
$repository->setUser(auth()->user());
- $array = $this->get('bills');
+ $array = $this->get('bills');
if (is_array($array)) {
foreach ($array as $billId) {
$billId = (int)$billId;
@@ -136,9 +123,6 @@ class GenericRequest extends FormRequest
}
}
- /**
- * @return Collection
- */
public function getBudgets(): Collection
{
$this->parseBudgets();
@@ -146,9 +130,6 @@ class GenericRequest extends FormRequest
return $this->budgets;
}
- /**
- *
- */
private function parseBudgets(): void
{
if (0 !== $this->budgets->count()) {
@@ -156,7 +137,7 @@ class GenericRequest extends FormRequest
}
$repository = app(BudgetRepositoryInterface::class);
$repository->setUser(auth()->user());
- $array = $this->get('budgets');
+ $array = $this->get('budgets');
if (is_array($array)) {
foreach ($array as $budgetId) {
$budgetId = (int)$budgetId;
@@ -168,9 +149,6 @@ class GenericRequest extends FormRequest
}
}
- /**
- * @return Collection
- */
public function getCategories(): Collection
{
$this->parseCategories();
@@ -178,9 +156,6 @@ class GenericRequest extends FormRequest
return $this->categories;
}
- /**
- *
- */
private function parseCategories(): void
{
if (0 !== $this->categories->count()) {
@@ -188,7 +163,7 @@ class GenericRequest extends FormRequest
}
$repository = app(CategoryRepositoryInterface::class);
$repository->setUser(auth()->user());
- $array = $this->get('categories');
+ $array = $this->get('categories');
if (is_array($array)) {
foreach ($array as $categoryId) {
$categoryId = (int)$categoryId;
@@ -200,9 +175,6 @@ class GenericRequest extends FormRequest
}
}
- /**
- * @return Carbon
- */
public function getEnd(): Carbon
{
$date = $this->getCarbonDate('end');
@@ -211,17 +183,15 @@ class GenericRequest extends FormRequest
return $date;
}
- /**
- * @return Collection
- */
public function getExpenseAccounts(): Collection
{
$this->parseAccounts();
$return = new Collection();
+
/** @var Account $account */
foreach ($this->accounts as $account) {
$type = $account->accountType->type;
- if ($type === AccountType::EXPENSE) {
+ if (AccountType::EXPENSE === $type) {
$return->push($account);
}
}
@@ -229,17 +199,15 @@ class GenericRequest extends FormRequest
return $return;
}
- /**
- * @return Collection
- */
public function getRevenueAccounts(): Collection
{
$this->parseAccounts();
$return = new Collection();
+
/** @var Account $account */
foreach ($this->accounts as $account) {
$type = $account->accountType->type;
- if ($type === AccountType::REVENUE) {
+ if (AccountType::REVENUE === $type) {
$return->push($account);
}
}
@@ -247,9 +215,6 @@ class GenericRequest extends FormRequest
return $return;
}
- /**
- * @return Carbon
- */
public function getStart(): Carbon
{
$date = $this->getCarbonDate('start');
@@ -258,9 +223,6 @@ class GenericRequest extends FormRequest
return $date;
}
- /**
- * @return Collection
- */
public function getTags(): Collection
{
$this->parseTags();
@@ -268,9 +230,6 @@ class GenericRequest extends FormRequest
return $this->tags;
}
- /**
- *
- */
private function parseTags(): void
{
if (0 !== $this->tags->count()) {
@@ -278,7 +237,7 @@ class GenericRequest extends FormRequest
}
$repository = app(TagRepositoryInterface::class);
$repository->setUser(auth()->user());
- $array = $this->get('tags');
+ $array = $this->get('tags');
if (is_array($array)) {
foreach ($array as $tagId) {
$tagId = (int)$tagId;
@@ -292,8 +251,6 @@ class GenericRequest extends FormRequest
/**
* The rules that the incoming request must be matched against.
- *
- * @return array
*/
public function rules(): array
{
diff --git a/app/Api/V1/Requests/Models/Account/StoreRequest.php b/app/Api/V1/Requests/Models/Account/StoreRequest.php
index d46322bea9..c78184381d 100644
--- a/app/Api/V1/Requests/Models/Account/StoreRequest.php
+++ b/app/Api/V1/Requests/Models/Account/StoreRequest.php
@@ -26,6 +26,7 @@ namespace FireflyIII\Api\V1\Requests\Models\Account;
use FireflyIII\Models\Location;
use FireflyIII\Rules\IsBoolean;
+use FireflyIII\Rules\IsValidPositiveAmount;
use FireflyIII\Rules\UniqueAccountNumber;
use FireflyIII\Rules\UniqueIban;
use FireflyIII\Support\Request\AppendsLocationData;
@@ -35,18 +36,13 @@ use Illuminate\Foundation\Http\FormRequest;
/**
* Class StoreRequest
- *
-
*/
class StoreRequest extends FormRequest
{
- use ConvertsDataTypes;
use AppendsLocationData;
use ChecksLogin;
+ use ConvertsDataTypes;
- /**
- * @return array
- */
public function getAllAccountData(): array
{
$active = true;
@@ -57,7 +53,7 @@ class StoreRequest extends FormRequest
if (null !== $this->get('include_net_worth')) {
$includeNetWorth = $this->boolean('include_net_worth');
}
- $data = [
+ $data = [
'name' => $this->convertString('name'),
'active' => $active,
'include_net_worth' => $includeNetWorth,
@@ -80,7 +76,7 @@ class StoreRequest extends FormRequest
'interest_period' => $this->convertString('interest_period'),
];
// append location information.
- $data = $this->appendLocationData($data, null);
+ $data = $this->appendLocationData($data, null);
if ('liability' === $data['account_type_name'] || 'liabilities' === $data['account_type_name']) {
$data['account_type_name'] = $this->convertString('liability_type');
@@ -93,8 +89,6 @@ class StoreRequest extends FormRequest
/**
* The rules that the incoming request must be matched against.
- *
- * @return array
*/
public function rules(): array
{
@@ -104,10 +98,10 @@ class StoreRequest extends FormRequest
$type = $this->convertString('type');
$rules = [
'name' => 'required|max:1024|min:1|uniqueAccountForUser',
- 'type' => 'required|max:1024|min:1|' . sprintf('in:%s', $types),
+ 'type' => 'required|max:1024|min:1|'.sprintf('in:%s', $types),
'iban' => ['iban', 'nullable', new UniqueIban(null, $type)],
'bic' => 'bic|nullable',
- 'account_number' => ['between:1,255', 'nullable', new UniqueAccountNumber(null, $type)],
+ 'account_number' => ['min:1', 'max:255', 'nullable', new UniqueAccountNumber(null, $type)],
'opening_balance' => 'numeric|required_with:opening_balance_date|nullable',
'opening_balance_date' => 'date|required_with:opening_balance|nullable',
'virtual_balance' => 'numeric|nullable',
@@ -120,12 +114,12 @@ class StoreRequest extends FormRequest
'credit_card_type' => sprintf('nullable|in:%s|required_if:account_role,ccAsset', $ccPaymentTypes),
'monthly_payment_date' => 'nullable|date|required_if:account_role,ccAsset|required_if:credit_card_type,monthlyFull',
'liability_type' => 'nullable|required_if:type,liability|required_if:type,liabilities|in:loan,debt,mortgage',
- 'liability_amount' => 'required_with:liability_start_date|min:0|numeric|max:1000000000',
+ 'liability_amount' => ['required_with:liability_start_date', new IsValidPositiveAmount()],
'liability_start_date' => 'required_with:liability_amount|date',
'liability_direction' => 'nullable|required_if:type,liability|required_if:type,liabilities|in:credit,debit',
- 'interest' => 'between:0,100|numeric',
- 'interest_period' => sprintf('nullable|in:%s', join(',', config('firefly.interest_periods'))),
- 'notes' => 'min:0|max:65536',
+ 'interest' => 'min:0|max:100|numeric',
+ 'interest_period' => sprintf('nullable|in:%s', implode(',', config('firefly.interest_periods'))),
+ 'notes' => 'min:0|max:32768',
];
return Location::requestRules($rules);
diff --git a/app/Api/V1/Requests/Models/Account/UpdateRequest.php b/app/Api/V1/Requests/Models/Account/UpdateRequest.php
index d50f9d10eb..5ea693c645 100644
--- a/app/Api/V1/Requests/Models/Account/UpdateRequest.php
+++ b/app/Api/V1/Requests/Models/Account/UpdateRequest.php
@@ -36,18 +36,13 @@ use Illuminate\Foundation\Http\FormRequest;
/**
* Class UpdateRequest
- *
-
*/
class UpdateRequest extends FormRequest
{
- use ConvertsDataTypes;
use AppendsLocationData;
use ChecksLogin;
+ use ConvertsDataTypes;
- /**
- * @return array
- */
public function getUpdateData(): array
{
$fields = [
@@ -82,8 +77,6 @@ class UpdateRequest extends FormRequest
/**
* The rules that the incoming request must be matched against.
- *
- * @return array
*/
public function rules(): array
{
@@ -93,12 +86,12 @@ class UpdateRequest extends FormRequest
$types = implode(',', array_keys(config('firefly.subTitlesByIdentifier')));
$ccPaymentTypes = implode(',', array_keys(config('firefly.ccTypes')));
- $rules = [
+ $rules = [
'name' => sprintf('min:1|max:1024|uniqueAccountForUser:%d', $account->id),
'type' => sprintf('in:%s', $types),
'iban' => ['iban', 'nullable', new UniqueIban($account, $this->convertString('type'))],
'bic' => 'bic|nullable',
- 'account_number' => ['between:1,255', 'nullable', new UniqueAccountNumber($account, $this->convertString('type'))],
+ 'account_number' => ['min:1', 'max:255', 'nullable', new UniqueAccountNumber($account, $this->convertString('type'))],
'opening_balance' => 'numeric|required_with:opening_balance_date|nullable',
'opening_balance_date' => 'date|required_with:opening_balance|nullable',
'virtual_balance' => 'numeric|nullable',
@@ -109,12 +102,12 @@ class UpdateRequest extends FormRequest
'include_net_worth' => [new IsBoolean()],
'account_role' => sprintf('in:%s|nullable|required_if:type,asset', $accountRoles),
'credit_card_type' => sprintf('in:%s|nullable|required_if:account_role,ccAsset', $ccPaymentTypes),
- 'monthly_payment_date' => 'date' . '|nullable|required_if:account_role,ccAsset|required_if:credit_card_type,monthlyFull',
+ 'monthly_payment_date' => 'date|nullable|required_if:account_role,ccAsset|required_if:credit_card_type,monthlyFull',
'liability_type' => 'required_if:type,liability|in:loan,debt,mortgage',
'liability_direction' => 'required_if:type,liability|in:credit,debit',
- 'interest' => 'required_if:type,liability|between:0,100|numeric',
+ 'interest' => 'required_if:type,liability|min:0|max:100|numeric',
'interest_period' => 'required_if:type,liability|in:daily,monthly,yearly',
- 'notes' => 'min:0|max:65536',
+ 'notes' => 'min:0|max:32768',
];
return Location::requestRules($rules);
diff --git a/app/Api/V1/Requests/Models/Attachment/StoreRequest.php b/app/Api/V1/Requests/Models/Attachment/StoreRequest.php
index 565c8a4cd4..174cd2f543 100644
--- a/app/Api/V1/Requests/Models/Attachment/StoreRequest.php
+++ b/app/Api/V1/Requests/Models/Attachment/StoreRequest.php
@@ -30,18 +30,14 @@ use Illuminate\Foundation\Http\FormRequest;
/**
* Class StoreRequest
- *
-
*/
class StoreRequest extends FormRequest
{
- use ConvertsDataTypes;
use ChecksLogin;
+ use ConvertsDataTypes;
/**
* Get all data from the request.
- *
- * @return array
*/
public function getAll(): array
{
@@ -56,8 +52,6 @@ class StoreRequest extends FormRequest
/**
* The rules that the incoming request must be matched against.
- *
- * @return array
*/
public function rules(): array
{
@@ -72,9 +66,9 @@ class StoreRequest extends FormRequest
$model = $this->convertString('attachable_type');
return [
- 'filename' => 'required|between:1,255',
- 'title' => 'between:1,255',
- 'notes' => 'between:1,65000',
+ 'filename' => 'required|min:1|max:255',
+ 'title' => ['min:1', 'max:255'],
+ 'notes' => 'min:1|max:32768',
'attachable_type' => sprintf('required|in:%s', $models),
'attachable_id' => ['required', 'numeric', new IsValidAttachmentModel($model)],
];
diff --git a/app/Api/V1/Requests/Models/Attachment/UpdateRequest.php b/app/Api/V1/Requests/Models/Attachment/UpdateRequest.php
index 854a156df4..0ec07affd5 100644
--- a/app/Api/V1/Requests/Models/Attachment/UpdateRequest.php
+++ b/app/Api/V1/Requests/Models/Attachment/UpdateRequest.php
@@ -30,18 +30,14 @@ use Illuminate\Foundation\Http\FormRequest;
/**
* Class UpdateRequest
- *
-
*/
class UpdateRequest extends FormRequest
{
- use ConvertsDataTypes;
use ChecksLogin;
+ use ConvertsDataTypes;
/**
* Get all data from the request.
- *
- * @return array
*/
public function getAll(): array
{
@@ -58,8 +54,6 @@ class UpdateRequest extends FormRequest
/**
* The rules that the incoming request must be matched against.
- *
- * @return array
*/
public function rules(): array
{
@@ -74,9 +68,9 @@ class UpdateRequest extends FormRequest
$model = $this->convertString('attachable_type');
return [
- 'filename' => 'between:1,255',
- 'title' => 'between:1,255',
- 'notes' => 'between:1,65000',
+ 'filename' => ['min:1', 'max:255'],
+ 'title' => ['min:1', 'max:255'],
+ 'notes' => 'min:1|max:32768',
'attachable_type' => sprintf('in:%s', $models),
'attachable_id' => ['numeric', new IsValidAttachmentModel($model)],
];
diff --git a/app/Api/V1/Requests/Models/AvailableBudget/Request.php b/app/Api/V1/Requests/Models/AvailableBudget/Request.php
index f92de0da5a..9abf3d3ee2 100644
--- a/app/Api/V1/Requests/Models/AvailableBudget/Request.php
+++ b/app/Api/V1/Requests/Models/AvailableBudget/Request.php
@@ -24,25 +24,23 @@ declare(strict_types=1);
namespace FireflyIII\Api\V1\Requests\Models\AvailableBudget;
use Carbon\Carbon;
+use FireflyIII\Rules\IsValidPositiveAmount;
use FireflyIII\Support\Request\ChecksLogin;
use FireflyIII\Support\Request\ConvertsDataTypes;
use Illuminate\Foundation\Http\FormRequest;
+use Illuminate\Support\Facades\Log;
use Illuminate\Validation\Validator;
/**
* Class Request
- *
-
*/
class Request extends FormRequest
{
- use ConvertsDataTypes;
use ChecksLogin;
+ use ConvertsDataTypes;
/**
* Get all data from the request.
- *
- * @return array
*/
public function getAll(): array
{
@@ -60,15 +58,13 @@ class Request extends FormRequest
/**
* The rules that the incoming request must be matched against.
- *
- * @return array
*/
public function rules(): array
{
return [
'currency_id' => 'numeric|exists:transaction_currencies,id',
'currency_code' => 'min:3|max:51|exists:transaction_currencies,code',
- 'amount' => 'numeric|gt:0',
+ 'amount' => ['nullable', new IsValidPositiveAmount()],
'start' => 'date',
'end' => 'date',
];
@@ -76,15 +72,11 @@ class Request extends FormRequest
/**
* Configure the validator instance with special rules for after the basic validation rules.
- *
- * @param Validator $validator
- *
- * @return void
*/
public function withValidator(Validator $validator): void
{
$validator->after(
- function (Validator $validator) {
+ static function (Validator $validator): void {
// validate start before end only if both are there.
$data = $validator->getData();
if (array_key_exists('start', $data) && array_key_exists('end', $data)) {
@@ -96,5 +88,8 @@ class Request extends FormRequest
}
}
);
+ if ($validator->fails()) {
+ Log::channel('audit')->error(sprintf('Validation errors in %s', __CLASS__), $validator->errors()->toArray());
+ }
}
}
diff --git a/app/Api/V1/Requests/Models/Bill/StoreRequest.php b/app/Api/V1/Requests/Models/Bill/StoreRequest.php
index 416d73ac99..70d48c2a2e 100644
--- a/app/Api/V1/Requests/Models/Bill/StoreRequest.php
+++ b/app/Api/V1/Requests/Models/Bill/StoreRequest.php
@@ -25,6 +25,7 @@ declare(strict_types=1);
namespace FireflyIII\Api\V1\Requests\Models\Bill;
use FireflyIII\Rules\IsBoolean;
+use FireflyIII\Rules\IsValidPositiveAmount;
use FireflyIII\Support\Request\ChecksLogin;
use FireflyIII\Support\Request\ConvertsDataTypes;
use Illuminate\Foundation\Http\FormRequest;
@@ -33,22 +34,18 @@ use Illuminate\Validation\Validator;
/**
* Class StoreRequest
- *
-
*/
class StoreRequest extends FormRequest
{
- use ConvertsDataTypes;
use ChecksLogin;
+ use ConvertsDataTypes;
/**
* Get all data from the request.
- *
- * @return array
*/
public function getAll(): array
{
- Log::debug('Raw fields in Bill StoreRequest', $this->all());
+ app('log')->debug('Raw fields in Bill StoreRequest', $this->all());
$fields = [
'name' => ['name', 'convertString'],
'amount_min' => ['amount_min', 'convertString'],
@@ -72,38 +69,32 @@ class StoreRequest extends FormRequest
/**
* The rules that the incoming request must be matched against.
- *
- * @return array
*/
public function rules(): array
{
return [
- 'name' => 'between:1,255|uniqueObjectForUser:bills,name',
- 'amount_min' => 'numeric|gt:0|required',
- 'amount_max' => 'numeric|gt:0|required',
+ 'name' => 'min:1|max:255|uniqueObjectForUser:bills,name',
+ 'amount_min' => ['required', new IsValidPositiveAmount()],
+ 'amount_max' => ['required', new IsValidPositiveAmount()],
'currency_id' => 'numeric|exists:transaction_currencies,id',
'currency_code' => 'min:3|max:51|exists:transaction_currencies,code',
'date' => 'date|required',
'end_date' => 'date|after:date',
'extension_date' => 'date|after:date',
'repeat_freq' => 'in:weekly,monthly,quarterly,half-year,yearly|required',
- 'skip' => 'between:0,31',
+ 'skip' => 'min:0|max:31|numeric',
'active' => [new IsBoolean()],
- 'notes' => 'between:1,65536',
+ 'notes' => 'min:1|max:32768',
];
}
/**
* Configure the validator instance.
- *
- * @param Validator $validator
- *
- * @return void
*/
public function withValidator(Validator $validator): void
{
$validator->after(
- static function (Validator $validator) {
+ static function (Validator $validator): void {
$data = $validator->getData();
$min = (string)($data['amount_min'] ?? '0');
$max = (string)($data['amount_max'] ?? '0');
@@ -113,5 +104,8 @@ class StoreRequest extends FormRequest
}
}
);
+ if ($validator->fails()) {
+ Log::channel('audit')->error(sprintf('Validation errors in %s', __CLASS__), $validator->errors()->toArray());
+ }
}
}
diff --git a/app/Api/V1/Requests/Models/Bill/UpdateRequest.php b/app/Api/V1/Requests/Models/Bill/UpdateRequest.php
index 25adeb2705..0df5139965 100644
--- a/app/Api/V1/Requests/Models/Bill/UpdateRequest.php
+++ b/app/Api/V1/Requests/Models/Bill/UpdateRequest.php
@@ -26,25 +26,23 @@ namespace FireflyIII\Api\V1\Requests\Models\Bill;
use FireflyIII\Models\Bill;
use FireflyIII\Rules\IsBoolean;
+use FireflyIII\Rules\IsValidPositiveAmount;
use FireflyIII\Support\Request\ChecksLogin;
use FireflyIII\Support\Request\ConvertsDataTypes;
use Illuminate\Foundation\Http\FormRequest;
+use Illuminate\Support\Facades\Log;
use Illuminate\Validation\Validator;
/**
* Class UpdateRequest
- *
-
*/
class UpdateRequest extends FormRequest
{
- use ConvertsDataTypes;
use ChecksLogin;
+ use ConvertsDataTypes;
/**
* Get all data from the request.
- *
- * @return array
*/
public function getAll(): array
{
@@ -71,8 +69,6 @@ class UpdateRequest extends FormRequest
/**
* The rules that the incoming request must be matched against.
- *
- * @return array
*/
public function rules(): array
{
@@ -80,32 +76,28 @@ class UpdateRequest extends FormRequest
$bill = $this->route()->parameter('bill');
return [
- 'name' => sprintf('between:1,255|uniqueObjectForUser:bills,name,%d', $bill->id),
- 'amount_min' => 'numeric|gt:0',
- 'amount_max' => 'numeric|gt:0',
+ 'name' => sprintf('min:1|max:255|uniqueObjectForUser:bills,name,%d', $bill->id),
+ 'amount_min' => ['nullable', new IsValidPositiveAmount()],
+ 'amount_max' => ['nullable', new IsValidPositiveAmount()],
'currency_id' => 'numeric|exists:transaction_currencies,id',
'currency_code' => 'min:3|max:51|exists:transaction_currencies,code',
'date' => 'date',
'end_date' => 'date|after:date',
'extension_date' => 'date|after:date',
'repeat_freq' => 'in:weekly,monthly,quarterly,half-year,yearly',
- 'skip' => 'between:0,31',
+ 'skip' => 'min:0|max:31|numeric',
'active' => [new IsBoolean()],
- 'notes' => 'between:1,65536',
+ 'notes' => 'min:1|max:32768',
];
}
/**
* Configure the validator instance.
- *
- * @param Validator $validator
- *
- * @return void
*/
public function withValidator(Validator $validator): void
{
$validator->after(
- static function (Validator $validator) {
+ static function (Validator $validator): void {
$data = $validator->getData();
if (array_key_exists('amount_min', $data) && array_key_exists('amount_max', $data)) {
$min = $data['amount_min'] ?? '0';
@@ -117,5 +109,8 @@ class UpdateRequest extends FormRequest
}
}
);
+ if ($validator->fails()) {
+ Log::channel('audit')->error(sprintf('Validation errors in %s', __CLASS__), $validator->errors()->toArray());
+ }
}
}
diff --git a/app/Api/V1/Requests/Models/Budget/StoreRequest.php b/app/Api/V1/Requests/Models/Budget/StoreRequest.php
index 78714bb474..243136dd05 100644
--- a/app/Api/V1/Requests/Models/Budget/StoreRequest.php
+++ b/app/Api/V1/Requests/Models/Budget/StoreRequest.php
@@ -24,27 +24,25 @@ declare(strict_types=1);
namespace FireflyIII\Api\V1\Requests\Models\Budget;
use FireflyIII\Rules\IsBoolean;
+use FireflyIII\Rules\IsValidPositiveAmount;
use FireflyIII\Support\Request\ChecksLogin;
use FireflyIII\Support\Request\ConvertsDataTypes;
use FireflyIII\Validation\AutoBudget\ValidatesAutoBudgetRequest;
use Illuminate\Foundation\Http\FormRequest;
+use Illuminate\Support\Facades\Log;
use Illuminate\Validation\Validator;
/**
* Class StoreRequest
- *
-
*/
class StoreRequest extends FormRequest
{
+ use ChecksLogin;
use ConvertsDataTypes;
use ValidatesAutoBudgetRequest;
- use ChecksLogin;
/**
* Get all data from the request.
- *
- * @return array
*/
public function getAll(): array
{
@@ -67,38 +65,35 @@ class StoreRequest extends FormRequest
/**
* The rules that the incoming request must be matched against.
- *
- * @return array
*/
public function rules(): array
{
return [
- 'name' => 'required|between:1,100|uniqueObjectForUser:budgets,name',
+ 'name' => 'required|min:1|max:255|uniqueObjectForUser:budgets,name',
'active' => [new IsBoolean()],
'currency_id' => 'exists:transaction_currencies,id',
'currency_code' => 'exists:transaction_currencies,code',
- 'notes' => 'nullable|between:1,65536',
+ 'notes' => 'nullable|min:1|max:32768',
// auto budget info
'auto_budget_type' => 'in:reset,rollover,adjusted,none',
- 'auto_budget_amount' => 'numeric|min:0|max:1000000000|required_if:auto_budget_type,reset|required_if:auto_budget_type,rollover|required_if:auto_budget_type,adjusted',
+ 'auto_budget_amount' => ['required_if:auto_budget_type,reset', 'required_if:auto_budget_type,rollover', 'required_if:auto_budget_type,adjusted', new IsValidPositiveAmount()],
'auto_budget_period' => 'in:daily,weekly,monthly,quarterly,half_year,yearly|required_if:auto_budget_type,reset|required_if:auto_budget_type,rollover|required_if:auto_budget_type,adjusted',
];
}
/**
* Configure the validator instance with special rules for after the basic validation rules.
- *
- * @param Validator $validator
- *
- * @return void
*/
public function withValidator(Validator $validator): void
{
$validator->after(
- function (Validator $validator) {
+ function (Validator $validator): void {
// validate all account info
$this->validateAutoBudgetAmount($validator);
}
);
+ if ($validator->fails()) {
+ Log::channel('audit')->error(sprintf('Validation errors in %s', __CLASS__), $validator->errors()->toArray());
+ }
}
}
diff --git a/app/Api/V1/Requests/Models/Budget/UpdateRequest.php b/app/Api/V1/Requests/Models/Budget/UpdateRequest.php
index 2fd5e43560..2e8509db61 100644
--- a/app/Api/V1/Requests/Models/Budget/UpdateRequest.php
+++ b/app/Api/V1/Requests/Models/Budget/UpdateRequest.php
@@ -25,27 +25,25 @@ namespace FireflyIII\Api\V1\Requests\Models\Budget;
use FireflyIII\Models\Budget;
use FireflyIII\Rules\IsBoolean;
+use FireflyIII\Rules\IsValidPositiveAmount;
use FireflyIII\Support\Request\ChecksLogin;
use FireflyIII\Support\Request\ConvertsDataTypes;
use FireflyIII\Validation\AutoBudget\ValidatesAutoBudgetRequest;
use Illuminate\Foundation\Http\FormRequest;
+use Illuminate\Support\Facades\Log;
use Illuminate\Validation\Validator;
/**
* Class UpdateRequest
- *
-
*/
class UpdateRequest extends FormRequest
{
+ use ChecksLogin;
use ConvertsDataTypes;
use ValidatesAutoBudgetRequest;
- use ChecksLogin;
/**
* Get all data from the request.
- *
- * @return array
*/
public function getAll(): array
{
@@ -77,8 +75,6 @@ class UpdateRequest extends FormRequest
/**
* The rules that the incoming request must be matched against.
- *
- * @return array
*/
public function rules(): array
{
@@ -86,31 +82,30 @@ class UpdateRequest extends FormRequest
$budget = $this->route()->parameter('budget');
return [
- 'name' => sprintf('between:1,100|uniqueObjectForUser:budgets,name,%d', $budget->id),
+ 'name' => sprintf('min:1|max:100|uniqueObjectForUser:budgets,name,%d', $budget->id),
'active' => [new IsBoolean()],
- 'notes' => 'nullable|between:1,65536',
+ 'notes' => 'nullable|min:1|max:32768',
'auto_budget_type' => 'in:reset,rollover,adjusted,none',
'auto_budget_currency_id' => 'exists:transaction_currencies,id',
'auto_budget_currency_code' => 'exists:transaction_currencies,code',
- 'auto_budget_amount' => 'min:0|max:1000000000',
+ 'auto_budget_amount' => ['nullable', new IsValidPositiveAmount()],
'auto_budget_period' => 'in:daily,weekly,monthly,quarterly,half_year,yearly',
];
}
/**
* Configure the validator instance with special rules for after the basic validation rules.
- *
- * @param Validator $validator
- *
- * @return void
*/
public function withValidator(Validator $validator): void
{
$validator->after(
- function (Validator $validator) {
+ function (Validator $validator): void {
// validate all account info
$this->validateAutoBudgetAmount($validator);
}
);
+ if ($validator->fails()) {
+ Log::channel('audit')->error(sprintf('Validation errors in %s', __CLASS__), $validator->errors()->toArray());
+ }
}
}
diff --git a/app/Api/V1/Requests/Models/BudgetLimit/StoreRequest.php b/app/Api/V1/Requests/Models/BudgetLimit/StoreRequest.php
index 1c003221ef..a47e705ff8 100644
--- a/app/Api/V1/Requests/Models/BudgetLimit/StoreRequest.php
+++ b/app/Api/V1/Requests/Models/BudgetLimit/StoreRequest.php
@@ -23,24 +23,21 @@ declare(strict_types=1);
namespace FireflyIII\Api\V1\Requests\Models\BudgetLimit;
+use FireflyIII\Rules\IsValidPositiveAmount;
use FireflyIII\Support\Request\ChecksLogin;
use FireflyIII\Support\Request\ConvertsDataTypes;
use Illuminate\Foundation\Http\FormRequest;
/**
* Class StoreRequest
- *
-
*/
class StoreRequest extends FormRequest
{
- use ConvertsDataTypes;
use ChecksLogin;
+ use ConvertsDataTypes;
/**
* Get all data from the request.
- *
- * @return array
*/
public function getAll(): array
{
@@ -55,15 +52,13 @@ class StoreRequest extends FormRequest
/**
* The rules that the incoming request must be matched against.
- *
- * @return array
*/
public function rules(): array
{
return [
'start' => 'required|before:end|date',
'end' => 'required|after:start|date',
- 'amount' => 'required|gt:0',
+ 'amount' => ['required', new IsValidPositiveAmount()],
'currency_id' => 'numeric|exists:transaction_currencies,id',
'currency_code' => 'min:3|max:51|exists:transaction_currencies,code',
];
diff --git a/app/Api/V1/Requests/Models/BudgetLimit/UpdateRequest.php b/app/Api/V1/Requests/Models/BudgetLimit/UpdateRequest.php
index 4df2b88936..67060a6dd2 100644
--- a/app/Api/V1/Requests/Models/BudgetLimit/UpdateRequest.php
+++ b/app/Api/V1/Requests/Models/BudgetLimit/UpdateRequest.php
@@ -24,25 +24,23 @@ declare(strict_types=1);
namespace FireflyIII\Api\V1\Requests\Models\BudgetLimit;
use Carbon\Carbon;
+use FireflyIII\Rules\IsValidPositiveAmount;
use FireflyIII\Support\Request\ChecksLogin;
use FireflyIII\Support\Request\ConvertsDataTypes;
use Illuminate\Foundation\Http\FormRequest;
+use Illuminate\Support\Facades\Log;
use Illuminate\Validation\Validator;
/**
* Class UpdateRequest
- *
-
*/
class UpdateRequest extends FormRequest
{
- use ConvertsDataTypes;
use ChecksLogin;
+ use ConvertsDataTypes;
/**
* Get all data from the request.
- *
- * @return array
*/
public function getAll(): array
{
@@ -59,15 +57,13 @@ class UpdateRequest extends FormRequest
/**
* The rules that the incoming request must be matched against.
- *
- * @return array
*/
public function rules(): array
{
return [
'start' => 'date',
'end' => 'date',
- 'amount' => 'gt:0',
+ 'amount' => ['nullable', new IsValidPositiveAmount()],
'currency_id' => 'numeric|exists:transaction_currencies,id',
'currency_code' => 'min:3|max:51|exists:transaction_currencies,code',
];
@@ -75,16 +71,12 @@ class UpdateRequest extends FormRequest
/**
* Configure the validator instance with special rules for after the basic validation rules.
- *
- * @param Validator $validator
- * TODO duplicate code
- *
- * @return void
+ * TODO duplicate code.
*/
public function withValidator(Validator $validator): void
{
$validator->after(
- function (Validator $validator) {
+ static function (Validator $validator): void {
// validate start before end only if both are there.
$data = $validator->getData();
if (array_key_exists('start', $data) && array_key_exists('end', $data)) {
@@ -96,5 +88,8 @@ class UpdateRequest extends FormRequest
}
}
);
+ if ($validator->fails()) {
+ Log::channel('audit')->error(sprintf('Validation errors in %s', __CLASS__), $validator->errors()->toArray());
+ }
}
}
diff --git a/app/Api/V1/Requests/Models/Category/StoreRequest.php b/app/Api/V1/Requests/Models/Category/StoreRequest.php
index 5bff239013..a1cc9268de 100644
--- a/app/Api/V1/Requests/Models/Category/StoreRequest.php
+++ b/app/Api/V1/Requests/Models/Category/StoreRequest.php
@@ -23,25 +23,20 @@ declare(strict_types=1);
namespace FireflyIII\Api\V1\Requests\Models\Category;
-use FireflyIII\Rules\ZeroOrMore;
use FireflyIII\Support\Request\ChecksLogin;
use FireflyIII\Support\Request\ConvertsDataTypes;
use Illuminate\Foundation\Http\FormRequest;
/**
* Class StoreRequest
- *
-
*/
class StoreRequest extends FormRequest
{
- use ConvertsDataTypes;
use ChecksLogin;
+ use ConvertsDataTypes;
/**
* Get all data from the request.
- *
- * @return array
*/
public function getAll(): array
{
@@ -53,13 +48,11 @@ class StoreRequest extends FormRequest
/**
* The rules that the incoming request must be matched against.
- *
- * @return array
*/
public function rules(): array
{
return [
- 'name' => 'required|between:1,100|uniqueObjectForUser:categories,name',
+ 'name' => 'required|min:1|max:100|uniqueObjectForUser:categories,name',
];
}
}
diff --git a/app/Api/V1/Requests/Models/Category/UpdateRequest.php b/app/Api/V1/Requests/Models/Category/UpdateRequest.php
index aaaf9bfde1..48653cf597 100644
--- a/app/Api/V1/Requests/Models/Category/UpdateRequest.php
+++ b/app/Api/V1/Requests/Models/Category/UpdateRequest.php
@@ -30,18 +30,14 @@ use Illuminate\Foundation\Http\FormRequest;
/**
* Class UpdateRequest
- *
-
*/
class UpdateRequest extends FormRequest
{
- use ConvertsDataTypes;
use ChecksLogin;
+ use ConvertsDataTypes;
/**
* Get all data from the request.
- *
- * @return array
*/
public function getAll(): array
{
@@ -55,8 +51,6 @@ class UpdateRequest extends FormRequest
/**
* The rules that the incoming request must be matched against.
- *
- * @return array
*/
public function rules(): array
{
@@ -64,7 +58,7 @@ class UpdateRequest extends FormRequest
$category = $this->route()->parameter('category');
return [
- 'name' => sprintf('between:1,100|uniqueObjectForUser:categories,name,%d', $category->id),
+ 'name' => sprintf('min:1|max:100|uniqueObjectForUser:categories,name,%d', $category->id),
];
}
}
diff --git a/app/Api/V1/Requests/Models/ObjectGroup/UpdateRequest.php b/app/Api/V1/Requests/Models/ObjectGroup/UpdateRequest.php
index 9a9f96d8da..17b5a41e16 100644
--- a/app/Api/V1/Requests/Models/ObjectGroup/UpdateRequest.php
+++ b/app/Api/V1/Requests/Models/ObjectGroup/UpdateRequest.php
@@ -31,17 +31,12 @@ use Illuminate\Foundation\Http\FormRequest;
/**
* Class UpdateRequest
- *
-
*/
class UpdateRequest extends FormRequest
{
- use ConvertsDataTypes;
use ChecksLogin;
+ use ConvertsDataTypes;
- /**
- * @return array
- */
public function getUpdateData(): array
{
$fields = [
@@ -54,8 +49,6 @@ class UpdateRequest extends FormRequest
/**
* The rules that the incoming request must be matched against.
- *
- * @return array
*/
public function rules(): array
{
diff --git a/app/Api/V1/Requests/Models/PiggyBank/StoreRequest.php b/app/Api/V1/Requests/Models/PiggyBank/StoreRequest.php
index d737a7e00e..f6069a68ed 100644
--- a/app/Api/V1/Requests/Models/PiggyBank/StoreRequest.php
+++ b/app/Api/V1/Requests/Models/PiggyBank/StoreRequest.php
@@ -23,24 +23,21 @@ declare(strict_types=1);
namespace FireflyIII\Api\V1\Requests\Models\PiggyBank;
+use FireflyIII\Rules\IsValidPositiveAmount;
use FireflyIII\Support\Request\ChecksLogin;
use FireflyIII\Support\Request\ConvertsDataTypes;
use Illuminate\Foundation\Http\FormRequest;
/**
* Class StoreRequest
- *
-
*/
class StoreRequest extends FormRequest
{
- use ConvertsDataTypes;
use ChecksLogin;
+ use ConvertsDataTypes;
/**
* Get all data from the request.
- *
- * @return array
*/
public function getAll(): array
{
@@ -63,18 +60,16 @@ class StoreRequest extends FormRequest
/**
* The rules that the incoming request must be matched against.
- *
- * @return array
*/
public function rules(): array
{
return [
- 'name' => 'required|between:1,255|uniquePiggyBankForUser',
- 'current_amount' => ['numeric', 'gte:0', 'lte:target_amount'],
+ 'name' => 'required|min:1|max:255|uniquePiggyBankForUser',
+ 'current_amount' => ['nullable', new IsValidPositiveAmount()],
'account_id' => 'required|numeric|belongsToUser:accounts,id',
'object_group_id' => 'numeric|belongsToUser:object_groups,id',
- 'object_group_title' => 'between:1,255',
- 'target_amount' => ['numeric', 'gte:0', 'lte:target_amount', 'required'],
+ 'object_group_title' => ['min:1', 'max:255'],
+ 'target_amount' => ['required', new IsValidPositiveAmount()],
'start_date' => 'date|nullable',
'target_date' => 'date|nullable|after:start_date',
'notes' => 'max:65000',
diff --git a/app/Api/V1/Requests/Models/PiggyBank/UpdateRequest.php b/app/Api/V1/Requests/Models/PiggyBank/UpdateRequest.php
index 7eb4ae1dba..a169e0434c 100644
--- a/app/Api/V1/Requests/Models/PiggyBank/UpdateRequest.php
+++ b/app/Api/V1/Requests/Models/PiggyBank/UpdateRequest.php
@@ -25,6 +25,7 @@ namespace FireflyIII\Api\V1\Requests\Models\PiggyBank;
use FireflyIII\Models\PiggyBank;
use FireflyIII\Rules\IsAssetAccountId;
+use FireflyIII\Rules\IsValidPositiveAmount;
use FireflyIII\Rules\LessThanPiggyTarget;
use FireflyIII\Support\Request\ChecksLogin;
use FireflyIII\Support\Request\ConvertsDataTypes;
@@ -32,18 +33,14 @@ use Illuminate\Foundation\Http\FormRequest;
/**
* Class UpdateRequest
- *
-
*/
class UpdateRequest extends FormRequest
{
- use ConvertsDataTypes;
use ChecksLogin;
+ use ConvertsDataTypes;
/**
* Get all data from the request.
- *
- * @return array
*/
public function getAll(): array
{
@@ -65,8 +62,6 @@ class UpdateRequest extends FormRequest
/**
* The rules that the incoming request must be matched against.
- *
- * @return array
*/
public function rules(): array
{
@@ -74,9 +69,9 @@ class UpdateRequest extends FormRequest
$piggyBank = $this->route()->parameter('piggyBank');
return [
- 'name' => 'between:1,255|uniquePiggyBankForUser:' . $piggyBank->id,
- 'current_amount' => ['numeric', 'gte:0', new LessThanPiggyTarget()],
- 'target_amount' => 'numeric|gte:0',
+ 'name' => 'min:1|max:255|uniquePiggyBankForUser:'.$piggyBank->id,
+ 'current_amount' => ['nullable', new LessThanPiggyTarget(), new IsValidPositiveAmount()],
+ 'target_amount' => ['nullable', new IsValidPositiveAmount()],
'start_date' => 'date|nullable',
'target_date' => 'date|nullable|after:start_date',
'notes' => 'max:65000',
diff --git a/app/Api/V1/Requests/Models/Recurrence/StoreRequest.php b/app/Api/V1/Requests/Models/Recurrence/StoreRequest.php
index bfd273969d..e6f9b52d28 100644
--- a/app/Api/V1/Requests/Models/Recurrence/StoreRequest.php
+++ b/app/Api/V1/Requests/Models/Recurrence/StoreRequest.php
@@ -25,6 +25,7 @@ namespace FireflyIII\Api\V1\Requests\Models\Recurrence;
use FireflyIII\Rules\BelongsUser;
use FireflyIII\Rules\IsBoolean;
+use FireflyIII\Rules\IsValidPositiveAmount;
use FireflyIII\Support\Request\ChecksLogin;
use FireflyIII\Support\Request\ConvertsDataTypes;
use FireflyIII\Support\Request\GetRecurrenceData;
@@ -32,6 +33,7 @@ use FireflyIII\Validation\CurrencyValidation;
use FireflyIII\Validation\RecurrenceValidation;
use FireflyIII\Validation\TransactionValidation;
use Illuminate\Foundation\Http\FormRequest;
+use Illuminate\Support\Facades\Log;
use Illuminate\Validation\Validator;
/**
@@ -39,17 +41,15 @@ use Illuminate\Validation\Validator;
*/
class StoreRequest extends FormRequest
{
+ use ChecksLogin;
use ConvertsDataTypes;
- use RecurrenceValidation;
- use TransactionValidation;
use CurrencyValidation;
use GetRecurrenceData;
- use ChecksLogin;
+ use RecurrenceValidation;
+ use TransactionValidation;
/**
* Get all data from the request.
- *
- * @return array
*/
public function getAll(): array
{
@@ -76,18 +76,18 @@ class StoreRequest extends FormRequest
/**
* Returns the transaction data as it is found in the submitted data. It's a complex method according to code
* standards but it just has a lot of ??-statements because of the fields that may or may not exist.
- *
- * @return array
*/
private function getTransactionData(): array
{
- $return = [];
+ $return = [];
+
// transaction data:
- /** @var array|null $transactions */
+ /** @var null|array $transactions */
$transactions = $this->get('transactions');
if (null === $transactions) {
return [];
}
+
/** @var array $transaction */
foreach ($transactions as $transaction) {
$return[] = $this->getSingleTransactionData($transaction);
@@ -98,21 +98,21 @@ class StoreRequest extends FormRequest
/**
* Returns the repetition data as it is found in the submitted data.
- *
- * @return array
*/
private function getRepetitionData(): array
{
- $return = [];
+ $return = [];
+
// repetition data:
- /** @var array|null $repetitions */
+ /** @var null|array $repetitions */
$repetitions = $this->get('repetitions');
if (null === $repetitions) {
return [];
}
+
/** @var array $repetition */
foreach ($repetitions as $repetition) {
- $current = [];
+ $current = [];
if (array_key_exists('type', $repetition)) {
$current['type'] = $repetition['type'];
}
@@ -134,60 +134,54 @@ class StoreRequest extends FormRequest
/**
* The rules that the incoming request must be matched against.
- *
- * @return array
*/
public function rules(): array
{
return [
- 'type' => 'required|in:withdrawal,transfer,deposit',
- 'title' => 'required|between:1,255|uniqueObjectForUser:recurrences,title',
- 'description' => 'between:1,65000',
- 'first_date' => 'required|date',
- 'apply_rules' => [new IsBoolean()],
- 'active' => [new IsBoolean()],
- 'repeat_until' => 'nullable|date',
- 'nr_of_repetitions' => 'nullable|numeric|between:1,31',
+ 'type' => 'required|in:withdrawal,transfer,deposit',
+ 'title' => 'required|min:1|max:255|uniqueObjectForUser:recurrences,title',
+ 'description' => 'min:1|max:32768',
+ 'first_date' => 'required|date',
+ 'apply_rules' => [new IsBoolean()],
+ 'active' => [new IsBoolean()],
+ 'repeat_until' => 'nullable|date',
+ 'nr_of_repetitions' => 'nullable|numeric|min:1|max:31',
- 'repetitions.*.type' => 'required|in:daily,weekly,ndom,monthly,yearly',
- 'repetitions.*.moment' => 'between:0,10',
- 'repetitions.*.skip' => 'nullable|numeric|between:0,31',
- 'repetitions.*.weekend' => 'numeric|min:1|max:4',
+ 'repetitions.*.type' => 'required|in:daily,weekly,ndom,monthly,yearly',
+ 'repetitions.*.moment' => 'min:0|max:10',
+ 'repetitions.*.skip' => 'nullable|numeric|min:0|max:31',
+ 'repetitions.*.weekend' => 'numeric|min:1|max:4',
- 'transactions.*.description' => 'required|between:1,255',
- 'transactions.*.amount' => 'required|numeric|gt:0',
- 'transactions.*.foreign_amount' => 'nullable|numeric|gt:0',
+ 'transactions.*.description' => 'required|min:1|max:255',
+ 'transactions.*.amount' => ['required', new IsValidPositiveAmount()],
+ 'transactions.*.foreign_amount' => ['nullable', new IsValidPositiveAmount()],
'transactions.*.currency_id' => 'nullable|numeric|exists:transaction_currencies,id',
'transactions.*.currency_code' => 'nullable|min:3|max:51|exists:transaction_currencies,code',
'transactions.*.foreign_currency_id' => 'nullable|numeric|exists:transaction_currencies,id',
'transactions.*.foreign_currency_code' => 'nullable|min:3|max:51|exists:transaction_currencies,code',
'transactions.*.source_id' => ['numeric', 'nullable', new BelongsUser()],
- 'transactions.*.source_name' => 'between:1,255|nullable',
+ 'transactions.*.source_name' => 'min:1|max:255|nullable',
'transactions.*.destination_id' => ['numeric', 'nullable', new BelongsUser()],
- 'transactions.*.destination_name' => 'between:1,255|nullable',
+ 'transactions.*.destination_name' => 'min:1|max:255|nullable',
// new and updated fields:
'transactions.*.budget_id' => ['nullable', 'mustExist:budgets,id', new BelongsUser()],
- 'transactions.*.budget_name' => ['between:1,255', 'nullable', new BelongsUser()],
+ 'transactions.*.budget_name' => ['min:1', 'max:255', 'nullable', new BelongsUser()],
'transactions.*.category_id' => ['nullable', 'mustExist:categories,id', new BelongsUser()],
- 'transactions.*.category_name' => 'between:1,255|nullable',
+ 'transactions.*.category_name' => 'min:1|max:255|nullable',
'transactions.*.piggy_bank_id' => ['nullable', 'numeric', 'mustExist:piggy_banks,id', new BelongsUser()],
- 'transactions.*.piggy_bank_name' => ['between:1,255', 'nullable', new BelongsUser()],
- 'transactions.*.tags' => 'nullable|between:1,64000',
+ 'transactions.*.piggy_bank_name' => ['min:1', 'max:255', 'nullable', new BelongsUser()],
+ 'transactions.*.tags' => 'nullable|min:1|max:255',
];
}
/**
* Configure the validator instance.
- *
- * @param Validator $validator
- *
- * @return void
*/
public function withValidator(Validator $validator): void
{
$validator->after(
- function (Validator $validator) {
+ function (Validator $validator): void {
$this->validateRecurringConfig($validator);
$this->validateOneRecurrenceTransaction($validator);
$this->validateOneRepetition($validator);
@@ -197,5 +191,8 @@ class StoreRequest extends FormRequest
$this->validateAccountInformation($validator);
}
);
+ if ($validator->fails()) {
+ Log::channel('audit')->error(sprintf('Validation errors in %s', __CLASS__), $validator->errors()->toArray());
+ }
}
}
diff --git a/app/Api/V1/Requests/Models/Recurrence/UpdateRequest.php b/app/Api/V1/Requests/Models/Recurrence/UpdateRequest.php
index 8d5f790c4c..6bc7913069 100644
--- a/app/Api/V1/Requests/Models/Recurrence/UpdateRequest.php
+++ b/app/Api/V1/Requests/Models/Recurrence/UpdateRequest.php
@@ -26,6 +26,7 @@ namespace FireflyIII\Api\V1\Requests\Models\Recurrence;
use FireflyIII\Models\Recurrence;
use FireflyIII\Rules\BelongsUser;
use FireflyIII\Rules\IsBoolean;
+use FireflyIII\Rules\IsValidPositiveAmount;
use FireflyIII\Support\Request\ChecksLogin;
use FireflyIII\Support\Request\ConvertsDataTypes;
use FireflyIII\Support\Request\GetRecurrenceData;
@@ -33,6 +34,7 @@ use FireflyIII\Validation\CurrencyValidation;
use FireflyIII\Validation\RecurrenceValidation;
use FireflyIII\Validation\TransactionValidation;
use Illuminate\Foundation\Http\FormRequest;
+use Illuminate\Support\Facades\Log;
use Illuminate\Validation\Validator;
/**
@@ -40,22 +42,20 @@ use Illuminate\Validation\Validator;
*/
class UpdateRequest extends FormRequest
{
+ use ChecksLogin;
use ConvertsDataTypes;
- use RecurrenceValidation;
- use TransactionValidation;
use CurrencyValidation;
use GetRecurrenceData;
- use ChecksLogin;
+ use RecurrenceValidation;
+ use TransactionValidation;
/**
* Get all data from the request.
- *
- * @return array
*/
public function getAll(): array
{
// this is the way:
- $fields = [
+ $fields = [
'title' => ['title', 'convertString'],
'description' => ['description', 'convertString'],
'first_date' => ['first_date', 'convertDateTime'],
@@ -65,38 +65,36 @@ class UpdateRequest extends FormRequest
'active' => ['active', 'boolean'],
'notes' => ['notes', 'convertString'],
];
- $reps = $this->getRepetitionData();
- $transactions = $this->getTransactionData();
- $return = [
+ $reps = $this->getRepetitionData();
+ $transactions = $this->getTransactionData();
+ $return = [
'recurrence' => $this->getAllData($fields),
];
if (null !== $reps) {
$return['repetitions'] = $reps;
}
- if (null !== $transactions) {
- $return['transactions'] = $transactions;
- }
+ $return['transactions'] = $transactions;
return $return;
}
/**
* Returns the repetition data as it is found in the submitted data.
- *
- * @return array|null
*/
private function getRepetitionData(): ?array
{
- $return = [];
+ $return = [];
+
// repetition data:
- /** @var array|null $repetitions */
+ /** @var null|array $repetitions */
$repetitions = $this->get('repetitions');
if (null === $repetitions) {
return null;
}
+
/** @var array $repetition */
foreach ($repetitions as $repetition) {
- $current = [];
+ $current = [];
if (array_key_exists('type', $repetition)) {
$current['type'] = $repetition['type'];
}
@@ -124,18 +122,18 @@ class UpdateRequest extends FormRequest
/**
* Returns the transaction data as it is found in the submitted data. It's a complex method according to code
* standards but it just has a lot of ??-statements because of the fields that may or may not exist.
- *
- * @return array|null
*/
- private function getTransactionData(): ?array
+ private function getTransactionData(): array
{
- $return = [];
+ $return = [];
+
// transaction data:
- /** @var array|null $transactions */
+ /** @var null|array $transactions */
$transactions = $this->get('transactions');
if (null === $transactions) {
- return null;
+ return [];
}
+
/** @var array $transaction */
foreach ($transactions as $transaction) {
$return[] = $this->getSingleTransactionData($transaction);
@@ -146,8 +144,6 @@ class UpdateRequest extends FormRequest
/**
* The rules that the incoming request must be matched against.
- *
- * @return array
*/
public function rules(): array
{
@@ -155,57 +151,51 @@ class UpdateRequest extends FormRequest
$recurrence = $this->route()->parameter('recurrence');
return [
- 'title' => sprintf('between:1,255|uniqueObjectForUser:recurrences,title,%d', $recurrence->id),
- 'description' => 'between:1,65000',
- 'first_date' => 'date',
- 'apply_rules' => [new IsBoolean()],
- 'active' => [new IsBoolean()],
- 'repeat_until' => 'nullable|date',
- 'nr_of_repetitions' => 'nullable|numeric|between:1,31',
+ 'title' => sprintf('min:1|max:255|uniqueObjectForUser:recurrences,title,%d', $recurrence->id),
+ 'description' => 'min:1|max:32768',
+ 'first_date' => 'date',
+ 'apply_rules' => [new IsBoolean()],
+ 'active' => [new IsBoolean()],
+ 'repeat_until' => 'nullable|date',
+ 'nr_of_repetitions' => 'nullable|numeric|min:1|max:31',
- 'repetitions.*.type' => 'in:daily,weekly,ndom,monthly,yearly',
- 'repetitions.*.moment' => 'between:0,10',
- 'repetitions.*.skip' => 'nullable|numeric|between:0,31',
- 'repetitions.*.weekend' => 'nullable|numeric|min:1|max:4',
+ 'repetitions.*.type' => 'in:daily,weekly,ndom,monthly,yearly',
+ 'repetitions.*.moment' => 'min:0|max:10|numeric',
+ 'repetitions.*.skip' => 'nullable|numeric|min:0|max:31',
+ 'repetitions.*.weekend' => 'nullable|numeric|min:1|max:4',
- 'transactions.*.description' => 'between:1,255',
- 'transactions.*.amount' => 'numeric|gt:0',
- 'transactions.*.foreign_amount' => 'nullable|numeric|gt:0',
+ 'transactions.*.description' => ['min:1', 'max:255'],
+ 'transactions.*.amount' => [new IsValidPositiveAmount()],
+ 'transactions.*.foreign_amount' => ['nullable', new IsValidPositiveAmount()],
'transactions.*.currency_id' => 'nullable|numeric|exists:transaction_currencies,id',
'transactions.*.currency_code' => 'nullable|min:3|max:51|exists:transaction_currencies,code',
'transactions.*.foreign_currency_id' => 'nullable|numeric|exists:transaction_currencies,id',
'transactions.*.foreign_currency_code' => 'nullable|min:3|max:51|exists:transaction_currencies,code',
'transactions.*.source_id' => ['numeric', 'nullable', new BelongsUser()],
- 'transactions.*.source_name' => 'between:1,255|nullable',
+ 'transactions.*.source_name' => 'min:1|max:255|nullable',
'transactions.*.destination_id' => ['numeric', 'nullable', new BelongsUser()],
- 'transactions.*.destination_name' => 'between:1,255|nullable',
+ 'transactions.*.destination_name' => 'min:1|max:255|nullable',
// new and updated fields:
'transactions.*.budget_id' => ['nullable', 'mustExist:budgets,id', new BelongsUser()],
- 'transactions.*.budget_name' => ['between:1,255', 'nullable', new BelongsUser()],
+ 'transactions.*.budget_name' => ['min:1', 'max:255', 'nullable', new BelongsUser()],
'transactions.*.category_id' => ['nullable', 'mustExist:categories,id', new BelongsUser()],
- 'transactions.*.category_name' => 'between:1,255|nullable',
+ 'transactions.*.category_name' => 'min:1|max:255|nullable',
'transactions.*.piggy_bank_id' => ['nullable', 'numeric', 'mustExist:piggy_banks,id', new BelongsUser()],
- 'transactions.*.piggy_bank_name' => ['between:1,255', 'nullable', new BelongsUser()],
- 'transactions.*.tags' => 'nullable|between:1,64000',
-
+ 'transactions.*.piggy_bank_name' => ['min:1', 'max:255', 'nullable', new BelongsUser()],
+ 'transactions.*.tags' => 'nullable|min:1|max:255',
];
}
/**
* Configure the validator instance.
- *
- * @param Validator $validator
- *
- * @return void
*/
public function withValidator(Validator $validator): void
{
$validator->after(
- function (Validator $validator) {
- //$this->validateOneRecurrenceTransaction($validator);
- //$this->validateOneRepetitionUpdate($validator);
-
+ function (Validator $validator): void {
+ // $this->validateOneRecurrenceTransaction($validator);
+ // $this->validateOneRepetitionUpdate($validator);
/** @var Recurrence $recurrence */
$recurrence = $this->route()->parameter('recurrence');
@@ -216,6 +206,8 @@ class UpdateRequest extends FormRequest
$this->valUpdateAccountInfo($validator);
}
);
+ if ($validator->fails()) {
+ Log::channel('audit')->error(sprintf('Validation errors in %s', __CLASS__), $validator->errors()->toArray());
+ }
}
-
}
diff --git a/app/Api/V1/Requests/Models/Rule/StoreRequest.php b/app/Api/V1/Requests/Models/Rule/StoreRequest.php
index 2b241f0e96..dff5c76d8d 100644
--- a/app/Api/V1/Requests/Models/Rule/StoreRequest.php
+++ b/app/Api/V1/Requests/Models/Rule/StoreRequest.php
@@ -28,27 +28,24 @@ use FireflyIII\Support\Request\ChecksLogin;
use FireflyIII\Support\Request\ConvertsDataTypes;
use FireflyIII\Support\Request\GetRuleConfiguration;
use Illuminate\Foundation\Http\FormRequest;
+use Illuminate\Support\Facades\Log;
use Illuminate\Validation\Validator;
-use function is_array;
-
/**
* Class StoreRequest
*/
class StoreRequest extends FormRequest
{
+ use ChecksLogin;
use ConvertsDataTypes;
use GetRuleConfiguration;
- use ChecksLogin;
/**
* Get all data from the request.
- *
- * @return array
*/
public function getAll(): array
{
- $fields = [
+ $fields = [
'title' => ['title', 'convertString'],
'description' => ['description', 'convertString'],
'rule_group_id' => ['rule_group_id', 'convertInteger'],
@@ -59,7 +56,7 @@ class StoreRequest extends FormRequest
'stop_processing' => ['stop_processing', 'boolean'],
'active' => ['active', 'boolean'],
];
- $data = $this->getAllData($fields);
+ $data = $this->getAllData($fields);
$data['triggers'] = $this->getRuleTriggers();
$data['actions'] = $this->getRuleActions();
@@ -67,9 +64,6 @@ class StoreRequest extends FormRequest
return $data;
}
- /**
- * @return array
- */
private function getRuleTriggers(): array
{
$triggers = $this->get('triggers');
@@ -88,9 +82,6 @@ class StoreRequest extends FormRequest
return $return;
}
- /**
- * @return array
- */
private function getRuleActions(): array
{
$actions = $this->get('actions');
@@ -111,30 +102,28 @@ class StoreRequest extends FormRequest
/**
* The rules that the incoming request must be matched against.
- *
- * @return array
*/
public function rules(): array
{
- $validTriggers = $this->getTriggers();
- $validActions = array_keys(config('firefly.rule-actions'));
+ $validTriggers = $this->getTriggers();
+ $validActions = array_keys(config('firefly.rule-actions'));
// some triggers and actions require text:
$contextTriggers = implode(',', $this->getTriggersWithContext());
$contextActions = implode(',', config('firefly.context-rule-actions'));
return [
- 'title' => 'required|between:1,100|uniqueObjectForUser:rules,title',
- 'description' => 'between:1,5000|nullable',
+ 'title' => 'required|min:1|max:100|uniqueObjectForUser:rules,title',
+ 'description' => 'min:1|max:32768|nullable',
'rule_group_id' => 'belongsToUser:rule_groups|required_without:rule_group_title',
- 'rule_group_title' => 'nullable|between:1,255|required_without:rule_group_id|belongsToUser:rule_groups,title',
+ 'rule_group_title' => 'nullable|min:1|max:255|required_without:rule_group_id|belongsToUser:rule_groups,title',
'trigger' => 'required|in:store-journal,update-journal',
- 'triggers.*.type' => 'required|in:' . implode(',', $validTriggers),
- 'triggers.*.value' => 'required_if:actions.*.type,' . $contextTriggers . '|min:1|ruleTriggerValue|max:1024',
+ 'triggers.*.type' => 'required|in:'.implode(',', $validTriggers),
+ 'triggers.*.value' => 'required_if:actions.*.type,'.$contextTriggers.'|min:1|ruleTriggerValue|max:1024',
'triggers.*.stop_processing' => [new IsBoolean()],
'triggers.*.active' => [new IsBoolean()],
- 'actions.*.type' => 'required|in:' . implode(',', $validActions),
- 'actions.*.value' => 'required_if:actions.*.type,' . $contextActions . '|ruleActionValue',
+ 'actions.*.type' => 'required|in:'.implode(',', $validActions),
+ 'actions.*.value' => 'required_if:actions.*.type,'.$contextActions.'|ruleActionValue',
'actions.*.stop_processing' => [new IsBoolean()],
'actions.*.active' => [new IsBoolean()],
'strict' => [new IsBoolean()],
@@ -145,27 +134,24 @@ class StoreRequest extends FormRequest
/**
* Configure the validator instance.
- *
- * @param Validator $validator
- *
- * @return void
*/
public function withValidator(Validator $validator): void
{
$validator->after(
- function (Validator $validator) {
+ function (Validator $validator): void {
$this->atLeastOneTrigger($validator);
$this->atLeastOneAction($validator);
$this->atLeastOneActiveTrigger($validator);
$this->atLeastOneActiveAction($validator);
}
);
+ if ($validator->fails()) {
+ Log::channel('audit')->error(sprintf('Validation errors in %s', __CLASS__), $validator->errors()->toArray());
+ }
}
/**
* Adds an error to the validator when there are no triggers in the array of data.
- *
- * @param Validator $validator
*/
protected function atLeastOneTrigger(Validator $validator): void
{
@@ -179,8 +165,6 @@ class StoreRequest extends FormRequest
/**
* Adds an error to the validator when there are no repetitions in the array of data.
- *
- * @param Validator $validator
*/
protected function atLeastOneAction(Validator $validator): void
{
@@ -194,13 +178,13 @@ class StoreRequest extends FormRequest
/**
* Adds an error to the validator when there are no ACTIVE triggers in the array of data.
- *
- * @param Validator $validator
*/
protected function atLeastOneActiveTrigger(Validator $validator): void
{
- $data = $validator->getData();
- $triggers = $data['triggers'] ?? [];
+ $data = $validator->getData();
+
+ /** @var null|array|int|string $triggers */
+ $triggers = $data['triggers'] ?? [];
// need at least one trigger
if (!is_countable($triggers) || 0 === count($triggers)) {
return;
@@ -223,13 +207,13 @@ class StoreRequest extends FormRequest
/**
* Adds an error to the validator when there are no ACTIVE actions in the array of data.
- *
- * @param Validator $validator
*/
protected function atLeastOneActiveAction(Validator $validator): void
{
- $data = $validator->getData();
- $actions = $data['actions'] ?? [];
+ $data = $validator->getData();
+
+ /** @var null|array|int|string $actions */
+ $actions = $data['actions'] ?? [];
// need at least one trigger
if (!is_countable($actions) || 0 === count($actions)) {
return;
diff --git a/app/Api/V1/Requests/Models/Rule/TestRequest.php b/app/Api/V1/Requests/Models/Rule/TestRequest.php
index 331c4922c3..1b081e2e88 100644
--- a/app/Api/V1/Requests/Models/Rule/TestRequest.php
+++ b/app/Api/V1/Requests/Models/Rule/TestRequest.php
@@ -34,12 +34,9 @@ use Illuminate\Foundation\Http\FormRequest;
*/
class TestRequest extends FormRequest
{
- use ConvertsDataTypes;
use ChecksLogin;
+ use ConvertsDataTypes;
- /**
- * @return array
- */
public function getTestParameters(): array
{
return [
@@ -47,39 +44,34 @@ class TestRequest extends FormRequest
'start' => $this->getDate('start'),
'end' => $this->getDate('end'),
'accounts' => $this->getAccounts(),
-
];
}
- /**
- * @return int
- */
private function getPage(): int
{
return 0 === (int)$this->query('page') ? 1 : (int)$this->query('page');
}
- /**
- * @param string $field
- *
- * @return Carbon|null
- */
private function getDate(string $field): ?Carbon
{
- return null === $this->query($field) ? null : Carbon::createFromFormat('Y-m-d', $this->query($field));
+ $value = $this->query($field);
+ if (is_array($value)) {
+ return null;
+ }
+ $value = (string)$value;
+ $result = null === $this->query($field) ? null : Carbon::createFromFormat('Y-m-d', substr($value, 0, 10));
+ if (false === $result) {
+ return null;
+ }
+
+ return $result;
}
- /**
- * @return array
- */
private function getAccounts(): array
{
return $this->get('accounts');
}
- /**
- * @return array
- */
public function rules(): array
{
return [
diff --git a/app/Api/V1/Requests/Models/Rule/TriggerRequest.php b/app/Api/V1/Requests/Models/Rule/TriggerRequest.php
index 12785842c1..f0ccc1b0b5 100644
--- a/app/Api/V1/Requests/Models/Rule/TriggerRequest.php
+++ b/app/Api/V1/Requests/Models/Rule/TriggerRequest.php
@@ -34,12 +34,9 @@ use Illuminate\Foundation\Http\FormRequest;
*/
class TriggerRequest extends FormRequest
{
- use ConvertsDataTypes;
use ChecksLogin;
+ use ConvertsDataTypes;
- /**
- * @return array
- */
public function getTriggerParameters(): array
{
return [
@@ -49,27 +46,26 @@ class TriggerRequest extends FormRequest
];
}
- /**
- * @param string $field
- *
- * @return Carbon|null
- */
private function getDate(string $field): ?Carbon
{
- return null === $this->query($field) ? null : Carbon::createFromFormat('Y-m-d', substr($this->query($field), 0, 10));
+ $value = $this->query($field);
+ if (is_array($value)) {
+ return null;
+ }
+ $value = (string)$value;
+ $result = null === $this->query($field) ? null : Carbon::createFromFormat('Y-m-d', substr($value, 0, 10));
+ if (false === $result) {
+ return null;
+ }
+
+ return $result;
}
- /**
- * @return array
- */
private function getAccounts(): array
{
return $this->get('accounts') ?? [];
}
- /**
- * @return array
- */
public function rules(): array
{
return [
diff --git a/app/Api/V1/Requests/Models/Rule/UpdateRequest.php b/app/Api/V1/Requests/Models/Rule/UpdateRequest.php
index 363dc7eef6..3e89716d7f 100644
--- a/app/Api/V1/Requests/Models/Rule/UpdateRequest.php
+++ b/app/Api/V1/Requests/Models/Rule/UpdateRequest.php
@@ -29,27 +29,24 @@ use FireflyIII\Support\Request\ChecksLogin;
use FireflyIII\Support\Request\ConvertsDataTypes;
use FireflyIII\Support\Request\GetRuleConfiguration;
use Illuminate\Foundation\Http\FormRequest;
+use Illuminate\Support\Facades\Log;
use Illuminate\Validation\Validator;
-use function is_array;
-
/**
* Class UpdateRequest
*/
class UpdateRequest extends FormRequest
{
+ use ChecksLogin;
use ConvertsDataTypes;
use GetRuleConfiguration;
- use ChecksLogin;
/**
* Get all data from the request.
- *
- * @return array
*/
public function getAll(): array
{
- $fields = [
+ $fields = [
'title' => ['title', 'convertString'],
'description' => ['description', 'stringWithNewlines'],
'rule_group_id' => ['rule_group_id', 'convertInteger'],
@@ -73,9 +70,6 @@ class UpdateRequest extends FormRequest
return $return;
}
- /**
- * @return array|null
- */
private function getRuleTriggers(): ?array
{
if (!$this->has('triggers')) {
@@ -99,9 +93,6 @@ class UpdateRequest extends FormRequest
return $return;
}
- /**
- * @return array|null
- */
private function getRuleActions(): ?array
{
if (!$this->has('actions')) {
@@ -125,65 +116,60 @@ class UpdateRequest extends FormRequest
/**
* The rules that the incoming request must be matched against.
- *
- * @return array
*/
public function rules(): array
{
- $validTriggers = $this->getTriggers();
- $validActions = array_keys(config('firefly.rule-actions'));
+ $validTriggers = $this->getTriggers();
+ $validActions = array_keys(config('firefly.rule-actions'));
/** @var Rule $rule */
- $rule = $this->route()->parameter('rule');
+ $rule = $this->route()->parameter('rule');
// some triggers and actions require text:
$contextTriggers = implode(',', $this->getTriggersWithContext());
$contextActions = implode(',', config('firefly.context-rule-actions'));
return [
- 'title' => sprintf('between:1,100|uniqueObjectForUser:rules,title,%d', $rule->id),
- 'description' => 'between:1,5000|nullable',
+ 'title' => sprintf('min:1|max:100|uniqueObjectForUser:rules,title,%d', $rule->id),
+ 'description' => 'min:1|max:32768|nullable',
'rule_group_id' => 'belongsToUser:rule_groups',
- 'rule_group_title' => 'nullable|between:1,255|belongsToUser:rule_groups,title',
+ 'rule_group_title' => 'nullable|min:1|max:255|belongsToUser:rule_groups,title',
'trigger' => 'in:store-journal,update-journal',
- 'triggers.*.type' => 'required|in:' . implode(',', $validTriggers),
- 'triggers.*.value' => 'required_if:actions.*.type,' . $contextTriggers . '|min:1|ruleTriggerValue|max:1024',
+ 'triggers.*.type' => 'required|in:'.implode(',', $validTriggers),
+ 'triggers.*.value' => 'required_if:actions.*.type,'.$contextTriggers.'|min:1|ruleTriggerValue|max:1024',
'triggers.*.stop_processing' => [new IsBoolean()],
'triggers.*.active' => [new IsBoolean()],
- 'actions.*.type' => 'required|in:' . implode(',', $validActions),
- 'actions.*.value' => 'required_if:actions.*.type,' . $contextActions . '|ruleActionValue',
+ 'actions.*.type' => 'required|in:'.implode(',', $validActions),
+ 'actions.*.value' => 'required_if:actions.*.type,'.$contextActions.'|ruleActionValue',
'actions.*.stop_processing' => [new IsBoolean()],
'actions.*.active' => [new IsBoolean()],
'strict' => [new IsBoolean()],
'stop_processing' => [new IsBoolean()],
'active' => [new IsBoolean()],
- 'order' => 'numeric|between:1,1337',
+ 'order' => 'numeric|min:1|max:2048',
];
}
/**
* Configure the validator instance.
- *
- * @param Validator $validator
- *
- * @return void
*/
public function withValidator(Validator $validator): void
{
$validator->after(
- function (Validator $validator) {
+ function (Validator $validator): void {
$this->atLeastOneTrigger($validator);
$this->atLeastOneValidTrigger($validator);
$this->atLeastOneAction($validator);
$this->atLeastOneValidAction($validator);
}
);
+ if ($validator->fails()) {
+ Log::channel('audit')->error(sprintf('Validation errors in %s', __CLASS__), $validator->errors()->toArray());
+ }
}
/**
* Adds an error to the validator when there are no repetitions in the array of data.
- *
- * @param Validator $validator
*/
protected function atLeastOneTrigger(Validator $validator): void
{
@@ -197,8 +183,6 @@ class UpdateRequest extends FormRequest
/**
* Adds an error to the validator when there are no repetitions in the array of data.
- *
- * @param Validator $validator
*/
protected function atLeastOneValidTrigger(Validator $validator): void
{
@@ -226,8 +210,6 @@ class UpdateRequest extends FormRequest
/**
* Adds an error to the validator when there are no repetitions in the array of data.
- *
- * @param Validator $validator
*/
protected function atLeastOneAction(Validator $validator): void
{
@@ -241,8 +223,6 @@ class UpdateRequest extends FormRequest
/**
* Adds an error to the validator when there are no repetitions in the array of data.
- *
- * @param Validator $validator
*/
protected function atLeastOneValidAction(Validator $validator): void
{
diff --git a/app/Api/V1/Requests/Models/RuleGroup/StoreRequest.php b/app/Api/V1/Requests/Models/RuleGroup/StoreRequest.php
index 00ffa6ec55..fbefe0606b 100644
--- a/app/Api/V1/Requests/Models/RuleGroup/StoreRequest.php
+++ b/app/Api/V1/Requests/Models/RuleGroup/StoreRequest.php
@@ -33,13 +33,11 @@ use Illuminate\Foundation\Http\FormRequest;
*/
class StoreRequest extends FormRequest
{
- use ConvertsDataTypes;
use ChecksLogin;
+ use ConvertsDataTypes;
/**
* Get all data from the request.
- *
- * @return array
*/
public function getAll(): array
{
@@ -62,14 +60,12 @@ class StoreRequest extends FormRequest
/**
* The rules that the incoming request must be matched against.
- *
- * @return array
*/
public function rules(): array
{
return [
- 'title' => 'required|between:1,100|uniqueObjectForUser:rule_groups,title',
- 'description' => 'between:1,5000|nullable',
+ 'title' => 'required|min:1|max:100|uniqueObjectForUser:rule_groups,title',
+ 'description' => 'min:1|max:32768|nullable',
'active' => [new IsBoolean()],
];
}
diff --git a/app/Api/V1/Requests/Models/RuleGroup/TestRequest.php b/app/Api/V1/Requests/Models/RuleGroup/TestRequest.php
index 81226973b5..c7927ee67d 100644
--- a/app/Api/V1/Requests/Models/RuleGroup/TestRequest.php
+++ b/app/Api/V1/Requests/Models/RuleGroup/TestRequest.php
@@ -34,12 +34,9 @@ use Illuminate\Foundation\Http\FormRequest;
*/
class TestRequest extends FormRequest
{
- use ConvertsDataTypes;
use ChecksLogin;
+ use ConvertsDataTypes;
- /**
- * @return array
- */
public function getTestParameters(): array
{
return [
@@ -49,27 +46,26 @@ class TestRequest extends FormRequest
];
}
- /**
- * @param string $field
- *
- * @return Carbon|null
- */
private function getDate(string $field): ?Carbon
{
- return null === $this->query($field) ? null : Carbon::createFromFormat('Y-m-d', $this->query($field));
+ $value = $this->query($field);
+ if (is_array($value)) {
+ return null;
+ }
+ $value = (string)$value;
+ $result = null === $this->query($field) ? null : Carbon::createFromFormat('Y-m-d', substr($value, 0, 10));
+ if (false === $result) {
+ return null;
+ }
+
+ return $result;
}
- /**
- * @return array
- */
private function getAccounts(): array
{
return $this->get('accounts');
}
- /**
- * @return array
- */
public function rules(): array
{
return [
diff --git a/app/Api/V1/Requests/Models/RuleGroup/TriggerRequest.php b/app/Api/V1/Requests/Models/RuleGroup/TriggerRequest.php
index 4d9514307a..37f2a65513 100644
--- a/app/Api/V1/Requests/Models/RuleGroup/TriggerRequest.php
+++ b/app/Api/V1/Requests/Models/RuleGroup/TriggerRequest.php
@@ -34,12 +34,9 @@ use Illuminate\Foundation\Http\FormRequest;
*/
class TriggerRequest extends FormRequest
{
- use ConvertsDataTypes;
use ChecksLogin;
+ use ConvertsDataTypes;
- /**
- * @return array
- */
public function getTriggerParameters(): array
{
return [
@@ -49,27 +46,30 @@ class TriggerRequest extends FormRequest
];
}
- /**
- * @param string $field
- *
- * @return Carbon|null
- */
private function getDate(string $field): ?Carbon
{
- return null === $this->query($field) ? null : Carbon::createFromFormat('Y-m-d', $this->query($field));
+ $value = $this->query($field);
+ if (is_array($value)) {
+ return null;
+ }
+ $value = (string)$value;
+ $result = null === $this->query($field) ? null : Carbon::createFromFormat('Y-m-d', substr($value, 0, 10));
+ if (false === $result) {
+ return null;
+ }
+
+ return $result;
}
- /**
- * @return array
- */
private function getAccounts(): array
{
+ if (null === $this->get('accounts')) {
+ return [];
+ }
+
return $this->get('accounts');
}
- /**
- * @return array
- */
public function rules(): array
{
return [
diff --git a/app/Api/V1/Requests/Models/RuleGroup/UpdateRequest.php b/app/Api/V1/Requests/Models/RuleGroup/UpdateRequest.php
index a417570bce..3889c2ee61 100644
--- a/app/Api/V1/Requests/Models/RuleGroup/UpdateRequest.php
+++ b/app/Api/V1/Requests/Models/RuleGroup/UpdateRequest.php
@@ -34,13 +34,11 @@ use Illuminate\Foundation\Http\FormRequest;
*/
class UpdateRequest extends FormRequest
{
- use ConvertsDataTypes;
use ChecksLogin;
+ use ConvertsDataTypes;
/**
* Get all data from the request.
- *
- * @return array
*/
public function getAll(): array
{
@@ -57,8 +55,6 @@ class UpdateRequest extends FormRequest
/**
* The rules that the incoming request must be matched against.
- *
- * @return array
*/
public function rules(): array
{
@@ -66,8 +62,8 @@ class UpdateRequest extends FormRequest
$ruleGroup = $this->route()->parameter('ruleGroup');
return [
- 'title' => 'between:1,100|uniqueObjectForUser:rule_groups,title,' . $ruleGroup->id,
- 'description' => 'between:1,5000|nullable',
+ 'title' => 'min:1|max:100|uniqueObjectForUser:rule_groups,title,'.$ruleGroup->id,
+ 'description' => 'min:1|max:32768|nullable',
'active' => [new IsBoolean()],
];
}
diff --git a/app/Api/V1/Requests/Models/Tag/StoreRequest.php b/app/Api/V1/Requests/Models/Tag/StoreRequest.php
index 5f0ce7737b..4a17b58cf1 100644
--- a/app/Api/V1/Requests/Models/Tag/StoreRequest.php
+++ b/app/Api/V1/Requests/Models/Tag/StoreRequest.php
@@ -31,19 +31,15 @@ use Illuminate\Foundation\Http\FormRequest;
/**
* Class StoreRequest
- *
-
*/
class StoreRequest extends FormRequest
{
- use ConvertsDataTypes;
- use ChecksLogin;
use AppendsLocationData;
+ use ChecksLogin;
+ use ConvertsDataTypes;
/**
* Get all data from the request.
- *
- * @return array
*/
public function getAll(): array
{
@@ -59,14 +55,12 @@ class StoreRequest extends FormRequest
/**
* The rules that the incoming request must be matched against.
- *
- * @return array
*/
public function rules(): array
{
$rules = [
'tag' => 'required|min:1|uniqueObjectForUser:tags,tag|max:1024',
- 'description' => 'min:1|nullable|max:65536',
+ 'description' => 'min:1|nullable|max:32768',
'date' => 'date|nullable',
];
diff --git a/app/Api/V1/Requests/Models/Tag/UpdateRequest.php b/app/Api/V1/Requests/Models/Tag/UpdateRequest.php
index d364e8605f..be069c289e 100644
--- a/app/Api/V1/Requests/Models/Tag/UpdateRequest.php
+++ b/app/Api/V1/Requests/Models/Tag/UpdateRequest.php
@@ -33,19 +33,15 @@ use Illuminate\Foundation\Http\FormRequest;
/**
* Class UpdateRequest
- *
-
*/
class UpdateRequest extends FormRequest
{
- use ConvertsDataTypes;
- use ChecksLogin;
use AppendsLocationData;
+ use ChecksLogin;
+ use ConvertsDataTypes;
/**
* Get all data from the request.
- *
- * @return array
*/
public function getAll(): array
{
@@ -62,17 +58,15 @@ class UpdateRequest extends FormRequest
/**
* The rules that the incoming request must be matched against.
- *
- * @return array
*/
public function rules(): array
{
/** @var Tag $tag */
- $tag = $this->route()->parameter('tagOrId');
+ $tag = $this->route()->parameter('tagOrId');
// TODO check if uniqueObjectForUser is obsolete
$rules = [
- 'tag' => 'min:1|max:1024|uniqueObjectForUser:tags,tag,' . $tag->id,
- 'description' => 'min:1|nullable|max:65536',
+ 'tag' => 'min:1|max:1024|uniqueObjectForUser:tags,tag,'.$tag->id,
+ 'description' => 'min:1|nullable|max:32768',
'date' => 'date|nullable',
];
diff --git a/app/Api/V1/Requests/Models/Transaction/StoreRequest.php b/app/Api/V1/Requests/Models/Transaction/StoreRequest.php
index 932d3061cf..7910be0d16 100644
--- a/app/Api/V1/Requests/Models/Transaction/StoreRequest.php
+++ b/app/Api/V1/Requests/Models/Transaction/StoreRequest.php
@@ -27,6 +27,8 @@ namespace FireflyIII\Api\V1\Requests\Models\Transaction;
use FireflyIII\Rules\BelongsUser;
use FireflyIII\Rules\IsBoolean;
use FireflyIII\Rules\IsDateOrTime;
+use FireflyIII\Rules\IsValidPositiveAmount;
+use FireflyIII\Rules\IsValidZeroOrMoreAmount;
use FireflyIII\Support\NullArrayObject;
use FireflyIII\Support\Request\AppendsLocationData;
use FireflyIII\Support\Request\ChecksLogin;
@@ -43,21 +45,19 @@ use Illuminate\Validation\Validator;
*/
class StoreRequest extends FormRequest
{
- use TransactionValidation;
- use GroupValidation;
- use CurrencyValidation;
- use ConvertsDataTypes;
- use ChecksLogin;
use AppendsLocationData;
+ use ChecksLogin;
+ use ConvertsDataTypes;
+ use CurrencyValidation;
+ use GroupValidation;
+ use TransactionValidation;
/**
* Get all data. Is pretty complex because of all the ??-statements.
- *
- * @return array
*/
public function getAll(): array
{
- Log::debug('get all data in TransactionStoreRequest');
+ app('log')->debug('get all data in TransactionStoreRequest');
return [
'group_title' => $this->convertString('group_title'),
@@ -71,95 +71,93 @@ class StoreRequest extends FormRequest
/**
* Get transaction data.
- *
- * @return array
*/
private function getTransactionData(): array
{
$return = [];
+
/**
* @var array $transaction
*/
foreach ($this->get('transactions') as $transaction) {
$object = new NullArrayObject($transaction);
$return[] = [
- 'type' => $this->clearString($object['type'], false),
- 'date' => $this->dateFromValue($object['date']),
- 'order' => $this->integerFromValue((string)$object['order']),
+ 'type' => $this->clearString($object['type']),
+ 'date' => $this->dateFromValue($object['date']),
+ 'order' => $this->integerFromValue((string)$object['order']),
'currency_id' => $this->integerFromValue((string)$object['currency_id']),
- 'currency_code' => $this->clearString((string)$object['currency_code'], false),
+ 'currency_code' => $this->clearString((string)$object['currency_code']),
// foreign currency info:
'foreign_currency_id' => $this->integerFromValue((string)$object['foreign_currency_id']),
- 'foreign_currency_code' => $this->clearString((string)$object['foreign_currency_code'], false),
+ 'foreign_currency_code' => $this->clearString((string)$object['foreign_currency_code']),
// amount and foreign amount. Cannot be 0.
- 'amount' => $this->clearString((string)$object['amount'], false),
- 'foreign_amount' => $this->clearString((string)$object['foreign_amount'], false),
+ 'amount' => $this->clearString((string)$object['amount']),
+ 'foreign_amount' => $this->clearString((string)$object['foreign_amount']),
// description.
- 'description' => $this->clearString($object['description'], false),
+ 'description' => $this->clearString($object['description']),
// source of transaction. If everything is null, assume cash account.
'source_id' => $this->integerFromValue((string)$object['source_id']),
- 'source_name' => $this->clearString((string)$object['source_name'], false),
- 'source_iban' => $this->clearString((string)$object['source_iban'], false),
- 'source_number' => $this->clearString((string)$object['source_number'], false),
- 'source_bic' => $this->clearString((string)$object['source_bic'], false),
+ 'source_name' => $this->clearString((string)$object['source_name']),
+ 'source_iban' => $this->clearString((string)$object['source_iban']),
+ 'source_number' => $this->clearString((string)$object['source_number']),
+ 'source_bic' => $this->clearString((string)$object['source_bic']),
// destination of transaction. If everything is null, assume cash account.
'destination_id' => $this->integerFromValue((string)$object['destination_id']),
- 'destination_name' => $this->clearString((string)$object['destination_name'], false),
- 'destination_iban' => $this->clearString((string)$object['destination_iban'], false),
- 'destination_number' => $this->clearString((string)$object['destination_number'], false),
- 'destination_bic' => $this->clearString((string)$object['destination_bic'], false),
+ 'destination_name' => $this->clearString((string)$object['destination_name']),
+ 'destination_iban' => $this->clearString((string)$object['destination_iban']),
+ 'destination_number' => $this->clearString((string)$object['destination_number']),
+ 'destination_bic' => $this->clearString((string)$object['destination_bic']),
// budget info
'budget_id' => $this->integerFromValue((string)$object['budget_id']),
- 'budget_name' => $this->clearString((string)$object['budget_name'], false),
+ 'budget_name' => $this->clearString((string)$object['budget_name']),
// category info
'category_id' => $this->integerFromValue((string)$object['category_id']),
- 'category_name' => $this->clearString((string)$object['category_name'], false),
+ 'category_name' => $this->clearString((string)$object['category_name']),
// journal bill reference. Optional. Will only work for withdrawals
'bill_id' => $this->integerFromValue((string)$object['bill_id']),
- 'bill_name' => $this->clearString((string)$object['bill_name'], false),
+ 'bill_name' => $this->clearString((string)$object['bill_name']),
// piggy bank reference. Optional. Will only work for transfers
'piggy_bank_id' => $this->integerFromValue((string)$object['piggy_bank_id']),
- 'piggy_bank_name' => $this->clearString((string)$object['piggy_bank_name'], false),
+ 'piggy_bank_name' => $this->clearString((string)$object['piggy_bank_name']),
// some other interesting properties
'reconciled' => $this->convertBoolean((string)$object['reconciled']),
- 'notes' => $this->clearString((string)$object['notes']),
+ 'notes' => $this->clearStringKeepNewlines((string)$object['notes']),
'tags' => $this->arrayFromValue($object['tags']),
// all custom fields:
- 'internal_reference' => $this->clearString((string)$object['internal_reference'], false),
- 'external_id' => $this->clearString((string)$object['external_id'], false),
+ 'internal_reference' => $this->clearString((string)$object['internal_reference']),
+ 'external_id' => $this->clearString((string)$object['external_id']),
'original_source' => sprintf('ff3-v%s|api-v%s', config('firefly.version'), config('firefly.api_version')),
'recurrence_id' => $this->integerFromValue($object['recurrence_id']),
- 'bunq_payment_id' => $this->clearString((string)$object['bunq_payment_id'], false),
- 'external_url' => $this->clearString((string)$object['external_url'], false),
+ 'bunq_payment_id' => $this->clearString((string)$object['bunq_payment_id']),
+ 'external_url' => $this->clearString((string)$object['external_url']),
- 'sepa_cc' => $this->clearString((string)$object['sepa_cc'], false),
- 'sepa_ct_op' => $this->clearString((string)$object['sepa_ct_op'], false),
- 'sepa_ct_id' => $this->clearString((string)$object['sepa_ct_id'], false),
- 'sepa_db' => $this->clearString((string)$object['sepa_db'], false),
- 'sepa_country' => $this->clearString((string)$object['sepa_country'], false),
- 'sepa_ep' => $this->clearString((string)$object['sepa_ep'], false),
- 'sepa_ci' => $this->clearString((string)$object['sepa_ci'], false),
- 'sepa_batch_id' => $this->clearString((string)$object['sepa_batch_id'], false),
+ 'sepa_cc' => $this->clearString((string)$object['sepa_cc']),
+ 'sepa_ct_op' => $this->clearString((string)$object['sepa_ct_op']),
+ 'sepa_ct_id' => $this->clearString((string)$object['sepa_ct_id']),
+ 'sepa_db' => $this->clearString((string)$object['sepa_db']),
+ 'sepa_country' => $this->clearString((string)$object['sepa_country']),
+ 'sepa_ep' => $this->clearString((string)$object['sepa_ep']),
+ 'sepa_ci' => $this->clearString((string)$object['sepa_ci']),
+ 'sepa_batch_id' => $this->clearString((string)$object['sepa_batch_id']),
// custom date fields. Must be Carbon objects. Presence is optional.
- 'interest_date' => $this->dateFromValue($object['interest_date']),
- 'book_date' => $this->dateFromValue($object['book_date']),
- 'process_date' => $this->dateFromValue($object['process_date']),
- 'due_date' => $this->dateFromValue($object['due_date']),
- 'payment_date' => $this->dateFromValue($object['payment_date']),
- 'invoice_date' => $this->dateFromValue($object['invoice_date']),
-
+ 'interest_date' => $this->dateFromValue($object['interest_date']),
+ 'book_date' => $this->dateFromValue($object['book_date']),
+ 'process_date' => $this->dateFromValue($object['process_date']),
+ 'due_date' => $this->dateFromValue($object['due_date']),
+ 'payment_date' => $this->dateFromValue($object['payment_date']),
+ 'invoice_date' => $this->dateFromValue($object['invoice_date']),
];
}
@@ -168,16 +166,15 @@ class StoreRequest extends FormRequest
/**
* The rules that the incoming request must be matched against.
- *
- * @return array
*/
public function rules(): array
{
- Log::debug('Collect rules of TransactionStoreRequest');
+ app('log')->debug('Collect rules of TransactionStoreRequest');
+ $validProtocols = config('firefly.valid_url_protocols');
return [
// basic fields for group:
- 'group_title' => 'between:1,1000|nullable',
+ 'group_title' => 'min:1|max:1000|nullable',
'error_if_duplicate_hash' => [new IsBoolean()],
'apply_rules' => [new IsBoolean()],
@@ -193,47 +190,48 @@ class StoreRequest extends FormRequest
'transactions.*.foreign_currency_code' => 'min:3|max:51|exists:transaction_currencies,code|nullable',
// amount
- 'transactions.*.amount' => 'required|numeric|gt:0',
- 'transactions.*.foreign_amount' => 'numeric',
+ 'transactions.*.amount' => ['required', new IsValidPositiveAmount()],
+ 'transactions.*.foreign_amount' => ['nullable', new IsValidZeroOrMoreAmount()],
// description
- 'transactions.*.description' => 'nullable|between:1,1000',
+ 'transactions.*.description' => 'nullable|min:1|max:1000',
// source of transaction
'transactions.*.source_id' => ['numeric', 'nullable', new BelongsUser()],
- 'transactions.*.source_name' => 'between:1,255|nullable',
- 'transactions.*.source_iban' => 'between:1,255|nullable|iban',
- 'transactions.*.source_number' => 'between:1,255|nullable',
- 'transactions.*.source_bic' => 'between:1,255|nullable|bic',
+ 'transactions.*.source_name' => 'min:1|max:255|nullable',
+ 'transactions.*.source_iban' => 'min:1|max:255|nullable|iban',
+ 'transactions.*.source_number' => 'min:1|max:255|nullable',
+ 'transactions.*.source_bic' => 'min:1|max:255|nullable|bic',
// destination of transaction
'transactions.*.destination_id' => ['numeric', 'nullable', new BelongsUser()],
- 'transactions.*.destination_name' => 'between:1,255|nullable',
- 'transactions.*.destination_iban' => 'between:1,255|nullable|iban',
- 'transactions.*.destination_number' => 'between:1,255|nullable',
- 'transactions.*.destination_bic' => 'between:1,255|nullable|bic',
+ 'transactions.*.destination_name' => 'min:1|max:255|nullable',
+ 'transactions.*.destination_iban' => 'min:1|max:255|nullable|iban',
+ 'transactions.*.destination_number' => 'min:1|max:255|nullable',
+ 'transactions.*.destination_bic' => 'min:1|max:255|nullable|bic',
// budget, category, bill and piggy
'transactions.*.budget_id' => ['mustExist:budgets,id', new BelongsUser()],
- 'transactions.*.budget_name' => ['between:1,255', 'nullable', new BelongsUser()],
+ 'transactions.*.budget_name' => ['min:1', 'max:255', 'nullable', new BelongsUser()],
'transactions.*.category_id' => ['mustExist:categories,id', new BelongsUser(), 'nullable'],
- 'transactions.*.category_name' => 'between:1,255|nullable',
+ 'transactions.*.category_name' => 'min:1|max:255|nullable',
'transactions.*.bill_id' => ['numeric', 'nullable', 'mustExist:bills,id', new BelongsUser()],
- 'transactions.*.bill_name' => ['between:1,255', 'nullable', new BelongsUser()],
+ 'transactions.*.bill_name' => ['min:1', 'max:255', 'nullable', new BelongsUser()],
'transactions.*.piggy_bank_id' => ['numeric', 'nullable', 'mustExist:piggy_banks,id', new BelongsUser()],
- 'transactions.*.piggy_bank_name' => ['between:1,255', 'nullable', new BelongsUser()],
+ 'transactions.*.piggy_bank_name' => ['min:1', 'max:255', 'nullable', new BelongsUser()],
// other interesting fields
'transactions.*.reconciled' => [new IsBoolean()],
- 'transactions.*.notes' => 'min:1|max:50000|nullable',
- 'transactions.*.tags' => 'between:0,255',
+ 'transactions.*.notes' => 'min:1|max:32768|nullable',
+ 'transactions.*.tags' => 'min:0|max:255',
+ 'transactions.*.tags.*' => 'min:0|max:255',
// meta info fields
'transactions.*.internal_reference' => 'min:1|max:255|nullable',
'transactions.*.external_id' => 'min:1|max:255|nullable',
'transactions.*.recurrence_id' => 'min:1|max:255|nullable',
'transactions.*.bunq_payment_id' => 'min:1|max:255|nullable',
- 'transactions.*.external_url' => 'min:1|max:255|nullable|url',
+ 'transactions.*.external_url' => sprintf('min:1|max:255|nullable|url:%s', $validProtocols),
// SEPA fields:
'transactions.*.sepa_cc' => 'min:1|max:255|nullable',
@@ -257,22 +255,18 @@ class StoreRequest extends FormRequest
/**
* Configure the validator instance.
- *
- * @param Validator $validator
- *
- * @return void
*/
public function withValidator(Validator $validator): void
{
$validator->after(
- function (Validator $validator) {
+ function (Validator $validator): void {
// must be valid array.
$this->validateTransactionArray($validator);
// must submit at least one transaction.
- Log::debug('Now going to validateOneTransaction');
+ app('log')->debug('Now going to validateOneTransaction');
$this->validateOneTransaction($validator);
- Log::debug('Now done with validateOneTransaction');
+ app('log')->debug('Now done with validateOneTransaction');
// all journals must have a description
$this->validateDescriptions($validator);
@@ -293,5 +287,8 @@ class StoreRequest extends FormRequest
$this->validateGroupDescription($validator);
}
);
+ if ($validator->fails()) {
+ Log::channel('audit')->error(sprintf('Validation errors in %s', __CLASS__), $validator->errors()->toArray());
+ }
}
}
diff --git a/app/Api/V1/Requests/Models/Transaction/UpdateRequest.php b/app/Api/V1/Requests/Models/Transaction/UpdateRequest.php
index 0d8f931568..b6a3f570b4 100644
--- a/app/Api/V1/Requests/Models/Transaction/UpdateRequest.php
+++ b/app/Api/V1/Requests/Models/Transaction/UpdateRequest.php
@@ -29,6 +29,8 @@ use FireflyIII\Models\TransactionGroup;
use FireflyIII\Rules\BelongsUser;
use FireflyIII\Rules\IsBoolean;
use FireflyIII\Rules\IsDateOrTime;
+use FireflyIII\Rules\IsValidPositiveAmount;
+use FireflyIII\Rules\IsValidZeroOrMoreAmount;
use FireflyIII\Support\Request\ChecksLogin;
use FireflyIII\Support\Request\ConvertsDataTypes;
use FireflyIII\Validation\GroupValidation;
@@ -42,10 +44,10 @@ use Illuminate\Validation\Validator;
*/
class UpdateRequest extends FormRequest
{
- use TransactionValidation;
- use GroupValidation;
- use ConvertsDataTypes;
use ChecksLogin;
+ use ConvertsDataTypes;
+ use GroupValidation;
+ use TransactionValidation;
private array $arrayFields;
private array $booleanFields;
@@ -58,81 +60,20 @@ class UpdateRequest extends FormRequest
/**
* Get all data. Is pretty complex because of all the ??-statements.
*
- * @return array
* @throws FireflyException
*/
public function getAll(): array
{
- Log::debug(sprintf('Now in %s', __METHOD__));
- $this->integerFields = [
- 'order',
- 'currency_id',
- 'foreign_currency_id',
- 'transaction_journal_id',
- 'source_id',
- 'destination_id',
- 'budget_id',
- 'category_id',
- 'bill_id',
- 'recurrence_id',
- ];
-
- $this->dateFields = [
- 'date',
- 'interest_date',
- 'book_date',
- 'process_date',
- 'due_date',
- 'payment_date',
- 'invoice_date',
- ];
-
- $this->textareaFields = [
- 'notes',
- ];
-
- $this->floatFields = [ // not really floats, for validation.
- 'amount',
- 'foreign_amount',
- ];
-
- $this->stringFields = [
- 'type',
- 'currency_code',
- 'foreign_currency_code',
- 'description',
- 'source_name',
- 'source_iban',
- 'source_number',
- 'source_bic',
- 'destination_name',
- 'destination_iban',
- 'destination_number',
- 'destination_bic',
- 'budget_name',
- 'category_name',
- 'bill_name',
- 'internal_reference',
- 'external_id',
- 'bunq_payment_id',
- 'sepa_cc',
- 'sepa_ct_op',
- 'sepa_ct_id',
- 'sepa_db',
- 'sepa_country',
- 'sepa_ep',
- 'sepa_ci',
- 'sepa_batch_id',
- 'external_url',
- ];
- $this->booleanFields = [
- 'reconciled',
- ];
-
- $this->arrayFields = [
- 'tags',
- ];
- $data = [];
+ app('log')->debug(sprintf('Now in %s', __METHOD__));
+ $this->integerFields = ['order', 'currency_id', 'foreign_currency_id', 'transaction_journal_id', 'source_id', 'destination_id', 'budget_id', 'category_id', 'bill_id', 'recurrence_id'];
+ $this->dateFields = ['date', 'interest_date', 'book_date', 'process_date', 'due_date', 'payment_date', 'invoice_date'];
+ $this->textareaFields = ['notes'];
+ // not really floats, for validation.
+ $this->floatFields = ['amount', 'foreign_amount'];
+ $this->stringFields = ['type', 'currency_code', 'foreign_currency_code', 'description', 'source_name', 'source_iban', 'source_number', 'source_bic', 'destination_name', 'destination_iban', 'destination_number', 'destination_bic', 'budget_name', 'category_name', 'bill_name', 'internal_reference', 'external_id', 'bunq_payment_id', 'sepa_cc', 'sepa_ct_op', 'sepa_ct_id', 'sepa_db', 'sepa_country', 'sepa_ep', 'sepa_ci', 'sepa_batch_id', 'external_url'];
+ $this->booleanFields = ['reconciled'];
+ $this->arrayFields = ['tags'];
+ $data = [];
if ($this->has('transactions')) {
$data['transactions'] = $this->getTransactionData();
}
@@ -152,20 +93,22 @@ class UpdateRequest extends FormRequest
/**
* Get transaction data.
*
- * @return array
* @throws FireflyException
*/
private function getTransactionData(): array
{
- Log::debug(sprintf('Now in %s', __METHOD__));
- $return = [];
+ app('log')->debug(sprintf('Now in %s', __METHOD__));
+ $return = [];
- if (!is_countable($this->get('transactions'))) {
+ /** @var null|array $transactions */
+ $transactions = $this->get('transactions');
+
+ if (!is_countable($transactions)) {
return $return;
}
- /** @var array $transaction */
- foreach ($this->get('transactions') as $transaction) {
+ /** @var null|array $transaction */
+ foreach ($transactions as $transaction) {
if (!is_array($transaction)) {
throw new FireflyException('Invalid data submitted: transaction is not array.');
}
@@ -187,10 +130,8 @@ class UpdateRequest extends FormRequest
/**
* For each field, add it to the array if a reference is present in the request:
*
- * @param array $current
- * @param array $transaction
- *
- * @return array
+ * @param array $current
+ * @param array $transaction
*/
private function getIntegerData(array $current, array $transaction): array
{
@@ -204,31 +145,12 @@ class UpdateRequest extends FormRequest
}
/**
- * @param array $current
- * @param array $transaction
- *
- * @return array
+ * @param array $current
+ * @param array $transaction
*/
private function getStringData(array $current, array $transaction): array
{
foreach ($this->stringFields as $fieldName) {
- if (array_key_exists($fieldName, $transaction)) {
- $current[$fieldName] = $this->clearString((string)$transaction[$fieldName], false);
- }
- }
-
- return $current;
- }
-
- /**
- * @param array $current
- * @param array $transaction
- *
- * @return array
- */
- private function getNlStringData(array $current, array $transaction): array
- {
- foreach ($this->textareaFields as $fieldName) {
if (array_key_exists($fieldName, $transaction)) {
$current[$fieldName] = $this->clearString((string)$transaction[$fieldName]);
}
@@ -238,17 +160,30 @@ class UpdateRequest extends FormRequest
}
/**
- * @param array $current
- * @param array $transaction
- *
- * @return array
+ * @param array $current
+ * @param array $transaction
+ */
+ private function getNlStringData(array $current, array $transaction): array
+ {
+ foreach ($this->textareaFields as $fieldName) {
+ if (array_key_exists($fieldName, $transaction)) {
+ $current[$fieldName] = $this->clearStringKeepNewlines((string)$transaction[$fieldName]); // keep newlines
+ }
+ }
+
+ return $current;
+ }
+
+ /**
+ * @param array $current
+ * @param array $transaction
*/
private function getDateData(array $current, array $transaction): array
{
foreach ($this->dateFields as $fieldName) {
- Log::debug(sprintf('Now at date field %s', $fieldName));
+ app('log')->debug(sprintf('Now at date field %s', $fieldName));
if (array_key_exists($fieldName, $transaction)) {
- Log::debug(sprintf('New value: "%s"', (string)$transaction[$fieldName]));
+ app('log')->debug(sprintf('New value: "%s"', (string)$transaction[$fieldName]));
$current[$fieldName] = $this->dateFromValue((string)$transaction[$fieldName]);
}
}
@@ -257,10 +192,8 @@ class UpdateRequest extends FormRequest
}
/**
- * @param array $current
- * @param array $transaction
- *
- * @return array
+ * @param array $current
+ * @param array $transaction
*/
private function getBooleanData(array $current, array $transaction): array
{
@@ -274,10 +207,8 @@ class UpdateRequest extends FormRequest
}
/**
- * @param array $current
- * @param array $transaction
- *
- * @return array
+ * @param array $current
+ * @param array $transaction
*/
private function getArrayData(array $current, array $transaction): array
{
@@ -291,10 +222,8 @@ class UpdateRequest extends FormRequest
}
/**
- * @param array $current
- * @param array $transaction
- *
- * @return array
+ * @param array $current
+ * @param array $transaction
*/
private function getFloatData(array $current, array $transaction): array
{
@@ -315,16 +244,15 @@ class UpdateRequest extends FormRequest
/**
* The rules that the incoming request must be matched against.
- *
- * @return array
*/
public function rules(): array
{
- Log::debug(sprintf('Now in %s', __METHOD__));
+ app('log')->debug(sprintf('Now in %s', __METHOD__));
+ $validProtocols = config('firefly.valid_url_protocols');
return [
// basic fields for group:
- 'group_title' => 'between:1,1000|nullable',
+ 'group_title' => 'min:1|max:1000|nullable',
'apply_rules' => [new IsBoolean()],
// transaction rules (in array for splits):
@@ -335,7 +263,6 @@ class UpdateRequest extends FormRequest
// group id:
'transactions.*.transaction_journal_id' => ['nullable', 'numeric', new BelongsUser()],
-
// currency info
'transactions.*.currency_id' => 'numeric|exists:transaction_currencies,id|nullable',
'transactions.*.currency_code' => 'min:3|max:51|exists:transaction_currencies,code|nullable',
@@ -343,39 +270,40 @@ class UpdateRequest extends FormRequest
'transactions.*.foreign_currency_code' => 'nullable|min:3|max:51|exists:transaction_currencies,code',
// amount
- 'transactions.*.amount' => 'numeric|gt:0|max:100000000000',
- 'transactions.*.foreign_amount' => 'nullable|numeric|gte:0',
+ 'transactions.*.amount' => [new IsValidPositiveAmount()],
+ 'transactions.*.foreign_amount' => ['nullable', new IsValidZeroOrMoreAmount()],
// description
- 'transactions.*.description' => 'nullable|between:1,1000',
+ 'transactions.*.description' => 'nullable|min:1|max:1000',
// source of transaction
'transactions.*.source_id' => ['numeric', 'nullable', new BelongsUser()],
- 'transactions.*.source_name' => 'between:1,255|nullable',
+ 'transactions.*.source_name' => 'min:1|max:255|nullable',
// destination of transaction
'transactions.*.destination_id' => ['numeric', 'nullable', new BelongsUser()],
- 'transactions.*.destination_name' => 'between:1,255|nullable',
+ 'transactions.*.destination_name' => 'min:1|max:255|nullable',
// budget, category, bill and piggy
'transactions.*.budget_id' => ['mustExist:budgets,id', new BelongsUser(), 'nullable'],
- 'transactions.*.budget_name' => ['between:1,255', 'nullable', new BelongsUser()],
+ 'transactions.*.budget_name' => ['min:1', 'max:255', 'nullable', new BelongsUser()],
'transactions.*.category_id' => ['mustExist:categories,id', new BelongsUser(), 'nullable'],
- 'transactions.*.category_name' => 'between:1,255|nullable',
+ 'transactions.*.category_name' => 'min:1|max:255|nullable',
'transactions.*.bill_id' => ['numeric', 'nullable', 'mustExist:bills,id', new BelongsUser()],
- 'transactions.*.bill_name' => ['between:1,255', 'nullable', new BelongsUser()],
+ 'transactions.*.bill_name' => ['min:1', 'max:255', 'nullable', new BelongsUser()],
// other interesting fields
'transactions.*.reconciled' => [new IsBoolean()],
- 'transactions.*.notes' => 'min:1|max:50000|nullable',
- 'transactions.*.tags' => 'between:0,255|nullable',
+ 'transactions.*.notes' => 'min:1|max:32768|nullable',
+ 'transactions.*.tags' => 'min:0|max:255|nullable',
+ 'transactions.*.tags.*' => 'min:0|max:255',
// meta info fields
'transactions.*.internal_reference' => 'min:1|max:255|nullable',
'transactions.*.external_id' => 'min:1|max:255|nullable',
'transactions.*.recurrence_id' => 'min:1|max:255|nullable',
'transactions.*.bunq_payment_id' => 'min:1|max:255|nullable',
- 'transactions.*.external_url' => 'min:1|max:255|nullable|url',
+ 'transactions.*.external_url' => sprintf('min:1|max:255|nullable|url:%s', $validProtocols),
// SEPA fields:
'transactions.*.sepa_cc' => 'min:1|max:255|nullable',
@@ -399,34 +327,39 @@ class UpdateRequest extends FormRequest
/**
* Configure the validator instance.
- *
- * @param Validator $validator
- *
- * @return void
*/
public function withValidator(Validator $validator): void
{
- Log::debug('Now in withValidator');
+ app('log')->debug('Now in withValidator');
+
/** @var TransactionGroup $transactionGroup */
$transactionGroup = $this->route()->parameter('transactionGroup');
$validator->after(
- function (Validator $validator) use ($transactionGroup) {
+ function (Validator $validator) use ($transactionGroup): void {
// if more than one, verify that there are journal ID's present.
$this->validateJournalIds($validator, $transactionGroup);
// all transaction types must be equal:
$this->validateTransactionTypesForUpdate($validator);
+ // user wants to update a reconciled transaction.
+ // source, destination, amount + foreign_amount cannot be changed
+ // and must be omitted from the request.
+ $this->preventUpdateReconciled($validator, $transactionGroup);
+
// validate source/destination is equal, depending on the transaction journal type.
$this->validateEqualAccountsForUpdate($validator, $transactionGroup);
- // a catch when users submit splits with no source or destination info at all.
- $this->preventNoAccountInfo($validator, );
+ // see method:
+ // $this->preventNoAccountInfo($validator, );
// validate that the currency fits the source and/or destination account.
// validate all account info
$this->validateAccountInformationUpdate($validator, $transactionGroup);
}
);
+ if ($validator->fails()) {
+ Log::channel('audit')->error(sprintf('Validation errors in %s', __CLASS__), $validator->errors()->toArray());
+ }
}
}
diff --git a/app/Api/V1/Requests/Models/TransactionCurrency/StoreRequest.php b/app/Api/V1/Requests/Models/TransactionCurrency/StoreRequest.php
index 479348c85b..17ec1b4e3b 100644
--- a/app/Api/V1/Requests/Models/TransactionCurrency/StoreRequest.php
+++ b/app/Api/V1/Requests/Models/TransactionCurrency/StoreRequest.php
@@ -30,18 +30,14 @@ use Illuminate\Foundation\Http\FormRequest;
/**
* Class StoreRequest
- *
-
*/
class StoreRequest extends FormRequest
{
- use ConvertsDataTypes;
use ChecksLogin;
+ use ConvertsDataTypes;
/**
* Get all data from the request.
- *
- * @return array
*/
public function getAll(): array
{
@@ -66,19 +62,16 @@ class StoreRequest extends FormRequest
/**
* The rules that the incoming request must be matched against.
- *
- * @return array
*/
public function rules(): array
{
return [
- 'name' => 'required|between:1,255|unique:transaction_currencies,name',
- 'code' => 'required|between:3,51|unique:transaction_currencies,code',
- 'symbol' => 'required|between:1,51|unique:transaction_currencies,symbol',
- 'decimal_places' => 'between:0,20|numeric|min:0|max:12',
+ 'name' => 'required|min:1|max:255|unique:transaction_currencies,name',
+ 'code' => 'required|min:3|max:32|unique:transaction_currencies,code',
+ 'symbol' => 'required|min:1|max:32|unique:transaction_currencies,symbol',
+ 'decimal_places' => 'numeric|min:0|max:12',
'enabled' => [new IsBoolean()],
'default' => [new IsBoolean()],
-
];
}
}
diff --git a/app/Api/V1/Requests/Models/TransactionCurrency/UpdateRequest.php b/app/Api/V1/Requests/Models/TransactionCurrency/UpdateRequest.php
index 5e673d42b4..1344f8d546 100644
--- a/app/Api/V1/Requests/Models/TransactionCurrency/UpdateRequest.php
+++ b/app/Api/V1/Requests/Models/TransactionCurrency/UpdateRequest.php
@@ -31,22 +31,18 @@ use Illuminate\Foundation\Http\FormRequest;
/**
* Class UpdateRequest
- *
-
*/
class UpdateRequest extends FormRequest
{
- use ConvertsDataTypes;
use ChecksLogin;
+ use ConvertsDataTypes;
/**
* Get all data from the request.
- *
- * @return array
*/
public function getAll(): array
{
- // return nothing that isn't explicitely in the array:
+ // return nothing that isn't explicitly in the array:
$fields = [
'name' => ['name', 'convertString'],
'code' => ['code', 'convertString'],
@@ -57,13 +53,10 @@ class UpdateRequest extends FormRequest
];
return $this->getAllData($fields);
- // return $return;
}
/**
* The rules that the incoming request must be matched against.
- *
- * @return array
*/
public function rules(): array
{
@@ -71,10 +64,10 @@ class UpdateRequest extends FormRequest
$currency = $this->route()->parameter('currency_code');
return [
- 'name' => sprintf('between:1,255|unique:transaction_currencies,name,%d', $currency->id),
- 'code' => sprintf('between:3,51|unique:transaction_currencies,code,%d', $currency->id),
- 'symbol' => sprintf('between:1,51|unique:transaction_currencies,symbol,%d', $currency->id),
- 'decimal_places' => 'between:0,20|numeric|min:0|max:12',
+ 'name' => sprintf('min:1|max:255|unique:transaction_currencies,name,%d', $currency->id),
+ 'code' => sprintf('min:3|max:32|unique:transaction_currencies,code,%d', $currency->id),
+ 'symbol' => sprintf('min:1|max:32|unique:transaction_currencies,symbol,%d', $currency->id),
+ 'decimal_places' => 'numeric|min:0|max:12',
'enabled' => [new IsBoolean()],
'default' => [new IsBoolean()],
];
diff --git a/app/Api/V1/Requests/Models/TransactionLink/StoreRequest.php b/app/Api/V1/Requests/Models/TransactionLink/StoreRequest.php
index dd97a2a4c1..788cadf1b8 100644
--- a/app/Api/V1/Requests/Models/TransactionLink/StoreRequest.php
+++ b/app/Api/V1/Requests/Models/TransactionLink/StoreRequest.php
@@ -29,6 +29,7 @@ use FireflyIII\Support\Request\ChecksLogin;
use FireflyIII\Support\Request\ConvertsDataTypes;
use FireflyIII\User;
use Illuminate\Foundation\Http\FormRequest;
+use Illuminate\Support\Facades\Log;
use Illuminate\Validation\Validator;
/**
@@ -36,13 +37,11 @@ use Illuminate\Validation\Validator;
*/
class StoreRequest extends FormRequest
{
- use ConvertsDataTypes;
use ChecksLogin;
+ use ConvertsDataTypes;
/**
* Get all data from the request.
- *
- * @return array
*/
public function getAll(): array
{
@@ -57,8 +56,6 @@ class StoreRequest extends FormRequest
/**
* The rules that the incoming request must be matched against.
- *
- * @return array
*/
public function rules(): array
{
@@ -67,46 +64,43 @@ class StoreRequest extends FormRequest
'link_type_name' => 'exists:link_types,name|required_without:link_type_id',
'inward_id' => 'required|belongsToUser:transaction_journals,id|different:outward_id',
'outward_id' => 'required|belongsToUser:transaction_journals,id|different:inward_id',
- 'notes' => 'between:0,65000',
+ 'notes' => 'min:1|max:32768|nullable',
];
}
/**
* Configure the validator instance.
- *
- * @param Validator $validator
- *
- * @return void
*/
public function withValidator(Validator $validator): void
{
$validator->after(
- function (Validator $validator) {
+ function (Validator $validator): void {
$this->validateExistingLink($validator);
}
);
+ if ($validator->fails()) {
+ Log::channel('audit')->error(sprintf('Validation errors in %s', __CLASS__), $validator->errors()->toArray());
+ }
}
- /**
- * @param Validator $validator
- */
private function validateExistingLink(Validator $validator): void
{
/** @var User $user */
- $user = auth()->user();
+ $user = auth()->user();
+
/** @var LinkTypeRepositoryInterface $repository */
- $repository = app(LinkTypeRepositoryInterface::class);
+ $repository = app(LinkTypeRepositoryInterface::class);
$repository->setUser($user);
/** @var JournalRepositoryInterface $journalRepos */
$journalRepos = app(JournalRepositoryInterface::class);
$journalRepos->setUser($user);
- $data = $validator->getData();
- $inwardId = (int)($data['inward_id'] ?? 0);
- $outwardId = (int)($data['outward_id'] ?? 0);
- $inward = $journalRepos->find($inwardId);
- $outward = $journalRepos->find($outwardId);
+ $data = $validator->getData();
+ $inwardId = (int)($data['inward_id'] ?? 0);
+ $outwardId = (int)($data['outward_id'] ?? 0);
+ $inward = $journalRepos->find($inwardId);
+ $outward = $journalRepos->find($outwardId);
if (null === $inward) {
$validator->errors()->add('inward_id', 'Invalid inward ID.');
diff --git a/app/Api/V1/Requests/Models/TransactionLink/UpdateRequest.php b/app/Api/V1/Requests/Models/TransactionLink/UpdateRequest.php
index 92cc96c909..f5fcd7d48e 100644
--- a/app/Api/V1/Requests/Models/TransactionLink/UpdateRequest.php
+++ b/app/Api/V1/Requests/Models/TransactionLink/UpdateRequest.php
@@ -29,6 +29,7 @@ use FireflyIII\Repositories\LinkType\LinkTypeRepositoryInterface;
use FireflyIII\Support\Request\ChecksLogin;
use FireflyIII\Support\Request\ConvertsDataTypes;
use Illuminate\Foundation\Http\FormRequest;
+use Illuminate\Support\Facades\Log;
use Illuminate\Validation\Validator;
/**
@@ -36,13 +37,11 @@ use Illuminate\Validation\Validator;
*/
class UpdateRequest extends FormRequest
{
- use ConvertsDataTypes;
use ChecksLogin;
+ use ConvertsDataTypes;
/**
* Get all data from the request.
- *
- * @return array
*/
public function getAll(): array
{
@@ -57,8 +56,6 @@ class UpdateRequest extends FormRequest
/**
* The rules that the incoming request must be matched against.
- *
- * @return array
*/
public function rules(): array
{
@@ -67,46 +64,43 @@ class UpdateRequest extends FormRequest
'link_type_name' => 'exists:link_types,name',
'inward_id' => 'belongsToUser:transaction_journals,id|different:outward_id',
'outward_id' => 'belongsToUser:transaction_journals,id|different:inward_id',
- 'notes' => 'between:0,65000',
+ 'notes' => 'min:1|max:32768|nullable',
];
}
/**
* Configure the validator instance.
- *
- * @param Validator $validator
- *
- * @return void
*/
public function withValidator(Validator $validator): void
{
$validator->after(
- function (Validator $validator) {
+ function (Validator $validator): void {
$this->validateUpdate($validator);
}
);
+ if ($validator->fails()) {
+ Log::channel('audit')->error(sprintf('Validation errors in %s', __CLASS__), $validator->errors()->toArray());
+ }
}
- /**
- * @param Validator $validator
- */
private function validateUpdate(Validator $validator): void
{
/** @var TransactionJournalLink $existing */
- $existing = $this->route()->parameter('journalLink');
- $data = $validator->getData();
+ $existing = $this->route()->parameter('journalLink');
+ $data = $validator->getData();
+
/** @var LinkTypeRepositoryInterface $repository */
- $repository = app(LinkTypeRepositoryInterface::class);
+ $repository = app(LinkTypeRepositoryInterface::class);
$repository->setUser(auth()->user());
/** @var JournalRepositoryInterface $journalRepos */
$journalRepos = app(JournalRepositoryInterface::class);
$journalRepos->setUser(auth()->user());
- $inwardId = $data['inward_id'] ?? $existing->source_id;
- $outwardId = $data['outward_id'] ?? $existing->destination_id;
- $inward = $journalRepos->find((int)$inwardId);
- $outward = $journalRepos->find((int)$outwardId);
+ $inwardId = $data['inward_id'] ?? $existing->source_id;
+ $outwardId = $data['outward_id'] ?? $existing->destination_id;
+ $inward = $journalRepos->find((int)$inwardId);
+ $outward = $journalRepos->find((int)$outwardId);
if (null === $inward) {
$inward = $existing->source;
}
@@ -118,7 +112,7 @@ class UpdateRequest extends FormRequest
$validator->errors()->add('outward_id', 'Inward ID must be different from outward ID.');
}
- $inDB = $repository->findSpecificLink($existing->linkType, $inward, $outward);
+ $inDB = $repository->findSpecificLink($existing->linkType, $inward, $outward);
if (null === $inDB) {
return;
}
diff --git a/app/Api/V1/Requests/Models/TransactionLinkType/StoreRequest.php b/app/Api/V1/Requests/Models/TransactionLinkType/StoreRequest.php
index cc9a4a0dcf..abcde7dd2c 100644
--- a/app/Api/V1/Requests/Models/TransactionLinkType/StoreRequest.php
+++ b/app/Api/V1/Requests/Models/TransactionLinkType/StoreRequest.php
@@ -29,18 +29,14 @@ use Illuminate\Foundation\Http\FormRequest;
/**
* Class StoreRequest
- *
-
*/
class StoreRequest extends FormRequest
{
- use ConvertsDataTypes;
use ChecksLogin;
+ use ConvertsDataTypes;
/**
* Get all data from the request.
- *
- * @return array
*/
public function getAll(): array
{
@@ -53,8 +49,6 @@ class StoreRequest extends FormRequest
/**
* The rules that the incoming request must be matched against.
- *
- * @return array
*/
public function rules(): array
{
diff --git a/app/Api/V1/Requests/Models/TransactionLinkType/UpdateRequest.php b/app/Api/V1/Requests/Models/TransactionLinkType/UpdateRequest.php
index ed3d1e7c95..7f660107e4 100644
--- a/app/Api/V1/Requests/Models/TransactionLinkType/UpdateRequest.php
+++ b/app/Api/V1/Requests/Models/TransactionLinkType/UpdateRequest.php
@@ -31,18 +31,14 @@ use Illuminate\Validation\Rule;
/**
* Class UpdateRequest
- *
-
*/
class UpdateRequest extends FormRequest
{
- use ConvertsDataTypes;
use ChecksLogin;
+ use ConvertsDataTypes;
/**
* Get all data from the request.
- *
- * @return array
*/
public function getAll(): array
{
@@ -55,8 +51,6 @@ class UpdateRequest extends FormRequest
/**
* The rules that the incoming request must be matched against.
- *
- * @return array
*/
public function rules(): array
{
diff --git a/app/Api/V1/Requests/Models/Webhook/CreateRequest.php b/app/Api/V1/Requests/Models/Webhook/CreateRequest.php
index 24c4084bf0..94e58c9ffa 100644
--- a/app/Api/V1/Requests/Models/Webhook/CreateRequest.php
+++ b/app/Api/V1/Requests/Models/Webhook/CreateRequest.php
@@ -37,16 +37,13 @@ class CreateRequest extends FormRequest
use ChecksLogin;
use ConvertsDataTypes;
- /**
- * @return array
- */
public function getData(): array
{
- $triggers = Webhook::getTriggersForValidation();
- $responses = Webhook::getResponsesForValidation();
- $deliveries = Webhook::getDeliveriesForValidation();
+ $triggers = Webhook::getTriggersForValidation();
+ $responses = Webhook::getResponsesForValidation();
+ $deliveries = Webhook::getDeliveriesForValidation();
- $fields = [
+ $fields = [
'title' => ['title', 'convertString'],
'active' => ['active', 'boolean'],
'trigger' => ['trigger', 'convertString'],
@@ -57,31 +54,30 @@ class CreateRequest extends FormRequest
// this is the way.
$return = $this->getAllData($fields);
- $return['trigger'] = $triggers[$return['trigger']] ?? intval($return['trigger']);
- $return['response'] = $responses[$return['response']] ?? intval($return['response']);
- $return['delivery'] = $deliveries[$return['delivery']] ?? intval($return['delivery']);
+ $return['trigger'] = $triggers[$return['trigger']] ?? (int)$return['trigger'];
+ $return['response'] = $responses[$return['response']] ?? (int)$return['response'];
+ $return['delivery'] = $deliveries[$return['delivery']] ?? (int)$return['delivery'];
return $return;
}
/**
* Rules for this request.
- *
- * @return array
*/
public function rules(): array
{
- $triggers = implode(',', array_keys(Webhook::getTriggersForValidation()));
- $responses = implode(',', array_keys(Webhook::getResponsesForValidation()));
- $deliveries = implode(',', array_keys(Webhook::getDeliveriesForValidation()));
+ $triggers = implode(',', array_keys(Webhook::getTriggersForValidation()));
+ $responses = implode(',', array_keys(Webhook::getResponsesForValidation()));
+ $deliveries = implode(',', array_keys(Webhook::getDeliveriesForValidation()));
+ $validProtocols = config('firefly.valid_url_protocols');
return [
- 'title' => 'required|between:1,512|uniqueObjectForUser:webhooks,title',
+ 'title' => 'required|min:1|max:255|uniqueObjectForUser:webhooks,title',
'active' => [new IsBoolean()],
'trigger' => sprintf('required|in:%s', $triggers),
'response' => sprintf('required|in:%s', $responses),
'delivery' => sprintf('required|in:%s', $deliveries),
- 'url' => ['required', 'url', 'uniqueWebhook'],
+ 'url' => ['required', sprintf('url:%s', $validProtocols), 'uniqueWebhook'],
];
}
}
diff --git a/app/Api/V1/Requests/Models/Webhook/UpdateRequest.php b/app/Api/V1/Requests/Models/Webhook/UpdateRequest.php
index 157c2f5716..5fc21ee4f2 100644
--- a/app/Api/V1/Requests/Models/Webhook/UpdateRequest.php
+++ b/app/Api/V1/Requests/Models/Webhook/UpdateRequest.php
@@ -37,16 +37,13 @@ class UpdateRequest extends FormRequest
use ChecksLogin;
use ConvertsDataTypes;
- /**
- * @return array
- */
public function getData(): array
{
- $triggers = Webhook::getTriggersForValidation();
- $responses = Webhook::getResponsesForValidation();
- $deliveries = Webhook::getDeliveriesForValidation();
+ $triggers = Webhook::getTriggersForValidation();
+ $responses = Webhook::getResponsesForValidation();
+ $deliveries = Webhook::getDeliveriesForValidation();
- $fields = [
+ $fields = [
'title' => ['title', 'convertString'],
'active' => ['active', 'boolean'],
'trigger' => ['trigger', 'convertString'],
@@ -56,7 +53,7 @@ class UpdateRequest extends FormRequest
];
// this is the way.
- $return = $this->getAllData($fields);
+ $return = $this->getAllData($fields);
if (array_key_exists('trigger', $return)) {
$return['trigger'] = $triggers[$return['trigger']] ?? 0;
}
@@ -76,25 +73,24 @@ class UpdateRequest extends FormRequest
/**
* Rules for this request.
- *
- * @return array
*/
public function rules(): array
{
- $triggers = implode(',', array_keys(Webhook::getTriggersForValidation()));
- $responses = implode(',', array_keys(Webhook::getResponsesForValidation()));
- $deliveries = implode(',', array_keys(Webhook::getDeliveriesForValidation()));
+ $triggers = implode(',', array_keys(Webhook::getTriggersForValidation()));
+ $responses = implode(',', array_keys(Webhook::getResponsesForValidation()));
+ $deliveries = implode(',', array_keys(Webhook::getDeliveriesForValidation()));
+ $validProtocols = config('firefly.valid_url_protocols');
/** @var Webhook $webhook */
- $webhook = $this->route()->parameter('webhook');
+ $webhook = $this->route()->parameter('webhook');
return [
- 'title' => sprintf('between:1,512|uniqueObjectForUser:webhooks,title,%d', $webhook->id),
+ 'title' => sprintf('min:1|max:255|uniqueObjectForUser:webhooks,title,%d', $webhook->id),
'active' => [new IsBoolean()],
'trigger' => sprintf('in:%s', $triggers),
'response' => sprintf('in:%s', $responses),
'delivery' => sprintf('in:%s', $deliveries),
- 'url' => ['url', sprintf('uniqueExistingWebhook:%d', $webhook->id)],
+ 'url' => [sprintf('url:%s', $validProtocols), sprintf('uniqueExistingWebhook:%d', $webhook->id)],
];
}
}
diff --git a/app/Api/V1/Requests/System/CronRequest.php b/app/Api/V1/Requests/System/CronRequest.php
index 3af1094aa2..4ce959c635 100644
--- a/app/Api/V1/Requests/System/CronRequest.php
+++ b/app/Api/V1/Requests/System/CronRequest.php
@@ -29,8 +29,6 @@ use Illuminate\Foundation\Http\FormRequest;
/**
* Class CronRequest
- *
-
*/
class CronRequest extends FormRequest
{
@@ -38,8 +36,6 @@ class CronRequest extends FormRequest
/**
* Verify the request.
- *
- * @return bool
*/
public function authorize(): bool
{
@@ -48,8 +44,6 @@ class CronRequest extends FormRequest
/**
* Get all data from the request.
- *
- * @return array
*/
public function getAll(): array
{
@@ -69,8 +63,6 @@ class CronRequest extends FormRequest
/**
* The rules that the incoming request must be matched against.
- *
- * @return array
*/
public function rules(): array
{
diff --git a/app/Api/V1/Requests/System/UpdateRequest.php b/app/Api/V1/Requests/System/UpdateRequest.php
index 5c6c59fe07..2f9c39af0e 100644
--- a/app/Api/V1/Requests/System/UpdateRequest.php
+++ b/app/Api/V1/Requests/System/UpdateRequest.php
@@ -31,27 +31,23 @@ use Illuminate\Foundation\Http\FormRequest;
/**
* Class UpdateRequest
- *
-
*/
class UpdateRequest extends FormRequest
{
- use ConvertsDataTypes;
use ChecksLogin;
+ use ConvertsDataTypes;
/**
* Get all data from the request.
- *
- * @return array
*/
public function getAll(): array
{
$name = $this->route()->parameter('dynamicConfigKey');
- if ($name === 'configuration.is_demo_site' || $name === 'configuration.single_user_mode') {
+ if ('configuration.is_demo_site' === $name || 'configuration.single_user_mode' === $name) {
return ['value' => $this->boolean('value')];
}
- if ($name === 'configuration.permission_update_check' || $name === 'configuration.last_update_check') {
+ if ('configuration.permission_update_check' === $name || 'configuration.last_update_check' === $name) {
return ['value' => $this->convertInteger('value')];
}
@@ -60,20 +56,18 @@ class UpdateRequest extends FormRequest
/**
* The rules that the incoming request must be matched against.
- *
- * @return array
*/
public function rules(): array
{
$name = $this->route()->parameter('configName');
- if ($name === 'configuration.is_demo_site' || $name === 'configuration.single_user_mode') {
+ if ('configuration.is_demo_site' === $name || 'configuration.single_user_mode' === $name) {
return ['value' => ['required', new IsBoolean()]];
}
- if ($name === 'configuration.permission_update_check') {
- return ['value' => 'required|numeric|between:-1,1'];
+ if ('configuration.permission_update_check' === $name) {
+ return ['value' => 'required|numeric|min:-1|max:1'];
}
- if ($name === 'configuration.last_update_check') {
+ if ('configuration.last_update_check' === $name) {
return ['value' => 'required|numeric|min:464272080'];
}
diff --git a/app/Api/V1/Requests/System/UserStoreRequest.php b/app/Api/V1/Requests/System/UserStoreRequest.php
index 28dae61728..9ca9409ec8 100644
--- a/app/Api/V1/Requests/System/UserStoreRequest.php
+++ b/app/Api/V1/Requests/System/UserStoreRequest.php
@@ -34,13 +34,11 @@ use Illuminate\Foundation\Http\FormRequest;
*/
class UserStoreRequest extends FormRequest
{
- use ConvertsDataTypes;
use ChecksLogin;
+ use ConvertsDataTypes;
/**
* Logged in + owner
- *
- * @return bool
*/
public function authorize(): bool
{
@@ -49,8 +47,6 @@ class UserStoreRequest extends FormRequest
/**
* Get all data from the request.
- *
- * @return array
*/
public function getAll(): array
{
@@ -69,8 +65,6 @@ class UserStoreRequest extends FormRequest
/**
* The rules that the incoming request must be matched against.
- *
- * @return array
*/
public function rules(): array
{
diff --git a/app/Api/V1/Requests/System/UserUpdateRequest.php b/app/Api/V1/Requests/System/UserUpdateRequest.php
index 87013e88fd..19cda61d3d 100644
--- a/app/Api/V1/Requests/System/UserUpdateRequest.php
+++ b/app/Api/V1/Requests/System/UserUpdateRequest.php
@@ -29,6 +29,7 @@ use FireflyIII\Support\Request\ChecksLogin;
use FireflyIII\Support\Request\ConvertsDataTypes;
use FireflyIII\User;
use Illuminate\Foundation\Http\FormRequest;
+use Illuminate\Support\Facades\Log;
use Illuminate\Validation\Validator;
/**
@@ -36,13 +37,11 @@ use Illuminate\Validation\Validator;
*/
class UserUpdateRequest extends FormRequest
{
- use ConvertsDataTypes;
use ChecksLogin;
+ use ConvertsDataTypes;
/**
* Logged in + owner
- *
- * @return bool
*/
public function authorize(): bool
{
@@ -51,8 +50,6 @@ class UserUpdateRequest extends FormRequest
/**
* Get all data from the request.
- *
- * @return array
*/
public function getAll(): array
{
@@ -71,8 +68,6 @@ class UserUpdateRequest extends FormRequest
/**
* The rules that the incoming request must be matched against.
- *
- * @return array
*/
public function rules(): array
{
@@ -89,17 +84,13 @@ class UserUpdateRequest extends FormRequest
/**
* Configure the validator instance.
- *
- * @param Validator $validator
- *
- * @return void
*/
public function withValidator(Validator $validator): void
{
- /** @var User|null $current */
+ /** @var null|User $current */
$current = $this->route()->parameter('user');
$validator->after(
- static function (Validator $validator) use ($current) {
+ static function (Validator $validator) use ($current): void {
$isAdmin = auth()->user()->hasRole('owner');
// not admin, and not own user?
if (auth()->check() && false === $isAdmin && $current?->id !== auth()->user()->id) {
@@ -107,5 +98,8 @@ class UserUpdateRequest extends FormRequest
}
}
);
+ if ($validator->fails()) {
+ Log::channel('audit')->error(sprintf('Validation errors in %s', __CLASS__), $validator->errors()->toArray());
+ }
}
}
diff --git a/app/Api/V1/Requests/User/PreferenceStoreRequest.php b/app/Api/V1/Requests/User/PreferenceStoreRequest.php
index 9a4a896682..21be1db0d4 100644
--- a/app/Api/V1/Requests/User/PreferenceStoreRequest.php
+++ b/app/Api/V1/Requests/User/PreferenceStoreRequest.php
@@ -35,9 +35,6 @@ class PreferenceStoreRequest extends FormRequest
use ChecksLogin;
use ConvertsDataTypes;
- /**
- * @return array
- */
public function getAll(): array
{
$array = [
diff --git a/app/Api/V1/Requests/User/PreferenceUpdateRequest.php b/app/Api/V1/Requests/User/PreferenceUpdateRequest.php
index cac9397713..3f62c47f87 100644
--- a/app/Api/V1/Requests/User/PreferenceUpdateRequest.php
+++ b/app/Api/V1/Requests/User/PreferenceUpdateRequest.php
@@ -36,9 +36,6 @@ class PreferenceUpdateRequest extends FormRequest
use ChecksLogin;
use ConvertsDataTypes;
- /**
- * @return array
- */
public function getAll(): array
{
$array = [
diff --git a/app/Api/V2/Controllers/Autocomplete/AccountController.php b/app/Api/V2/Controllers/Autocomplete/AccountController.php
index 5da7fc8381..46082d4c79 100644
--- a/app/Api/V2/Controllers/Autocomplete/AccountController.php
+++ b/app/Api/V2/Controllers/Autocomplete/AccountController.php
@@ -32,7 +32,6 @@ use FireflyIII\Models\AccountType;
use FireflyIII\Repositories\Account\AccountRepositoryInterface;
use FireflyIII\Repositories\UserGroups\Account\AccountRepositoryInterface as AdminAccountRepositoryInterface;
use FireflyIII\Support\Http\Api\AccountFilter;
-use http\Env\Response;
use Illuminate\Http\JsonResponse;
/**
@@ -57,7 +56,7 @@ class AccountController extends Controller
$this->repository = app(AccountRepositoryInterface::class);
$this->adminRepository = app(AdminAccountRepositoryInterface::class);
- $userGroup = $this->validateUserGroup($request);
+ $userGroup = $this->validateUserGroup($request);
if (null !== $userGroup) {
$this->adminRepository->setUserGroup($userGroup);
}
@@ -65,7 +64,7 @@ class AccountController extends Controller
return $next($request);
}
);
- $this->balanceTypes = [AccountType::ASSET, AccountType::LOAN, AccountType::DEBT, AccountType::MORTGAGE,];
+ $this->balanceTypes = [AccountType::ASSET, AccountType::LOAN, AccountType::DEBT, AccountType::MORTGAGE];
}
/**
@@ -77,9 +76,6 @@ class AccountController extends Controller
* 4. Endpoint is documented.
* 5. Collector uses user_group_id
*
- * @param AutocompleteRequest $request
- *
- * @return JsonResponse
* @throws FireflyException
* @throws FireflyException
*/
@@ -91,8 +87,9 @@ class AccountController extends Controller
$date = $this->parameters->get('date') ?? today(config('app.timezone'));
$result = $this->adminRepository->searchAccount((string)$query, $types, $data['limit']);
$defaultCurrency = app('amount')->getDefaultCurrency();
+ $groupedResult = [];
+ $allItems = [];
- $allItems = [];
/** @var Account $account */
foreach ($result as $account) {
$nameWithBalance = $account->name;
@@ -102,12 +99,12 @@ class AccountController extends Controller
$balance = app('steam')->balance($account, $date);
$nameWithBalance = sprintf('%s (%s)', $account->name, app('amount')->formatAnything($currency, $balance, false));
}
- $type = (string)trans(sprintf('firefly.%s', $account->accountType->type));
- $groupedResult[$type] = $groupedResult[$type] ?? [
+ $type = (string)trans(sprintf('firefly.%s', $account->accountType->type));
+ $groupedResult[$type] ??= [
'group ' => $type,
'items' => [],
];
- $allItems[] = [
+ $allItems[] = [
'id' => (string)$account->id,
'value' => (string)$account->id,
'name' => $account->name,
@@ -124,14 +121,15 @@ class AccountController extends Controller
usort(
$allItems,
- function (array $a, array $b): int {
- $order = [AccountType::ASSET, AccountType::REVENUE, AccountType::EXPENSE];
- $pos_a = array_search($a['type'], $order, true);
- $pos_b = array_search($b['type'], $order, true);
+ static function (array $left, array $right): int {
+ $order = [AccountType::ASSET, AccountType::REVENUE, AccountType::EXPENSE];
+ $posLeft = (int)array_search($left['type'], $order, true);
+ $posRight = (int)array_search($right['type'], $order, true);
- return $pos_a - $pos_b;
+ return $posLeft - $posRight;
}
);
+
return response()->json($allItems);
}
}
diff --git a/app/Api/V2/Controllers/Autocomplete/CategoryController.php b/app/Api/V2/Controllers/Autocomplete/CategoryController.php
new file mode 100644
index 0000000000..0df59ffbe2
--- /dev/null
+++ b/app/Api/V2/Controllers/Autocomplete/CategoryController.php
@@ -0,0 +1,83 @@
+.
+ */
+
+declare(strict_types=1);
+
+namespace FireflyIII\Api\V2\Controllers\Autocomplete;
+
+use FireflyIII\Api\V2\Controllers\Controller;
+use FireflyIII\Api\V2\Request\Autocomplete\AutocompleteRequest;
+use FireflyIII\Models\Category;
+use FireflyIII\Repositories\UserGroups\Category\CategoryRepositoryInterface;
+use Illuminate\Http\JsonResponse;
+
+/**
+ * Class CategoryController
+ */
+class CategoryController extends Controller
+{
+ private CategoryRepositoryInterface $repository;
+
+ /**
+ * AccountController constructor.
+ */
+ public function __construct()
+ {
+ parent::__construct();
+ $this->middleware(
+ function ($request, $next) {
+ $this->repository = app(CategoryRepositoryInterface::class);
+
+ $userGroup = $this->validateUserGroup($request);
+ if (null !== $userGroup) {
+ $this->repository->setUserGroup($userGroup);
+ }
+
+ return $next($request);
+ }
+ );
+ }
+
+ /**
+ * Documentation for this endpoint:
+ * TODO list of checks
+ * 1. use dates from ParameterBag
+ * 2. Request validates dates
+ * 3. Request includes user_group_id
+ * 4. Endpoint is documented.
+ * 5. Collector uses user_group_id
+ */
+ public function categories(AutocompleteRequest $request): JsonResponse
+ {
+ $data = $request->getData();
+ $result = $this->repository->searchCategory($data['query'], $this->parameters->get('limit'));
+ $filtered = $result->map(
+ static function (Category $item) {
+ return [
+ 'id' => (string)$item->id,
+ 'name' => $item->name,
+ ];
+ }
+ );
+
+ return response()->json($filtered);
+ }
+}
diff --git a/app/Api/V2/Controllers/Autocomplete/TagController.php b/app/Api/V2/Controllers/Autocomplete/TagController.php
new file mode 100644
index 0000000000..2c977f3bf6
--- /dev/null
+++ b/app/Api/V2/Controllers/Autocomplete/TagController.php
@@ -0,0 +1,85 @@
+.
+ */
+
+declare(strict_types=1);
+
+namespace FireflyIII\Api\V2\Controllers\Autocomplete;
+
+use FireflyIII\Api\V2\Controllers\Controller;
+use FireflyIII\Api\V2\Request\Autocomplete\AutocompleteRequest;
+use FireflyIII\Models\Tag;
+use FireflyIII\Repositories\UserGroups\Tag\TagRepositoryInterface;
+use Illuminate\Http\JsonResponse;
+
+/**
+ * Class TagController
+ */
+class TagController extends Controller
+{
+ private TagRepositoryInterface $repository;
+
+ /**
+ * AccountController constructor.
+ */
+ public function __construct()
+ {
+ parent::__construct();
+ $this->middleware(
+ function ($request, $next) {
+ $this->repository = app(TagRepositoryInterface::class);
+
+ $userGroup = $this->validateUserGroup($request);
+ if (null !== $userGroup) {
+ $this->repository->setUserGroup($userGroup);
+ }
+
+ return $next($request);
+ }
+ );
+ }
+
+ /**
+ * Documentation for this endpoint:
+ * TODO list of checks
+ * 1. use dates from ParameterBag
+ * 2. Request validates dates
+ * 3. Request includes user_group_id
+ * 4. Endpoint is documented.
+ * 5. Collector uses user_group_id
+ */
+ public function tags(AutocompleteRequest $request): JsonResponse
+ {
+ $data = $request->getData();
+ $result = $this->repository->searchTag($data['query'], $data['limit']);
+ $filtered = $result->map(
+ static function (Tag $item) {
+ return [
+ 'id' => (string)$item->id,
+ 'name' => $item->tag,
+ 'value' => (string)$item->id,
+ 'label' => $item->tag,
+ ];
+ }
+ );
+
+ return response()->json($filtered);
+ }
+}
diff --git a/app/Api/V2/Controllers/Autocomplete/TransactionController.php b/app/Api/V2/Controllers/Autocomplete/TransactionController.php
index 175e787969..e255adfe1b 100644
--- a/app/Api/V2/Controllers/Autocomplete/TransactionController.php
+++ b/app/Api/V2/Controllers/Autocomplete/TransactionController.php
@@ -46,7 +46,7 @@ class TransactionController extends Controller
function ($request, $next) {
$this->repository = app(JournalRepositoryInterface::class);
- $userGroup = $this->validateUserGroup($request);
+ $userGroup = $this->validateUserGroup($request);
if (null !== $userGroup) {
$this->repository->setUserGroup($userGroup);
}
@@ -64,14 +64,11 @@ class TransactionController extends Controller
* 3. Request includes user_group_id
* 4. Endpoint is documented.
* 5. Collector uses user_group_id
- *
- *
- * @return JsonResponse
*/
public function transactionDescriptions(AutocompleteRequest $request): JsonResponse
{
- $data = $request->getData();
- $result = $this->repository->searchJournalDescriptions($data['query'], $data['limit']);
+ $data = $request->getData();
+ $result = $this->repository->searchJournalDescriptions($data['query'], $data['limit']);
// limit and unique
$filtered = $result->unique('description');
@@ -88,7 +85,5 @@ class TransactionController extends Controller
}
return response()->json($array);
-
}
-
}
diff --git a/app/Api/V2/Controllers/Chart/AccountController.php b/app/Api/V2/Controllers/Chart/AccountController.php
index b45fa09e9f..0df13c4e0e 100644
--- a/app/Api/V2/Controllers/Chart/AccountController.php
+++ b/app/Api/V2/Controllers/Chart/AccountController.php
@@ -26,7 +26,7 @@ namespace FireflyIII\Api\V2\Controllers\Chart;
use Carbon\Carbon;
use FireflyIII\Api\V2\Controllers\Controller;
-use FireflyIII\Api\V2\Request\Generic\DateRequest;
+use FireflyIII\Api\V2\Request\Chart\DashboardChartRequest;
use FireflyIII\Exceptions\FireflyException;
use FireflyIII\Models\Account;
use FireflyIII\Models\AccountType;
@@ -35,8 +35,7 @@ use FireflyIII\Repositories\UserGroups\Account\AccountRepositoryInterface;
use FireflyIII\Support\Http\Api\CleansChartData;
use FireflyIII\Support\Http\Api\ValidatesUserGroupTrait;
use Illuminate\Http\JsonResponse;
-use Psr\Container\ContainerExceptionInterface;
-use Psr\Container\NotFoundExceptionInterface;
+use Illuminate\Support\Collection;
/**
* Class AccountController
@@ -48,9 +47,6 @@ class AccountController extends Controller
private AccountRepositoryInterface $repository;
- /**
- *
- */
public function __construct()
{
parent::__construct();
@@ -78,80 +74,97 @@ class AccountController extends Controller
*
* TODO validate and set user_group_id from request
*
- * @param DateRequest $request
- *
- * @return JsonResponse
- * @throws ContainerExceptionInterface
- * @throws NotFoundExceptionInterface
* @throws FireflyException
+ *
+ * @SuppressWarnings(PHPMD.UnusedFormalParameter)
*/
- public function dashboard(DateRequest $request): JsonResponse
+ public function dashboard(DashboardChartRequest $request): JsonResponse
{
/** @var Carbon $start */
- $start = $this->parameters->get('start');
+ $start = $this->parameters->get('start');
+
/** @var Carbon $end */
- $end = $this->parameters->get('end');
+ $end = $this->parameters->get('end');
$end->endOfDay();
- // user's preferences
- $defaultSet = $this->repository->getAccountsByType([AccountType::ASSET, AccountType::DEFAULT])->pluck('id')->toArray();
- $frontPage = app('preferences')->get('frontPageAccounts', $defaultSet);
/** @var TransactionCurrency $default */
$default = app('amount')->getDefaultCurrency();
- $accounts = $this->repository->getAccountsById($frontPage->data);
+ $params = $request->getAll();
+
+ /** @var Collection $accounts */
+ $accounts = $params['accounts'];
$chartData = [];
- if (!(is_array($frontPage->data) && count($frontPage->data) > 0)) {
- $frontPage->data = $defaultSet;
- $frontPage->save();
+ // user's preferences
+ if (0 === $accounts->count()) {
+ $defaultSet = $this->repository->getAccountsByType([AccountType::ASSET, AccountType::DEFAULT])->pluck('id')->toArray();
+ $frontPage = app('preferences')->get('frontPageAccounts', $defaultSet);
+
+ if (!(is_array($frontPage->data) && count($frontPage->data) > 0)) {
+ $frontPage->data = $defaultSet;
+ $frontPage->save();
+ }
+
+ $accounts = $this->repository->getAccountsById($frontPage->data);
}
+
+ // both options are overruled by "preselected"
+ if ('all' === $params['preselected']) {
+ $accounts = $this->repository->getAccountsByType([AccountType::ASSET, AccountType::DEFAULT, AccountType::LOAN, AccountType::DEBT, AccountType::MORTGAGE]);
+ }
+ if ('assets' === $params['preselected']) {
+ $accounts = $this->repository->getAccountsByType([AccountType::ASSET, AccountType::DEFAULT]);
+ }
+ if ('liabilities' === $params['preselected']) {
+ $accounts = $this->repository->getAccountsByType([AccountType::LOAN, AccountType::DEBT, AccountType::MORTGAGE]);
+ }
+
/** @var Account $account */
foreach ($accounts as $account) {
- $currency = $this->repository->getAccountCurrency($account);
+ $currency = $this->repository->getAccountCurrency($account);
if (null === $currency) {
$currency = $default;
}
- $currentSet = [
- 'label' => $account->name,
+ $currentSet = [
+ 'label' => $account->name,
// the currency that belongs to the account.
- 'currency_id' => (string)$currency->id,
- 'currency_code' => $currency->code,
- 'currency_symbol' => $currency->symbol,
- 'currency_decimal_places' => $currency->decimal_places,
+ 'currency_id' => (string)$currency->id,
+ 'currency_code' => $currency->code,
+ 'currency_symbol' => $currency->symbol,
+ 'currency_decimal_places' => $currency->decimal_places,
// the default currency of the user (could be the same!)
- 'native_id' => (string)$default->id,
- 'native_code' => $default->code,
- 'native_symbol' => $default->symbol,
- 'native_decimal_places' => (int)$default->decimal_places,
- 'start' => $start->toAtomString(),
- 'end' => $end->toAtomString(),
- 'period' => '1D',
- 'entries' => [],
- 'native_entries' => [],
+ 'native_currency_id' => (string)$default->id,
+ 'native_currency_code' => $default->code,
+ 'native_currency_symbol' => $default->symbol,
+ 'native_currency_decimal_places' => $default->decimal_places,
+ 'start' => $start->toAtomString(),
+ 'end' => $end->toAtomString(),
+ 'period' => '1D',
+ 'entries' => [],
+ 'native_entries' => [],
];
- $currentStart = clone $start;
- $range = app('steam')->balanceInRange($account, $start, clone $end, $currency);
- $rangeConverted = app('steam')->balanceInRangeConverted($account, $start, clone $end, $default);
+ $currentStart = clone $start;
+ $range = app('steam')->balanceInRange($account, $start, clone $end, $currency);
+ $rangeConverted = app('steam')->balanceInRangeConverted($account, $start, clone $end, $default);
$previous = array_values($range)[0];
$previousConverted = array_values($rangeConverted)[0];
while ($currentStart <= $end) {
- $format = $currentStart->format('Y-m-d');
- $label = $currentStart->toAtomString();
- $balance = array_key_exists($format, $range) ? $range[$format] : $previous;
- $balanceConverted = array_key_exists($format, $rangeConverted) ? $rangeConverted[$format] : $previousConverted;
- $previous = $balance;
- $previousConverted = $balanceConverted;
+ $format = $currentStart->format('Y-m-d');
+ $label = $currentStart->toAtomString();
+ $balance = array_key_exists($format, $range) ? $range[$format] : $previous;
+ $balanceConverted = array_key_exists($format, $rangeConverted) ? $rangeConverted[$format] : $previousConverted;
+ $previous = $balance;
+ $previousConverted = $balanceConverted;
$currentStart->addDay();
$currentSet['entries'][$label] = $balance;
$currentSet['native_entries'][$label] = $balanceConverted;
}
- $chartData[] = $currentSet;
+ $chartData[] = $currentSet;
}
return response()->json($this->clean($chartData));
}
-
}
diff --git a/app/Api/V2/Controllers/Chart/BalanceController.php b/app/Api/V2/Controllers/Chart/BalanceController.php
index 8ba070f627..a35e4c8480 100644
--- a/app/Api/V2/Controllers/Chart/BalanceController.php
+++ b/app/Api/V2/Controllers/Chart/BalanceController.php
@@ -1,6 +1,5 @@
middleware(
- function ($request, $next) {
- $this->repository = app(AccountRepositoryInterface::class);
-
- return $next($request);
- }
- );
- }
-
/**
* The code is practically a duplicate of ReportController::operations.
*
@@ -74,189 +55,47 @@ class BalanceController extends Controller
* TODO validate and set user_group_id
* TODO collector set group, not user
*
- * @param BalanceChartRequest $request
- *
- * @return JsonResponse
* @throws FireflyException
*/
public function balance(BalanceChartRequest $request): JsonResponse
{
- $params = $request->getAll();
+ $params = $request->getAll();
+
/** @var Carbon $start */
- $start = $this->parameters->get('start');
+ $start = $this->parameters->get('start');
+
/** @var Carbon $end */
- $end = $this->parameters->get('end');
+ $end = $this->parameters->get('end');
$end->endOfDay();
+
/** @var Collection $accounts */
$accounts = $params['accounts'];
+
+ /** @var string $preferredRange */
$preferredRange = $params['period'];
- // set some formats, based on input parameters.
- $format = app('navigation')->preferredCarbonFormatByPeriod($preferredRange);
-
// prepare for currency conversion and data collection:
- $ids = $accounts->pluck('id')->toArray();
/** @var TransactionCurrency $default */
- $default = app('amount')->getDefaultCurrency();
- $converter = new ExchangeRateConverter();
- $currencies = [(int)$default->id => $default,]; // currency cache
- $data = [];
- $chartData = [];
+ $default = app('amount')->getDefaultCurrency();
// get journals for entire period:
/** @var GroupCollectorInterface $collector */
- $collector = app(GroupCollectorInterface::class);
+ $collector = app(GroupCollectorInterface::class);
$collector->setRange($start, $end)->withAccountInformation();
$collector->setXorAccounts($accounts);
$collector->setTypes([TransactionType::WITHDRAWAL, TransactionType::DEPOSIT, TransactionType::RECONCILIATION, TransactionType::TRANSFER]);
- $journals = $collector->getExtractedJournals();
+ $journals = $collector->getExtractedJournals();
- // set array for default currency (even if unused later on)
- $defaultCurrencyId = (int)$default->id;
- $data[$defaultCurrencyId] = [
- 'currency_id' => (string)$defaultCurrencyId,
- 'currency_symbol' => $default->symbol,
- 'currency_code' => $default->code,
- 'currency_name' => $default->name,
- 'currency_decimal_places' => (int)$default->decimal_places,
- 'native_id' => (string)$defaultCurrencyId,
- 'native_symbol' => $default->symbol,
- 'native_code' => $default->code,
- 'native_name' => $default->name,
- 'native_decimal_places' => (int)$default->decimal_places,
- ];
+ $object = new AccountBalanceGrouped();
+ $object->setPreferredRange($preferredRange);
+ $object->setDefault($default);
+ $object->setAccounts($accounts);
+ $object->setJournals($journals);
+ $object->setStart($start);
+ $object->setEnd($end);
+ $object->groupByCurrencyAndPeriod();
+ $chartData = $object->convertToChartData();
-
- // loop. group by currency and by period.
- /** @var array $journal */
- foreach ($journals as $journal) {
- // format the date according to the period
- $period = $journal['date']->format($format);
-
- // collect (and cache) currency information for this journal.
- $currencyId = (int)$journal['currency_id'];
- $currency = $currencies[$currencyId] ?? TransactionCurrency::find($currencyId);
- $currencies[$currencyId] = $currency; // may just re-assign itself, don't mind.
-
- // set the array with monetary info, if it does not exist.
- $data[$currencyId] = $data[$currencyId] ?? [
- 'currency_id' => (string)$currencyId,
- 'currency_symbol' => $journal['currency_symbol'],
- 'currency_code' => $journal['currency_code'],
- 'currency_name' => $journal['currency_name'],
- 'currency_decimal_places' => $journal['currency_decimal_places'],
- // native currency info (could be the same)
- 'native_id' => (string)$default->id,
- 'native_code' => $default->code,
- 'native_symbol' => $default->symbol,
- 'native_decimal_places' => (int)$default->decimal_places,
- ];
-
- // set the array (in monetary info) with spent/earned in this $period, if it does not exist.
- $data[$currencyId][$period] = $data[$currencyId][$period] ?? [
- 'period' => $period,
- 'spent' => '0',
- 'earned' => '0',
- 'native_spent' => '0',
- 'native_earned' => '0',
- ];
- // is this journal's amount in- our outgoing?
- $key = 'spent';
- $amount = app('steam')->negative($journal['amount']);
- // deposit = incoming
- // transfer or reconcile or opening balance, and these accounts are the destination.
- if (
- TransactionType::DEPOSIT === $journal['transaction_type_type']
- ||
-
- (
- (
- TransactionType::TRANSFER === $journal['transaction_type_type']
- || TransactionType::RECONCILIATION === $journal['transaction_type_type']
- || TransactionType::OPENING_BALANCE === $journal['transaction_type_type']
- )
- && in_array($journal['destination_account_id'], $ids, true)
- )
- ) {
- $key = 'earned';
- $amount = app('steam')->positive($journal['amount']);
- }
- // get conversion rate
- $rate = $converter->getCurrencyRate($currency, $default, $journal['date']);
- $amountConverted = bcmul($amount, $rate);
-
- // perhaps transaction already has the foreign amount in the native currency.
- if ((int)$journal['foreign_currency_id'] === (int)$default->id) {
- $amountConverted = $journal['foreign_amount'] ?? '0';
- $amountConverted = 'earned' === $key ? app('steam')->positive($amountConverted) : app('steam')->negative($amountConverted);
- }
-
- // add normal entry
- $data[$currencyId][$period][$key] = bcadd($data[$currencyId][$period][$key], $amount);
-
- // add converted entry
- $convertedKey = sprintf('native_%s', $key);
- $data[$currencyId][$period][$convertedKey] = bcadd($data[$currencyId][$period][$convertedKey], $amountConverted);
- }
-
- // loop this data, make chart bars for each currency:
- /** @var array $currency */
- foreach ($data as $currency) {
- // income and expense array prepped:
- $income = [
- 'label' => 'earned',
- 'currency_id' => (string)$currency['currency_id'],
- 'currency_symbol' => $currency['currency_symbol'],
- 'currency_code' => $currency['currency_code'],
- 'currency_decimal_places' => $currency['currency_decimal_places'],
- 'native_id' => (string)$currency['native_id'],
- 'native_symbol' => $currency['native_symbol'],
- 'native_code' => $currency['native_code'],
- 'native_decimal_places' => $currency['native_decimal_places'],
- 'start' => $start->toAtomString(),
- 'end' => $end->toAtomString(),
- 'period' => $preferredRange,
- 'entries' => [],
- 'native_entries' => [],
- ];
- $expense = [
- 'label' => 'spent',
- 'currency_id' => (string)$currency['currency_id'],
- 'currency_symbol' => $currency['currency_symbol'],
- 'currency_code' => $currency['currency_code'],
- 'currency_decimal_places' => $currency['currency_decimal_places'],
- 'native_id' => (string)$currency['native_id'],
- 'native_symbol' => $currency['native_symbol'],
- 'native_code' => $currency['native_code'],
- 'native_decimal_places' => $currency['native_decimal_places'],
- 'start' => $start->toAtomString(),
- 'end' => $end->toAtomString(),
- 'period' => $preferredRange,
- 'entries' => [],
- 'native_entries' => [],
-
- ];
- // loop all possible periods between $start and $end, and add them to the correct dataset.
- $currentStart = clone $start;
- while ($currentStart <= $end) {
- $key = $currentStart->format($format);
- $label = $currentStart->toAtomString();
- // normal entries
- $income['entries'][$label] = app('steam')->bcround(($currency[$key]['earned'] ?? '0'), $currency['currency_decimal_places']);
- $expense['entries'][$label] = app('steam')->bcround(($currency[$key]['spent'] ?? '0'), $currency['currency_decimal_places']);
-
- // converted entries
- $income['native_entries'][$label] = app('steam')->bcround(($currency[$key]['native_earned'] ?? '0'), $currency['native_decimal_places']);
- $expense['native_entries'][$label] = app('steam')->bcround(($currency[$key]['native_spent'] ?? '0'), $currency['native_decimal_places']);
-
- // next loop
- $currentStart = app('navigation')->addPeriod($currentStart, $preferredRange, 0);
- }
-
- $chartData[] = $income;
- $chartData[] = $expense;
- }
return response()->json($this->clean($chartData));
}
-
}
diff --git a/app/Api/V2/Controllers/Chart/BudgetController.php b/app/Api/V2/Controllers/Chart/BudgetController.php
index 39008f0106..72987816f4 100644
--- a/app/Api/V2/Controllers/Chart/BudgetController.php
+++ b/app/Api/V2/Controllers/Chart/BudgetController.php
@@ -1,6 +1,5 @@
opsRepository = app(OperationsRepositoryInterface::class);
$this->currency = app('amount')->getDefaultCurrency();
- $userGroup = $this->validateUserGroup($request);
+ $userGroup = $this->validateUserGroup($request);
if (null !== $userGroup) {
$this->repository->setUserGroup($userGroup);
$this->opsRepository->setUserGroup($userGroup);
@@ -78,38 +77,32 @@ class BudgetController extends Controller
}
/**
- * @param DateRequest $request
- *
* TODO see autocomplete/accountcontroller
- *
- * @return JsonResponse
- * @throws FireflyException
*/
public function dashboard(DateRequest $request): JsonResponse
{
- $params = $request->getAll();
+ $params = $request->getAll();
+
/** @var Carbon $start */
- $start = $params['start'];
+ $start = $params['start'];
+
/** @var Carbon $end */
- $end = $params['end'];
+ $end = $params['end'];
// code from FrontpageChartGenerator, but not in separate class
$budgets = $this->repository->getActiveBudgets();
$data = [];
+
/** @var Budget $budget */
foreach ($budgets as $budget) {
// could return multiple arrays, so merge.
$data = array_merge($data, $this->processBudget($budget, $start, $end));
}
+
return response()->json($this->clean($data));
}
/**
- * @param Budget $budget
- * @param Carbon $start
- * @param Carbon $end
- *
- * @return array
* @throws FireflyException
*/
private function processBudget(Budget $budget, Carbon $start, Carbon $end): array
@@ -130,24 +123,24 @@ class BudgetController extends Controller
$return = [];
foreach ($rows as $row) {
$current = [
- 'label' => $budget->name,
- 'currency_id' => (string)$row['currency_id'],
- 'currency_code' => $row['currency_code'],
- 'currency_name' => $row['currency_name'],
- 'currency_decimal_places' => $row['currency_decimal_places'],
- 'native_id' => (string)$row['native_id'],
- 'native_code' => $row['native_code'],
- 'native_name' => $row['native_name'],
- 'native_decimal_places' => $row['native_decimal_places'],
- 'period' => null,
- 'start' => $row['start'],
- 'end' => $row['end'],
- 'entries' => [
+ 'label' => $budget->name,
+ 'currency_id' => (string)$row['currency_id'],
+ 'currency_code' => $row['currency_code'],
+ 'currency_name' => $row['currency_name'],
+ 'currency_decimal_places' => $row['currency_decimal_places'],
+ 'native_currency_id' => (string)$row['native_currency_id'],
+ 'native_currency_code' => $row['native_currency_code'],
+ 'native_currency_name' => $row['native_currency_name'],
+ 'native_currency_decimal_places' => $row['native_currency_decimal_places'],
+ 'period' => null,
+ 'start' => $row['start'],
+ 'end' => $row['end'],
+ 'entries' => [
'spent' => $row['spent'],
'left' => $row['left'],
'overspent' => $row['overspent'],
],
- 'native_entries' => [
+ 'native_entries' => [
'spent' => $row['native_spent'],
'left' => $row['native_left'],
'overspent' => $row['native_overspent'],
@@ -155,6 +148,7 @@ class BudgetController extends Controller
];
$return[] = $current;
}
+
return $return;
}
@@ -162,33 +156,26 @@ class BudgetController extends Controller
* When no budget limits are present, the expenses of the whole period are collected and grouped.
* This is grouped per currency. Because there is no limit set, "left to spend" and "overspent" are empty.
*
- * @param Budget $budget
- * @param Carbon $start
- * @param Carbon $end
- *
- * @return array
* @throws FireflyException
*/
private function noBudgetLimits(Budget $budget, Carbon $start, Carbon $end): array
{
- $budgetId = (int)$budget->id;
- $spent = $this->opsRepository->listExpenses($start, $end, null, new Collection([$budget]));
- return $this->processExpenses($budgetId, $spent, $start, $end);
+ $spent = $this->opsRepository->listExpenses($start, $end, null, new Collection([$budget]));
+
+ return $this->processExpenses($budget->id, $spent, $start, $end);
}
/**
- * Shared between the "noBudgetLimits" function and "processLimit".
+ * Shared between the "noBudgetLimits" function and "processLimit". Will take a single set of expenses and return
+ * its info.
*
- * Will take a single set of expenses and return its info.
+ * @param array> $array
*
- * @param int $budgetId
- * @param array $array
- *
- * @return array
* @throws FireflyException
*/
private function processExpenses(int $budgetId, array $array, Carbon $start, Carbon $end): array
{
+ Log::debug(sprintf('Created new ExchangeRateConverter in %s', __METHOD__));
$converter = new ExchangeRateConverter();
$return = [];
@@ -200,36 +187,35 @@ class BudgetController extends Controller
* @var array $block
*/
foreach ($array as $currencyId => $block) {
- $this->currencies[$currencyId] = $this->currencies[$currencyId] ?? TransactionCurrency::find($currencyId);
- $return[$currencyId] = $return[$currencyId] ?? [
- 'currency_id' => (string)$currencyId,
- 'currency_code' => $block['currency_code'],
- 'currency_name' => $block['currency_name'],
- 'currency_symbol' => $block['currency_symbol'],
- 'currency_decimal_places' => (int)$block['currency_decimal_places'],
- 'native_id' => (string)$this->currency->id,
- 'native_code' => $this->currency->code,
- 'native_name' => $this->currency->name,
- 'native_symbol' => $this->currency->symbol,
- 'native_decimal_places' => (int)$this->currency->decimal_places,
- 'start' => $start->toAtomString(),
- 'end' => $end->toAtomString(),
- 'spent' => '0',
- 'native_spent' => '0',
- 'left' => '0',
- 'native_left' => '0',
- 'overspent' => '0',
- 'native_overspent' => '0',
-
+ $this->currencies[$currencyId] ??= TransactionCurrency::find($currencyId);
+ $return[$currencyId] ??= [
+ 'currency_id' => (string)$currencyId,
+ 'currency_code' => $block['currency_code'],
+ 'currency_name' => $block['currency_name'],
+ 'currency_symbol' => $block['currency_symbol'],
+ 'currency_decimal_places' => (int)$block['currency_decimal_places'],
+ 'native_currency_id' => (string)$this->currency->id,
+ 'native_currency_code' => $this->currency->code,
+ 'native_currency_name' => $this->currency->name,
+ 'native_currency_symbol' => $this->currency->symbol,
+ 'native_currency_decimal_places' => $this->currency->decimal_places,
+ 'start' => $start->toAtomString(),
+ 'end' => $end->toAtomString(),
+ 'spent' => '0',
+ 'native_spent' => '0',
+ 'left' => '0',
+ 'native_left' => '0',
+ 'overspent' => '0',
+ 'native_overspent' => '0',
];
- $currentBudgetArray = $block['budgets'][$budgetId];
- //var_dump($return);
+ $currentBudgetArray = $block['budgets'][$budgetId];
+
+ // var_dump($return);
/** @var array $journal */
foreach ($currentBudgetArray['transaction_journals'] as $journal) {
-
// convert the amount to the native currency.
- $rate = $converter->getCurrencyRate($this->currencies[$currencyId], $this->currency, $journal['date']);
- $convertedAmount = bcmul($journal['amount'], $rate);
+ $rate = $converter->getCurrencyRate($this->currencies[$currencyId], $this->currency, $journal['date']);
+ $convertedAmount = bcmul($journal['amount'], $rate);
if ($journal['foreign_currency_id'] === $this->currency->id) {
$convertedAmount = $journal['foreign_amount'];
}
@@ -238,6 +224,8 @@ class BudgetController extends Controller
$return[$currencyId]['native_spent'] = bcadd($return[$currencyId]['native_spent'], $convertedAmount);
}
}
+ $converter->summarize();
+
return $return;
}
@@ -249,16 +237,13 @@ class BudgetController extends Controller
*
* If you have a budget limit in EUR, and a transaction in GBP, it will not be considered for the EUR budget limit.
*
- * @param Budget $budget
- * @param Collection $limits
- *
- * @return array
* @throws FireflyException
*/
private function budgetLimits(Budget $budget, Collection $limits): array
{
app('log')->debug(sprintf('Now in budgetLimits(#%d)', $budget->id));
$data = [];
+
/** @var BudgetLimit $limit */
foreach ($limits as $limit) {
$data = array_merge($data, $this->processLimit($budget, $limit));
@@ -268,26 +253,21 @@ class BudgetController extends Controller
}
/**
- * @param Budget $budget
- * @param BudgetLimit $limit
- *
- * @return array
* @throws FireflyException
*/
private function processLimit(Budget $budget, BudgetLimit $limit): array
{
- $budgetId = (int)$budget->id;
- $end = clone $limit->end_date;
+ Log::debug(sprintf('Created new ExchangeRateConverter in %s', __METHOD__));
+ $end = clone $limit->end_date;
$end->endOfDay();
$spent = $this->opsRepository->listExpenses($limit->start_date, $end, null, new Collection([$budget]));
- $limitCurrencyId = (int)$limit->transaction_currency_id;
+ $limitCurrencyId = $limit->transaction_currency_id;
$limitCurrency = $limit->transactionCurrency;
$converter = new ExchangeRateConverter();
$filtered = [];
$rate = $converter->getCurrencyRate($limitCurrency, $this->currency, $limit->start_date);
$convertedLimitAmount = bcmul($limit->amount, $rate);
-
/** @var array $entry */
foreach ($spent as $currencyId => $entry) {
// only spent the entry where the entry's currency matches the budget limit's currency
@@ -296,9 +276,9 @@ class BudgetController extends Controller
$filtered[$currencyId] = $entry;
}
}
- $result = $this->processExpenses($budgetId, $filtered, $limit->start_date, $end);
+ $result = $this->processExpenses($budget->id, $filtered, $limit->start_date, $end);
if (1 === count($result)) {
- $compare = bccomp((string)$limit->amount, app('steam')->positive($result[$limitCurrencyId]['spent']));
+ $compare = bccomp($limit->amount, app('steam')->positive($result[$limitCurrencyId]['spent']));
if (1 === $compare) {
// convert this amount into the native currency:
$result[$limitCurrencyId]['left'] = bcadd($limit->amount, $result[$limitCurrencyId]['spent']);
@@ -309,8 +289,8 @@ class BudgetController extends Controller
$result[$limitCurrencyId]['native_overspent'] = app('steam')->positive(bcadd($convertedLimitAmount, $result[$limitCurrencyId]['native_spent']));
}
}
+ $converter->summarize();
+
return $result;
}
-
-
}
diff --git a/app/Api/V2/Controllers/Chart/CategoryController.php b/app/Api/V2/Controllers/Chart/CategoryController.php
index 0ca99d6c36..09124d9a8c 100644
--- a/app/Api/V2/Controllers/Chart/CategoryController.php
+++ b/app/Api/V2/Controllers/Chart/CategoryController.php
@@ -1,6 +1,5 @@
accountRepos->setUserGroup($userGroup);
}
+
return $next($request);
}
);
@@ -70,15 +71,17 @@ class CategoryController extends Controller
* TODO may be worth to move to a handler but the data is simple enough.
* TODO see autoComplete/account controller
*
- * @param DateRequest $request
- *
- * @return JsonResponse
* @throws FireflyException
+ *
+ * @SuppressWarnings(PHPMD.UnusedFormalParameter)
*/
public function dashboard(DateRequest $request): JsonResponse
{
+ Log::debug(sprintf('Created new ExchangeRateConverter in %s', __METHOD__));
+
/** @var Carbon $start */
- $start = $this->parameters->get('start');
+ $start = $this->parameters->get('start');
+
/** @var Carbon $end */
$end = $this->parameters->get('end');
$accounts = $this->accountRepos->getAccountsByType([AccountType::DEBT, AccountType::LOAN, AccountType::MORTGAGE, AccountType::ASSET, AccountType::DEFAULT]);
@@ -89,56 +92,56 @@ class CategoryController extends Controller
// get journals for entire period:
/** @var GroupCollectorInterface $collector */
- $collector = app(GroupCollectorInterface::class);
+ $collector = app(GroupCollectorInterface::class);
$collector->setRange($start, $end)->withAccountInformation();
$collector->setXorAccounts($accounts)->withCategoryInformation();
$collector->setTypes([TransactionType::WITHDRAWAL, TransactionType::RECONCILIATION]);
- $journals = $collector->getExtractedJournals();
+ $journals = $collector->getExtractedJournals();
/** @var array $journal */
foreach ($journals as $journal) {
- $currencyId = (int)$journal['currency_id'];
- $currency = $currencies[$currencyId] ?? $this->currencyRepos->find($currencyId);
- $currencies[$currencyId] = $currency;
- $categoryName = null === $journal['category_name'] ? (string)trans('firefly.no_category') : $journal['category_name'];
- $amount = app('steam')->positive($journal['amount']);
- $nativeAmount = $converter->convert($default, $currency, $journal['date'], $amount);
- $key = sprintf('%s-%s', $categoryName, $currency->code);
- if ((int)$journal['foreign_currency_id'] === (int)$default->id) {
+ $currencyId = (int)$journal['currency_id'];
+ $currency = $currencies[$currencyId] ?? $this->currencyRepos->find($currencyId);
+ $currencies[$currencyId] = $currency;
+ $categoryName = null === $journal['category_name'] ? (string)trans('firefly.no_category') : $journal['category_name'];
+ $amount = app('steam')->positive($journal['amount']);
+ $nativeAmount = $converter->convert($default, $currency, $journal['date'], $amount);
+ $key = sprintf('%s-%s', $categoryName, $currency->code);
+ if ((int)$journal['foreign_currency_id'] === $default->id) {
$nativeAmount = app('steam')->positive($journal['foreign_amount']);
}
// create arrays
- $return[$key] = $return[$key] ?? [
- 'label' => $categoryName,
- 'currency_id' => (string)$currency->id,
- 'currency_code' => $currency->code,
- 'currency_name' => $currency->name,
- 'currency_symbol' => $currency->symbol,
- 'currency_decimal_places' => (int)$currency->decimal_places,
- 'native_id' => (string)$default->id,
- 'native_code' => $default->code,
- 'native_name' => $default->name,
- 'native_symbol' => $default->symbol,
- 'native_decimal_places' => (int)$default->decimal_places,
- 'period' => null,
- 'start' => $start->toAtomString(),
- 'end' => $end->toAtomString(),
- 'amount' => '0',
- 'native_amount' => '0',
+ $return[$key] ??= [
+ 'label' => $categoryName,
+ 'currency_id' => (string)$currency->id,
+ 'currency_code' => $currency->code,
+ 'currency_name' => $currency->name,
+ 'currency_symbol' => $currency->symbol,
+ 'currency_decimal_places' => $currency->decimal_places,
+ 'native_currency_id' => (string)$default->id,
+ 'native_currency_code' => $default->code,
+ 'native_currency_name' => $default->name,
+ 'native_currency_symbol' => $default->symbol,
+ 'native_currency_decimal_places' => $default->decimal_places,
+ 'period' => null,
+ 'start' => $start->toAtomString(),
+ 'end' => $end->toAtomString(),
+ 'amount' => '0',
+ 'native_amount' => '0',
];
-
// add monies
$return[$key]['amount'] = bcadd($return[$key]['amount'], $amount);
$return[$key]['native_amount'] = bcadd($return[$key]['native_amount'], $nativeAmount);
}
- $return = array_values($return);
+ $return = array_values($return);
// order by native amount
- usort($return, function (array $a, array $b) {
+ usort($return, static function (array $a, array $b) {
return (float)$a['native_amount'] < (float)$b['native_amount'] ? 1 : -1;
});
+ $converter->summarize();
+
return response()->json($this->clean($return));
}
-
}
diff --git a/app/Api/V2/Controllers/Controller.php b/app/Api/V2/Controllers/Controller.php
index 6783b2e812..99f30570d0 100644
--- a/app/Api/V2/Controllers/Controller.php
+++ b/app/Api/V2/Controllers/Controller.php
@@ -33,7 +33,6 @@ use Illuminate\Database\Eloquent\Model;
use Illuminate\Pagination\LengthAwarePaginator;
use Illuminate\Routing\Controller as BaseController;
use Illuminate\Support\Collection;
-use Illuminate\Support\Facades\Log;
use League\Fractal\Manager;
use League\Fractal\Pagination\IlluminatePaginatorAdapter;
use League\Fractal\Resource\Collection as FractalCollection;
@@ -46,17 +45,17 @@ use Symfony\Component\HttpFoundation\ParameterBag;
/**
* Class Controller
+ *
+ * @SuppressWarnings(PHPMD.CouplingBetweenObjects)
+ * @SuppressWarnings(PHPMD.NumberOfChildren)
*/
class Controller extends BaseController
{
use ValidatesUserGroupTrait;
- protected const CONTENT_TYPE = 'application/vnd.api+json';
+ protected const string CONTENT_TYPE = 'application/vnd.api+json';
protected ParameterBag $parameters;
- /**
- *
- */
public function __construct()
{
$this->middleware(
@@ -66,22 +65,22 @@ class Controller extends BaseController
return $next($request);
}
);
-
}
/**
* TODO duplicate from V1 controller
* Method to grab all parameters from the URL.
*
- * @return ParameterBag
+ * @SuppressWarnings(PHPMD.NPathComplexity)
*/
private function getParameters(): ParameterBag
{
- $bag = new ParameterBag();
+ $bag = new ParameterBag();
$bag->set('limit', 50);
+
try {
$page = (int)request()->get('page');
- } catch (ContainerExceptionInterface | NotFoundExceptionInterface $e) {
+ } catch (ContainerExceptionInterface|NotFoundExceptionInterface $e) {
$page = 1;
}
@@ -100,19 +99,20 @@ class Controller extends BaseController
foreach ($dates as $field) {
$date = null;
$obj = null;
+
try {
$date = request()->query->get($field);
} catch (BadRequestException $e) {
- Log::error(sprintf('Request field "%s" contains a non-scalar value. Value set to NULL.', $field));
- Log::error($e->getMessage());
- Log::error($e->getTraceAsString());
+ app('log')->error(sprintf('Request field "%s" contains a non-scalar value. Value set to NULL.', $field));
+ app('log')->error($e->getMessage());
+ app('log')->error($e->getTraceAsString());
}
if (null !== $date) {
try {
- $obj = Carbon::parse($date, config('app.timezone'));
- } catch (InvalidDateException | InvalidFormatException $e) {
+ $obj = Carbon::parse((string)$date, config('app.timezone'));
+ } catch (InvalidDateException|InvalidFormatException $e) {
// don't care
- app('log')->warning(sprintf('Ignored invalid date "%s" in API v2 controller parameter check: %s', substr($date, 0, 20), $e->getMessage()));
+ app('log')->warning(sprintf('Ignored invalid date "%s" in API v2 controller parameter check: %s', substr((string)$date, 0, 20), $e->getMessage()));
}
// out of range? set to null.
if (null !== $obj && ($obj->year <= 1900 || $obj->year > 2099)) {
@@ -128,8 +128,8 @@ class Controller extends BaseController
try {
$value = request()->query->get($integer);
} catch (BadRequestException $e) {
- Log::error(sprintf('Request field "%s" contains a non-scalar value. Value set to NULL.', $integer));
- Log::error($e->getMessage());
+ app('log')->error(sprintf('Request field "%s" contains a non-scalar value. Value set to NULL.', $integer));
+ app('log')->error($e->getMessage());
$value = null;
}
if (null !== $value) {
@@ -148,20 +148,13 @@ class Controller extends BaseController
return $bag;
}
- /**
- * @param string $key
- * @param LengthAwarePaginator $paginator
- * @param AbstractTransformer $transformer
- *
- * @return array
- */
final protected function jsonApiList(string $key, LengthAwarePaginator $paginator, AbstractTransformer $transformer): array
{
- $manager = new Manager();
- $baseUrl = request()->getSchemeAndHttpHost() . '/api/v2';
+ $manager = new Manager();
+ $baseUrl = request()->getSchemeAndHttpHost().'/api/v2';
$manager->setSerializer(new JsonApiSerializer($baseUrl));
- $objects = $paginator->getCollection();
+ $objects = $paginator->getCollection();
// the transformer, at this point, needs to collect information that ALL items in the collection
// require, like meta-data and stuff like that, and save it for later.
@@ -176,17 +169,13 @@ class Controller extends BaseController
/**
* Returns a JSON API object and returns it.
*
- * @param string $key
- * @param Model $object
- * @param AbstractTransformer $transformer
- *
- * @return array
+ * @param array|Model $object
*/
- final protected function jsonApiObject(string $key, array | Model $object, AbstractTransformer $transformer): array
+ final protected function jsonApiObject(string $key, array|Model $object, AbstractTransformer $transformer): array
{
// create some objects:
- $manager = new Manager();
- $baseUrl = request()->getSchemeAndHttpHost() . '/api/v2';
+ $manager = new Manager();
+ $baseUrl = request()->getSchemeAndHttpHost().'/api/v2';
$manager->setSerializer(new JsonApiSerializer($baseUrl));
$transformer->collectMetaData(new Collection([$object]));
diff --git a/app/Api/V2/Controllers/Data/Bulk/AccountController.php b/app/Api/V2/Controllers/Data/Bulk/AccountController.php
index d869b8843f..3dbfd0343d 100644
--- a/app/Api/V2/Controllers/Data/Bulk/AccountController.php
+++ b/app/Api/V2/Controllers/Data/Bulk/AccountController.php
@@ -29,6 +29,4 @@ use FireflyIII\Api\V2\Controllers\Controller;
/**
* Class AccountController
*/
-class AccountController extends Controller
-{
-}
+class AccountController extends Controller {}
diff --git a/app/Api/V2/Controllers/Data/Export/AccountController.php b/app/Api/V2/Controllers/Data/Export/AccountController.php
index 3787530d57..4526f0f399 100644
--- a/app/Api/V2/Controllers/Data/Export/AccountController.php
+++ b/app/Api/V2/Controllers/Data/Export/AccountController.php
@@ -29,6 +29,4 @@ use FireflyIII\Api\V2\Controllers\Controller;
/**
* Class AccountController
*/
-class AccountController extends Controller
-{
-}
+class AccountController extends Controller {}
diff --git a/app/Api/V2/Controllers/Data/MassDestroy/AccountController.php b/app/Api/V2/Controllers/Data/MassDestroy/AccountController.php
index 51c18b60fe..6d11f3473e 100644
--- a/app/Api/V2/Controllers/Data/MassDestroy/AccountController.php
+++ b/app/Api/V2/Controllers/Data/MassDestroy/AccountController.php
@@ -29,6 +29,4 @@ use FireflyIII\Api\V2\Controllers\Controller;
/**
* Class AccountController
*/
-class AccountController extends Controller
-{
-}
+class AccountController extends Controller {}
diff --git a/app/Api/V2/Controllers/Model/Account/ShowController.php b/app/Api/V2/Controllers/Model/Account/ShowController.php
index 8f62d0b94d..e6c43c7cf1 100644
--- a/app/Api/V2/Controllers/Model/Account/ShowController.php
+++ b/app/Api/V2/Controllers/Model/Account/ShowController.php
@@ -28,9 +28,10 @@ use FireflyIII\Api\V2\Controllers\Controller;
use FireflyIII\Models\Account;
use FireflyIII\Transformers\V2\AccountTransformer;
use Illuminate\Http\JsonResponse;
-use Illuminate\Http\Request;
/**
+ * Show = show a single account.
+ * Index = show all accounts
* Class ShowController
*/
class ShowController extends Controller
@@ -38,13 +39,14 @@ class ShowController extends Controller
/**
* TODO this endpoint is not yet reachable.
*/
- public function show(Request $request, Account $account): JsonResponse
+ public function show(Account $account): JsonResponse
{
$transformer = new AccountTransformer();
$transformer->setParameters($this->parameters);
return response()
->api($this->jsonApiObject('accounts', $account, $transformer))
- ->header('Content-Type', self::CONTENT_TYPE);
+ ->header('Content-Type', self::CONTENT_TYPE)
+ ;
}
}
diff --git a/app/Api/V2/Controllers/Model/Bill/IndexController.php b/app/Api/V2/Controllers/Model/Bill/IndexController.php
new file mode 100644
index 0000000000..3ddc846b36
--- /dev/null
+++ b/app/Api/V2/Controllers/Model/Bill/IndexController.php
@@ -0,0 +1,80 @@
+.
+ */
+
+declare(strict_types=1);
+
+namespace FireflyIII\Api\V2\Controllers\Model\Bill;
+
+use FireflyIII\Api\V2\Controllers\Controller;
+use FireflyIII\Repositories\UserGroups\Bill\BillRepositoryInterface;
+use FireflyIII\Support\Http\Api\ValidatesUserGroupTrait;
+use FireflyIII\Transformers\V2\BillTransformer;
+use Illuminate\Http\JsonResponse;
+use Illuminate\Pagination\LengthAwarePaginator;
+
+/**
+ * Class ShowController
+ */
+class IndexController extends Controller
+{
+ use ValidatesUserGroupTrait;
+
+ private BillRepositoryInterface $repository;
+
+ public function __construct()
+ {
+ parent::__construct();
+ $this->middleware(
+ function ($request, $next) {
+ $this->repository = app(BillRepositoryInterface::class);
+
+ // new way of user group validation
+ $userGroup = $this->validateUserGroup($request);
+ if (null !== $userGroup) {
+ $this->repository->setUserGroup($userGroup);
+ }
+
+ return $next($request);
+ }
+ );
+ }
+
+ /**
+ * TODO see autocomplete/accountcontroller for list.
+ */
+ public function index(): JsonResponse
+ {
+ $this->repository->correctOrder();
+ $bills = $this->repository->getBills();
+ $pageSize = $this->parameters->get('limit');
+ $count = $bills->count();
+ $bills = $bills->slice(($this->parameters->get('page') - 1) * $pageSize, $pageSize);
+ $paginator = new LengthAwarePaginator($bills, $count, $pageSize, $this->parameters->get('page'));
+ $transformer = new BillTransformer();
+ $transformer->setParameters($this->parameters); // give params to transformer
+
+ return response()
+ ->json($this->jsonApiList('subscriptions', $paginator, $transformer))
+ ->header('Content-Type', self::CONTENT_TYPE)
+ ;
+ }
+}
diff --git a/app/Api/V2/Controllers/Model/Bill/ShowController.php b/app/Api/V2/Controllers/Model/Bill/ShowController.php
index 6c2793fa1c..db6d59e420 100644
--- a/app/Api/V2/Controllers/Model/Bill/ShowController.php
+++ b/app/Api/V2/Controllers/Model/Bill/ShowController.php
@@ -1,6 +1,5 @@
repository = app(BillRepositoryInterface::class);
// new way of user group validation
- $userGroup = $this->validateUserGroup($request);
+ $userGroup = $this->validateUserGroup($request);
if (null !== $userGroup) {
$this->repository->setUserGroup($userGroup);
}
@@ -63,39 +58,17 @@ class ShowController extends Controller
);
}
- /**
- * @param Request $request
- *
- * TODO see autocomplete/accountcontroller for list.
- *
- * @return JsonResponse
- */
- public function index(Request $request): JsonResponse
- {
- $this->repository->correctOrder();
- $bills = $this->repository->getBills();
- $pageSize = $this->parameters->get('limit');
- $count = $bills->count();
- $bills = $bills->slice(($this->parameters->get('page') - 1) * $pageSize, $pageSize);
- $paginator = new LengthAwarePaginator($bills, $count, $pageSize, $this->parameters->get('page'));
- $transformer = new BillTransformer();
- $transformer->setParameters($this->parameters); // give params to transformer
-
- return response()
- ->json($this->jsonApiList('subscriptions', $paginator, $transformer))
- ->header('Content-Type', self::CONTENT_TYPE);
- }
-
/**
* TODO this endpoint is not documented
*/
- public function show(Request $request, Bill $bill): JsonResponse
+ public function show(Bill $bill): JsonResponse
{
$transformer = new BillTransformer();
$transformer->setParameters($this->parameters);
return response()
->api($this->jsonApiObject('subscriptions', $bill, $transformer))
- ->header('Content-Type', self::CONTENT_TYPE);
+ ->header('Content-Type', self::CONTENT_TYPE)
+ ;
}
}
diff --git a/app/Api/V2/Controllers/Model/Bill/SumController.php b/app/Api/V2/Controllers/Model/Bill/SumController.php
index 782cd940c6..76dd2dca96 100644
--- a/app/Api/V2/Controllers/Model/Bill/SumController.php
+++ b/app/Api/V2/Controllers/Model/Bill/SumController.php
@@ -26,7 +26,6 @@ namespace FireflyIII\Api\V2\Controllers\Model\Bill;
use FireflyIII\Api\V2\Controllers\Controller;
use FireflyIII\Api\V2\Request\Generic\DateRequest;
-use FireflyIII\Exceptions\FireflyException;
use FireflyIII\Repositories\UserGroups\Bill\BillRepositoryInterface;
use FireflyIII\Support\Http\Api\ValidatesUserGroupTrait;
use Illuminate\Http\JsonResponse;
@@ -40,9 +39,6 @@ class SumController extends Controller
private BillRepositoryInterface $repository;
- /**
- *
- */
public function __construct()
{
parent::__construct();
@@ -50,12 +46,11 @@ class SumController extends Controller
function ($request, $next) {
$this->repository = app(BillRepositoryInterface::class);
- $userGroup = $this->validateUserGroup($request);
+ $userGroup = $this->validateUserGroup($request);
if (null !== $userGroup) {
$this->repository->setUserGroup($userGroup);
}
-
return $next($request);
}
);
@@ -67,9 +62,7 @@ class SumController extends Controller
*
* TODO see autocomplete/accountcontroller for list.
*
- * @param DateRequest $request
- *
- * @return JsonResponse
+ * @SuppressWarnings(PHPMD.UnusedFormalParameter)
*/
public function paid(DateRequest $request): JsonResponse
{
@@ -85,9 +78,7 @@ class SumController extends Controller
*
* TODO see autocomplete/accountcontroller for list.
*
- * @param DateRequest $request
- *
- * @return JsonResponse
+ * @SuppressWarnings(PHPMD.UnusedFormalParameter)
*/
public function unpaid(DateRequest $request): JsonResponse
{
diff --git a/app/Api/V2/Controllers/Model/Budget/ListController.php b/app/Api/V2/Controllers/Model/Budget/IndexController.php
similarity index 75%
rename from app/Api/V2/Controllers/Model/Budget/ListController.php
rename to app/Api/V2/Controllers/Model/Budget/IndexController.php
index b7bbaff1c7..a1b7ab41c6 100644
--- a/app/Api/V2/Controllers/Model/Budget/ListController.php
+++ b/app/Api/V2/Controllers/Model/Budget/IndexController.php
@@ -28,13 +28,12 @@ use FireflyIII\Api\V2\Controllers\Controller;
use FireflyIII\Repositories\Budget\BudgetRepositoryInterface;
use FireflyIII\Transformers\V2\BudgetTransformer;
use Illuminate\Http\JsonResponse;
-use Illuminate\Http\Request;
use Illuminate\Pagination\LengthAwarePaginator;
/**
- * Class ListController
+ * Class IndexController
*/
-class ListController extends Controller
+class IndexController extends Controller
{
private BudgetRepositoryInterface $repository;
@@ -53,24 +52,20 @@ class ListController extends Controller
/**
* This endpoint is documented at:
* https://api-docs.firefly-iii.org/?urls.primaryName=2.0.0%20(v2)#/budgets/listBudgets
- *
- * @param Request $request
- *
- * @return JsonResponse
*/
- public function index(Request $request): JsonResponse
+ public function index(): JsonResponse
{
- echo 'this needs move to Administration';
- exit;
- $collection = $this->repository->getActiveBudgets();
- $total = $collection->count();
- $collection->slice($this->pageXSize * $this->parameters->get('page'), $this->pXageSize);
+ $pageSize = $this->parameters->get('limit');
+ $collection = $this->repository->getActiveBudgets();
+ $total = $collection->count();
+ $collection->slice($pageSize * $this->parameters->get('page'), $pageSize);
- $paginator = new LengthAwarePaginator($collection, $total, $this->pagXeSize, $this->parameters->get('page'));
+ $paginator = new LengthAwarePaginator($collection, $total, $pageSize, $this->parameters->get('page'));
$transformer = new BudgetTransformer();
return response()
->api($this->jsonApiList('budgets', $paginator, $transformer))
- ->header('Content-Type', self::CONTENT_TYPE);
+ ->header('Content-Type', self::CONTENT_TYPE)
+ ;
}
}
diff --git a/app/Api/V2/Controllers/Model/Budget/ShowController.php b/app/Api/V2/Controllers/Model/Budget/ShowController.php
index 70a0490b45..6e5f9499c1 100644
--- a/app/Api/V2/Controllers/Model/Budget/ShowController.php
+++ b/app/Api/V2/Controllers/Model/Budget/ShowController.php
@@ -1,6 +1,5 @@
getAll();
- $result = $this->repository->budgetedInPeriodForBudget($budget, $data['start'], $data['end']);
- $converted = $this->cerSum(array_values($result));
+ $data = $request->getAll();
+ $result = $this->repository->budgetedInPeriodForBudget($budget, $data['start'], $data['end']);
- return response()->json($converted);
+ return response()->json($result);
+ }
+
+ /**
+ * Show a budget.
+ */
+ public function show(Budget $budget): JsonResponse
+ {
+ $transformer = new BudgetTransformer();
+ $transformer->setParameters($this->parameters);
+
+ return response()
+ ->api($this->jsonApiObject('budgets', $budget, $transformer))
+ ->header('Content-Type', self::CONTENT_TYPE)
+ ;
}
/**
* This endpoint is documented at:
* TODO add URL
- *
*/
public function spent(DateRequest $request, Budget $budget): JsonResponse
{
- $data = $request->getAll();
- $result = $this->repository->spentInPeriodForBudget($budget, $data['start'], $data['end']);
- $converted = $this->cerSum(array_values($result));
+ $data = $request->getAll();
+ $result = $this->repository->spentInPeriodForBudget($budget, $data['start'], $data['end']);
- return response()->json($converted);
+ return response()->json($result);
}
}
diff --git a/app/Api/V2/Controllers/Model/Budget/SumController.php b/app/Api/V2/Controllers/Model/Budget/SumController.php
index 394ee1bc00..0147fd061c 100644
--- a/app/Api/V2/Controllers/Model/Budget/SumController.php
+++ b/app/Api/V2/Controllers/Model/Budget/SumController.php
@@ -26,9 +26,7 @@ namespace FireflyIII\Api\V2\Controllers\Model\Budget;
use FireflyIII\Api\V2\Controllers\Controller;
use FireflyIII\Api\V2\Request\Generic\DateRequest;
-use FireflyIII\Exceptions\FireflyException;
use FireflyIII\Repositories\Budget\BudgetRepositoryInterface;
-use FireflyIII\Support\Http\Api\ConvertsExchangeRates;
use Illuminate\Http\JsonResponse;
/**
@@ -36,13 +34,8 @@ use Illuminate\Http\JsonResponse;
*/
class SumController extends Controller
{
- use ConvertsExchangeRates;
-
private BudgetRepositoryInterface $repository;
- /**
- *
- */
public function __construct()
{
parent::__construct();
@@ -58,34 +51,24 @@ class SumController extends Controller
/**
* This endpoint is documented at:
* https://api-docs.firefly-iii.org/?urls.primaryName=2.0.0%20(v2)#/budgets/getBudgetedForBudget
- *
- * @param DateRequest $request
- *
- * @return JsonResponse
*/
public function budgeted(DateRequest $request): JsonResponse
{
- $data = $request->getAll();
- $result = $this->repository->budgetedInPeriod($data['start'], $data['end']);
- $converted = $this->cerSum(array_values($result));
+ $data = $request->getAll();
+ $result = $this->repository->budgetedInPeriod($data['start'], $data['end']);
- return response()->json($converted);
+ return response()->json($result);
}
/**
* This endpoint is documented at:
* https://api-docs.firefly-iii.org/?urls.primaryName=2.0.0%20(v2)#/budgets/getSpentForBudget
- *
- * @param DateRequest $request
- *
- * @return JsonResponse
*/
public function spent(DateRequest $request): JsonResponse
{
- $data = $request->getAll();
- $result = $this->repository->spentInPeriod($data['start'], $data['end']);
- $converted = $this->cerSum(array_values($result));
+ $data = $request->getAll();
+ $result = $this->repository->spentInPeriod($data['start'], $data['end']);
- return response()->json($converted);
+ return response()->json($result);
}
}
diff --git a/app/Api/V2/Controllers/Model/BudgetLimit/IndexController.php b/app/Api/V2/Controllers/Model/BudgetLimit/IndexController.php
new file mode 100644
index 0000000000..c0c27c83e0
--- /dev/null
+++ b/app/Api/V2/Controllers/Model/BudgetLimit/IndexController.php
@@ -0,0 +1,65 @@
+.
+ */
+
+declare(strict_types=1);
+
+namespace FireflyIII\Api\V2\Controllers\Model\BudgetLimit;
+
+use FireflyIII\Api\V2\Controllers\Controller;
+use FireflyIII\Models\Budget;
+use FireflyIII\Repositories\Budget\BudgetLimitRepositoryInterface;
+use FireflyIII\Transformers\V2\BudgetLimitTransformer;
+use Illuminate\Http\JsonResponse;
+use Illuminate\Pagination\LengthAwarePaginator;
+
+class IndexController extends Controller
+{
+ private BudgetLimitRepositoryInterface $repository;
+
+ public function __construct()
+ {
+ parent::__construct();
+ $this->middleware(
+ function ($request, $next) {
+ $this->repository = app(BudgetLimitRepositoryInterface::class);
+
+ return $next($request);
+ }
+ );
+ }
+
+ /**
+ * This endpoint is documented at:
+ * TODO add URL
+ */
+ public function index(Budget $budget): JsonResponse
+ {
+ $pageSize = $this->parameters->get('limit');
+ $collection = $this->repository->getBudgetLimits($budget);
+ $total = $collection->count();
+ $collection->slice($pageSize * $this->parameters->get('page'), $pageSize);
+
+ $paginator = new LengthAwarePaginator($collection, $total, $pageSize, $this->parameters->get('page'));
+ $transformer = new BudgetLimitTransformer();
+
+ return response()->api($this->jsonApiList('budget-limits', $paginator, $transformer))->header('Content-Type', self::CONTENT_TYPE);
+ }
+}
diff --git a/app/Api/V2/Controllers/Model/BudgetLimit/ListController.php b/app/Api/V2/Controllers/Model/BudgetLimit/ListController.php
index cf7ef4f9d7..5272aa7a4d 100644
--- a/app/Api/V2/Controllers/Model/BudgetLimit/ListController.php
+++ b/app/Api/V2/Controllers/Model/BudgetLimit/ListController.php
@@ -25,49 +25,47 @@ declare(strict_types=1);
namespace FireflyIII\Api\V2\Controllers\Model\BudgetLimit;
use FireflyIII\Api\V2\Controllers\Controller;
-use FireflyIII\Api\V2\Request\Generic\DateRequest;
-use FireflyIII\Models\Budget;
-use FireflyIII\Repositories\Budget\BudgetLimitRepositoryInterface;
-use FireflyIII\Transformers\V2\BudgetLimitTransformer;
use Illuminate\Http\JsonResponse;
-use Illuminate\Pagination\LengthAwarePaginator;
/**
* Class ListController
*/
class ListController extends Controller
{
- private BudgetLimitRepositoryInterface $repository;
-
- public function __construct()
- {
- parent::__construct();
- $this->middleware(
- function ($request, $next) {
- $this->repository = app(BudgetLimitRepositoryInterface::class);
-
- return $next($request);
- }
- );
- }
+ // private BudgetLimitRepositoryInterface $repository;
+ //
+ // public function __construct()
+ // {
+ // parent::__construct();
+ // $this->middleware(
+ // function ($request, $next) {
+ // $this->repository = app(BudgetLimitRepositoryInterface::class);
+ //
+ // return $next($request);
+ // }
+ // );
+ // }
/**
* This endpoint is documented at:
* https://api-docs.firefly-iii.org/?urls.primaryName=2.0.0%20(v2)#/budgets/listBudgetLimitByBudget
+ * // DateRequest $request, Budget $budget
*/
- public function index(DateRequest $request, Budget $budget): JsonResponse
+ public function index(): JsonResponse
{
- $pageSize = $this->parameters->get('limit');
- $dates = $request->getAll();
- $collection = $this->repository->getBudgetLimits($budget, $dates['start'], $dates['end']);
- $total = $collection->count();
- $collection->slice($pageSize * $this->parameters->get('page'), $pageSize);
-
- $paginator = new LengthAwarePaginator($collection, $total, $pageSize, $this->parameters->get('page'));
- $transformer = new BudgetLimitTransformer();
-
- return response()
- ->api($this->jsonApiList('budget_limits', $paginator, $transformer))
- ->header('Content-Type', self::CONTENT_TYPE);
+ return response()->json([]);
+ // throw new FireflyException('Needs refactoring, move to IndexController.');
+ // $pageSize = $this->parameters->get('limit');
+ // $dates = $request->getAll();
+ // $collection = $this->repository->getBudgetLimits($budget, $dates['start'], $dates['end']);
+ // $total = $collection->count();
+ // $collection->slice($pageSize * $this->parameters->get('page'), $pageSize);
+ //
+ // $paginator = new LengthAwarePaginator($collection, $total, $pageSize, $this->parameters->get('page'));
+ // $transformer = new BudgetLimitTransformer();
+ //
+ // return response()
+ // ->api($this->jsonApiList('budget-limits', $paginator, $transformer))
+ // ->header('Content-Type', self::CONTENT_TYPE);
}
}
diff --git a/app/Api/V2/Controllers/Model/Currency/IndexController.php b/app/Api/V2/Controllers/Model/Currency/IndexController.php
new file mode 100644
index 0000000000..bcaaae0d7d
--- /dev/null
+++ b/app/Api/V2/Controllers/Model/Currency/IndexController.php
@@ -0,0 +1,72 @@
+.
+ */
+
+declare(strict_types=1);
+
+namespace FireflyIII\Api\V2\Controllers\Model\Currency;
+
+use FireflyIII\Api\V2\Controllers\Controller;
+use FireflyIII\Repositories\UserGroups\Currency\CurrencyRepositoryInterface;
+use FireflyIII\Transformers\V2\CurrencyTransformer;
+use Illuminate\Http\JsonResponse;
+use Illuminate\Pagination\LengthAwarePaginator;
+
+/**
+ * Class IndexController
+ */
+class IndexController extends Controller
+{
+ private CurrencyRepositoryInterface $repository;
+
+ public function __construct()
+ {
+ parent::__construct();
+ $this->middleware(
+ function ($request, $next) {
+ $this->repository = app(CurrencyRepositoryInterface::class);
+
+ return $next($request);
+ }
+ );
+ }
+
+ /**
+ * TODO This endpoint is not yet documented.
+ *
+ * Display a listing of the resource.
+ */
+ public function index(): JsonResponse
+ {
+ $bills = $this->repository->getAll();
+ $pageSize = $this->parameters->get('limit');
+ $count = $bills->count();
+ $bills = $bills->slice(($this->parameters->get('page') - 1) * $pageSize, $pageSize);
+ $paginator = new LengthAwarePaginator($bills, $count, $pageSize, $this->parameters->get('page'));
+ $transformer = new CurrencyTransformer();
+ $transformer->setParameters($this->parameters); // give params to transformer
+
+ return response()
+ ->json($this->jsonApiList('currencies', $paginator, $transformer))
+ ->header('Content-Type', self::CONTENT_TYPE)
+ ;
+ }
+}
diff --git a/app/Api/V2/Controllers/Model/PiggyBank/ShowController.php b/app/Api/V2/Controllers/Model/PiggyBank/IndexController.php
similarity index 87%
rename from app/Api/V2/Controllers/Model/PiggyBank/ShowController.php
rename to app/Api/V2/Controllers/Model/PiggyBank/IndexController.php
index e75e8b8866..bdad3f4cf1 100644
--- a/app/Api/V2/Controllers/Model/PiggyBank/ShowController.php
+++ b/app/Api/V2/Controllers/Model/PiggyBank/IndexController.php
@@ -1,6 +1,5 @@
repository = app(PiggyBankRepositoryInterface::class);
- $userGroup = $this->validateUserGroup($request);
+ $userGroup = $this->validateUserGroup($request);
if (null !== $userGroup) {
$this->repository->setUserGroup($userGroup);
}
@@ -61,13 +58,9 @@ class ShowController extends Controller
}
/**
- * @param Request $request
- *
* TODO see autocomplete/accountcontroller for list.
- *
- * @return JsonResponse
*/
- public function index(Request $request): JsonResponse
+ public function index(): JsonResponse
{
$piggies = $this->repository->getPiggyBanks();
$pageSize = $this->parameters->get('limit');
@@ -79,6 +72,7 @@ class ShowController extends Controller
return response()
->json($this->jsonApiList('piggy-banks', $paginator, $transformer))
- ->header('Content-Type', self::CONTENT_TYPE);
+ ->header('Content-Type', self::CONTENT_TYPE)
+ ;
}
}
diff --git a/app/Api/V2/Controllers/Model/Transaction/ShowController.php b/app/Api/V2/Controllers/Model/Transaction/ShowController.php
new file mode 100644
index 0000000000..c2adf07d15
--- /dev/null
+++ b/app/Api/V2/Controllers/Model/Transaction/ShowController.php
@@ -0,0 +1,43 @@
+.
+ */
+
+declare(strict_types=1);
+
+namespace FireflyIII\Api\V2\Controllers\Model\Transaction;
+
+use FireflyIII\Api\V2\Controllers\Controller;
+use FireflyIII\Models\TransactionGroup;
+use FireflyIII\Transformers\V2\TransactionGroupTransformer;
+use Illuminate\Http\JsonResponse;
+
+class ShowController extends Controller
+{
+ /**
+ * TODO this endpoint is not yet reachable.
+ */
+ public function show(TransactionGroup $transactionGroup): JsonResponse
+ {
+ $transformer = new TransactionGroupTransformer();
+ $transformer->setParameters($this->parameters);
+
+ return response()->api($this->jsonApiObject('transactions', $transactionGroup, $transformer))->header('Content-Type', self::CONTENT_TYPE);
+ }
+}
diff --git a/app/Api/V2/Controllers/Model/Transaction/StoreController.php b/app/Api/V2/Controllers/Model/Transaction/StoreController.php
index dc14f8b22e..d41596d714 100644
--- a/app/Api/V2/Controllers/Model/Transaction/StoreController.php
+++ b/app/Api/V2/Controllers/Model/Transaction/StoreController.php
@@ -1,6 +1,5 @@
middleware(
function ($request, $next) {
$this->groupRepository = app(TransactionGroupRepositoryInterface::class);
+
return $next($request);
}
);
@@ -63,13 +63,11 @@ class StoreController extends Controller
/**
* TODO this method is practically the same as the V1 method and borrows as much code as possible.
*
- * @return JsonResponse
* @throws FireflyException
* @throws ValidationException
*/
public function post(StoreRequest $request): JsonResponse
{
-
app('log')->debug('Now in API v2 StoreController::store()');
$data = $request->getAll();
$userGroup = $request->getUserGroup();
@@ -82,47 +80,50 @@ class StoreController extends Controller
try {
$transactionGroup = $this->groupRepository->store($data);
- } catch (DuplicateTransactionException $e) {
+ } catch (DuplicateTransactionException $e) { // @phpstan-ignore-line
app('log')->warning('Caught a duplicate transaction. Return error message.');
$validator = Validator::make(
['transactions' => [['description' => $e->getMessage()]]],
['transactions.0.description' => new IsDuplicateTransaction()]
);
- throw new ValidationException($validator, 0, $e);
- } catch (FireflyException $e) {
+
+ throw new ValidationException($validator); // @phpstan-ignore-line
+ } catch (FireflyException $e) { // @phpstan-ignore-line
app('log')->warning('Caught an exception. Return error message.');
app('log')->error($e->getMessage());
$message = sprintf('Internal exception: %s', $e->getMessage());
$validator = Validator::make(['transactions' => [['description' => $message]]], ['transactions.0.description' => new IsDuplicateTransaction()]);
- throw new ValidationException($validator, 0, $e);
+
+ throw new ValidationException($validator); // @phpstan-ignore-line
}
app('preferences')->mark();
- $applyRules = $data['apply_rules'] ?? true;
- $fireWebhooks = $data['fire_webhooks'] ?? true;
+ $applyRules = $data['apply_rules'] ?? true;
+ $fireWebhooks = $data['fire_webhooks'] ?? true;
event(new StoredTransactionGroup($transactionGroup, $applyRules, $fireWebhooks));
/** @var User $admin */
- $admin = auth()->user();
+ $admin = auth()->user();
+
// use new group collector:
/** @var GroupCollectorInterface $collector */
- $collector = app(GroupCollectorInterface::class);
+ $collector = app(GroupCollectorInterface::class);
$collector
->setUser($admin)
// filter on transaction group.
- ->setTransactionGroup($transactionGroup);
+ ->setTransactionGroup($transactionGroup)
+ ;
- $selectedGroup = $collector->getGroups()->first();
+ $selectedGroup = $collector->getGroups()->first();
if (null === $selectedGroup) {
throw new FireflyException('200032: Cannot find transaction. Possibly, a rule deleted this transaction after its creation.');
}
- $transformer = new TransactionGroupTransformer();
+ $transformer = new TransactionGroupTransformer();
$transformer->setParameters($this->parameters);
return response()
->api($this->jsonApiObject('transactions', $selectedGroup, $transformer))
- ->header('Content-Type', self::CONTENT_TYPE);
+ ->header('Content-Type', self::CONTENT_TYPE)
+ ;
}
-
-
}
diff --git a/app/Api/V2/Controllers/Model/Transaction/UpdateController.php b/app/Api/V2/Controllers/Model/Transaction/UpdateController.php
new file mode 100644
index 0000000000..61129391cf
--- /dev/null
+++ b/app/Api/V2/Controllers/Model/Transaction/UpdateController.php
@@ -0,0 +1,93 @@
+middleware(
+ function ($request, $next) {
+ $this->groupRepository = app(TransactionGroupRepositoryInterface::class);
+
+ return $next($request);
+ }
+ );
+ }
+
+ /**
+ * This endpoint is documented at:
+ * https://api-docs.firefly-iii.org/?urls.primaryName=2.0.0%20(v1)#/transactions/updateTransaction
+ *
+ * Update a transaction.
+ *
+ * @throws FireflyException
+ */
+ public function update(UpdateRequest $request, TransactionGroup $transactionGroup): JsonResponse
+ {
+ app('log')->debug('Now in update routine for transaction group [v2]!');
+ $data = $request->getAll();
+ $transactionGroup = $this->groupRepository->update($transactionGroup, $data);
+ $applyRules = $data['apply_rules'] ?? true;
+ $fireWebhooks = $data['fire_webhooks'] ?? true;
+
+ event(new UpdatedTransactionGroup($transactionGroup, $applyRules, $fireWebhooks));
+ app('preferences')->mark();
+
+ /** @var User $admin */
+ $admin = auth()->user();
+
+ // use new group collector:
+ /** @var GroupCollectorInterface $collector */
+ $collector = app(GroupCollectorInterface::class);
+ $collector->setUser($admin)->setTransactionGroup($transactionGroup);
+
+ $selectedGroup = $collector->getGroups()->first();
+ if (null === $selectedGroup) {
+ throw new FireflyException('200032: Cannot find transaction. Possibly, a rule deleted this transaction after its creation.');
+ }
+
+ $transformer = new TransactionGroupTransformer();
+ $transformer->setParameters($this->parameters);
+
+ return response()->api($this->jsonApiObject('transactions', $selectedGroup, $transformer))->header('Content-Type', self::CONTENT_TYPE);
+ }
+}
diff --git a/app/Api/V2/Controllers/Search/AccountController.php b/app/Api/V2/Controllers/Search/AccountController.php
index 9c107899cf..af87a73b5a 100644
--- a/app/Api/V2/Controllers/Search/AccountController.php
+++ b/app/Api/V2/Controllers/Search/AccountController.php
@@ -29,6 +29,4 @@ use FireflyIII\Api\V2\Controllers\Controller;
/**
* Class AccountController
*/
-class AccountController extends Controller
-{
-}
+class AccountController extends Controller {}
diff --git a/app/Api/V2/Controllers/Summary/BasicController.php b/app/Api/V2/Controllers/Summary/BasicController.php
index 3b35875c86..c166f3573b 100644
--- a/app/Api/V2/Controllers/Summary/BasicController.php
+++ b/app/Api/V2/Controllers/Summary/BasicController.php
@@ -25,7 +25,6 @@ declare(strict_types=1);
namespace FireflyIII\Api\V2\Controllers\Summary;
use Carbon\Carbon;
-use Exception;
use FireflyIII\Api\V2\Controllers\Controller;
use FireflyIII\Api\V2\Request\Generic\DateRequest;
use FireflyIII\Exceptions\FireflyException;
@@ -33,7 +32,6 @@ use FireflyIII\Helpers\Collector\GroupCollectorInterface;
use FireflyIII\Helpers\Report\NetWorthInterface;
use FireflyIII\Models\Account;
use FireflyIII\Models\AccountType;
-use FireflyIII\Models\TransactionCurrency;
use FireflyIII\Models\TransactionType;
use FireflyIII\Models\UserGroup;
use FireflyIII\Repositories\UserGroups\Account\AccountRepositoryInterface;
@@ -41,11 +39,13 @@ use FireflyIII\Repositories\UserGroups\Bill\BillRepositoryInterface;
use FireflyIII\Repositories\UserGroups\Budget\AvailableBudgetRepositoryInterface;
use FireflyIII\Repositories\UserGroups\Budget\BudgetRepositoryInterface;
use FireflyIII\Repositories\UserGroups\Budget\OperationsRepositoryInterface;
-use FireflyIII\Repositories\Currency\CurrencyRepositoryInterface;
+use FireflyIII\Repositories\UserGroups\Currency\CurrencyRepositoryInterface;
use FireflyIII\Support\Http\Api\ExchangeRateConverter;
+use FireflyIII\Support\Http\Api\SummaryBalanceGrouped;
use FireflyIII\Support\Http\Api\ValidatesUserGroupTrait;
use FireflyIII\User;
use Illuminate\Http\JsonResponse;
+use Illuminate\Support\Facades\Log;
/**
* Class BasicController
@@ -63,8 +63,6 @@ class BasicController extends Controller
/**
* BasicController constructor.
- *
-
*/
public function __construct()
{
@@ -78,7 +76,7 @@ class BasicController extends Controller
$this->currencyRepos = app(CurrencyRepositoryInterface::class);
$this->opsRepository = app(OperationsRepositoryInterface::class);
- $userGroup = $this->validateUserGroup($request);
+ $userGroup = $this->validateUserGroup($request);
if (null !== $userGroup) {
$this->abRepository->setUserGroup($userGroup);
$this->accountRepository->setUserGroup($userGroup);
@@ -96,16 +94,15 @@ class BasicController extends Controller
* This endpoint is documented at:
* https://api-docs.firefly-iii.org/?urls.primaryName=2.0.0%20(v2)#/summary/getBasicSummary
*
- * @param DateRequest $request
+ * @throws \Exception
*
- * @return JsonResponse
- * @throws Exception
+ * @SuppressWarnings(PHPMD.UnusedFormalParameter)
*/
public function basic(DateRequest $request): JsonResponse
{
// parameters for boxes:
- $start = $this->parameters->get('start');
- $end = $this->parameters->get('end');
+ $start = $this->parameters->get('start');
+ $end = $this->parameters->get('end');
// balance information:
$balanceData = $this->getBalanceInformation($start, $end);
@@ -113,34 +110,22 @@ class BasicController extends Controller
$spentData = $this->getLeftToSpendInfo($start, $end);
$netWorthData = $this->getNetWorthInfo($start, $end);
$total = array_merge($balanceData, $billData, $spentData, $netWorthData);
+
return response()->json($total);
}
/**
- * @param Carbon $start
- * @param Carbon $end
- *
- * @return array
* @throws FireflyException
*/
private function getBalanceInformation(Carbon $start, Carbon $end): array
{
- // prep some arrays:
- $incomes = [
- 'native' => '0',
- ];
- $expenses = [
- 'native' => '0',
- ];
- $sums = [
- 'native' => '0',
- ];
- $return = [];
- $currencies = [];
- $converter = new ExchangeRateConverter();
- $default = app('amount')->getDefaultCurrency();
+ $object = new SummaryBalanceGrouped();
+ $default = app('amount')->getDefaultCurrency();
+
+ $object->setDefault($default);
+
/** @var User $user */
- $user = auth()->user();
+ $user = auth()->user();
// collect income of user using the new group collector.
/** @var GroupCollectorInterface $collector */
@@ -152,33 +137,11 @@ class BasicController extends Controller
->setPage($this->parameters->get('page'))
// set types of transactions to return.
->setTypes([TransactionType::DEPOSIT])
- ->setRange($start, $end);
+ ->setRange($start, $end)
+ ;
- $set = $collector->getExtractedJournals();
- /** @var array $transactionJournal */
- foreach ($set as $transactionJournal) {
- // transaction info:
- $currencyId = (int)$transactionJournal['currency_id'];
- $amount = bcmul($transactionJournal['amount'], '-1');
- $currency = $currencies[$currencyId] ?? TransactionCurrency::find($currencyId);
- $currencies[$currencyId] = $currency;
- $nativeAmount = $converter->convert($currency, $default, $transactionJournal['date'], $amount);
- if ((int)$transactionJournal['foreign_currency_id'] === (int)$default->id) {
- // use foreign amount instead
- $nativeAmount = $transactionJournal['foreign_amount'];
- }
- // prep the arrays
- $incomes[$currencyId] = $incomes[$currencyId] ?? '0';
- $incomes['native'] = $incomes['native'] ?? '0';
- $sums[$currencyId] = $sums[$currencyId] ?? '0';
- $sums['native'] = $sums['native'] ?? '0';
-
- // add values:
- $incomes[$currencyId] = bcadd($incomes[$currencyId], $amount);
- $sums[$currencyId] = bcadd($sums[$currencyId], $amount);
- $incomes['native'] = bcadd($incomes['native'], $nativeAmount);
- $sums['native'] = bcadd($sums['native'], $nativeAmount);
- }
+ $set = $collector->getExtractedJournals();
+ $object->groupTransactions('income', $set);
// collect expenses of user using the new group collector.
/** @var GroupCollectorInterface $collector */
@@ -190,105 +153,14 @@ class BasicController extends Controller
->setPage($this->parameters->get('page'))
// set types of transactions to return.
->setTypes([TransactionType::WITHDRAWAL])
- ->setRange($start, $end);
- $set = $collector->getExtractedJournals();
+ ->setRange($start, $end)
+ ;
+ $set = $collector->getExtractedJournals();
+ $object->groupTransactions('expense', $set);
- /** @var array $transactionJournal */
- foreach ($set as $transactionJournal) {
- // transaction info
- $currencyId = (int)$transactionJournal['currency_id'];
- $amount = $transactionJournal['amount'];
- $currency = $currencies[$currencyId] ?? $this->currencyRepos->find($currencyId);
- $currencies[$currencyId] = $currency;
- $nativeAmount = $converter->convert($currency, $default, $transactionJournal['date'], $amount);
- if ((int)$transactionJournal['foreign_currency_id'] === (int)$default->id) {
- // use foreign amount instead
- $nativeAmount = $transactionJournal['foreign_amount'];
- }
-
- // prep arrays
- $expenses[$currencyId] = $expenses[$currencyId] ?? '0';
- $expenses['native'] = $expenses['native'] ?? '0';
- $sums[$currencyId] = $sums[$currencyId] ?? '0';
- $sums['native'] = $sums['native'] ?? '0';
-
- // add values
- $expenses[$currencyId] = bcadd($expenses[$currencyId], $amount);
- $sums[$currencyId] = bcadd($sums[$currencyId], $amount);
- $expenses['native'] = bcadd($expenses['native'], $nativeAmount);
- $sums['native'] = bcadd($sums['native'], $nativeAmount);
- }
-
- // create special array for native currency:
- $return[] = [
- 'key' => 'balance-in-native',
- 'value' => $sums['native'],
- 'currency_id' => (string)$default->id,
- 'currency_code' => $default->code,
- 'currency_symbol' => $default->symbol,
- 'currency_decimal_places' => $default->decimal_places,
- ];
- $return[] = [
- 'key' => 'spent-in-native',
- 'value' => $expenses['native'],
- 'currency_id' => (string)$default->id,
- 'currency_code' => $default->code,
- 'currency_symbol' => $default->symbol,
- 'currency_decimal_places' => $default->decimal_places,
- ];
- $return[] = [
- 'key' => 'earned-in-native',
- 'value' => $incomes['native'],
- 'currency_id' => (string)$default->id,
- 'currency_code' => $default->code,
- 'currency_symbol' => $default->symbol,
- 'currency_decimal_places' => $default->decimal_places,
- ];
-
- // format amounts:
- $keys = array_keys($sums);
- foreach ($keys as $currencyId) {
- if ('native' === $currencyId) {
- // skip native entries.
- continue;
- }
- $currency = $currencies[$currencyId] ?? $this->currencyRepos->find($currencyId);
- $currencies[$currencyId] = $currency;
- // create objects for big array.
- $return[] = [
- 'key' => sprintf('balance-in-%s', $currency->code),
- 'value' => $sums[$currencyId] ?? '0',
- 'currency_id' => (string)$currency->id,
- 'currency_code' => $currency->code,
- 'currency_symbol' => $currency->symbol,
- 'currency_decimal_places' => $currency->decimal_places,
- ];
- $return[] = [
- 'key' => sprintf('spent-in-%s', $currency->code),
- 'value' => $expenses[$currencyId] ?? '0',
- 'currency_id' => (string)$currency->id,
- 'currency_code' => $currency->code,
- 'currency_symbol' => $currency->symbol,
- 'currency_decimal_places' => $currency->decimal_places,
- ];
- $return[] = [
- 'key' => sprintf('earned-in-%s', $currency->code),
- 'value' => $incomes[$currencyId] ?? '0',
- 'currency_id' => (string)$currency->id,
- 'currency_code' => $currency->code,
- 'currency_symbol' => $currency->symbol,
- 'currency_decimal_places' => $currency->decimal_places,
- ];
- }
- return $return;
+ return $object->groupData();
}
- /**
- * @param Carbon $start
- * @param Carbon $end
- *
- * @return array
- */
private function getBillInformation(Carbon $start, Carbon $end): array
{
/*
@@ -298,7 +170,8 @@ class BasicController extends Controller
$paidAmount = $this->billRepository->sumPaidInRange($start, $end);
$unpaidAmount = $this->billRepository->sumUnpaidInRange($start, $end);
- $return = [];
+ $return = [];
+
/**
* @var array $info
*/
@@ -316,10 +189,10 @@ class BasicController extends Controller
$return[] = [
'key' => 'bills-paid-in-native',
'value' => $nativeAmount,
- 'currency_id' => (string)$info['native_id'],
- 'currency_code' => $info['native_code'],
- 'currency_symbol' => $info['native_symbol'],
- 'currency_decimal_places' => $info['native_decimal_places'],
+ 'currency_id' => (string)$info['native_currency_id'],
+ 'currency_code' => $info['native_currency_code'],
+ 'currency_symbol' => $info['native_currency_symbol'],
+ 'currency_decimal_places' => $info['native_currency_decimal_places'],
];
}
@@ -340,10 +213,10 @@ class BasicController extends Controller
$return[] = [
'key' => 'bills-unpaid-in-native',
'value' => $nativeAmount,
- 'currency_id' => (string)$info['native_id'],
- 'currency_code' => $info['native_code'],
- 'currency_symbol' => $info['native_symbol'],
- 'currency_decimal_places' => $info['native_decimal_places'],
+ 'currency_id' => (string)$info['native_currency_id'],
+ 'currency_code' => $info['native_currency_code'],
+ 'currency_symbol' => $info['native_currency_symbol'],
+ 'currency_decimal_places' => $info['native_currency_decimal_places'],
];
}
@@ -351,23 +224,20 @@ class BasicController extends Controller
}
/**
- * @param Carbon $start
- * @param Carbon $end
- *
- * @return array
- * @throws Exception
+ * @SuppressWarnings(PHPMD.ExcessiveMethodLength)
*/
private function getLeftToSpendInfo(Carbon $start, Carbon $end): array
{
+ Log::debug(sprintf('Created new ExchangeRateConverter in %s', __METHOD__));
app('log')->debug('Now in getLeftToSpendInfo');
- $return = [];
- $today = today(config('app.timezone'));
- $available = $this->abRepository->getAvailableBudgetWithCurrency($start, $end);
- $budgets = $this->budgetRepository->getActiveBudgets();
- $spent = $this->opsRepository->listExpenses($start, $end, null, $budgets);
- $default = app('amount')->getDefaultCurrency();
- $currencies = [];
- $converter = new ExchangeRateConverter();
+ $return = [];
+ $today = today(config('app.timezone'));
+ $available = $this->abRepository->getAvailableBudgetWithCurrency($start, $end);
+ $budgets = $this->budgetRepository->getActiveBudgets();
+ $spent = $this->opsRepository->listExpenses($start, $end, null, $budgets);
+ $default = app('amount')->getDefaultCurrency();
+ $currencies = [];
+ $converter = new ExchangeRateConverter();
// native info:
$nativeLeft = [
@@ -376,7 +246,7 @@ class BasicController extends Controller
'currency_id' => (string)$default->id,
'currency_code' => $default->code,
'currency_symbol' => $default->symbol,
- 'currency_decimal_places' => (int)$default->decimal_places,
+ 'currency_decimal_places' => $default->decimal_places,
];
$nativePerDay = [
'key' => 'left-per-day-to-spend-in-native',
@@ -384,7 +254,7 @@ class BasicController extends Controller
'currency_id' => (string)$default->id,
'currency_code' => $default->code,
'currency_symbol' => $default->symbol,
- 'currency_decimal_places' => (int)$default->decimal_places,
+ 'currency_decimal_places' => $default->decimal_places,
];
/**
@@ -393,13 +263,14 @@ class BasicController extends Controller
*/
foreach ($spent as $currencyId => $row) {
app('log')->debug(sprintf('Processing spent array in currency #%d', $currencyId));
- $currencyId = (int)$currencyId;
- $spent = '0';
- $spentNative = '0';
+ $spent = '0';
+ $spentNative = '0';
+
// get the sum from the array of transactions (double loop but who cares)
/** @var array $budget */
foreach ($row['budgets'] as $budget) {
app('log')->debug(sprintf('Processing expenses in budget "%s".', $budget['name']));
+
/** @var array $journal */
foreach ($budget['transaction_journals'] as $journal) {
$journalCurrencyId = $journal['currency_id'];
@@ -407,11 +278,11 @@ class BasicController extends Controller
$currencies[$currencyId] = $currency;
$amount = app('steam')->negative($journal['amount']);
$amountNative = $converter->convert($default, $currency, $start, $amount);
- if ((int)$journal['foreign_currency_id'] === (int)$default->id) {
+ if ((int)$journal['foreign_currency_id'] === $default->id) {
$amountNative = $journal['foreign_amount'];
}
- $spent = bcadd($spent, $amount);
- $spentNative = bcadd($spentNative, $amountNative);
+ $spent = bcadd($spent, $amount);
+ $spentNative = bcadd($spentNative, $amountNative);
}
app('log')->debug(sprintf('Total spent in budget "%s" is %s', $budget['name'], $spent));
}
@@ -427,9 +298,9 @@ class BasicController extends Controller
app('log')->debug(sprintf('Amount left is %s', $left));
// how much left per day?
- $days = $today->diffInDays($end) + 1;
- $perDay = '0';
- $perDayNative = '0';
+ $days = $today->diffInDays($end) + 1;
+ $perDay = '0';
+ $perDayNative = '0';
if (0 !== $days && bccomp($left, '0') > -1) {
$perDay = bcdiv($left, (string)$days);
}
@@ -438,7 +309,7 @@ class BasicController extends Controller
}
// left
- $return[] = [
+ $return[] = [
'key' => sprintf('left-to-spend-in-%s', $row['currency_code']),
'value' => $left,
'currency_id' => (string)$row['currency_id'],
@@ -447,10 +318,10 @@ class BasicController extends Controller
'currency_decimal_places' => (int)$row['currency_decimal_places'],
];
// left (native)
- $nativeLeft['value'] = $leftNative;
+ $nativeLeft['value'] = $leftNative;
// left per day:
- $return[] = [
+ $return[] = [
'key' => sprintf('left-per-day-to-spend-in-%s', $row['currency_code']),
'value' => $perDay,
'currency_id' => (string)$row['currency_id'],
@@ -460,25 +331,20 @@ class BasicController extends Controller
];
// left per day (native)
- $nativePerDay['value'] = $perDayNative;
+ $nativePerDay['value'] = $perDayNative;
}
- $return[] = $nativeLeft;
- $return[] = $nativePerDay;
+ $return[] = $nativeLeft;
+ $return[] = $nativePerDay;
+ $converter->summarize();
return $return;
}
- /**
- * @param Carbon $start
- * @param Carbon $end
- *
- * @return array
- */
private function getNetWorthInfo(Carbon $start, Carbon $end): array
{
/** @var UserGroup $userGroup */
- $userGroup = auth()->user()->userGroup;
- $date = today(config('app.timezone'))->startOfDay();
+ $userGroup = auth()->user()->userGroup;
+ $date = today(config('app.timezone'))->startOfDay();
// start and end in the future? use $end
if ($this->notInDateRange($date, $start, $end)) {
/** @var Carbon $date */
@@ -488,12 +354,12 @@ class BasicController extends Controller
/** @var NetWorthInterface $netWorthHelper */
$netWorthHelper = app(NetWorthInterface::class);
$netWorthHelper->setUserGroup($userGroup);
- $allAccounts = $this->accountRepository->getActiveAccountsByType(
+ $allAccounts = $this->accountRepository->getActiveAccountsByType(
[AccountType::ASSET, AccountType::DEFAULT, AccountType::LOAN, AccountType::MORTGAGE, AccountType::DEBT]
);
// filter list on preference of being included.
- $filtered = $allAccounts->filter(
+ $filtered = $allAccounts->filter(
function (Account $account) {
$includeNetWorth = $this->accountRepository->getMetaValue($account, 'include_net_worth');
@@ -501,10 +367,10 @@ class BasicController extends Controller
}
);
- $netWorthSet = $netWorthHelper->byAccounts($filtered, $date);
- $return = [];
+ $netWorthSet = $netWorthHelper->byAccounts($filtered, $date);
+ $return = [];
// in native amount
- $return[] = [
+ $return[] = [
'key' => 'net-worth-in-native',
'value' => $netWorthSet['native']['balance'],
'currency_id' => (string)$netWorthSet['native']['currency_id'],
@@ -531,13 +397,6 @@ class BasicController extends Controller
/**
* Check if date is outside session range.
- *
- * @param Carbon $date
- *
- * @param Carbon $start
- * @param Carbon $end
- *
- * @return bool
*/
protected function notInDateRange(Carbon $date, Carbon $start, Carbon $end): bool // Validate a preference
{
diff --git a/app/Api/V2/Controllers/Summary/NetWorthController.php b/app/Api/V2/Controllers/Summary/NetWorthController.php
index 553721d3f6..52921a98f7 100644
--- a/app/Api/V2/Controllers/Summary/NetWorthController.php
+++ b/app/Api/V2/Controllers/Summary/NetWorthController.php
@@ -27,7 +27,9 @@ namespace FireflyIII\Api\V2\Controllers\Summary;
use FireflyIII\Api\V2\Controllers\Controller;
use FireflyIII\Api\V2\Request\Generic\SingleDateRequest;
use FireflyIII\Helpers\Report\NetWorthInterface;
-use FireflyIII\Support\Http\Api\ConvertsExchangeRates;
+use FireflyIII\Models\Account;
+use FireflyIII\Models\AccountType;
+use FireflyIII\Repositories\UserGroups\Account\AccountRepositoryInterface;
use FireflyIII\Support\Http\Api\ValidatesUserGroupTrait;
use Illuminate\Http\JsonResponse;
@@ -37,24 +39,22 @@ use Illuminate\Http\JsonResponse;
class NetWorthController extends Controller
{
use ValidatesUserGroupTrait;
- use ConvertsExchangeRates;
- private NetWorthInterface $netWorth;
+ private NetWorthInterface $netWorth;
+ private AccountRepositoryInterface $repository;
- /**
- *
- */
public function __construct()
{
parent::__construct();
$this->middleware(
function ($request, $next) {
- $this->netWorth = app(NetWorthInterface::class);
-
+ $this->netWorth = app(NetWorthInterface::class);
+ $this->repository = app(AccountRepositoryInterface::class);
// new way of user group validation
- $userGroup = $this->validateUserGroup($request);
+ $userGroup = $this->validateUserGroup($request);
if (null !== $userGroup) {
$this->netWorth->setUserGroup($userGroup);
+ $this->repository->setUserGroup($userGroup);
}
return $next($request);
@@ -65,17 +65,24 @@ class NetWorthController extends Controller
/**
* This endpoint is documented at:
* https://api-docs.firefly-iii.org/?urls.primaryName=2.0.0%20(v2)#/net-worth/getNetWorth
- *
- * @param SingleDateRequest $request
- *
- * @return JsonResponse
*/
public function get(SingleDateRequest $request): JsonResponse
{
- $date = $request->getDate();
- $result = $this->netWorth->sumNetWorthByCurrency($date);
- $converted = $this->cerSum($result);
+ $date = $request->getDate();
+ $accounts = $this->repository->getAccountsByType([AccountType::ASSET, AccountType::DEFAULT, AccountType::LOAN, AccountType::DEBT, AccountType::MORTGAGE]);
- return response()->api($converted);
+ // filter list on preference of being included.
+ $filtered = $accounts->filter(
+ function (Account $account) {
+ $includeNetWorth = $this->repository->getMetaValue($account, 'include_net_worth');
+
+ return null === $includeNetWorth || '1' === $includeNetWorth;
+ }
+ );
+
+ // skip accounts that should not be in the net worth
+ $result = $this->netWorth->byAccounts($filtered, $date);
+
+ return response()->api($result);
}
}
diff --git a/app/Api/V2/Controllers/System/ConfigurationController.php b/app/Api/V2/Controllers/System/ConfigurationController.php
index 0002de25a4..e7c9b63ec6 100644
--- a/app/Api/V2/Controllers/System/ConfigurationController.php
+++ b/app/Api/V2/Controllers/System/ConfigurationController.php
@@ -27,6 +27,4 @@ namespace FireflyIII\Api\V2\Controllers\System;
/**
* Class ConfigurationController
*/
-class ConfigurationController
-{
-}
+class ConfigurationController {}
diff --git a/app/Api/V2/Controllers/System/DebugController.php b/app/Api/V2/Controllers/System/DebugController.php
index 5f9838c023..d87a51973c 100644
--- a/app/Api/V2/Controllers/System/DebugController.php
+++ b/app/Api/V2/Controllers/System/DebugController.php
@@ -29,6 +29,4 @@ use FireflyIII\Api\V2\Controllers\Controller;
/**
* Class DebugController
*/
-class DebugController extends Controller
-{
-}
+class DebugController extends Controller {}
diff --git a/app/Api/V2/Controllers/System/PreferencesController.php b/app/Api/V2/Controllers/System/PreferencesController.php
index 915ab2ce3d..5cc40ea225 100644
--- a/app/Api/V2/Controllers/System/PreferencesController.php
+++ b/app/Api/V2/Controllers/System/PreferencesController.php
@@ -37,15 +37,12 @@ class PreferencesController extends Controller
/**
* This endpoint is documented at:
* https://api-docs.firefly-iii.org/?urls.primaryName=2.0.0%20(v2)#/preferences/getPreference
- *
- * @param Preference $preference
- *
- * @return JsonResponse
*/
public function get(Preference $preference): JsonResponse
{
return response()
->json($this->jsonApiObject('preferences', $preference, new PreferenceTransformer()))
- ->header('Content-Type', self::CONTENT_TYPE);
+ ->header('Content-Type', self::CONTENT_TYPE)
+ ;
}
}
diff --git a/app/Api/V2/Controllers/System/VersionUpdateController.php b/app/Api/V2/Controllers/System/VersionUpdateController.php
index 35d4b3fb3f..979bdb1ece 100644
--- a/app/Api/V2/Controllers/System/VersionUpdateController.php
+++ b/app/Api/V2/Controllers/System/VersionUpdateController.php
@@ -29,6 +29,4 @@ use FireflyIII\Api\V2\Controllers\Controller;
/**
* Class VersionUpdateController
*/
-class VersionUpdateController extends Controller
-{
-}
+class VersionUpdateController extends Controller {}
diff --git a/app/Api/V2/Controllers/Transaction/List/AccountController.php b/app/Api/V2/Controllers/Transaction/List/AccountController.php
index ceb6f7802d..56f9c612e1 100644
--- a/app/Api/V2/Controllers/Transaction/List/AccountController.php
+++ b/app/Api/V2/Controllers/Transaction/List/AccountController.php
@@ -43,30 +43,25 @@ class AccountController extends Controller
/**
* This endpoint is documented at:
* https://api-docs.firefly-iii.org/?urls.primaryName=2.0.0%20(v2)#/accounts/listTransactionByAccount
- *
- * @param ListRequest $request
- * @param Account $account
- *
- * @return JsonResponse
*/
public function list(ListRequest $request, Account $account): JsonResponse
{
// collect transactions:
- $page = $request->getPage();
- $page = max($page, 1);
- $pageSize = $this->parameters->get('limit');
-
+ $page = $request->getPage();
+ $page = max($page, 1);
+ $pageSize = $this->parameters->get('limit');
/** @var GroupCollectorInterface $collector */
$collector = app(GroupCollectorInterface::class);
$collector->setAccounts(new Collection([$account]))
- ->withAPIInformation()
- ->setLimit($pageSize)
- ->setPage($page)
- ->setTypes($request->getTransactionTypes());
+ ->withAPIInformation()
+ ->setLimit($pageSize)
+ ->setPage($page)
+ ->setTypes($request->getTransactionTypes())
+ ;
- $start = $request->getStartDate();
- $end = $request->getEndDate();
+ $start = $request->getStartDate();
+ $end = $request->getEndDate();
if (null !== $start) {
app('log')->debug(sprintf('Set start date to %s', $start->toIso8601String()));
$collector->setStart($start);
@@ -87,6 +82,7 @@ class AccountController extends Controller
return response()
->json($this->jsonApiList('transactions', $paginator, new TransactionGroupTransformer()))
- ->header('Content-Type', self::CONTENT_TYPE);
+ ->header('Content-Type', self::CONTENT_TYPE)
+ ;
}
}
diff --git a/app/Api/V2/Controllers/Transaction/List/TransactionController.php b/app/Api/V2/Controllers/Transaction/List/TransactionController.php
index 9bcc831a16..50731dbf73 100644
--- a/app/Api/V2/Controllers/Transaction/List/TransactionController.php
+++ b/app/Api/V2/Controllers/Transaction/List/TransactionController.php
@@ -24,6 +24,7 @@ declare(strict_types=1);
namespace FireflyIII\Api\V2\Controllers\Transaction\List;
use FireflyIII\Api\V2\Controllers\Controller;
+use FireflyIII\Api\V2\Request\Model\Transaction\InfiniteListRequest;
use FireflyIII\Api\V2\Request\Model\Transaction\ListRequest;
use FireflyIII\Helpers\Collector\GroupCollectorInterface;
use FireflyIII\Transformers\V2\TransactionGroupTransformer;
@@ -34,29 +35,24 @@ use Illuminate\Http\JsonResponse;
*/
class TransactionController extends Controller
{
- /**
- * @param ListRequest $request
- *
- * @return JsonResponse
- */
public function list(ListRequest $request): JsonResponse
{
// collect transactions:
- $pageSize = $this->parameters->get('limit');
- $page = $request->getPage();
- $page = max($page, 1);
-
+ $pageSize = $this->parameters->get('limit');
+ $page = $request->getPage();
+ $page = max($page, 1);
/** @var GroupCollectorInterface $collector */
$collector = app(GroupCollectorInterface::class);
$collector->setUserGroup(auth()->user()->userGroup)
- ->withAPIInformation()
- ->setLimit($pageSize)
- ->setPage($page)
- ->setTypes($request->getTransactionTypes());
+ ->withAPIInformation()
+ ->setLimit($pageSize)
+ ->setPage($page)
+ ->setTypes($request->getTransactionTypes())
+ ;
- $start = $this->parameters->get('start');
- $end = $this->parameters->get('end');
+ $start = $this->parameters->get('start');
+ $end = $this->parameters->get('end');
if (null !== $start) {
$collector->setStart($start);
}
@@ -64,9 +60,6 @@ class TransactionController extends Controller
$collector->setEnd($end);
}
- // $collector->dumpQuery();
- // exit;
-
$paginator = $collector->getPaginatedGroups();
$params = $request->buildParams($pageSize);
$paginator->setPath(
@@ -79,8 +72,48 @@ class TransactionController extends Controller
return response()
->json($this->jsonApiList('transactions', $paginator, new TransactionGroupTransformer()))
- ->header('Content-Type', self::CONTENT_TYPE);
+ ->header('Content-Type', self::CONTENT_TYPE)
+ ;
}
+ public function infiniteList(InfiniteListRequest $request): JsonResponse
+ {
+ // get sort instructions
+ $instructions = $request->getSortInstructions();
+ // collect transactions:
+ /** @var GroupCollectorInterface $collector */
+ $collector = app(GroupCollectorInterface::class);
+ $collector->setUserGroup(auth()->user()->userGroup)
+ ->withAPIInformation()
+ ->setStartRow($request->getStartRow())
+ ->setEndRow($request->getEndRow())
+ ->setTypes($request->getTransactionTypes())
+ ->setSorting($instructions)
+ ;
+
+ $start = $this->parameters->get('start');
+ $end = $this->parameters->get('end');
+ if (null !== $start) {
+ $collector->setStart($start);
+ }
+ if (null !== $end) {
+ $collector->setEnd($end);
+ }
+
+ $paginator = $collector->getPaginatedGroups();
+ $params = $request->buildParams();
+ $paginator->setPath(
+ sprintf(
+ '%s?%s',
+ route('api.v2.infinite.transactions.list'),
+ $params
+ )
+ );
+
+ return response()
+ ->json($this->jsonApiList('transactions', $paginator, new TransactionGroupTransformer()))
+ ->header('Content-Type', self::CONTENT_TYPE)
+ ;
+ }
}
diff --git a/app/Api/V2/Controllers/Transaction/Sum/BillController.php b/app/Api/V2/Controllers/Transaction/Sum/BillController.php
index fc976b62f5..19428e98e2 100644
--- a/app/Api/V2/Controllers/Transaction/Sum/BillController.php
+++ b/app/Api/V2/Controllers/Transaction/Sum/BillController.php
@@ -29,6 +29,4 @@ use FireflyIII\Api\V2\Controllers\Controller;
/**
* Class BillController
*/
-class BillController extends Controller
-{
-}
+class BillController extends Controller {}
diff --git a/app/Api/V2/Controllers/UserGroup/DestroyController.php b/app/Api/V2/Controllers/UserGroup/DestroyController.php
index 123b9eded6..216d00b9e9 100644
--- a/app/Api/V2/Controllers/UserGroup/DestroyController.php
+++ b/app/Api/V2/Controllers/UserGroup/DestroyController.php
@@ -1,6 +1,5 @@
user();
+ $user = auth()->user();
+ // to access this function: must be group owner or sysadmin.
// need owner role or system owner role to delete user group.
- $access = $user->hasRoleInGroup($userGroup, UserRoleEnum::OWNER, false, true);
+ $access = $user->hasSpecificRoleInGroup($userGroup, UserRoleEnum::OWNER) || $user->hasRole('owner');
if (false === $access) {
throw new NotFoundHttpException();
}
$this->repository->destroy($userGroup);
+
return response()->json([], 204);
}
}
diff --git a/app/Api/V2/Controllers/UserGroup/ShowController.php b/app/Api/V2/Controllers/UserGroup/ShowController.php
index fbc441427e..3701ab81b4 100644
--- a/app/Api/V2/Controllers/UserGroup/ShowController.php
+++ b/app/Api/V2/Controllers/UserGroup/ShowController.php
@@ -1,6 +1,5 @@
parameters->get('limit');
+ $collection = new Collection();
+ $pageSize = $this->parameters->get('limit');
// if the user has the system owner role, get all. Otherwise, get only the users' groups.
if (!auth()->user()->hasRole('owner')) {
$collection = $this->repository->get();
@@ -72,8 +62,8 @@ class ShowController extends Controller
if (auth()->user()->hasRole('owner')) {
$collection = $this->repository->getAll();
}
- $count = $collection->count();
- $userGroups = $collection->slice(($this->parameters->get('page') - 1) * $pageSize, $pageSize);
+ $count = $collection->count();
+ $userGroups = $collection->slice(($this->parameters->get('page') - 1) * $pageSize, $pageSize);
$paginator = new LengthAwarePaginator($userGroups, $count, $pageSize, $this->parameters->get('page'));
$transformer = new UserGroupTransformer();
@@ -81,22 +71,18 @@ class ShowController extends Controller
return response()
->json($this->jsonApiList('user-groups', $paginator, $transformer))
- ->header('Content-Type', self::CONTENT_TYPE);
+ ->header('Content-Type', self::CONTENT_TYPE)
+ ;
}
- /**
- * @param Request $request
- * @param UserGroup $userGroup
- *
- * @return JsonResponse
- */
- public function show(Request $request, UserGroup $userGroup): JsonResponse
+ public function show(UserGroup $userGroup): JsonResponse
{
$transformer = new UserGroupTransformer();
$transformer->setParameters($this->parameters);
return response()
->api($this->jsonApiObject('user-groups', $userGroup, $transformer))
- ->header('Content-Type', self::CONTENT_TYPE);
+ ->header('Content-Type', self::CONTENT_TYPE)
+ ;
}
}
diff --git a/app/Api/V2/Controllers/UserGroup/StoreController.php b/app/Api/V2/Controllers/UserGroup/StoreController.php
index 4e74ab7c75..9b094cb3b9 100644
--- a/app/Api/V2/Controllers/UserGroup/StoreController.php
+++ b/app/Api/V2/Controllers/UserGroup/StoreController.php
@@ -1,6 +1,5 @@
getAll();
@@ -67,7 +58,7 @@ class StoreController extends Controller
return response()
->api($this->jsonApiObject('user-groups', $userGroup, $transformer))
- ->header('Content-Type', self::CONTENT_TYPE);
+ ->header('Content-Type', self::CONTENT_TYPE)
+ ;
}
-
}
diff --git a/app/Api/V2/Controllers/UserGroup/UpdateController.php b/app/Api/V2/Controllers/UserGroup/UpdateController.php
index 8630952bf6..afbcf1e9ee 100644
--- a/app/Api/V2/Controllers/UserGroup/UpdateController.php
+++ b/app/Api/V2/Controllers/UserGroup/UpdateController.php
@@ -1,6 +1,5 @@
getAll();
@@ -73,15 +63,10 @@ class UpdateController extends Controller
return response()
->api($this->jsonApiObject('user-groups', $userGroup, $transformer))
- ->header('Content-Type', self::CONTENT_TYPE);
+ ->header('Content-Type', self::CONTENT_TYPE)
+ ;
}
- /**
- * @param UpdateMembershipRequest $request
- * @param UserGroup $userGroup
- *
- * @return JsonResponse
- */
public function updateMembership(UpdateMembershipRequest $request, UserGroup $userGroup): JsonResponse
{
$all = $request->getAll();
@@ -91,6 +76,7 @@ class UpdateController extends Controller
return response()
->api($this->jsonApiObject('user-groups', $userGroup, $transformer))
- ->header('Content-Type', self::CONTENT_TYPE);
+ ->header('Content-Type', self::CONTENT_TYPE)
+ ;
}
}
diff --git a/app/Api/V2/Request/Autocomplete/AutocompleteRequest.php b/app/Api/V2/Request/Autocomplete/AutocompleteRequest.php
index 9da06a81be..8e5daf6b28 100644
--- a/app/Api/V2/Request/Autocomplete/AutocompleteRequest.php
+++ b/app/Api/V2/Request/Autocomplete/AutocompleteRequest.php
@@ -27,24 +27,18 @@ use FireflyIII\Enums\UserRoleEnum;
use FireflyIII\Models\AccountType;
use FireflyIII\Support\Request\ChecksLogin;
use FireflyIII\Support\Request\ConvertsDataTypes;
-use FireflyIII\User;
-use FireflyIII\Validation\Administration\ValidatesAdministrationAccess;
use Illuminate\Foundation\Http\FormRequest;
-use Illuminate\Validation\Validator;
/**
* Class AutocompleteRequest
*/
class AutocompleteRequest extends FormRequest
{
- use ConvertsDataTypes;
use ChecksLogin;
+ use ConvertsDataTypes;
protected array $acceptedRoles = [UserRoleEnum::MANAGE_TRANSACTIONS];
- /**
- * @return array
- */
public function getData(): array
{
$types = $this->convertString('types');
@@ -57,8 +51,6 @@ class AutocompleteRequest extends FormRequest
// remove 'initial balance' and another from allowed types. its internal
$array = array_diff($array, [AccountType::INITIAL_BALANCE, AccountType::RECONCILIATION]);
- /** @var User $user */
- $user = auth()->user();
return [
'types' => $array,
@@ -68,9 +60,6 @@ class AutocompleteRequest extends FormRequest
];
}
- /**
- * @return array
- */
public function rules(): array
{
return [
diff --git a/app/Api/V2/Request/Chart/BalanceChartRequest.php b/app/Api/V2/Request/Chart/BalanceChartRequest.php
index b2e137fe35..ed440c5d96 100644
--- a/app/Api/V2/Request/Chart/BalanceChartRequest.php
+++ b/app/Api/V2/Request/Chart/BalanceChartRequest.php
@@ -1,6 +1,5 @@
'required|date|after:1900-01-01|before:2099-12-31',
'end' => 'required|date|after_or_equal:start|before:2099-12-31|after:1900-01-01',
'accounts.*' => 'required|exists:accounts,id',
- 'period' => sprintf('required|in:%s', join(',', config('firefly.valid_view_ranges'))),
+ 'period' => sprintf('required|in:%s', implode(',', config('firefly.valid_view_ranges'))),
];
}
- /**
- * @param Validator $validator
- *
- * @return void
- */
public function withValidator(Validator $validator): void
{
$validator->after(
- function (Validator $validator) {
+ static function (Validator $validator): void {
// validate transaction query data.
$data = $validator->getData();
if (!array_key_exists('accounts', $data)) {
$validator->errors()->add('accounts', trans('validation.filled', ['attribute' => 'accounts']));
+
return;
}
if (!is_array($data['accounts'])) {
@@ -88,5 +80,8 @@ class BalanceChartRequest extends FormRequest
}
}
);
+ if ($validator->fails()) {
+ Log::channel('audit')->error(sprintf('Validation errors in %s', __CLASS__), $validator->errors()->toArray());
+ }
}
}
diff --git a/app/Api/V2/Request/Chart/DashboardChartRequest.php b/app/Api/V2/Request/Chart/DashboardChartRequest.php
new file mode 100644
index 0000000000..4b708a161d
--- /dev/null
+++ b/app/Api/V2/Request/Chart/DashboardChartRequest.php
@@ -0,0 +1,85 @@
+.
+ */
+
+declare(strict_types=1);
+
+namespace FireflyIII\Api\V2\Request\Chart;
+
+use FireflyIII\Support\Http\Api\ValidatesUserGroupTrait;
+use FireflyIII\Support\Request\ChecksLogin;
+use FireflyIII\Support\Request\ConvertsDataTypes;
+use Illuminate\Foundation\Http\FormRequest;
+use Illuminate\Support\Facades\Log;
+use Illuminate\Validation\Validator;
+
+/**
+ * Class DashboardChartRequest
+ */
+class DashboardChartRequest extends FormRequest
+{
+ use ChecksLogin;
+ use ConvertsDataTypes;
+ use ValidatesUserGroupTrait;
+
+ /**
+ * Get all data from the request.
+ */
+ public function getAll(): array
+ {
+ return [
+ 'accounts' => $this->getAccountList(),
+ 'preselected' => $this->convertString('preselected'),
+ ];
+ }
+
+ /**
+ * The rules that the incoming request must be matched against.
+ */
+ public function rules(): array
+ {
+ return [
+ 'start' => 'required|date|after:1900-01-01|before:2099-12-31',
+ 'end' => 'required|date|after_or_equal:start|before:2099-12-31|after:1900-01-01',
+ 'preselected' => sprintf('in:%s', implode(',', config('firefly.preselected_accounts'))),
+ 'accounts.*' => 'exists:accounts,id',
+ ];
+ }
+
+ public function withValidator(Validator $validator): void
+ {
+ $validator->after(
+ static function (Validator $validator): void {
+ // validate transaction query data.
+ $data = $validator->getData();
+ if (!array_key_exists('accounts', $data)) {
+ // $validator->errors()->add('accounts', trans('validation.filled', ['attribute' => 'accounts']));
+ return;
+ }
+ if (!is_array($data['accounts'])) {
+ $validator->errors()->add('accounts', trans('validation.filled', ['attribute' => 'accounts']));
+ }
+ }
+ );
+ if ($validator->fails()) {
+ Log::channel('audit')->error(sprintf('Validation errors in %s', __CLASS__), $validator->errors()->toArray());
+ }
+ }
+}
diff --git a/app/Api/V2/Request/Generic/DateRequest.php b/app/Api/V2/Request/Generic/DateRequest.php
index 4f8eff34d8..73aff18330 100644
--- a/app/Api/V2/Request/Generic/DateRequest.php
+++ b/app/Api/V2/Request/Generic/DateRequest.php
@@ -35,13 +35,11 @@ use Illuminate\Foundation\Http\FormRequest;
*/
class DateRequest extends FormRequest
{
- use ConvertsDataTypes;
use ChecksLogin;
+ use ConvertsDataTypes;
/**
* Get all data from the request.
- *
- * @return array
*/
public function getAll(): array
{
@@ -53,8 +51,6 @@ class DateRequest extends FormRequest
/**
* The rules that the incoming request must be matched against.
- *
- * @return array
*/
public function rules(): array
{
diff --git a/app/Api/V2/Request/Generic/SingleDateRequest.php b/app/Api/V2/Request/Generic/SingleDateRequest.php
index c76e6df39a..a9a3465b44 100644
--- a/app/Api/V2/Request/Generic/SingleDateRequest.php
+++ b/app/Api/V2/Request/Generic/SingleDateRequest.php
@@ -36,13 +36,11 @@ use Illuminate\Foundation\Http\FormRequest;
*/
class SingleDateRequest extends FormRequest
{
- use ConvertsDataTypes;
use ChecksLogin;
+ use ConvertsDataTypes;
/**
* Get all data from the request.
- *
- * @return Carbon
*/
public function getDate(): Carbon
{
@@ -51,8 +49,6 @@ class SingleDateRequest extends FormRequest
/**
* The rules that the incoming request must be matched against.
- *
- * @return array
*/
public function rules(): array
{
diff --git a/app/Api/V2/Request/Model/Transaction/InfiniteListRequest.php b/app/Api/V2/Request/Model/Transaction/InfiniteListRequest.php
new file mode 100644
index 0000000000..90d6df7fe0
--- /dev/null
+++ b/app/Api/V2/Request/Model/Transaction/InfiniteListRequest.php
@@ -0,0 +1,132 @@
+.
+ */
+
+declare(strict_types=1);
+
+namespace FireflyIII\Api\V2\Request\Model\Transaction;
+
+use Carbon\Carbon;
+use FireflyIII\Support\Http\Api\TransactionFilter;
+use FireflyIII\Support\Request\ChecksLogin;
+use FireflyIII\Support\Request\ConvertsDataTypes;
+use Illuminate\Foundation\Http\FormRequest;
+
+/**
+ * Class InfiniteListRequest
+ * Used specifically to list transactions.
+ */
+class InfiniteListRequest extends FormRequest
+{
+ use ChecksLogin;
+ use ConvertsDataTypes;
+ use TransactionFilter;
+
+ public function buildParams(): string
+ {
+ $array = [
+ 'start_row' => $this->getStartRow(),
+ 'end_row' => $this->getEndRow(),
+ ];
+
+ $start = $this->getStartDate();
+ $end = $this->getEndDate();
+ if (null !== $start && null !== $end) {
+ $array['start'] = $start->format('Y-m-d');
+ $array['end'] = $end->format('Y-m-d');
+ }
+
+ return http_build_query($array);
+ }
+
+ public function getStartRow(): int
+ {
+ $startRow = $this->convertInteger('start_row');
+
+ return $startRow < 0 || $startRow > 4294967296 ? 0 : $startRow;
+ }
+
+ public function getEndRow(): int
+ {
+ $endRow = $this->convertInteger('end_row');
+
+ return $endRow <= 0 || $endRow > 4294967296 ? 100 : $endRow;
+ }
+
+ public function getStartDate(): ?Carbon
+ {
+ return $this->getCarbonDate('start');
+ }
+
+ public function getEndDate(): ?Carbon
+ {
+ return $this->getCarbonDate('end');
+ }
+
+ public function getPage(): int
+ {
+ $page = $this->convertInteger('page');
+
+ return 0 === $page || $page > 65536 ? 1 : $page;
+ }
+
+ public function getSortInstructions(): array
+ {
+ $allowed = config('firefly.sorting.allowed.transactions');
+ $set = $this->get('sorting', []);
+ $result = [];
+ if (0 === count($set)) {
+ return [];
+ }
+ foreach ($set as $info) {
+ $column = $info['column'] ?? 'NOPE';
+ $direction = $info['direction'] ?? 'NOPE';
+ if ('asc' !== $direction && 'desc' !== $direction) {
+ // skip invalid direction
+ continue;
+ }
+ if (false === in_array($column, $allowed, true)) {
+ // skip invalid column
+ continue;
+ }
+ $result[$column] = $direction;
+ }
+
+ return $result;
+ }
+
+ public function getTransactionTypes(): array
+ {
+ $type = (string)$this->get('type', 'default');
+
+ return $this->mapTransactionTypes($type);
+ }
+
+ public function rules(): array
+ {
+ return [
+ 'start' => 'date',
+ 'end' => 'date|after:start',
+ 'start_row' => 'integer|min:0|max:4294967296',
+ 'end_row' => 'integer|min:0|max:4294967296|gt:start_row',
+ ];
+ }
+}
diff --git a/app/Api/V2/Request/Model/Transaction/ListRequest.php b/app/Api/V2/Request/Model/Transaction/ListRequest.php
index 8913feea10..45286d5cbf 100644
--- a/app/Api/V2/Request/Model/Transaction/ListRequest.php
+++ b/app/Api/V2/Request/Model/Transaction/ListRequest.php
@@ -40,9 +40,6 @@ class ListRequest extends FormRequest
use ConvertsDataTypes;
use TransactionFilter;
- /**
- * @return string
- */
public function buildParams(int $pageSize): string
{
$array = [
@@ -56,46 +53,34 @@ class ListRequest extends FormRequest
$array['start'] = $start->format('Y-m-d');
$array['end'] = $end->format('Y-m-d');
}
+
return http_build_query($array);
}
- /**
- * @return int
- */
public function getPage(): int
{
$page = $this->convertInteger('page');
+
return 0 === $page || $page > 65536 ? 1 : $page;
}
- /**
- * @return Carbon|null
- */
public function getStartDate(): ?Carbon
{
return $this->getCarbonDate('start');
}
- /**
- * @return Carbon|null
- */
public function getEndDate(): ?Carbon
{
return $this->getCarbonDate('end');
}
- /**
- * @return array
- */
public function getTransactionTypes(): array
{
$type = (string)$this->get('type', 'default');
+
return $this->mapTransactionTypes($type);
}
- /**
- * @return array
- */
public function rules(): array
{
return [
diff --git a/app/Api/V2/Request/Model/Transaction/StoreRequest.php b/app/Api/V2/Request/Model/Transaction/StoreRequest.php
index 4404f6f72e..872edca91e 100644
--- a/app/Api/V2/Request/Model/Transaction/StoreRequest.php
+++ b/app/Api/V2/Request/Model/Transaction/StoreRequest.php
@@ -28,6 +28,7 @@ use FireflyIII\Models\UserGroup;
use FireflyIII\Rules\BelongsUserGroup;
use FireflyIII\Rules\IsBoolean;
use FireflyIII\Rules\IsDateOrTime;
+use FireflyIII\Rules\IsValidPositiveAmount;
use FireflyIII\Support\NullArrayObject;
use FireflyIII\Support\Request\AppendsLocationData;
use FireflyIII\Support\Request\ChecksLogin;
@@ -37,6 +38,7 @@ use FireflyIII\Validation\CurrencyValidation;
use FireflyIII\Validation\GroupValidation;
use FireflyIII\Validation\TransactionValidation;
use Illuminate\Foundation\Http\FormRequest;
+use Illuminate\Support\Facades\Log;
use Illuminate\Validation\Validator;
/**
@@ -50,19 +52,18 @@ use Illuminate\Validation\Validator;
*/
class StoreRequest extends FormRequest
{
- use ChecksLogin;
- use ConvertsDataTypes;
-
- use TransactionValidation;
- use GroupValidation;
- use CurrencyValidation;
use AppendsLocationData;
+ use ChecksLogin;
+
+ use ConvertsDataTypes;
+ use CurrencyValidation;
+ use GroupValidation;
+ use TransactionValidation;
+
protected array $acceptedRoles = [UserRoleEnum::MANAGE_TRANSACTIONS];
/**
* Get all data.
- *
- * @return array
*/
public function getAll(): array
{
@@ -75,101 +76,100 @@ class StoreRequest extends FormRequest
'fire_webhooks' => $this->boolean('fire_webhooks', true),
'transactions' => $this->getTransactionData(),
];
- // TODO include location and ability to process it.
}
/**
* Get transaction data.
- *
- * @return array
*/
private function getTransactionData(): array
{
$return = [];
+
/**
* @var array $transaction
*/
foreach ($this->get('transactions') as $transaction) {
$object = new NullArrayObject($transaction);
- $return[] = [
- 'type' => $this->clearString($object['type'], false),
- 'date' => $this->dateFromValue($object['date']),
- 'order' => $this->integerFromValue((string)$object['order']),
+ $result = [
+ 'type' => $this->clearString($object['type']),
+ 'date' => $this->dateFromValue($object['date']),
+ 'order' => $this->integerFromValue((string)$object['order']),
'currency_id' => $this->integerFromValue((string)$object['currency_id']),
- 'currency_code' => $this->clearString((string)$object['currency_code'], false),
+ 'currency_code' => $this->clearString((string)$object['currency_code']),
// foreign currency info:
'foreign_currency_id' => $this->integerFromValue((string)$object['foreign_currency_id']),
- 'foreign_currency_code' => $this->clearString((string)$object['foreign_currency_code'], false),
+ 'foreign_currency_code' => $this->clearString((string)$object['foreign_currency_code']),
// amount and foreign amount. Cannot be 0.
- 'amount' => $this->clearString((string)$object['amount'], false),
- 'foreign_amount' => $this->clearString((string)$object['foreign_amount'], false),
+ 'amount' => $this->clearString((string)$object['amount']),
+ 'foreign_amount' => $this->clearString((string)$object['foreign_amount']),
// description.
- 'description' => $this->clearString($object['description'], false),
+ 'description' => $this->clearString($object['description']),
// source of transaction. If everything is null, assume cash account.
'source_id' => $this->integerFromValue((string)$object['source_id']),
- 'source_name' => $this->clearString((string)$object['source_name'], false),
- 'source_iban' => $this->clearString((string)$object['source_iban'], false),
- 'source_number' => $this->clearString((string)$object['source_number'], false),
- 'source_bic' => $this->clearString((string)$object['source_bic'], false),
+ 'source_name' => $this->clearString((string)$object['source_name']),
+ 'source_iban' => $this->clearString((string)$object['source_iban']),
+ 'source_number' => $this->clearString((string)$object['source_number']),
+ 'source_bic' => $this->clearString((string)$object['source_bic']),
// destination of transaction. If everything is null, assume cash account.
'destination_id' => $this->integerFromValue((string)$object['destination_id']),
- 'destination_name' => $this->clearString((string)$object['destination_name'], false),
- 'destination_iban' => $this->clearString((string)$object['destination_iban'], false),
- 'destination_number' => $this->clearString((string)$object['destination_number'], false),
- 'destination_bic' => $this->clearString((string)$object['destination_bic'], false),
+ 'destination_name' => $this->clearString((string)$object['destination_name']),
+ 'destination_iban' => $this->clearString((string)$object['destination_iban']),
+ 'destination_number' => $this->clearString((string)$object['destination_number']),
+ 'destination_bic' => $this->clearString((string)$object['destination_bic']),
// budget info
'budget_id' => $this->integerFromValue((string)$object['budget_id']),
- 'budget_name' => $this->clearString((string)$object['budget_name'], false),
+ 'budget_name' => $this->clearString((string)$object['budget_name']),
// category info
'category_id' => $this->integerFromValue((string)$object['category_id']),
- 'category_name' => $this->clearString((string)$object['category_name'], false),
+ 'category_name' => $this->clearString((string)$object['category_name']),
// journal bill reference. Optional. Will only work for withdrawals
'bill_id' => $this->integerFromValue((string)$object['bill_id']),
- 'bill_name' => $this->clearString((string)$object['bill_name'], false),
+ 'bill_name' => $this->clearString((string)$object['bill_name']),
// piggy bank reference. Optional. Will only work for transfers
'piggy_bank_id' => $this->integerFromValue((string)$object['piggy_bank_id']),
- 'piggy_bank_name' => $this->clearString((string)$object['piggy_bank_name'], false),
+ 'piggy_bank_name' => $this->clearString((string)$object['piggy_bank_name']),
// some other interesting properties
'reconciled' => $this->convertBoolean((string)$object['reconciled']),
- 'notes' => $this->clearString((string)$object['notes']),
+ 'notes' => $this->clearStringKeepNewlines((string)$object['notes']),
'tags' => $this->arrayFromValue($object['tags']),
// all custom fields:
- 'internal_reference' => $this->clearString((string)$object['internal_reference'], false),
- 'external_id' => $this->clearString((string)$object['external_id'], false),
+ 'internal_reference' => $this->clearString((string)$object['internal_reference']),
+ 'external_id' => $this->clearString((string)$object['external_id']),
'original_source' => sprintf('ff3-v%s|api-v%s', config('firefly.version'), config('firefly.api_version')),
'recurrence_id' => $this->integerFromValue($object['recurrence_id']),
- 'bunq_payment_id' => $this->clearString((string)$object['bunq_payment_id'], false),
- 'external_url' => $this->clearString((string)$object['external_url'], false),
+ 'bunq_payment_id' => $this->clearString((string)$object['bunq_payment_id']),
+ 'external_url' => $this->clearString((string)$object['external_url']),
- 'sepa_cc' => $this->clearString((string)$object['sepa_cc'], false),
- 'sepa_ct_op' => $this->clearString((string)$object['sepa_ct_op'], false),
- 'sepa_ct_id' => $this->clearString((string)$object['sepa_ct_id'], false),
- 'sepa_db' => $this->clearString((string)$object['sepa_db'], false),
- 'sepa_country' => $this->clearString((string)$object['sepa_country'], false),
- 'sepa_ep' => $this->clearString((string)$object['sepa_ep'], false),
- 'sepa_ci' => $this->clearString((string)$object['sepa_ci'], false),
- 'sepa_batch_id' => $this->clearString((string)$object['sepa_batch_id'], false),
+ 'sepa_cc' => $this->clearString((string)$object['sepa_cc']),
+ 'sepa_ct_op' => $this->clearString((string)$object['sepa_ct_op']),
+ 'sepa_ct_id' => $this->clearString((string)$object['sepa_ct_id']),
+ 'sepa_db' => $this->clearString((string)$object['sepa_db']),
+ 'sepa_country' => $this->clearString((string)$object['sepa_country']),
+ 'sepa_ep' => $this->clearString((string)$object['sepa_ep']),
+ 'sepa_ci' => $this->clearString((string)$object['sepa_ci']),
+ 'sepa_batch_id' => $this->clearString((string)$object['sepa_batch_id']),
// custom date fields. Must be Carbon objects. Presence is optional.
- 'interest_date' => $this->dateFromValue($object['interest_date']),
- 'book_date' => $this->dateFromValue($object['book_date']),
- 'process_date' => $this->dateFromValue($object['process_date']),
- 'due_date' => $this->dateFromValue($object['due_date']),
- 'payment_date' => $this->dateFromValue($object['payment_date']),
- 'invoice_date' => $this->dateFromValue($object['invoice_date']),
-
+ 'interest_date' => $this->dateFromValue($object['interest_date']),
+ 'book_date' => $this->dateFromValue($object['book_date']),
+ 'process_date' => $this->dateFromValue($object['process_date']),
+ 'due_date' => $this->dateFromValue($object['due_date']),
+ 'payment_date' => $this->dateFromValue($object['payment_date']),
+ 'invoice_date' => $this->dateFromValue($object['invoice_date']),
];
+ $result = $this->addFromromTransactionStore($transaction, $result);
+ $return[] = $result;
}
return $return;
@@ -177,8 +177,6 @@ class StoreRequest extends FormRequest
/**
* The rules that the incoming request must be matched against.
- *
- * @return array
*/
public function rules(): array
{
@@ -191,7 +189,7 @@ class StoreRequest extends FormRequest
return [
// basic fields for group:
- 'group_title' => 'between:1,1000|nullable',
+ 'group_title' => 'min:1|max:1000|nullable',
'error_if_duplicate_hash' => [new IsBoolean()],
'apply_rules' => [new IsBoolean()],
@@ -207,40 +205,41 @@ class StoreRequest extends FormRequest
'transactions.*.foreign_currency_code' => 'min:3|max:51|exists:transaction_currencies,code|nullable',
// amount
- 'transactions.*.amount' => 'required|numeric|gt:0',
- 'transactions.*.foreign_amount' => 'numeric',
+ 'transactions.*.amount' => ['required', new IsValidPositiveAmount()],
+ 'transactions.*.foreign_amount' => ['nullable', new IsValidPositiveAmount()],
// description
- 'transactions.*.description' => 'nullable|between:1,1000',
+ 'transactions.*.description' => 'nullable|min:1|max:1000',
// source of transaction
'transactions.*.source_id' => ['numeric', 'nullable', new BelongsUserGroup($userGroup)],
- 'transactions.*.source_name' => 'between:1,255|nullable',
- 'transactions.*.source_iban' => 'between:1,255|nullable|iban',
- 'transactions.*.source_number' => 'between:1,255|nullable',
- 'transactions.*.source_bic' => 'between:1,255|nullable|bic',
+ 'transactions.*.source_name' => 'min:1|max:255|nullable',
+ 'transactions.*.source_iban' => 'min:1|max:255|nullable|iban',
+ 'transactions.*.source_number' => 'min:1|max:255|nullable',
+ 'transactions.*.source_bic' => 'min:1|max:255|nullable|bic',
// destination of transaction
'transactions.*.destination_id' => ['numeric', 'nullable', new BelongsUserGroup($userGroup)],
- 'transactions.*.destination_name' => 'between:1,255|nullable',
- 'transactions.*.destination_iban' => 'between:1,255|nullable|iban',
- 'transactions.*.destination_number' => 'between:1,255|nullable',
- 'transactions.*.destination_bic' => 'between:1,255|nullable|bic',
+ 'transactions.*.destination_name' => 'min:1|max:255|nullable',
+ 'transactions.*.destination_iban' => 'min:1|max:255|nullable|iban',
+ 'transactions.*.destination_number' => 'min:1|max:255|nullable',
+ 'transactions.*.destination_bic' => 'min:1|max:255|nullable|bic',
// budget, category, bill and piggy
'transactions.*.budget_id' => ['mustExist:budgets,id', new BelongsUserGroup($userGroup)],
- 'transactions.*.budget_name' => ['between:1,255', 'nullable', new BelongsUserGroup($userGroup)],
+ 'transactions.*.budget_name' => ['min:1', 'max:255', 'nullable', new BelongsUserGroup($userGroup)],
'transactions.*.category_id' => ['mustExist:categories,id', new BelongsUserGroup($userGroup), 'nullable'],
- 'transactions.*.category_name' => 'between:1,255|nullable',
+ 'transactions.*.category_name' => 'min:1|max:255|nullable',
'transactions.*.bill_id' => ['numeric', 'nullable', 'mustExist:bills,id', new BelongsUserGroup($userGroup)],
- 'transactions.*.bill_name' => ['between:1,255', 'nullable', new BelongsUserGroup($userGroup)],
+ 'transactions.*.bill_name' => ['min:1', 'max:255', 'nullable', new BelongsUserGroup($userGroup)],
'transactions.*.piggy_bank_id' => ['numeric', 'nullable', 'mustExist:piggy_banks,id', new BelongsUserGroup($userGroup)],
- 'transactions.*.piggy_bank_name' => ['between:1,255', 'nullable', new BelongsUserGroup($userGroup)],
+ 'transactions.*.piggy_bank_name' => ['min:1', 'max:255', 'nullable', new BelongsUserGroup($userGroup)],
// other interesting fields
'transactions.*.reconciled' => [new IsBoolean()],
- 'transactions.*.notes' => 'min:1|max:50000|nullable',
- 'transactions.*.tags' => 'between:0,255',
+ 'transactions.*.notes' => 'min:1|max:32768|nullable',
+ 'transactions.*.tags' => 'min:0|max:255',
+ 'transactions.*.tags.*' => 'min:0|max:255',
// meta info fields
'transactions.*.internal_reference' => 'min:1|max:255|nullable',
@@ -266,24 +265,23 @@ class StoreRequest extends FormRequest
'transactions.*.due_date' => 'date|nullable',
'transactions.*.payment_date' => 'date|nullable',
'transactions.*.invoice_date' => 'date|nullable',
+
+ // TODO include location and ability to process it.
];
}
/**
* Configure the validator instance.
- *
- * @param Validator $validator
- *
- * @return void
*/
public function withValidator(Validator $validator): void
{
/** @var User $user */
- $user = auth()->user();
+ $user = auth()->user();
+
/** @var UserGroup $userGroup */
$userGroup = $this->getUserGroup();
$validator->after(
- function (Validator $validator) use ($user, $userGroup) {
+ function (Validator $validator) use ($user, $userGroup): void {
// must be valid array.
$this->validateTransactionArray($validator); // does not need group validation.
@@ -311,7 +309,8 @@ class StoreRequest extends FormRequest
$this->validateGroupDescription($validator);
}
);
+ if ($validator->fails()) {
+ Log::channel('audit')->error(sprintf('Validation errors in %s', __CLASS__), $validator->errors()->toArray());
+ }
}
-
-
}
diff --git a/app/Api/V2/Request/Model/Transaction/UpdateRequest.php b/app/Api/V2/Request/Model/Transaction/UpdateRequest.php
new file mode 100644
index 0000000000..b5a10e4e97
--- /dev/null
+++ b/app/Api/V2/Request/Model/Transaction/UpdateRequest.php
@@ -0,0 +1,366 @@
+debug(sprintf('Now in %s', __METHOD__));
+ $this->integerFields = ['order', 'currency_id', 'foreign_currency_id', 'transaction_journal_id', 'source_id', 'destination_id', 'budget_id', 'category_id', 'bill_id', 'recurrence_id'];
+ $this->dateFields = ['date', 'interest_date', 'book_date', 'process_date', 'due_date', 'payment_date', 'invoice_date'];
+ $this->textareaFields = ['notes'];
+ // not really floats, for validation.
+ $this->floatFields = ['amount', 'foreign_amount'];
+ $this->stringFields = ['type', 'currency_code', 'foreign_currency_code', 'description', 'source_name', 'source_iban', 'source_number', 'source_bic', 'destination_name', 'destination_iban', 'destination_number', 'destination_bic', 'budget_name', 'category_name', 'bill_name', 'internal_reference', 'external_id', 'bunq_payment_id', 'sepa_cc', 'sepa_ct_op', 'sepa_ct_id', 'sepa_db', 'sepa_country', 'sepa_ep', 'sepa_ci', 'sepa_batch_id', 'external_url'];
+ $this->booleanFields = ['reconciled'];
+ $this->arrayFields = ['tags'];
+ $data = [];
+ if ($this->has('transactions')) {
+ $data['transactions'] = $this->getTransactionData();
+ }
+ if ($this->has('apply_rules')) {
+ $data['apply_rules'] = $this->boolean('apply_rules', true);
+ }
+ if ($this->has('fire_webhooks')) {
+ $data['fire_webhooks'] = $this->boolean('fire_webhooks', true);
+ }
+ if ($this->has('group_title')) {
+ $data['group_title'] = $this->convertString('group_title');
+ }
+
+ return $data;
+ }
+
+ /**
+ * Get transaction data.
+ *
+ * @throws FireflyException
+ */
+ private function getTransactionData(): array
+ {
+ app('log')->debug(sprintf('Now in %s', __METHOD__));
+ $return = [];
+
+ /** @var null|array $transactions */
+ $transactions = $this->get('transactions');
+
+ if (!is_countable($transactions)) {
+ return $return;
+ }
+
+ /** @var null|array $transaction */
+ foreach ($transactions as $transaction) {
+ if (!is_array($transaction)) {
+ throw new FireflyException('Invalid data submitted: transaction is not array.');
+ }
+ // default response is to update nothing in the transaction:
+ $current = [];
+ $current = $this->getIntegerData($current, $transaction);
+ $current = $this->getStringData($current, $transaction);
+ $current = $this->getNlStringData($current, $transaction);
+ $current = $this->getDateData($current, $transaction);
+ $current = $this->getBooleanData($current, $transaction);
+ $current = $this->getArrayData($current, $transaction);
+ $current = $this->getFloatData($current, $transaction);
+ $return[] = $current;
+ }
+
+ return $return;
+ }
+
+ /**
+ * For each field, add it to the array if a reference is present in the request:
+ *
+ * @param array $current
+ * @param array $transaction
+ */
+ private function getIntegerData(array $current, array $transaction): array
+ {
+ foreach ($this->integerFields as $fieldName) {
+ if (array_key_exists($fieldName, $transaction)) {
+ $current[$fieldName] = $this->integerFromValue((string)$transaction[$fieldName]);
+ }
+ }
+
+ return $current;
+ }
+
+ /**
+ * @param array $current
+ * @param array $transaction
+ */
+ private function getStringData(array $current, array $transaction): array
+ {
+ foreach ($this->stringFields as $fieldName) {
+ if (array_key_exists($fieldName, $transaction)) {
+ $current[$fieldName] = $this->clearString((string)$transaction[$fieldName]);
+ }
+ }
+
+ return $current;
+ }
+
+ /**
+ * @param array $current
+ * @param array $transaction
+ */
+ private function getNlStringData(array $current, array $transaction): array
+ {
+ foreach ($this->textareaFields as $fieldName) {
+ if (array_key_exists($fieldName, $transaction)) {
+ $current[$fieldName] = $this->clearStringKeepNewlines((string)$transaction[$fieldName]); // keep newlines
+ }
+ }
+
+ return $current;
+ }
+
+ /**
+ * @param array $current
+ * @param array $transaction
+ */
+ private function getDateData(array $current, array $transaction): array
+ {
+ foreach ($this->dateFields as $fieldName) {
+ app('log')->debug(sprintf('Now at date field %s', $fieldName));
+ if (array_key_exists($fieldName, $transaction)) {
+ app('log')->debug(sprintf('New value: "%s"', (string)$transaction[$fieldName]));
+ $current[$fieldName] = $this->dateFromValue((string)$transaction[$fieldName]);
+ }
+ }
+
+ return $current;
+ }
+
+ /**
+ * @param array $current
+ * @param array $transaction
+ */
+ private function getBooleanData(array $current, array $transaction): array
+ {
+ foreach ($this->booleanFields as $fieldName) {
+ if (array_key_exists($fieldName, $transaction)) {
+ $current[$fieldName] = $this->convertBoolean((string)$transaction[$fieldName]);
+ }
+ }
+
+ return $current;
+ }
+
+ /**
+ * @param array $current
+ * @param array $transaction
+ */
+ private function getArrayData(array $current, array $transaction): array
+ {
+ foreach ($this->arrayFields as $fieldName) {
+ if (array_key_exists($fieldName, $transaction)) {
+ $current[$fieldName] = $this->arrayFromValue($transaction[$fieldName]);
+ }
+ }
+
+ return $current;
+ }
+
+ /**
+ * @param array $current
+ * @param array $transaction
+ */
+ private function getFloatData(array $current, array $transaction): array
+ {
+ foreach ($this->floatFields as $fieldName) {
+ if (array_key_exists($fieldName, $transaction)) {
+ $value = $transaction[$fieldName];
+ if (is_float($value)) {
+ $current[$fieldName] = sprintf('%.12f', $value);
+ }
+ if (!is_float($value)) {
+ $current[$fieldName] = (string)$value;
+ }
+ }
+ }
+
+ return $current;
+ }
+
+ /**
+ * The rules that the incoming request must be matched against.
+ */
+ public function rules(): array
+ {
+ app('log')->debug(sprintf('Now in %s', __METHOD__));
+ $validProtocols = config('firefly.valid_url_protocols');
+
+ return [
+ // basic fields for group:
+ 'group_title' => 'min:1|max:1000|nullable',
+ 'apply_rules' => [new IsBoolean()],
+
+ // transaction rules (in array for splits):
+ 'transactions.*.type' => 'in:withdrawal,deposit,transfer,opening-balance,reconciliation',
+ 'transactions.*.date' => [new IsDateOrTime()],
+ 'transactions.*.order' => 'numeric|min:0',
+
+ // group id:
+ 'transactions.*.transaction_journal_id' => ['nullable', 'numeric', new BelongsUser()],
+
+ // currency info
+ 'transactions.*.currency_id' => 'numeric|exists:transaction_currencies,id|nullable',
+ 'transactions.*.currency_code' => 'min:3|max:51|exists:transaction_currencies,code|nullable',
+ 'transactions.*.foreign_currency_id' => 'nullable|numeric|exists:transaction_currencies,id',
+ 'transactions.*.foreign_currency_code' => 'nullable|min:3|max:51|exists:transaction_currencies,code',
+
+ // amount
+ 'transactions.*.amount' => ['nullable', new IsValidPositiveAmount()],
+ 'transactions.*.foreign_amount' => ['nullable', new IsValidZeroOrMoreAmount()],
+
+ // description
+ 'transactions.*.description' => 'nullable|min:1|max:1000',
+
+ // source of transaction
+ 'transactions.*.source_id' => ['numeric', 'nullable', new BelongsUser()],
+ 'transactions.*.source_name' => 'min:1|max:255|nullable',
+
+ // destination of transaction
+ 'transactions.*.destination_id' => ['numeric', 'nullable', new BelongsUser()],
+ 'transactions.*.destination_name' => 'min:1|max:255|nullable',
+
+ // budget, category, bill and piggy
+ 'transactions.*.budget_id' => ['mustExist:budgets,id', new BelongsUser(), 'nullable'],
+ 'transactions.*.budget_name' => ['min:1', 'max:255', 'nullable', new BelongsUser()],
+ 'transactions.*.category_id' => ['mustExist:categories,id', new BelongsUser(), 'nullable'],
+ 'transactions.*.category_name' => 'min:1|max:255|nullable',
+ 'transactions.*.bill_id' => ['numeric', 'nullable', 'mustExist:bills,id', new BelongsUser()],
+ 'transactions.*.bill_name' => ['min:1', 'max:255', 'nullable', new BelongsUser()],
+
+ // other interesting fields
+ 'transactions.*.reconciled' => [new IsBoolean()],
+ 'transactions.*.notes' => 'min:1|max:32768|nullable',
+ 'transactions.*.tags' => 'min:0|max:255|nullable',
+ 'transactions.*.tags.*' => 'min:0|max:255',
+
+ // meta info fields
+ 'transactions.*.internal_reference' => 'min:1|max:255|nullable',
+ 'transactions.*.external_id' => 'min:1|max:255|nullable',
+ 'transactions.*.recurrence_id' => 'min:1|max:255|nullable',
+ 'transactions.*.bunq_payment_id' => 'min:1|max:255|nullable',
+ 'transactions.*.external_url' => sprintf('min:1|max:255|nullable|url:%s', $validProtocols),
+
+ // SEPA fields:
+ 'transactions.*.sepa_cc' => 'min:1|max:255|nullable',
+ 'transactions.*.sepa_ct_op' => 'min:1|max:255|nullable',
+ 'transactions.*.sepa_ct_id' => 'min:1|max:255|nullable',
+ 'transactions.*.sepa_db' => 'min:1|max:255|nullable',
+ 'transactions.*.sepa_country' => 'min:1|max:255|nullable',
+ 'transactions.*.sepa_ep' => 'min:1|max:255|nullable',
+ 'transactions.*.sepa_ci' => 'min:1|max:255|nullable',
+ 'transactions.*.sepa_batch_id' => 'min:1|max:255|nullable',
+
+ // dates
+ 'transactions.*.interest_date' => 'date|nullable',
+ 'transactions.*.book_date' => 'date|nullable',
+ 'transactions.*.process_date' => 'date|nullable',
+ 'transactions.*.due_date' => 'date|nullable',
+ 'transactions.*.payment_date' => 'date|nullable',
+ 'transactions.*.invoice_date' => 'date|nullable',
+ ];
+ }
+
+ /**
+ * Configure the validator instance.
+ */
+ public function withValidator(Validator $validator): void
+ {
+ app('log')->debug('Now in withValidator');
+
+ /** @var TransactionGroup $transactionGroup */
+ $transactionGroup = $this->route()->parameter('userGroupTransaction');
+ $validator->after(
+ function (Validator $validator) use ($transactionGroup): void {
+ // if more than one, verify that there are journal ID's present.
+ $this->validateJournalIds($validator, $transactionGroup);
+
+ // all transaction types must be equal:
+ $this->validateTransactionTypesForUpdate($validator);
+
+ // user wants to update a reconciled transaction.
+ // source, destination, amount + foreign_amount cannot be changed
+ // and must be omitted from the request.
+ $this->preventUpdateReconciled($validator, $transactionGroup);
+
+ // validate source/destination is equal, depending on the transaction journal type.
+ $this->validateEqualAccountsForUpdate($validator, $transactionGroup);
+
+ // see method:
+ // $this->preventNoAccountInfo($validator, );
+
+ // validate that the currency fits the source and/or destination account.
+ // validate all account info
+ $this->validateAccountInformationUpdate($validator, $transactionGroup);
+ }
+ );
+ if ($validator->fails()) {
+ Log::channel('audit')->error(sprintf('Validation errors in %s', __CLASS__), $validator->errors()->toArray());
+ }
+ }
+}
diff --git a/app/Api/V2/Request/UserGroup/StoreRequest.php b/app/Api/V2/Request/UserGroup/StoreRequest.php
index 21e5a76719..38685c84d9 100644
--- a/app/Api/V2/Request/UserGroup/StoreRequest.php
+++ b/app/Api/V2/Request/UserGroup/StoreRequest.php
@@ -1,6 +1,5 @@
'unique:user_groups,title|required|min:2|max:255',
+ 'title' => 'unique:user_groups,title|required|min:1|max:255',
];
}
}
diff --git a/app/Api/V2/Request/UserGroup/UpdateMembershipRequest.php b/app/Api/V2/Request/UserGroup/UpdateMembershipRequest.php
index 3a671268d8..c4a2fa9b81 100644
--- a/app/Api/V2/Request/UserGroup/UpdateMembershipRequest.php
+++ b/app/Api/V2/Request/UserGroup/UpdateMembershipRequest.php
@@ -1,6 +1,5 @@
value;
}
+
return [
'id' => 'exists:users,id|required_without:email',
'email' => 'exists:users,email|required_without:id',
- 'roles.*' => 'required|in:' . join(',', $validRoles),
+ 'roles.*' => 'required|in:'.implode(',', $validRoles),
];
}
}
diff --git a/app/Api/V2/Request/UserGroup/UpdateRequest.php b/app/Api/V2/Request/UserGroup/UpdateRequest.php
index d3b0481fcc..c0e0e50bb4 100644
--- a/app/Api/V2/Request/UserGroup/UpdateRequest.php
+++ b/app/Api/V2/Request/UserGroup/UpdateRequest.php
@@ -1,6 +1,5 @@
route()->parameter('userGroup');
+
return [
- 'title' => sprintf('required|min:2|max:255|unique:user_groups,title,%d', $userGroup->id),
+ 'title' => sprintf('required|min:1|max:255|unique:user_groups,title,%d', $userGroup->id),
];
}
}
diff --git a/app/Api/V2/Response/Sum/AutoSum.php b/app/Api/V2/Response/Sum/AutoSum.php
index 5953c7ed71..6ed1faa73e 100644
--- a/app/Api/V2/Response/Sum/AutoSum.php
+++ b/app/Api/V2/Response/Sum/AutoSum.php
@@ -24,7 +24,6 @@ declare(strict_types=1);
namespace FireflyIII\Api\V2\Response\Sum;
-use Closure;
use FireflyIII\Exceptions\FireflyException;
use FireflyIII\Models\TransactionCurrency;
use Illuminate\Database\Eloquent\Model;
@@ -38,24 +37,21 @@ use Illuminate\Support\Collection;
class AutoSum
{
/**
- * @param Collection $objects
- * @param Closure $getCurrency
- * @param Closure $getSum
- *
- * @return array
* @throws FireflyException
*/
- public function autoSum(Collection $objects, Closure $getCurrency, Closure $getSum): array
+ public function autoSum(Collection $objects, \Closure $getCurrency, \Closure $getSum): array
{
$return = [];
+
/** @var Model $object */
foreach ($objects as $object) {
/** @var TransactionCurrency $currency */
- $currency = $getCurrency($object);
- /** @var string $amount */
- $amount = $getSum($object);
+ $currency = $getCurrency($object);
- $return[$currency->id] = $return[$currency->id] ?? [
+ /** @var string $amount */
+ $amount = $getSum($object);
+
+ $return[$currency->id] ??= [
'id' => (string)$currency->id,
'name' => $currency->name,
'symbol' => $currency->symbol,
@@ -68,6 +64,7 @@ class AutoSum
}
var_dump(array_values($return));
+
throw new FireflyException('Not implemented');
}
}
diff --git a/app/Console/Commands/Correction/CorrectAmounts.php b/app/Console/Commands/Correction/CorrectAmounts.php
index a35b941aaa..cc7d11042b 100644
--- a/app/Console/Commands/Correction/CorrectAmounts.php
+++ b/app/Console/Commands/Correction/CorrectAmounts.php
@@ -34,7 +34,6 @@ use FireflyIII\Models\PiggyBankRepetition;
use FireflyIII\Models\RecurrenceTransaction;
use FireflyIII\Models\RuleTrigger;
use Illuminate\Console\Command;
-use ValueError;
/**
* Class ReportSkeleton
@@ -46,9 +45,6 @@ class CorrectAmounts extends Command
protected $description = 'This command makes sure positive and negative amounts are recorded correctly.';
protected $signature = 'firefly-iii:fix-amount-pos-neg';
- /**
- * @return int
- */
public function handle(): int
{
// auto budgets must be positive
@@ -70,13 +66,9 @@ class CorrectAmounts extends Command
// rule_triggers must be positive or zero (amount_less, amount_more, amount_is)
$this->fixRuleTriggers();
-
return 0;
}
- /**
- * @return void
- */
private function fixAutoBudgets(): void
{
$set = AutoBudget::where('amount', '<', 0)->get();
@@ -86,17 +78,15 @@ class CorrectAmounts extends Command
return;
}
+
/** @var AutoBudget $item */
foreach ($set as $item) {
- $item->amount = app('steam')->positive((string)$item->amount);
+ $item->amount = app('steam')->positive($item->amount);
$item->save();
}
$this->friendlyInfo(sprintf('Corrected %d auto budget amount(s).', $count));
}
- /**
- * @return void
- */
private function fixAvailableBudgets(): void
{
$set = AvailableBudget::where('amount', '<', 0)->get();
@@ -106,17 +96,15 @@ class CorrectAmounts extends Command
return;
}
+
/** @var AvailableBudget $item */
foreach ($set as $item) {
- $item->amount = app('steam')->positive((string)$item->amount);
+ $item->amount = app('steam')->positive($item->amount);
$item->save();
}
$this->friendlyInfo(sprintf('Corrected %d available budget amount(s).', $count));
}
- /**
- * @return void
- */
private function fixBills(): void
{
$set = Bill::where('amount_min', '<', 0)->orWhere('amount_max', '<', 0)->get();
@@ -126,18 +114,16 @@ class CorrectAmounts extends Command
return;
}
+
/** @var Bill $item */
foreach ($set as $item) {
- $item->amount_min = app('steam')->positive((string)$item->amount_min);
- $item->amount_max = app('steam')->positive((string)$item->amount_max);
+ $item->amount_min = app('steam')->positive($item->amount_min);
+ $item->amount_max = app('steam')->positive($item->amount_max);
$item->save();
}
$this->friendlyInfo(sprintf('Corrected %d bill amount(s).', $count));
}
- /**
- * @return void
- */
private function fixBudgetLimits(): void
{
$set = BudgetLimit::where('amount', '<', 0)->get();
@@ -147,17 +133,15 @@ class CorrectAmounts extends Command
return;
}
+
/** @var BudgetLimit $item */
foreach ($set as $item) {
- $item->amount = app('steam')->positive((string)$item->amount);
+ $item->amount = app('steam')->positive($item->amount);
$item->save();
}
$this->friendlyInfo(sprintf('Corrected %d budget limit amount(s).', $count));
}
- /**
- * @return void
- */
private function fixExchangeRates(): void
{
$set = CurrencyExchangeRate::where('rate', '<', 0)->get();
@@ -167,17 +151,15 @@ class CorrectAmounts extends Command
return;
}
- /** @var BudgetLimit $item */
+
+ /** @var CurrencyExchangeRate $item */
foreach ($set as $item) {
- $item->rate = app('steam')->positive((string)$item->rate);
+ $item->rate = app('steam')->positive($item->rate);
$item->save();
}
$this->friendlyInfo(sprintf('Corrected %d currency exchange rate(s).', $count));
}
- /**
- * @return void
- */
private function fixRepetitions(): void
{
$set = PiggyBankRepetition::where('currentamount', '<', 0)->get();
@@ -187,17 +169,15 @@ class CorrectAmounts extends Command
return;
}
+
/** @var PiggyBankRepetition $item */
foreach ($set as $item) {
- $item->currentamount = app('steam')->positive((string)$item->currentamount);
+ $item->currentamount = app('steam')->positive($item->currentamount);
$item->save();
}
$this->friendlyInfo(sprintf('Corrected %d piggy bank repetition amount(s).', $count));
}
- /**
- * @return void
- */
private function fixPiggyBanks(): void
{
$set = PiggyBank::where('targetamount', '<', 0)->get();
@@ -207,59 +187,58 @@ class CorrectAmounts extends Command
return;
}
- /** @var PiggyBankRepetition $item */
+
+ /** @var PiggyBank $item */
foreach ($set as $item) {
- $item->targetamount = app('steam')->positive((string)$item->targetamount);
+ $item->targetamount = app('steam')->positive($item->targetamount);
$item->save();
}
$this->friendlyInfo(sprintf('Corrected %d piggy bank amount(s).', $count));
}
- /**
- * @return void
- */
private function fixRecurrences(): void
{
$set = RecurrenceTransaction::where('amount', '<', 0)
- ->orWhere('foreign_amount', '<', 0)
- ->get();
+ ->orWhere('foreign_amount', '<', 0)
+ ->get()
+ ;
$count = $set->count();
if (0 === $count) {
$this->friendlyPositive('All recurring transaction amounts are positive.');
return;
}
- /** @var PiggyBankRepetition $item */
+
+ /** @var RecurrenceTransaction $item */
foreach ($set as $item) {
- $item->amount = app('steam')->positive((string)$item->amount);
- $item->foreign_amount = app('steam')->positive((string)$item->foreign_amount);
+ $item->amount = app('steam')->positive($item->amount);
+ $item->foreign_amount = app('steam')->positive($item->foreign_amount);
$item->save();
}
$this->friendlyInfo(sprintf('Corrected %d recurring transaction amount(s).', $count));
}
- /**
- * @return void
- */
private function fixRuleTriggers(): void
{
$set = RuleTrigger::whereIn('trigger_type', ['amount_less', 'amount_more', 'amount_is'])->get();
$fixed = 0;
+
/** @var RuleTrigger $item */
foreach ($set as $item) {
// basic check:
$check = 0;
+
try {
$check = bccomp((string)$item->trigger_value, '0');
- } catch (ValueError $e) {
+ } catch (\ValueError $e) {
$this->friendlyError(sprintf('Rule #%d contained invalid %s-trigger "%s". The trigger has been removed, and the rule is disabled.', $item->rule_id, $item->trigger_type, $item->trigger_value));
$item->rule->active = false;
$item->rule->save();
$item->forceDelete();
}
if (-1 === $check) {
- $fixed++;
- $item->trigger_value = app('steam')->positive((string)$item->trigger_value);
+ ++$fixed;
+ $item->trigger_value = app('steam')->positive($item->trigger_value);
$item->save();
}
}
@@ -270,5 +249,4 @@ class CorrectAmounts extends Command
}
$this->friendlyInfo(sprintf('Corrected %d rule trigger amount(s).', $fixed));
}
-
}
diff --git a/app/Console/Commands/Correction/CorrectDatabase.php b/app/Console/Commands/Correction/CorrectDatabase.php
index e7db8d30c5..8c22aaeab5 100644
--- a/app/Console/Commands/Correction/CorrectDatabase.php
+++ b/app/Console/Commands/Correction/CorrectDatabase.php
@@ -23,15 +23,11 @@ declare(strict_types=1);
namespace FireflyIII\Console\Commands\Correction;
-use Artisan;
use FireflyIII\Console\Commands\ShowsFriendlyMessages;
use Illuminate\Console\Command;
-use Schema;
/**
* Class CorrectDatabase
- *
-
*/
class CorrectDatabase extends Command
{
@@ -46,7 +42,7 @@ class CorrectDatabase extends Command
public function handle(): int
{
// if table does not exist, return false
- if (!Schema::hasTable('users')) {
+ if (!\Schema::hasTable('users')) {
$this->friendlyError('No "users"-table, will not continue.');
return 1;
diff --git a/app/Console/Commands/Correction/CorrectOpeningBalanceCurrencies.php b/app/Console/Commands/Correction/CorrectOpeningBalanceCurrencies.php
index 6fb2ea7116..a1dcf6c476 100644
--- a/app/Console/Commands/Correction/CorrectOpeningBalanceCurrencies.php
+++ b/app/Console/Commands/Correction/CorrectOpeningBalanceCurrencies.php
@@ -47,13 +47,12 @@ class CorrectOpeningBalanceCurrencies extends Command
/**
* Execute the console command.
- *
- * @return int
*/
public function handle(): int
{
$journals = $this->getJournals();
$count = 0;
+
/** @var TransactionJournal $journal */
foreach ($journals as $journal) {
$count += $this->correctJournal($journal);
@@ -71,22 +70,15 @@ class CorrectOpeningBalanceCurrencies extends Command
return 0;
}
- /**
- * @return Collection
- */
private function getJournals(): Collection
{
- /** @var Collection */
+ // @var Collection
return TransactionJournal::leftJoin('transaction_types', 'transaction_types.id', '=', 'transaction_journals.transaction_type_id')
- ->whereNull('transaction_journals.deleted_at')
- ->where('transaction_types.type', TransactionType::OPENING_BALANCE)->get(['transaction_journals.*']);
+ ->whereNull('transaction_journals.deleted_at')
+ ->where('transaction_types.type', TransactionType::OPENING_BALANCE)->get(['transaction_journals.*'])
+ ;
}
- /**
- * @param TransactionJournal $journal
- *
- * @return int
- */
private function correctJournal(TransactionJournal $journal): int
{
// get the asset account for this opening balance:
@@ -103,17 +95,13 @@ class CorrectOpeningBalanceCurrencies extends Command
return $this->setCorrectCurrency($account, $journal);
}
- /**
- * @param TransactionJournal $journal
- *
- * @return Account|null
- */
private function getAccount(TransactionJournal $journal): ?Account
{
$transactions = $journal->transactions()->get();
+
/** @var Transaction $transaction */
foreach ($transactions as $transaction) {
- /** @var Account $account */
+ /** @var null|Account $account */
$account = $transaction->account()->first();
if (null !== $account && AccountType::INITIAL_BALANCE !== $account->accountType()->first()->type) {
return $account;
@@ -123,45 +111,34 @@ class CorrectOpeningBalanceCurrencies extends Command
return null;
}
- /**
- * @param Account $account
- * @param TransactionJournal $journal
- *
- * @return int
- */
private function setCorrectCurrency(Account $account, TransactionJournal $journal): int
{
$currency = $this->getCurrency($account);
$count = 0;
- if ((int)$journal->transaction_currency_id !== (int)$currency->id) {
+ if ((int)$journal->transaction_currency_id !== $currency->id) {
$journal->transaction_currency_id = $currency->id;
$journal->save();
- $count = 1;
+ $count = 1;
}
/** @var Transaction $transaction */
foreach ($journal->transactions as $transaction) {
- if ((int)$transaction->transaction_currency_id !== (int)$currency->id) {
+ if ($transaction->transaction_currency_id !== $currency->id) {
$transaction->transaction_currency_id = $currency->id;
$transaction->save();
- $count = 1;
+ $count = 1;
}
}
return $count;
}
- /**
- * @param Account $account
- *
- * @return TransactionCurrency
- */
private function getCurrency(Account $account): TransactionCurrency
{
/** @var AccountRepositoryInterface $repos */
$repos = app(AccountRepositoryInterface::class);
$repos->setUser($account->user);
- return $repos->getAccountCurrency($account) ?? app('amount')->getDefaultCurrencyByUser($account->user);
+ return $repos->getAccountCurrency($account) ?? app('amount')->getDefaultCurrencyByUserGroup($account->userGroup);
}
}
diff --git a/app/Console/Commands/Correction/CorrectionSkeleton.php.stub b/app/Console/Commands/Correction/CorrectionSkeleton.php.stub
index 7d25d8ff5e..801dd0d845 100644
--- a/app/Console/Commands/Correction/CorrectionSkeleton.php.stub
+++ b/app/Console/Commands/Correction/CorrectionSkeleton.php.stub
@@ -10,17 +10,8 @@ use Illuminate\Console\Command;
*/
class CorrectionSkeleton extends Command
{
- /**
- * The console command description.
- *
- * @var string
- */
protected $description = 'DESCRIPTION HERE';
- /**
- * The name and signature of the console command.
- *
- * @var string
- */
+
protected $signature = 'firefly-iii:CORR_COMMAND';
/**
diff --git a/app/Console/Commands/Correction/CreateAccessTokens.php b/app/Console/Commands/Correction/CreateAccessTokens.php
index ab53dc2bcf..cf1ec32d0d 100644
--- a/app/Console/Commands/Correction/CreateAccessTokens.php
+++ b/app/Console/Commands/Correction/CreateAccessTokens.php
@@ -23,7 +23,6 @@ declare(strict_types=1);
namespace FireflyIII\Console\Commands\Correction;
-use Exception;
use FireflyIII\Console\Commands\ShowsFriendlyMessages;
use FireflyIII\Repositories\User\UserRepositoryInterface;
use FireflyIII\User;
@@ -36,24 +35,14 @@ class CreateAccessTokens extends Command
{
use ShowsFriendlyMessages;
- /**
- * The console command description.
- *
- * @var string
- */
protected $description = 'Creates user access tokens which are used for command line access to personal data.';
- /**
- * The name and signature of the console command.
- *
- * @var string
- */
- protected $signature = 'firefly-iii:create-access-tokens';
+
+ protected $signature = 'firefly-iii:create-access-tokens';
/**
* Execute the console command.
*
- * @return int
- * @throws Exception
+ * @throws \Exception
*/
public function handle(): int
{
@@ -61,8 +50,9 @@ class CreateAccessTokens extends Command
/** @var UserRepositoryInterface $repository */
$repository = app(UserRepositoryInterface::class);
- $count = 0;
- $users = $repository->all();
+ $count = 0;
+ $users = $repository->all();
+
/** @var User $user */
foreach ($users as $user) {
$pref = app('preferences')->getForUser($user, 'access_token');
diff --git a/app/Console/Commands/Correction/CreateLinkTypes.php b/app/Console/Commands/Correction/CreateLinkTypes.php
index 43620515eb..dd43d97456 100644
--- a/app/Console/Commands/Correction/CreateLinkTypes.php
+++ b/app/Console/Commands/Correction/CreateLinkTypes.php
@@ -34,23 +34,12 @@ class CreateLinkTypes extends Command
{
use ShowsFriendlyMessages;
- /**
- * The console command description.
- *
- * @var string
- */
protected $description = 'Creates all link types.';
- /**
- * The name and signature of the console command.
- *
- * @var string
- */
- protected $signature = 'firefly-iii:create-link-types';
+
+ protected $signature = 'firefly-iii:create-link-types';
/**
* Execute the console command.
- *
- * @return int
*/
public function handle(): int
{
@@ -62,8 +51,9 @@ class CreateLinkTypes extends Command
'Reimbursement' => ['(partially) reimburses', 'is (partially) reimbursed by'],
];
foreach ($set as $name => $values) {
- $link = LinkType::where('name', $name)
- ->first();
+ $link = LinkType::where('name', $name)
+ ->first()
+ ;
if (null === $link) {
$link = new LinkType();
$link->name = $name;
@@ -78,6 +68,7 @@ class CreateLinkTypes extends Command
if (0 === $count) {
$this->friendlyPositive('All link types are OK');
}
+
return 0;
}
}
diff --git a/app/Console/Commands/Correction/DeleteEmptyGroups.php b/app/Console/Commands/Correction/DeleteEmptyGroups.php
index 6948cfaa8f..aa769e9dde 100644
--- a/app/Console/Commands/Correction/DeleteEmptyGroups.php
+++ b/app/Console/Commands/Correction/DeleteEmptyGroups.php
@@ -41,15 +41,14 @@ class DeleteEmptyGroups extends Command
/**
* Execute the console command.
*
- * @return int
* @throws Exception;
- *
*/
public function handle(): int
{
$groupIds
- = TransactionGroup::leftJoin('transaction_journals', 'transaction_groups.id', '=', 'transaction_journals.transaction_group_id')
- ->whereNull('transaction_journals.id')->get(['transaction_groups.id'])->pluck('id')->toArray();
+ = TransactionGroup::leftJoin('transaction_journals', 'transaction_groups.id', '=', 'transaction_journals.transaction_group_id')
+ ->whereNull('transaction_journals.id')->get(['transaction_groups.id'])->pluck('id')->toArray()
+ ;
$total = count($groupIds);
if ($total > 0) {
diff --git a/app/Console/Commands/Correction/DeleteEmptyJournals.php b/app/Console/Commands/Correction/DeleteEmptyJournals.php
index 3ed726205c..a42fbbfbd0 100644
--- a/app/Console/Commands/Correction/DeleteEmptyJournals.php
+++ b/app/Console/Commands/Correction/DeleteEmptyJournals.php
@@ -23,13 +23,11 @@ declare(strict_types=1);
namespace FireflyIII\Console\Commands\Correction;
-use DB;
use FireflyIII\Console\Commands\ShowsFriendlyMessages;
use FireflyIII\Models\Transaction;
use FireflyIII\Models\TransactionJournal;
use Illuminate\Console\Command;
use Illuminate\Database\QueryException;
-use Illuminate\Support\Facades\Log;
/**
* Class DeleteEmptyJournals
@@ -38,23 +36,12 @@ class DeleteEmptyJournals extends Command
{
use ShowsFriendlyMessages;
- /**
- * The console command description.
- *
- * @var string
- */
protected $description = 'Delete empty and uneven transaction journals.';
- /**
- * The name and signature of the console command.
- *
- * @var string
- */
- protected $signature = 'firefly-iii:delete-empty-journals';
+
+ protected $signature = 'firefly-iii:delete-empty-journals';
/**
* Execute the console command.
- *
- * @return int
*/
public function handle(): int
{
@@ -70,27 +57,28 @@ class DeleteEmptyJournals extends Command
private function deleteUnevenJournals(): void
{
$set = Transaction::whereNull('deleted_at')
- ->groupBy('transactions.transaction_journal_id')
- ->get([DB::raw('COUNT(transactions.transaction_journal_id) as the_count'), 'transaction_journal_id']);
+ ->groupBy('transactions.transaction_journal_id')
+ ->get([\DB::raw('COUNT(transactions.transaction_journal_id) as the_count'), 'transaction_journal_id']) // @phpstan-ignore-line
+ ;
$total = 0;
+
/** @var Transaction $row */
foreach ($set as $row) {
$count = (int)$row->the_count;
if (1 === $count % 2) {
// uneven number, delete journal and transactions:
try {
- TransactionJournal::find((int)$row->transaction_journal_id)->delete();
+ TransactionJournal::find($row->transaction_journal_id)->delete();
} catch (QueryException $e) {
- Log::info(sprintf('Could not delete journal: %s', $e->getMessage()));
- Log::error($e->getTraceAsString());
+ app('log')->info(sprintf('Could not delete journal: %s', $e->getMessage()));
+ app('log')->error($e->getTraceAsString());
}
-
- Transaction::where('transaction_journal_id', (int)$row->transaction_journal_id)->delete();
+ Transaction::where('transaction_journal_id', $row->transaction_journal_id)->delete();
$this->friendlyWarning(
sprintf('Deleted transaction journal #%d because it had an uneven number of transactions.', $row->transaction_journal_id)
);
- $total++;
+ ++$total;
}
}
if (0 === $total) {
@@ -98,26 +86,23 @@ class DeleteEmptyJournals extends Command
}
}
- /**
- * @return void
- */
private function deleteEmptyJournals(): void
{
$count = 0;
$set = TransactionJournal::leftJoin('transactions', 'transactions.transaction_journal_id', '=', 'transaction_journals.id')
- ->groupBy('transaction_journals.id')
- ->whereNull('transactions.transaction_journal_id')
- ->get(['transaction_journals.id']);
+ ->groupBy('transaction_journals.id')
+ ->whereNull('transactions.transaction_journal_id')
+ ->get(['transaction_journals.id'])
+ ;
foreach ($set as $entry) {
try {
TransactionJournal::find($entry->id)->delete();
} catch (QueryException $e) {
- Log::info(sprintf('Could not delete entry: %s', $e->getMessage()));
- Log::error($e->getTraceAsString());
+ app('log')->info(sprintf('Could not delete entry: %s', $e->getMessage()));
+ app('log')->error($e->getTraceAsString());
}
-
$this->friendlyInfo(sprintf('Deleted empty transaction journal #%d', $entry->id));
++$count;
}
diff --git a/app/Console/Commands/Correction/DeleteOrphanedTransactions.php b/app/Console/Commands/Correction/DeleteOrphanedTransactions.php
index 802609decd..aacaa23ca3 100644
--- a/app/Console/Commands/Correction/DeleteOrphanedTransactions.php
+++ b/app/Console/Commands/Correction/DeleteOrphanedTransactions.php
@@ -23,12 +23,10 @@ declare(strict_types=1);
namespace FireflyIII\Console\Commands\Correction;
-use Exception;
use FireflyIII\Console\Commands\ShowsFriendlyMessages;
use FireflyIII\Models\Transaction;
use FireflyIII\Models\TransactionJournal;
use Illuminate\Console\Command;
-use stdClass;
/**
* Deletes transactions where the journal has been deleted.
@@ -37,24 +35,14 @@ class DeleteOrphanedTransactions extends Command
{
use ShowsFriendlyMessages;
- /**
- * The console command description.
- *
- * @var string
- */
protected $description = 'Deletes orphaned transactions.';
- /**
- * The name and signature of the console command.
- *
- * @var string
- */
- protected $signature = 'firefly-iii:delete-orphaned-transactions';
+
+ protected $signature = 'firefly-iii:delete-orphaned-transactions';
/**
* Execute the console command.
*
- * @return int
- * @throws Exception
+ * @throws \Exception
*/
public function handle(): int
{
@@ -65,23 +53,22 @@ class DeleteOrphanedTransactions extends Command
return 0;
}
- /**
- * @return void
- */
private function deleteOrphanedJournals(): void
{
$set = TransactionJournal::leftJoin('transaction_groups', 'transaction_journals.transaction_group_id', 'transaction_groups.id')
- ->whereNotNull('transaction_groups.deleted_at')
- ->whereNull('transaction_journals.deleted_at')
- ->get(['transaction_journals.id', 'transaction_journals.transaction_group_id']);
+ ->whereNotNull('transaction_groups.deleted_at')
+ ->whereNull('transaction_journals.deleted_at')
+ ->get(['transaction_journals.id', 'transaction_journals.transaction_group_id'])
+ ;
$count = $set->count();
if (0 === $count) {
$this->friendlyPositive('No orphaned journals.');
+
return;
}
$this->friendlyInfo(sprintf('Found %d orphaned journal(s).', $count));
foreach ($set as $entry) {
- $journal = TransactionJournal::withTrashed()->find((int)$entry->id);
+ $journal = TransactionJournal::withTrashed()->find($entry->id);
if (null !== $journal) {
$journal->delete();
$this->friendlyWarning(
@@ -96,22 +83,24 @@ class DeleteOrphanedTransactions extends Command
}
/**
- * @throws Exception
+ * @throws \Exception
*/
private function deleteOrphanedTransactions(): void
{
$count = 0;
$set = Transaction::leftJoin('transaction_journals', 'transactions.transaction_journal_id', '=', 'transaction_journals.id')
- ->whereNotNull('transaction_journals.deleted_at')
- ->whereNull('transactions.deleted_at')
- ->whereNotNull('transactions.id')
- ->get(
- [
- 'transaction_journals.id as journal_id',
- 'transactions.id as transaction_id',
- ]
- );
- /** @var stdClass $entry */
+ ->whereNotNull('transaction_journals.deleted_at')
+ ->whereNull('transactions.deleted_at')
+ ->whereNotNull('transactions.id')
+ ->get(
+ [
+ 'transaction_journals.id as journal_id',
+ 'transactions.id as transaction_id',
+ ]
+ )
+ ;
+
+ /** @var \stdClass $entry */
foreach ($set as $entry) {
$transaction = Transaction::find((int)$entry->transaction_id);
if (null !== $transaction) {
@@ -131,24 +120,23 @@ class DeleteOrphanedTransactions extends Command
}
}
- /**
- *
- */
private function deleteFromOrphanedAccounts(): void
{
$set
= Transaction::leftJoin('accounts', 'transactions.account_id', '=', 'accounts.id')
- ->whereNotNull('accounts.deleted_at')
- ->get(['transactions.*']);
+ ->whereNotNull('accounts.deleted_at')
+ ->get(['transactions.*'])
+ ;
$count = 0;
+
/** @var Transaction $transaction */
foreach ($set as $transaction) {
// delete journals
- $journal = TransactionJournal::find((int)$transaction->transaction_journal_id);
- if ($journal) {
+ $journal = TransactionJournal::find($transaction->transaction_journal_id);
+ if (null !== $journal) {
$journal->delete();
}
- Transaction::where('transaction_journal_id', (int)$transaction->transaction_journal_id)->delete();
+ Transaction::where('transaction_journal_id', $transaction->transaction_journal_id)->delete();
$this->friendlyWarning(
sprintf(
'Deleted transaction journal #%d because account #%d was already deleted.',
@@ -156,7 +144,7 @@ class DeleteOrphanedTransactions extends Command
$transaction->account_id
)
);
- $count++;
+ ++$count;
}
if (0 === $count) {
$this->friendlyPositive('No orphaned accounts.');
diff --git a/app/Console/Commands/Correction/DeleteZeroAmount.php b/app/Console/Commands/Correction/DeleteZeroAmount.php
index f0e52cdccf..4e0b86734d 100644
--- a/app/Console/Commands/Correction/DeleteZeroAmount.php
+++ b/app/Console/Commands/Correction/DeleteZeroAmount.php
@@ -35,29 +35,19 @@ class DeleteZeroAmount extends Command
{
use ShowsFriendlyMessages;
- /**
- * The console command description.
- *
- * @var string
- */
protected $description = 'Delete transactions with zero amount.';
- /**
- * The name and signature of the console command.
- *
- * @var string
- */
- protected $signature = 'firefly-iii:delete-zero-amount';
+
+ protected $signature = 'firefly-iii:delete-zero-amount';
/**
* Execute the console command.
- *
- * @return int
*/
public function handle(): int
{
$set = Transaction::where('amount', 0)->get(['transaction_journal_id'])->pluck('transaction_journal_id')->toArray();
$set = array_unique($set);
$journals = TransactionJournal::whereIn('id', $set)->get();
+
/** @var TransactionJournal $journal */
foreach ($journals as $journal) {
$this->friendlyWarning(sprintf('Deleted transaction journal #%d because the amount is zero (0.00).', $journal->id));
diff --git a/app/Console/Commands/Correction/EnableCurrencies.php b/app/Console/Commands/Correction/EnableCurrencies.php
index f2b2e094b5..a87843d0f6 100644
--- a/app/Console/Commands/Correction/EnableCurrencies.php
+++ b/app/Console/Commands/Correction/EnableCurrencies.php
@@ -26,11 +26,15 @@ namespace FireflyIII\Console\Commands\Correction;
use FireflyIII\Console\Commands\ShowsFriendlyMessages;
use FireflyIII\Models\AccountMeta;
use FireflyIII\Models\BudgetLimit;
+use FireflyIII\Models\GroupMembership;
use FireflyIII\Models\Transaction;
-use FireflyIII\Models\TransactionCurrency;
use FireflyIII\Models\TransactionJournal;
+use FireflyIII\Models\UserGroup;
+use FireflyIII\Repositories\UserGroups\Currency\CurrencyRepositoryInterface;
use Illuminate\Console\Command;
use Illuminate\Support\Collection;
+use Illuminate\Support\Facades\Log;
+use Symfony\Component\Console\Command\Command as CommandAlias;
/**
* Class EnableCurrencies
@@ -44,56 +48,98 @@ class EnableCurrencies extends Command
/**
* Execute the console command.
- *
- * @return int
*/
public function handle(): int
{
- $found = [];
+ $userGroups = UserGroup::get();
+ foreach ($userGroups as $userGroup) {
+ $this->correctCurrencies($userGroup);
+ }
+
+ return CommandAlias::SUCCESS;
+ }
+
+ private function correctCurrencies(UserGroup $userGroup): void
+ {
+ /** @var CurrencyRepositoryInterface $repos */
+ $repos = app(CurrencyRepositoryInterface::class);
+
+ // first check if the user has any default currency (not necessarily the case, so can be forced).
+ $defaultCurrency = app('amount')->getDefaultCurrencyByUserGroup($userGroup);
+
+ Log::debug(sprintf('Now correcting currencies for user group #%d', $userGroup->id));
+ $found = [$defaultCurrency->id];
+
// get all meta entries
- /** @var Collection $meta */
- $meta = AccountMeta::where('name', 'currency_id')->groupBy('data')->get(['data']);
+ $meta = AccountMeta::leftJoin('accounts', 'accounts.id', '=', 'account_meta.account_id')
+ ->where('accounts.user_group_id', $userGroup->id)
+ ->where('account_meta.name', 'currency_id')->groupBy('data')->get(['data'])
+ ;
foreach ($meta as $entry) {
$found[] = (int)$entry->data;
}
// get all from journals:
- $journals = TransactionJournal::groupBy('transaction_currency_id')->get(['transaction_currency_id']);
+ $journals = TransactionJournal::where('user_group_id', $userGroup->id)
+ ->groupBy('transaction_currency_id')->get(['transaction_currency_id'])
+ ;
foreach ($journals as $entry) {
$found[] = (int)$entry->transaction_currency_id;
}
// get all from transactions
- $transactions = Transaction::groupBy('transaction_currency_id', 'foreign_currency_id')->get(['transaction_currency_id', 'foreign_currency_id']);
+ $transactions = Transaction::leftJoin('transaction_journals', 'transaction_journals.id', '=', 'transactions.transaction_journal_id')
+ ->where('transaction_journals.user_group_id', $userGroup->id)
+ ->groupBy('transactions.transaction_currency_id', 'transactions.foreign_currency_id')
+ ->get(['transactions.transaction_currency_id', 'transactions.foreign_currency_id'])
+ ;
foreach ($transactions as $entry) {
$found[] = (int)$entry->transaction_currency_id;
$found[] = (int)$entry->foreign_currency_id;
}
// get all from budget limits
- $limits = BudgetLimit::groupBy('transaction_currency_id')->get(['transaction_currency_id']);
+ $limits = BudgetLimit::leftJoin('budgets', 'budgets.id', '=', 'budget_limits.budget_id')
+ ->groupBy('transaction_currency_id')
+ ->get(['budget_limits.transaction_currency_id'])
+ ;
foreach ($limits as $entry) {
- $found[] = (int)$entry->transaction_currency_id;
+ $found[] = $entry->transaction_currency_id;
}
- $found = array_values(array_unique($found));
- $found = array_values(
+ // also get all currencies already enabled.
+ $alreadyEnabled = $userGroup->currencies()->get(['transaction_currencies.id'])->pluck('id')->toArray();
+ foreach ($alreadyEnabled as $currencyId) {
+ $found[] = $currencyId;
+ }
+
+ $found = array_values(array_unique($found));
+ $found = array_values(
array_filter(
$found,
- function (int $currencyId) {
- return $currencyId !== 0;
+ static function (int $currencyId) {
+ return 0 !== $currencyId;
}
)
);
- $disabled = TransactionCurrency::whereIn('id', $found)->where('enabled', false)->count();
- if ($disabled > 0) {
- $this->friendlyInfo(sprintf('%d currencies were (was) disabled while in use by transactions. This has been corrected.', $disabled));
- }
- if (0 === $disabled) {
- $this->friendlyPositive('All currencies are correctly enabled or disabled.');
- }
- TransactionCurrency::whereIn('id', $found)->update(['enabled' => true]);
- return 0;
+ $valid = new Collection();
+
+ /** @var int $currencyId */
+ foreach ($found as $currencyId) {
+ $currency = $repos->find($currencyId);
+ if (null !== $currency) {
+ $valid->push($currency);
+ }
+ }
+ $ids = $valid->pluck('id')->toArray();
+ Log::debug(sprintf('Found currencies for user group #%d: %s', $userGroup->id, implode(', ', $ids)));
+ $userGroup->currencies()->sync($ids);
+
+ /** @var GroupMembership $membership */
+ foreach ($userGroup->groupMemberships()->get() as $membership) {
+ // make sure no individual different preferences.
+ $membership->user->currencies()->sync([]);
+ }
}
}
diff --git a/app/Console/Commands/Correction/FixAccountOrder.php b/app/Console/Commands/Correction/FixAccountOrder.php
index acc0276934..4928584052 100644
--- a/app/Console/Commands/Correction/FixAccountOrder.php
+++ b/app/Console/Commands/Correction/FixAccountOrder.php
@@ -42,8 +42,6 @@ class FixAccountOrder extends Command
/**
* Execute the console command.
- *
- * @return int
*/
public function handle(): int
{
@@ -64,8 +62,6 @@ class FixAccountOrder extends Command
* Laravel will execute ALL __construct() methods for ALL commands whenever a SINGLE command is
* executed. This leads to noticeable slow-downs and class calls. To prevent this, this method should
* be called from the handle method instead of using the constructor to initialize the command.
- *
-
*/
private function stupidLaravel(): void
{
diff --git a/app/Console/Commands/Correction/FixAccountTypes.php b/app/Console/Commands/Correction/FixAccountTypes.php
index a9d74e3d11..cc963e024f 100644
--- a/app/Console/Commands/Correction/FixAccountTypes.php
+++ b/app/Console/Commands/Correction/FixAccountTypes.php
@@ -34,7 +34,6 @@ use FireflyIII\Models\TransactionType;
use Illuminate\Console\Command;
use Illuminate\Database\Eloquent\Builder;
use Illuminate\Database\Query\JoinClause;
-use JsonException;
/**
* Class FixAccountTypes
@@ -52,8 +51,7 @@ class FixAccountTypes extends Command
/**
* Execute the console command.
*
- * @return int
- * @throws FireflyException|JsonException
+ * @throws FireflyException
*/
public function handle(): int
{
@@ -62,30 +60,31 @@ class FixAccountTypes extends Command
$this->expected = config('firefly.source_dests');
$expected = config('firefly.source_dests');
- $query = TransactionJournal::leftJoin('transaction_types', 'transaction_journals.transaction_type_id', '=', 'transaction_types.id')
- ->leftJoin(
- 'transactions as source',
- static function (JoinClause $join) {
- $join->on('transaction_journals.id', '=', 'source.transaction_journal_id')->where('source.amount', '<', 0);
- }
- )
- ->leftJoin(
- 'transactions as destination',
- static function (JoinClause $join) {
- $join->on('transaction_journals.id', '=', 'destination.transaction_journal_id')->where('destination.amount', '>', 0);
- }
- )
- ->leftJoin('accounts as source_account', 'source.account_id', '=', 'source_account.id')
- ->leftJoin('accounts as destination_account', 'destination.account_id', '=', 'destination_account.id')
- ->leftJoin('account_types as source_account_type', 'source_account.account_type_id', '=', 'source_account_type.id')
- ->leftJoin('account_types as destination_account_type', 'destination_account.account_type_id', '=', 'destination_account_type.id');
+ $query = TransactionJournal::leftJoin('transaction_types', 'transaction_journals.transaction_type_id', '=', 'transaction_types.id')
+ ->leftJoin(
+ 'transactions as source',
+ static function (JoinClause $join): void {
+ $join->on('transaction_journals.id', '=', 'source.transaction_journal_id')->where('source.amount', '<', 0);
+ }
+ )
+ ->leftJoin(
+ 'transactions as destination',
+ static function (JoinClause $join): void {
+ $join->on('transaction_journals.id', '=', 'destination.transaction_journal_id')->where('destination.amount', '>', 0);
+ }
+ )
+ ->leftJoin('accounts as source_account', 'source.account_id', '=', 'source_account.id')
+ ->leftJoin('accounts as destination_account', 'destination.account_id', '=', 'destination_account.id')
+ ->leftJoin('account_types as source_account_type', 'source_account.account_type_id', '=', 'source_account_type.id')
+ ->leftJoin('account_types as destination_account_type', 'destination_account.account_type_id', '=', 'destination_account_type.id')
+ ;
// list all valid combinations, those are allowed. So we select those which are broken.
- $query->where(function (Builder $q) use ($expected) {
+ $query->where(static function (Builder $q) use ($expected): void {
foreach ($expected as $transactionType => $info) {
foreach ($info as $source => $destinations) {
foreach ($destinations as $destination) {
- $q->whereNot(function (Builder $q1) use ($transactionType, $source, $destination) {
+ $q->whereNot(static function (Builder $q1) use ($transactionType, $source, $destination): void {
$q1->where('transaction_types.type', $transactionType);
$q1->where('source_account_type.type', $source);
$q1->where('destination_account_type.type', $destination);
@@ -95,18 +94,18 @@ class FixAccountTypes extends Command
}
});
- $resultSet = $query->get(
+ $resultSet = $query->get(
[
'transaction_journals.id',
- //'transaction_type_id as type_id',
+ // 'transaction_type_id as type_id',
'transaction_types.type as journal_type',
- //'source.id as source_transaction_id',
- //'source_account.id as source_account_id',
- //'source_account_type.id as source_account_type_id',
+ // 'source.id as source_transaction_id',
+ // 'source_account.id as source_account_id',
+ // 'source_account_type.id as source_account_type_id',
'source_account_type.type as source_account_type',
- //'destination.id as destination_transaction_id',
- //'destination_account.id as destination_account_id',
- //'destination_account_type.id as destination_account_type_id',
+ // 'destination.id as destination_transaction_id',
+ // 'destination_account.id as destination_account_id',
+ // 'destination_account_type.id as destination_account_type_id',
'destination_account_type.type as destination_account_type',
]
);
@@ -114,7 +113,7 @@ class FixAccountTypes extends Command
$this->friendlyLine(sprintf('Found %d journals that need to be fixed.', $resultSet->count()));
foreach ($resultSet as $entry) {
app('log')->debug(sprintf('Now fixing journal #%d', $entry->id));
- $journal = TransactionJournal::find((int)$entry->id);
+ $journal = TransactionJournal::find($entry->id);
if (null !== $journal) {
$this->inspectJournal($journal);
}
@@ -131,24 +130,15 @@ class FixAccountTypes extends Command
return 0;
}
- /**
- * @return void
- */
private function stupidLaravel(): void
{
$this->count = 0;
}
- /**
- * @param TransactionJournal $journal
- *
- * @throws FireflyException
- * @throws JsonException
- */
private function inspectJournal(TransactionJournal $journal): void
{
app('log')->debug(sprintf('Now inspecting journal #%d', $journal->id));
- $transactions = $journal->transactions()->count();
+ $transactions = $journal->transactions()->count();
if (2 !== $transactions) {
app('log')->debug(sprintf('Journal has %d transactions, so can\'t fix.', $transactions));
$this->friendlyError(sprintf('Cannot inspect transaction journal #%d because it has %d transaction(s) instead of 2.', $journal->id, $transactions));
@@ -175,168 +165,224 @@ class FixAccountTypes extends Command
return;
}
- $expectedTypes = $this->expected[$type][$sourceAccountType];
+ $expectedTypes = $this->expected[$type][$sourceAccountType];
if (!in_array($destAccountType, $expectedTypes, true)) {
app('log')->debug(sprintf('[b] Going to fix journal #%d', $journal->id));
$this->fixJournal($journal, $type, $sourceTransaction, $destTransaction);
}
}
- /**
- * @param TransactionJournal $journal
- *
- * @return Transaction
- */
private function getSourceTransaction(TransactionJournal $journal): Transaction
{
return $journal->transactions->firstWhere('amount', '<', 0);
}
- /**
- * @param TransactionJournal $journal
- *
- * @return Transaction
- */
private function getDestinationTransaction(TransactionJournal $journal): Transaction
{
return $journal->transactions->firstWhere('amount', '>', 0);
}
- /**
- * @param TransactionJournal $journal
- * @param string $type
- * @param Transaction $source
- * @param Transaction $dest
- *
- * @throws FireflyException
- * @throws JsonException
- */
- private function fixJournal(TransactionJournal $journal, string $type, Transaction $source, Transaction $dest): void
+ private function fixJournal(TransactionJournal $journal, string $transactionType, Transaction $source, Transaction $dest): void
{
app('log')->debug(sprintf('Going to fix journal #%d', $journal->id));
- $this->count++;
+ ++$this->count;
// variables:
- $combination = sprintf('%s%s%s', $type, $source->account->accountType->type, $dest->account->accountType->type);
+ $sourceType = $source->account->accountType->type;
+ $destinationType = $dest->account->accountType->type;
+ $combination = sprintf('%s%s%s', $transactionType, $source->account->accountType->type, $dest->account->accountType->type);
app('log')->debug(sprintf('Combination is "%s"', $combination));
- switch ($combination) {
- case sprintf('%s%s%s', TransactionType::TRANSFER, AccountType::ASSET, AccountType::LOAN):
- case sprintf('%s%s%s', TransactionType::TRANSFER, AccountType::ASSET, AccountType::DEBT):
- case sprintf('%s%s%s', TransactionType::TRANSFER, AccountType::ASSET, AccountType::MORTGAGE):
- // from an asset to a liability should be a withdrawal:
- $withdrawal = TransactionType::whereType(TransactionType::WITHDRAWAL)->first();
- $journal->transactionType()->associate($withdrawal);
- $journal->save();
- $message = sprintf('Converted transaction #%d from a transfer to a withdrawal.', $journal->id);
- $this->friendlyInfo($message);
- app('log')->debug($message);
- // check it again:
- $this->inspectJournal($journal);
- return;
- case sprintf('%s%s%s', TransactionType::TRANSFER, AccountType::LOAN, AccountType::ASSET):
- case sprintf('%s%s%s', TransactionType::TRANSFER, AccountType::DEBT, AccountType::ASSET):
- case sprintf('%s%s%s', TransactionType::TRANSFER, AccountType::MORTGAGE, AccountType::ASSET):
- // from a liability to an asset should be a deposit.
- $deposit = TransactionType::whereType(TransactionType::DEPOSIT)->first();
- $journal->transactionType()->associate($deposit);
- $journal->save();
- $message = sprintf('Converted transaction #%d from a transfer to a deposit.', $journal->id);
- $this->friendlyInfo($message);
- app('log')->debug($message);
- // check it again:
- $this->inspectJournal($journal);
- return;
- case sprintf('%s%s%s', TransactionType::WITHDRAWAL, AccountType::ASSET, AccountType::REVENUE):
- // withdrawals with a revenue account as destination instead of an expense account.
- $this->factory->setUser($journal->user);
- $oldDest = $dest->account;
- $result = $this->factory->findOrCreate($dest->account->name, AccountType::EXPENSE);
- $dest->account()->associate($result);
- $dest->save();
- $message = sprintf(
- 'Transaction journal #%d, destination account changed from #%d ("%s") to #%d ("%s").',
- $journal->id,
- $oldDest->id,
- $oldDest->name,
- $result->id,
- $result->name
- );
- $this->friendlyWarning($message);
- app('log')->debug($message);
- $this->inspectJournal($journal);
- return;
- case sprintf('%s%s%s', TransactionType::DEPOSIT, AccountType::EXPENSE, AccountType::ASSET):
- // deposits with an expense account as source instead of a revenue account.
- // find revenue account.
- $this->factory->setUser($journal->user);
- $result = $this->factory->findOrCreate($source->account->name, AccountType::REVENUE);
- $oldSource = $dest->account;
- $source->account()->associate($result);
- $source->save();
- $message = sprintf(
- 'Transaction journal #%d, source account changed from #%d ("%s") to #%d ("%s").',
- $journal->id,
- $oldSource->id,
- $oldSource->name,
- $result->id,
- $result->name
- );
- $this->friendlyWarning($message);
- app('log')->debug($message);
- $this->inspectJournal($journal);
- return;
+ if ($this->shouldBeTransfer($transactionType, $sourceType, $destinationType)) {
+ $this->makeTransfer($journal);
+
+ return;
+ }
+ if ($this->shouldBeDeposit($transactionType, $sourceType, $destinationType)) {
+ $this->makeDeposit($journal);
+
+ return;
+ }
+ if ($this->shouldGoToExpenseAccount($transactionType, $sourceType, $destinationType)) {
+ $this->makeExpenseDestination($journal, $dest);
+
+ return;
+ }
+ if ($this->shouldComeFromRevenueAccount($transactionType, $sourceType, $destinationType)) {
+ $this->makeRevenueSource($journal, $source);
+
+ return;
}
- app('log')->debug(sprintf('Fallback to fix transaction journal #%d of type "%s".', $journal->id, $type));
// transaction has no valid source.
- $validSources = array_keys($this->expected[$type]);
- if (!in_array($source->account->accountType->type, $validSources, true)) {
- app('log')->debug('Journal has no valid source.');
- // perhaps we can create the account of type we need:
+ $validSources = array_keys($this->expected[$transactionType]);
+ $canCreateSource = $this->canCreateSource($validSources);
+ $hasValidSource = $this->hasValidAccountType($validSources, $sourceType);
+ if (!$hasValidSource && $canCreateSource) {
+ $this->giveNewRevenue($journal, $source);
- if (in_array(AccountTypeEnum::REVENUE->value, $validSources, true)) {
- app('log')->debug(sprintf('An account of type "%s" could be a valid source.', AccountTypeEnum::REVENUE->value));
- $this->factory->setUser($journal->user);
- $newSource = $this->factory->findOrCreate($source->account->name, AccountTypeEnum::REVENUE->value);
- $source->account()->associate($newSource);
- $source->save();
- $this->friendlyPositive(sprintf('Firefly III gave transaction #%d a new source %s: #%d ("%s").', $journal->transaction_group_id, AccountTypeEnum::REVENUE->value, $newSource->id, $newSource->name));
- app('log')->debug(sprintf('Associated account #%d with transaction #%d', $newSource->id, $source->id));
- $this->inspectJournal($journal);
- return;
- }
- if (!in_array(AccountTypeEnum::REVENUE->value, $validSources, true)) {
- app('log')->debug('This transaction type has no source we can create. Just give error.');
- $message = sprintf('The source account of %s #%d cannot be of type "%s". Firefly III cannot fix this. You may have to remove the transaction yourself.', $type, $journal->id, $source->account->accountType->type);
- $this->friendlyError($message);
- app('log')->debug($message);
- }
+ return;
+ }
+ if (!$canCreateSource && !$hasValidSource) {
+ app('log')->debug('This transaction type has no source we can create. Just give error.');
+ $message = sprintf('The source account of %s #%d cannot be of type "%s". Firefly III cannot fix this. You may have to remove the transaction yourself.', $transactionType, $journal->id, $source->account->accountType->type);
+ $this->friendlyError($message);
+ app('log')->debug($message);
+
+ return;
}
- // transaction has no valid destination:
- $sourceType = $source->account->accountType->type;
- $validDestinations = $this->expected[$type][$sourceType] ?? [];
- if (!in_array($dest->account->accountType->type, $validDestinations, true)) {
- app('log')->debug('Journal has no valid destination (perhaps because the source is also broken).');
- // perhaps we can create the account of type we need:
- if (in_array(AccountTypeEnum::EXPENSE->value, $validDestinations, true)) {
- app('log')->debug(sprintf('An account of type "%s" could be a valid destination.', AccountTypeEnum::EXPENSE->value));
- $this->factory->setUser($journal->user);
- $newDestination = $this->factory->findOrCreate($dest->account->name, AccountTypeEnum::EXPENSE->value);
- $dest->account()->associate($newDestination);
- $dest->save();
- $this->friendlyPositive(sprintf('Firefly III gave transaction #%d a new destination %s: #%d ("%s").', $journal->transaction_group_id, AccountTypeEnum::EXPENSE->value, $newDestination->id, $newDestination->name));
- app('log')->debug(sprintf('Associated account #%d with transaction #%d', $newDestination->id, $source->id));
- $this->inspectJournal($journal);
- return;
- }
- if (!in_array(AccountTypeEnum::EXPENSE->value, $validSources, true)) {
- app('log')->debug('This transaction type has no destination we can create. Just give error.');
- $message = sprintf('The destination account of %s #%d cannot be of type "%s". Firefly III cannot fix this. You may have to remove the transaction yourself.', $type, $journal->id, $dest->account->accountType->type);
- $this->friendlyError($message);
- app('log')->debug($message);
- return;
- }
+ /** @var array $validDestinations */
+ $validDestinations = $this->expected[$transactionType][$sourceType] ?? [];
+ $canCreateDestination = $this->canCreateDestination($validDestinations);
+ $hasValidDestination = $this->hasValidAccountType($validDestinations, $destinationType);
+ if (!$hasValidDestination && $canCreateDestination) {
+ $this->giveNewExpense($journal, $dest);
+
+ return;
+ }
+ if (!$canCreateDestination && !$hasValidDestination) {
+ app('log')->debug('This transaction type has no destination we can create. Just give error.');
+ $message = sprintf('The destination account of %s #%d cannot be of type "%s". Firefly III cannot fix this. You may have to remove the transaction yourself.', $transactionType, $journal->id, $dest->account->accountType->type);
+ $this->friendlyError($message);
+ app('log')->debug($message);
}
}
+
+ private function shouldBeTransfer(string $transactionType, string $sourceType, string $destinationType): bool
+ {
+ return TransactionType::TRANSFER === $transactionType && AccountType::ASSET === $sourceType && $this->isLiability($destinationType);
+ }
+
+ private function isLiability(string $destinationType): bool
+ {
+ return AccountType::LOAN === $destinationType || AccountType::DEBT === $destinationType || AccountType::MORTGAGE === $destinationType;
+ }
+
+ private function makeTransfer(TransactionJournal $journal): void
+ {
+ // from an asset to a liability should be a withdrawal:
+ $withdrawal = TransactionType::whereType(TransactionType::WITHDRAWAL)->first();
+ $journal->transactionType()->associate($withdrawal);
+ $journal->save();
+ $message = sprintf('Converted transaction #%d from a transfer to a withdrawal.', $journal->id);
+ $this->friendlyInfo($message);
+ app('log')->debug($message);
+ // check it again:
+ $this->inspectJournal($journal);
+ }
+
+ private function shouldBeDeposit(string $transactionType, string $sourceType, string $destinationType): bool
+ {
+ return TransactionType::TRANSFER === $transactionType && $this->isLiability($sourceType) && AccountType::ASSET === $destinationType;
+ }
+
+ private function makeDeposit(TransactionJournal $journal): void
+ {
+ // from a liability to an asset should be a deposit.
+ $deposit = TransactionType::whereType(TransactionType::DEPOSIT)->first();
+ $journal->transactionType()->associate($deposit);
+ $journal->save();
+ $message = sprintf('Converted transaction #%d from a transfer to a deposit.', $journal->id);
+ $this->friendlyInfo($message);
+ app('log')->debug($message);
+ // check it again:
+ $this->inspectJournal($journal);
+ }
+
+ private function shouldGoToExpenseAccount(string $transactionType, string $sourceType, string $destinationType): bool
+ {
+ return TransactionType::WITHDRAWAL === $transactionType && AccountType::ASSET === $sourceType && AccountType::REVENUE === $destinationType;
+ }
+
+ private function makeExpenseDestination(TransactionJournal $journal, Transaction $destination): void
+ {
+ // withdrawals with a revenue account as destination instead of an expense account.
+ $this->factory->setUser($journal->user);
+ $oldDest = $destination->account;
+ $result = $this->factory->findOrCreate($destination->account->name, AccountType::EXPENSE);
+ $destination->account()->associate($result);
+ $destination->save();
+ $message = sprintf(
+ 'Transaction journal #%d, destination account changed from #%d ("%s") to #%d ("%s").',
+ $journal->id,
+ $oldDest->id,
+ $oldDest->name,
+ $result->id,
+ $result->name
+ );
+ $this->friendlyWarning($message);
+ app('log')->debug($message);
+ $this->inspectJournal($journal);
+ }
+
+ private function shouldComeFromRevenueAccount(string $transactionType, string $sourceType, string $destinationType): bool
+ {
+ return TransactionType::DEPOSIT === $transactionType && AccountType::EXPENSE === $sourceType && AccountType::ASSET === $destinationType;
+ }
+
+ private function makeRevenueSource(TransactionJournal $journal, Transaction $source): void
+ {
+ // deposits with an expense account as source instead of a revenue account.
+ // find revenue account.
+ $this->factory->setUser($journal->user);
+ $result = $this->factory->findOrCreate($source->account->name, AccountType::REVENUE);
+ $oldSource = $source->account;
+ $source->account()->associate($result);
+ $source->save();
+ $message = sprintf(
+ 'Transaction journal #%d, source account changed from #%d ("%s") to #%d ("%s").',
+ $journal->id,
+ $oldSource->id,
+ $oldSource->name,
+ $result->id,
+ $result->name
+ );
+ $this->friendlyWarning($message);
+ app('log')->debug($message);
+ $this->inspectJournal($journal);
+ }
+
+ /**
+ * Can only create revenue accounts out of the blue.
+ */
+ private function canCreateSource(array $validSources): bool
+ {
+ return in_array(AccountTypeEnum::REVENUE->value, $validSources, true);
+ }
+
+ private function hasValidAccountType(array $validTypes, string $accountType): bool
+ {
+ return in_array($accountType, $validTypes, true);
+ }
+
+ private function giveNewRevenue(TransactionJournal $journal, Transaction $source): void
+ {
+ app('log')->debug(sprintf('An account of type "%s" could be a valid source.', AccountTypeEnum::REVENUE->value));
+ $this->factory->setUser($journal->user);
+ $name = $source->account->name;
+ $newSource = $this->factory->findOrCreate($name, AccountTypeEnum::REVENUE->value);
+ $source->account()->associate($newSource);
+ $source->save();
+ $this->friendlyPositive(sprintf('Firefly III gave transaction #%d a new source %s: #%d ("%s").', $journal->transaction_group_id, AccountTypeEnum::REVENUE->value, $newSource->id, $newSource->name));
+ app('log')->debug(sprintf('Associated account #%d with transaction #%d', $newSource->id, $source->id));
+ $this->inspectJournal($journal);
+ }
+
+ private function canCreateDestination(array $validDestinations): bool
+ {
+ return in_array(AccountTypeEnum::EXPENSE->value, $validDestinations, true);
+ }
+
+ private function giveNewExpense(TransactionJournal $journal, Transaction $destination): void
+ {
+ app('log')->debug(sprintf('An account of type "%s" could be a valid destination.', AccountTypeEnum::EXPENSE->value));
+ $this->factory->setUser($journal->user);
+ $name = $destination->account->name;
+ $newDestination = $this->factory->findOrCreate($name, AccountTypeEnum::EXPENSE->value);
+ $destination->account()->associate($newDestination);
+ $destination->save();
+ $this->friendlyPositive(sprintf('Firefly III gave transaction #%d a new destination %s: #%d ("%s").', $journal->transaction_group_id, AccountTypeEnum::EXPENSE->value, $newDestination->id, $newDestination->name));
+ app('log')->debug(sprintf('Associated account #%d with transaction #%d', $newDestination->id, $destination->id));
+ $this->inspectJournal($journal);
+ }
}
diff --git a/app/Console/Commands/Correction/FixFrontpageAccounts.php b/app/Console/Commands/Correction/FixFrontpageAccounts.php
index 884b4d43e1..66c9348504 100644
--- a/app/Console/Commands/Correction/FixFrontpageAccounts.php
+++ b/app/Console/Commands/Correction/FixFrontpageAccounts.php
@@ -28,7 +28,6 @@ use FireflyIII\Console\Commands\ShowsFriendlyMessages;
use FireflyIII\Models\AccountType;
use FireflyIII\Models\Preference;
use FireflyIII\Repositories\Account\AccountRepositoryInterface;
-use FireflyIII\Support\Facades\Preferences;
use FireflyIII\User;
use Illuminate\Console\Command;
@@ -44,15 +43,14 @@ class FixFrontpageAccounts extends Command
/**
* Execute the console command.
- *
- * @return int
*/
public function handle(): int
{
$users = User::get();
+
/** @var User $user */
foreach ($users as $user) {
- $preference = Preferences::getForUser($user, 'frontPageAccounts');
+ $preference = app('preferences')->getForUser($user, 'frontPageAccounts');
if (null !== $preference) {
$this->fixPreference($preference);
}
@@ -62,19 +60,17 @@ class FixFrontpageAccounts extends Command
return 0;
}
- /**
- * @param Preference $preference
- */
private function fixPreference(Preference $preference): void
{
- $fixed = [];
+ $fixed = [];
+
/** @var AccountRepositoryInterface $repository */
$repository = app(AccountRepositoryInterface::class);
if (null === $preference->user) {
return;
}
$repository->setUser($preference->user);
- $data = $preference->data;
+ $data = $preference->data;
if (is_array($data)) {
/** @var string $accountId */
foreach ($data as $accountId) {
@@ -87,6 +83,6 @@ class FixFrontpageAccounts extends Command
}
}
}
- Preferences::setForUser($preference->user, 'frontPageAccounts', $fixed);
+ app('preferences')->setForUser($preference->user, 'frontPageAccounts', $fixed);
}
}
diff --git a/app/Console/Commands/Correction/FixGroupAccounts.php b/app/Console/Commands/Correction/FixGroupAccounts.php
index 9ddb1cddf6..51847ce2c0 100644
--- a/app/Console/Commands/Correction/FixGroupAccounts.php
+++ b/app/Console/Commands/Correction/FixGroupAccounts.php
@@ -24,7 +24,6 @@ declare(strict_types=1);
namespace FireflyIII\Console\Commands\Correction;
-use DB;
use FireflyIII\Console\Commands\ShowsFriendlyMessages;
use FireflyIII\Events\UpdatedTransactionGroup;
use FireflyIII\Handlers\Events\UpdatedGroupEventHandler;
@@ -44,14 +43,14 @@ class FixGroupAccounts extends Command
/**
* Execute the console command.
- *
- * @return int
*/
public function handle(): int
{
- $groups = [];
- $res = TransactionJournal::groupBy('transaction_group_id')
- ->get(['transaction_group_id', DB::raw('COUNT(transaction_group_id) as the_count')]);
+ $groups = [];
+ $res = TransactionJournal::groupBy('transaction_group_id')
+ ->get(['transaction_group_id', \DB::raw('COUNT(transaction_group_id) as the_count')])// @phpstan-ignore-line
+ ;
+
/** @var TransactionJournal $journal */
foreach ($res as $journal) {
if ((int)$journal->the_count > 1) {
diff --git a/app/Console/Commands/Correction/FixIbans.php b/app/Console/Commands/Correction/FixIbans.php
index 7afbd3c2cf..27e79a1c5b 100644
--- a/app/Console/Commands/Correction/FixIbans.php
+++ b/app/Console/Commands/Correction/FixIbans.php
@@ -39,12 +39,10 @@ class FixIbans extends Command
protected $description = 'Removes spaces from IBANs';
protected $signature = 'firefly-iii:fix-ibans';
- private int $count = 0;
+ private int $count = 0;
/**
* Execute the console command.
- *
- * @return int
*/
public function handle(): int
{
@@ -58,11 +56,6 @@ class FixIbans extends Command
return 0;
}
- /**
- * @param Collection $accounts
- *
- * @return void
- */
private function filterIbans(Collection $accounts): void
{
/** @var Account $account */
@@ -74,38 +67,33 @@ class FixIbans extends Command
$account->iban = $iban;
$account->save();
$this->friendlyInfo(sprintf('Removed spaces from IBAN of account #%d', $account->id));
- $this->count++;
+ ++$this->count;
}
}
}
}
- /**
- * @param Collection $accounts
- *
- * @return void
- */
private function countAndCorrectIbans(Collection $accounts): void
{
$set = [];
+
/** @var Account $account */
foreach ($accounts as $account) {
- $userId = (int)$account->user_id;
- $set[$userId] = $set[$userId] ?? [];
- $iban = (string)$account->iban;
+ $userId = $account->user_id;
+ $set[$userId] ??= [];
+ $iban = (string)$account->iban;
if ('' === $iban) {
continue;
}
- $type = $account->accountType->type;
+ $type = $account->accountType->type;
if (in_array($type, [AccountType::LOAN, AccountType::DEBT, AccountType::MORTGAGE], true)) {
$type = 'liabilities';
}
if (array_key_exists($iban, $set[$userId])) {
// iban already in use! two exceptions exist:
if (
- !(AccountType::EXPENSE === $set[$userId][$iban] && AccountType::REVENUE === $type)
- && // allowed combination
- !(AccountType::REVENUE === $set[$userId][$iban] && AccountType::EXPENSE === $type) // also allowed combination.
+ !(AccountType::EXPENSE === $set[$userId][$iban] && AccountType::REVENUE === $type) // allowed combination
+ && !(AccountType::REVENUE === $set[$userId][$iban] && AccountType::EXPENSE === $type) // also allowed combination.
) {
$this->friendlyWarning(
sprintf(
@@ -118,7 +106,7 @@ class FixIbans extends Command
);
$account->iban = null;
$account->save();
- $this->count++;
+ ++$this->count;
}
}
diff --git a/app/Console/Commands/Correction/FixLongDescriptions.php b/app/Console/Commands/Correction/FixLongDescriptions.php
index d9a2a04144..6830dd40e9 100644
--- a/app/Console/Commands/Correction/FixLongDescriptions.php
+++ b/app/Console/Commands/Correction/FixLongDescriptions.php
@@ -36,37 +36,37 @@ class FixLongDescriptions extends Command
{
use ShowsFriendlyMessages;
- private const MAX_LENGTH = 1000;
- protected $description = 'Fixes long descriptions in journals and groups.';
- protected $signature = 'firefly-iii:fix-long-descriptions';
+ private const int MAX_LENGTH = 1000;
+ protected $description = 'Fixes long descriptions in journals and groups.';
+ protected $signature = 'firefly-iii:fix-long-descriptions';
/**
* Execute the console command.
- *
- * @return int
*/
public function handle(): int
{
$journals = TransactionJournal::get(['id', 'description']);
$count = 0;
+
/** @var TransactionJournal $journal */
foreach ($journals as $journal) {
if (strlen($journal->description) > self::MAX_LENGTH) {
$journal->description = substr($journal->description, 0, self::MAX_LENGTH);
$journal->save();
$this->friendlyWarning(sprintf('Truncated description of transaction journal #%d', $journal->id));
- $count++;
+ ++$count;
}
}
- $groups = TransactionGroup::get(['id', 'title']);
+ $groups = TransactionGroup::get(['id', 'title']);
+
/** @var TransactionGroup $group */
foreach ($groups as $group) {
if (strlen((string)$group->title) > self::MAX_LENGTH) {
$group->title = substr($group->title, 0, self::MAX_LENGTH);
$group->save();
$this->friendlyWarning(sprintf('Truncated description of transaction group #%d', $group->id));
- $count++;
+ ++$count;
}
}
if (0 === $count) {
diff --git a/app/Console/Commands/Correction/FixPiggies.php b/app/Console/Commands/Correction/FixPiggies.php
index 8e15fc700a..7c5779e3b9 100644
--- a/app/Console/Commands/Correction/FixPiggies.php
+++ b/app/Console/Commands/Correction/FixPiggies.php
@@ -42,8 +42,6 @@ class FixPiggies extends Command
/**
* Execute the console command.
- *
- * @return int
*/
public function handle(): int
{
@@ -55,13 +53,15 @@ class FixPiggies extends Command
if (null === $event->transaction_journal_id) {
continue;
}
- /** @var TransactionJournal|null $journal */
+
+ /** @var null|TransactionJournal $journal */
$journal = $event->transactionJournal;
if (null === $journal) {
$event->transaction_journal_id = null;
$event->save();
- $count++;
+ ++$count;
+
continue;
}
}
diff --git a/app/Console/Commands/Correction/FixRecurringTransactions.php b/app/Console/Commands/Correction/FixRecurringTransactions.php
index ac2fc02cf8..a7c3e70bb3 100644
--- a/app/Console/Commands/Correction/FixRecurringTransactions.php
+++ b/app/Console/Commands/Correction/FixRecurringTransactions.php
@@ -40,16 +40,14 @@ class FixRecurringTransactions extends Command
{
use ShowsFriendlyMessages;
- protected $description = 'Fixes recurring transactions with the wrong transaction type.';
- protected $signature = 'firefly-iii:fix-recurring-transactions';
- private int $count = 0;
+ protected $description = 'Fixes recurring transactions with the wrong transaction type.';
+ protected $signature = 'firefly-iii:fix-recurring-transactions';
+ private int $count = 0;
private RecurringRepositoryInterface $recurringRepos;
private UserRepositoryInterface $userRepos;
/**
* Execute the console command.
- *
- * @return int
*/
public function handle(): int
{
@@ -66,8 +64,6 @@ class FixRecurringTransactions extends Command
* Laravel will execute ALL __construct() methods for ALL commands whenever a SINGLE command is
* executed. This leads to noticeable slow-downs and class calls. To prevent this, this method should
* be called from the handle method instead of using the constructor to initialize the command.
- *
-
*/
private function stupidLaravel(): void
{
@@ -75,34 +71,27 @@ class FixRecurringTransactions extends Command
$this->userRepos = app(UserRepositoryInterface::class);
}
- /**
- *
- */
private function correctTransactions(): void
{
$users = $this->userRepos->all();
+
/** @var User $user */
foreach ($users as $user) {
$this->processUser($user);
}
}
- /**
- * @param User $user
- */
private function processUser(User $user): void
{
$this->recurringRepos->setUser($user);
$recurrences = $this->recurringRepos->get();
+
/** @var Recurrence $recurrence */
foreach ($recurrences as $recurrence) {
$this->processRecurrence($recurrence);
}
}
- /**
- * @param Recurrence $recurrence
- */
private function processRecurrence(Recurrence $recurrence): void
{
/** @var RecurrenceTransaction $transaction */
@@ -111,10 +100,6 @@ class FixRecurringTransactions extends Command
}
}
- /**
- * @param Recurrence $recurrence
- * @param RecurrenceTransaction $transaction
- */
private function processTransaction(Recurrence $recurrence, RecurrenceTransaction $transaction): void
{
$source = $transaction->sourceAccount;
@@ -129,7 +114,7 @@ class FixRecurringTransactions extends Command
if (null !== $transactionType) {
$recurrence->transaction_type_id = $transactionType->id;
$recurrence->save();
- $this->count++;
+ ++$this->count;
}
}
}
diff --git a/app/Console/Commands/Correction/FixTransactionTypes.php b/app/Console/Commands/Correction/FixTransactionTypes.php
index 9fbd8a42ce..a5bcfb9e15 100644
--- a/app/Console/Commands/Correction/FixTransactionTypes.php
+++ b/app/Console/Commands/Correction/FixTransactionTypes.php
@@ -45,22 +45,21 @@ class FixTransactionTypes extends Command
/**
* Execute the console command.
- *
- * @return int
*/
public function handle(): int
{
$count = 0;
$journals = $this->collectJournals();
+
/** @var TransactionJournal $journal */
foreach ($journals as $journal) {
$fixed = $this->fixJournal($journal);
if (true === $fixed) {
- $count++;
+ ++$count;
}
}
if ($count > 0) {
- $this->friendlyInfo('Corrected transaction type of %d transaction journals.', $count);
+ $this->friendlyInfo(sprintf('Corrected transaction type of %d transaction journals.', $count));
return 0;
}
@@ -71,23 +70,18 @@ class FixTransactionTypes extends Command
/**
* Collect all transaction journals.
- *
- * @return Collection
*/
private function collectJournals(): Collection
{
return TransactionJournal::with(['transactionType', 'transactions', 'transactions.account', 'transactions.account.accountType'])
- ->get();
+ ->get()
+ ;
}
- /**
- * @param TransactionJournal $journal
- *
- * @return bool
- */
private function fixJournal(TransactionJournal $journal): bool
{
- $type = $journal->transactionType->type;
+ $type = $journal->transactionType->type;
+
try {
$source = $this->getSourceAccount($journal);
$destination = $this->getDestinationAccount($journal);
@@ -117,14 +111,11 @@ class FixTransactionTypes extends Command
}
/**
- * @param TransactionJournal $journal
- *
- * @return Account
* @throws FireflyException
*/
private function getSourceAccount(TransactionJournal $journal): Account
{
- $collection = $journal->transactions->filter(
+ $collection = $journal->transactions->filter(
static function (Transaction $transaction) {
return $transaction->amount < 0;
}
@@ -135,10 +126,12 @@ class FixTransactionTypes extends Command
if (1 !== $collection->count()) {
throw new FireflyException(sprintf('300002: Journal #%d has multiple source transactions.', $journal->id));
}
+
/** @var Transaction $transaction */
$transaction = $collection->first();
- /** @var Account|null $account */
- $account = $transaction->account;
+
+ /** @var null|Account $account */
+ $account = $transaction->account;
if (null === $account) {
throw new FireflyException(sprintf('300003: Journal #%d, transaction #%d has no source account.', $journal->id, $transaction->id));
}
@@ -147,14 +140,11 @@ class FixTransactionTypes extends Command
}
/**
- * @param TransactionJournal $journal
- *
- * @return Account
* @throws FireflyException
*/
private function getDestinationAccount(TransactionJournal $journal): Account
{
- $collection = $journal->transactions->filter(
+ $collection = $journal->transactions->filter(
static function (Transaction $transaction) {
return $transaction->amount > 0;
}
@@ -165,10 +155,12 @@ class FixTransactionTypes extends Command
if (1 !== $collection->count()) {
throw new FireflyException(sprintf('300005: Journal #%d has multiple destination transactions.', $journal->id));
}
+
/** @var Transaction $transaction */
$transaction = $collection->first();
- /** @var Account|null $account */
- $account = $transaction->account;
+
+ /** @var null|Account $account */
+ $account = $transaction->account;
if (null === $account) {
throw new FireflyException(sprintf('300006: Journal #%d, transaction #%d has no destination account.', $journal->id, $transaction->id));
}
@@ -176,10 +168,6 @@ class FixTransactionTypes extends Command
return $account;
}
- /**
- * @param TransactionJournal $journal
- * @param string $expectedType
- */
private function changeJournal(TransactionJournal $journal, string $expectedType): void
{
$type = TransactionType::whereType($expectedType)->first();
diff --git a/app/Console/Commands/Correction/FixUnevenAmount.php b/app/Console/Commands/Correction/FixUnevenAmount.php
index 9b09734392..608a3ea32c 100644
--- a/app/Console/Commands/Correction/FixUnevenAmount.php
+++ b/app/Console/Commands/Correction/FixUnevenAmount.php
@@ -23,12 +23,11 @@ declare(strict_types=1);
namespace FireflyIII\Console\Commands\Correction;
-use DB;
use FireflyIII\Console\Commands\ShowsFriendlyMessages;
use FireflyIII\Models\Transaction;
use FireflyIII\Models\TransactionJournal;
use Illuminate\Console\Command;
-use stdClass;
+use Illuminate\Support\Facades\Log;
/**
* Class FixUnevenAmount
@@ -42,20 +41,23 @@ class FixUnevenAmount extends Command
/**
* Execute the console command.
- *
- * @return int
*/
public function handle(): int
{
$count = 0;
- $journals = DB::table('transactions')
- ->groupBy('transaction_journal_id')
- ->whereNull('deleted_at')
- ->get(['transaction_journal_id', DB::raw('SUM(amount) AS the_sum')]);
- /** @var stdClass $entry */
+ $journals = \DB::table('transactions')
+ ->groupBy('transaction_journal_id')
+ ->whereNull('deleted_at')
+ ->get(['transaction_journal_id', \DB::raw('SUM(amount) AS the_sum')])
+ ;
+
+ /** @var \stdClass $entry */
foreach ($journals as $entry) {
$sum = (string)$entry->the_sum;
- if (!is_numeric($sum) || '' === $sum || str_contains($sum, 'e') || str_contains($sum, ',')) {
+ if (!is_numeric($sum)
+ || '' === $sum // @phpstan-ignore-line
+ || str_contains($sum, 'e')
+ || str_contains($sum, ',')) {
$message = sprintf(
'Journal #%d has an invalid sum ("%s"). No sure what to do.',
$entry->transaction_journal_id,
@@ -63,10 +65,20 @@ class FixUnevenAmount extends Command
);
$this->friendlyWarning($message);
app('log')->warning($message);
- $count++;
+ ++$count;
+
continue;
}
- if (0 !== bccomp((string)$entry->the_sum, '0')) {
+ $res = -1;
+
+ try {
+ $res = bccomp($sum, '0');
+ } catch (\ValueError $e) {
+ $this->friendlyError(sprintf('Could not bccomp("%s", "0").', $sum));
+ Log::error($e->getMessage());
+ Log::error($e->getTraceAsString());
+ }
+ if (0 !== $res) {
$message = sprintf(
'Sum of journal #%d is %s instead of zero.',
$entry->transaction_journal_id,
@@ -74,8 +86,8 @@ class FixUnevenAmount extends Command
);
$this->friendlyWarning($message);
app('log')->warning($message);
- $this->fixJournal((int)$entry->transaction_journal_id);
- $count++;
+ $this->fixJournal($entry->transaction_journal_id);
+ ++$count;
}
}
if (0 === $count) {
@@ -85,18 +97,16 @@ class FixUnevenAmount extends Command
return 0;
}
- /**
- * @param int $param
- */
private function fixJournal(int $param): void
{
// one of the transactions is bad.
- $journal = TransactionJournal::find($param);
- if (!$journal) {
+ $journal = TransactionJournal::find($param);
+ if (null === $journal) {
return;
}
- /** @var Transaction|null $source */
- $source = $journal->transactions()->where('amount', '<', 0)->first();
+
+ /** @var null|Transaction $source */
+ $source = $journal->transactions()->where('amount', '<', 0)->first();
if (null === $source) {
$this->friendlyError(
@@ -107,16 +117,16 @@ class FixUnevenAmount extends Command
)
);
Transaction::where('transaction_journal_id', $journal->id ?? 0)->forceDelete();
- TransactionJournal::where('id', $journal->description ?? 0)->forceDelete();
+ TransactionJournal::where('id', $journal->id ?? 0)->forceDelete();
return;
}
- $amount = bcmul('-1', (string)$source->amount);
+ $amount = bcmul('-1', $source->amount);
// fix amount of destination:
- /** @var Transaction|null $destination */
- $destination = $journal->transactions()->where('amount', '>', 0)->first();
+ /** @var null|Transaction $destination */
+ $destination = $journal->transactions()->where('amount', '>', 0)->first();
if (null === $destination) {
$this->friendlyError(
@@ -128,7 +138,7 @@ class FixUnevenAmount extends Command
);
Transaction::where('transaction_journal_id', $journal->id ?? 0)->forceDelete();
- TransactionJournal::where('id', $journal->description ?? 0)->forceDelete();
+ TransactionJournal::where('id', $journal->id ?? 0)->forceDelete();
return;
}
@@ -136,7 +146,7 @@ class FixUnevenAmount extends Command
$destination->amount = $amount;
$destination->save();
- $message = sprintf('Corrected amount in transaction journal #%d', $param);
+ $message = sprintf('Corrected amount in transaction journal #%d', $param);
$this->friendlyInfo($message);
}
}
diff --git a/app/Console/Commands/Correction/RemoveBills.php b/app/Console/Commands/Correction/RemoveBills.php
index a68ad038b4..e4dd225720 100644
--- a/app/Console/Commands/Correction/RemoveBills.php
+++ b/app/Console/Commands/Correction/RemoveBills.php
@@ -40,17 +40,16 @@ class RemoveBills extends Command
/**
* Execute the console command.
- *
- * @return int
*/
public function handle(): int
{
- /** @var TransactionType|null $withdrawal */
+ /** @var null|TransactionType $withdrawal */
$withdrawal = TransactionType::where('type', TransactionType::WITHDRAWAL)->first();
if (null === $withdrawal) {
return 0;
}
- $journals = TransactionJournal::whereNotNull('bill_id')->where('transaction_type_id', '!=', $withdrawal->id)->get();
+ $journals = TransactionJournal::whereNotNull('bill_id')->where('transaction_type_id', '!=', $withdrawal->id)->get();
+
/** @var TransactionJournal $journal */
foreach ($journals as $journal) {
$this->friendlyWarning(sprintf('Transaction journal #%d will be unlinked from bill #%d.', $journal->id, $journal->bill_id));
diff --git a/app/Console/Commands/Correction/RenameMetaFields.php b/app/Console/Commands/Correction/RenameMetaFields.php
index 1005114e61..e25c333e16 100644
--- a/app/Console/Commands/Correction/RenameMetaFields.php
+++ b/app/Console/Commands/Correction/RenameMetaFields.php
@@ -23,7 +23,6 @@ declare(strict_types=1);
namespace FireflyIII\Console\Commands\Correction;
-use DB;
use FireflyIII\Console\Commands\ShowsFriendlyMessages;
use Illuminate\Console\Command;
@@ -37,17 +36,13 @@ class RenameMetaFields extends Command
protected $description = 'Rename changed meta fields.';
protected $signature = 'firefly-iii:rename-meta-fields';
- private int $count;
+ private int $count = 0;
/**
* Execute the console command.
- *
- * @return int
*/
public function handle(): int
{
- $this->count = 0;
-
$changes = [
'original-source' => 'original_source',
'importHash' => 'import_hash',
@@ -71,18 +66,16 @@ class RenameMetaFields extends Command
if (0 !== $this->count) {
$this->friendlyInfo(sprintf('Renamed %d meta field(s).', $this->count));
}
+
return 0;
}
- /**
- * @param string $original
- * @param string $update
- */
private function rename(string $original, string $update): void
{
- $total = DB::table('journal_meta')
- ->where('name', '=', $original)
- ->update(['name' => $update]);
+ $total = \DB::table('journal_meta')
+ ->where('name', '=', $original)
+ ->update(['name' => $update])
+ ;
$this->count += $total;
}
}
diff --git a/app/Console/Commands/Correction/TransferBudgets.php b/app/Console/Commands/Correction/TransferBudgets.php
index 12372a57ef..e1bb7d3345 100644
--- a/app/Console/Commands/Correction/TransferBudgets.php
+++ b/app/Console/Commands/Correction/TransferBudgets.php
@@ -27,7 +27,6 @@ use FireflyIII\Console\Commands\ShowsFriendlyMessages;
use FireflyIII\Models\TransactionJournal;
use FireflyIII\Models\TransactionType;
use Illuminate\Console\Command;
-use Illuminate\Support\Facades\Log;
/**
* Class TransferBudgets
@@ -41,24 +40,24 @@ class TransferBudgets extends Command
/**
* Execute the console command.
- *
- * @return int
*/
public function handle(): int
{
$set = TransactionJournal::distinct()
- ->leftJoin('transaction_types', 'transaction_types.id', '=', 'transaction_journals.transaction_type_id')
- ->leftJoin('budget_transaction_journal', 'transaction_journals.id', '=', 'budget_transaction_journal.transaction_journal_id')
- ->whereNotIn('transaction_types.type', [TransactionType::WITHDRAWAL])
- ->whereNotNull('budget_transaction_journal.budget_id')->get(['transaction_journals.*']);
+ ->leftJoin('transaction_types', 'transaction_types.id', '=', 'transaction_journals.transaction_type_id')
+ ->leftJoin('budget_transaction_journal', 'transaction_journals.id', '=', 'budget_transaction_journal.transaction_journal_id')
+ ->whereNotIn('transaction_types.type', [TransactionType::WITHDRAWAL])
+ ->whereNotNull('budget_transaction_journal.budget_id')->get(['transaction_journals.*'])
+ ;
$count = 0;
+
/** @var TransactionJournal $entry */
foreach ($set as $entry) {
$message = sprintf('Transaction journal #%d is a %s, so has no longer a budget.', $entry->id, $entry->transactionType->type);
$this->friendlyInfo($message);
- Log::debug($message);
+ app('log')->debug($message);
$entry->budgets()->sync([]);
- $count++;
+ ++$count;
}
if (0 === $count) {
$message = 'No invalid budget/journal entries.';
@@ -66,9 +65,10 @@ class TransferBudgets extends Command
}
if (0 !== $count) {
$message = sprintf('Corrected %d invalid budget/journal entries (entry).', $count);
- Log::debug($message);
+ app('log')->debug($message);
$this->friendlyInfo($message);
}
+
return 0;
}
}
diff --git a/app/Console/Commands/Correction/TriggerCreditCalculation.php b/app/Console/Commands/Correction/TriggerCreditCalculation.php
index 21be5aa4fe..1cefe73a3a 100644
--- a/app/Console/Commands/Correction/TriggerCreditCalculation.php
+++ b/app/Console/Commands/Correction/TriggerCreditCalculation.php
@@ -1,6 +1,5 @@
whereIn('account_types.type', config('firefly.valid_liabilities'))
- ->get(['accounts.*']);
+ ->whereIn('account_types.type', config('firefly.valid_liabilities'))
+ ->get(['accounts.*'])
+ ;
foreach ($accounts as $account) {
$this->processAccount($account);
}
}
- /**
- * @param Account $account
- *
- * @return void
- */
private function processAccount(Account $account): void
{
/** @var CreditRecalculateService $object */
diff --git a/app/Console/Commands/Export/ExportData.php b/app/Console/Commands/Export/ExportData.php
index d3c03f1e8c..4e0ba1731a 100644
--- a/app/Console/Commands/Export/ExportData.php
+++ b/app/Console/Commands/Export/ExportData.php
@@ -25,7 +25,6 @@ declare(strict_types=1);
namespace FireflyIII\Console\Commands\Export;
use Carbon\Carbon;
-use Exception;
use FireflyIII\Console\Commands\ShowsFriendlyMessages;
use FireflyIII\Console\Commands\VerifiesAccessToken;
use FireflyIII\Exceptions\FireflyException;
@@ -36,10 +35,6 @@ use FireflyIII\Repositories\Journal\JournalRepositoryInterface;
use FireflyIII\Support\Export\ExportDataGenerator;
use Illuminate\Console\Command;
use Illuminate\Support\Collection;
-use Illuminate\Support\Facades\Log;
-use InvalidArgumentException;
-use Psr\Container\ContainerExceptionInterface;
-use Psr\Container\NotFoundExceptionInterface;
/**
* Class ExportData
@@ -49,18 +44,9 @@ class ExportData extends Command
use ShowsFriendlyMessages;
use VerifiesAccessToken;
- /**
- * The console command description.
- *
- * @var string
- */
protected $description = 'Command to export data from Firefly III.';
- /**
- * The name and signature of the console command.
- *
- * @var string
- */
- protected $signature = 'firefly-iii:export-data
+
+ protected $signature = 'firefly-iii:export-data
{--user=1 : The user ID that the export should run for.}
{--token= : The user\'s access token.}
{--start= : First transaction to export. Defaults to your very first transaction. Only applies to transaction export.}
@@ -83,10 +69,7 @@ class ExportData extends Command
/**
* Execute the console command.
*
- * @return int
* @throws FireflyException
- * @throws ContainerExceptionInterface
- * @throws NotFoundExceptionInterface
*/
public function handle(): int
{
@@ -98,9 +81,10 @@ class ExportData extends Command
}
// set up repositories.
$this->stupidLaravel();
- $user = $this->getUser();
+ $user = $this->getUser();
$this->journalRepository->setUser($user);
$this->accountRepository->setUser($user);
+
// get the options.
try {
$options = $this->parseOptions();
@@ -109,9 +93,10 @@ class ExportData extends Command
return 1;
}
+
// make export object and configure it.
/** @var ExportDataGenerator $exporter */
- $exporter = app(ExportDataGenerator::class);
+ $exporter = app(ExportDataGenerator::class);
$exporter->setUser($user);
$exporter->setStart($options['start']);
@@ -126,7 +111,7 @@ class ExportData extends Command
$exporter->setExportRules($options['export']['rules']);
$exporter->setExportBills($options['export']['bills']);
$exporter->setExportPiggies($options['export']['piggies']);
- $data = $exporter->export();
+ $data = $exporter->export();
if (0 === count($data)) {
$this->friendlyError('You must export *something*. Use --export-transactions or another option. See docs.firefly-iii.org');
}
@@ -148,8 +133,6 @@ class ExportData extends Command
* Laravel will execute ALL __construct() methods for ALL commands whenever a SINGLE command is
* executed. This leads to noticeable slow-downs and class calls. To prevent this, this method should
* be called from the handle method instead of using the constructor to initialize the command.
- *
-
*/
private function stupidLaravel(): void
{
@@ -158,9 +141,8 @@ class ExportData extends Command
}
/**
- * @return array
* @throws FireflyException
- * @throws Exception
+ * @throws \Exception
*/
private function parseOptions(): array
{
@@ -190,26 +172,33 @@ class ExportData extends Command
}
/**
- * @param string $field
- *
- * @return Carbon
- * @throws Exception
+ * @throws \Exception
*/
private function getDateParameter(string $field): Carbon
{
$date = today(config('app.timezone'))->subYear();
$error = false;
- if (null !== $this->option($field)) {
+
+ if (!in_array($field, ['start', 'end'], true)) {
+ throw new FireflyException(sprintf('Invalid field "%s" given, can only be "start" or "end".', $field));
+ }
+
+ if (is_string($this->option($field))) {
try {
$date = Carbon::createFromFormat('!Y-m-d', $this->option($field));
- } catch (InvalidArgumentException $e) {
- Log::error($e->getMessage());
+ } catch (\InvalidArgumentException $e) {
+ app('log')->error($e->getMessage());
$this->friendlyError(sprintf('%s date "%s" must be formatted YYYY-MM-DD. Field will be ignored.', $field, $this->option('start')));
$error = true;
}
+ if (false === $date) {
+ $this->friendlyError(sprintf('%s date "%s" must be formatted YYYY-MM-DD.', $field, $this->option('start')));
+
+ throw new FireflyException(sprintf('%s date "%s" must be formatted YYYY-MM-DD.', $field, $this->option('start')));
+ }
}
if (null === $this->option($field)) {
- Log::info(sprintf('No date given in field "%s"', $field));
+ app('log')->info(sprintf('No date given in field "%s"', $field));
$error = true;
}
@@ -217,12 +206,17 @@ class ExportData extends Command
$journal = $this->journalRepository->firstNull();
$date = null === $journal ? today(config('app.timezone'))->subYear() : $journal->date;
$date->startOfDay();
- }
- if (true === $error && 'end' === $field) {
+ return $date;
+ }
+ // field can only be 'end' at this point, so no need to include it in the check.
+ if (true === $error) {
$date = today(config('app.timezone'));
$date->endOfDay();
+
+ return $date;
}
+
if ('end' === $field) {
$date->endOfDay();
}
@@ -231,22 +225,22 @@ class ExportData extends Command
}
/**
- * @return Collection
* @throws FireflyException
*/
private function getAccountsParameter(): Collection
{
$final = new Collection();
$accounts = new Collection();
- $accountList = $this->option('accounts');
+ $accountList = (string)$this->option('accounts');
$types = [AccountType::ASSET, AccountType::LOAN, AccountType::DEBT, AccountType::MORTGAGE];
- if (null !== $accountList && '' !== (string)$accountList) {
+ if ('' !== $accountList) {
$accountIds = explode(',', $accountList);
$accounts = $this->accountRepository->getAccountsById($accountIds);
}
- if (null === $accountList) {
+ if ('' === $accountList) {
$accounts = $this->accountRepository->getAccountsByType($types);
}
+
// filter accounts,
/** @var Account $account */
foreach ($accounts as $account) {
@@ -262,14 +256,12 @@ class ExportData extends Command
}
/**
- * @return string
* @throws FireflyException
- *
*/
private function getExportDirectory(): string
{
$directory = (string)$this->option('export_directory');
- if (null === $directory) {
+ if ('' === $directory) {
$directory = './';
}
if (!is_writable($directory)) {
@@ -280,9 +272,6 @@ class ExportData extends Command
}
/**
- * @param array $options
- * @param array $data
- *
* @throws FireflyException
*/
private function exportData(array $options, array $data): void
diff --git a/app/Console/Commands/Integrity/CreateGroupMemberships.php b/app/Console/Commands/Integrity/CreateGroupMemberships.php
index 5351c496f9..0927f1b7cb 100644
--- a/app/Console/Commands/Integrity/CreateGroupMemberships.php
+++ b/app/Console/Commands/Integrity/CreateGroupMemberships.php
@@ -40,14 +40,13 @@ class CreateGroupMemberships extends Command
{
use ShowsFriendlyMessages;
- public const CONFIG_NAME = '560_create_group_memberships';
- protected $description = 'Update group memberships';
- protected $signature = 'firefly-iii:create-group-memberships';
+ public const string CONFIG_NAME = '560_create_group_memberships';
+ protected $description = 'Update group memberships';
+ protected $signature = 'firefly-iii:create-group-memberships';
/**
* Execute the console command.
*
- * @return int
* @throws FireflyException
*/
public function handle(): int
@@ -59,12 +58,12 @@ class CreateGroupMemberships extends Command
}
/**
- *
* @throws FireflyException
*/
private function createGroupMemberships(): void
{
$users = User::get();
+
/** @var User $user */
foreach ($users as $user) {
self::createGroupMembership($user);
@@ -74,26 +73,25 @@ class CreateGroupMemberships extends Command
/**
* TODO move to helper.
*
- * @param User $user
- *
* @throws FireflyException
*/
public static function createGroupMembership(User $user): void
{
// check if membership exists
- $userGroup = UserGroup::where('title', $user->email)->first();
+ $userGroup = UserGroup::where('title', $user->email)->first();
if (null === $userGroup) {
$userGroup = UserGroup::create(['title' => $user->email]);
}
- $userRole = UserRole::where('title', UserRoleEnum::OWNER->value)->first();
+ $userRole = UserRole::where('title', UserRoleEnum::OWNER->value)->first();
if (null === $userRole) {
throw new FireflyException('Firefly III could not find a user role. Please make sure all migrations have run.');
}
$membership = GroupMembership::where('user_id', $user->id)
- ->where('user_group_id', $userGroup->id)
- ->where('user_role_id', $userRole->id)->first();
+ ->where('user_group_id', $userGroup->id)
+ ->where('user_role_id', $userRole->id)->first()
+ ;
if (null === $membership) {
GroupMembership::create(
[
diff --git a/app/Console/Commands/Integrity/ReportEmptyObjects.php b/app/Console/Commands/Integrity/ReportEmptyObjects.php
index 2152694ed8..1aa793c763 100644
--- a/app/Console/Commands/Integrity/ReportEmptyObjects.php
+++ b/app/Console/Commands/Integrity/ReportEmptyObjects.php
@@ -29,7 +29,6 @@ use FireflyIII\Models\Budget;
use FireflyIII\Models\Category;
use FireflyIII\Models\Tag;
use Illuminate\Console\Command;
-use stdClass;
/**
* Class ReportEmptyObjects
@@ -38,23 +37,12 @@ class ReportEmptyObjects extends Command
{
use ShowsFriendlyMessages;
- /**
- * The console command description.
- *
- * @var string
- */
protected $description = 'Reports on empty database objects.';
- /**
- * The name and signature of the console command.
- *
- * @var string
- */
- protected $signature = 'firefly-iii:report-empty-objects';
+
+ protected $signature = 'firefly-iii:report-empty-objects';
/**
* Execute the console command.
- *
- * @return int
*/
public function handle(): int
{
@@ -73,13 +61,14 @@ class ReportEmptyObjects extends Command
private function reportEmptyBudgets(): void
{
$set = Budget::leftJoin('budget_transaction_journal', 'budgets.id', '=', 'budget_transaction_journal.budget_id')
- ->leftJoin('users', 'budgets.user_id', '=', 'users.id')
- ->distinct()
- ->whereNull('budget_transaction_journal.budget_id')
- ->whereNull('budgets.deleted_at')
- ->get(['budgets.id', 'budgets.name', 'budgets.user_id', 'users.email']);
+ ->leftJoin('users', 'budgets.user_id', '=', 'users.id')
+ ->distinct()
+ ->whereNull('budget_transaction_journal.budget_id')
+ ->whereNull('budgets.deleted_at')
+ ->get(['budgets.id', 'budgets.name', 'budgets.user_id', 'users.email'])
+ ;
- /** @var stdClass $entry */
+ /** @var \stdClass $entry */
foreach ($set as $entry) {
$line = sprintf(
'User #%d (%s) has budget #%d ("%s") which has no transaction journals.',
@@ -98,13 +87,14 @@ class ReportEmptyObjects extends Command
private function reportEmptyCategories(): void
{
$set = Category::leftJoin('category_transaction_journal', 'categories.id', '=', 'category_transaction_journal.category_id')
- ->leftJoin('users', 'categories.user_id', '=', 'users.id')
- ->distinct()
- ->whereNull('category_transaction_journal.category_id')
- ->whereNull('categories.deleted_at')
- ->get(['categories.id', 'categories.name', 'categories.user_id', 'users.email']);
+ ->leftJoin('users', 'categories.user_id', '=', 'users.id')
+ ->distinct()
+ ->whereNull('category_transaction_journal.category_id')
+ ->whereNull('categories.deleted_at')
+ ->get(['categories.id', 'categories.name', 'categories.user_id', 'users.email'])
+ ;
- /** @var stdClass $entry */
+ /** @var \stdClass $entry */
foreach ($set as $entry) {
$line = sprintf(
'User #%d (%s) has category #%d ("%s") which has no transaction journals.',
@@ -117,19 +107,17 @@ class ReportEmptyObjects extends Command
}
}
- /**
- *
- */
private function reportEmptyTags(): void
{
$set = Tag::leftJoin('tag_transaction_journal', 'tags.id', '=', 'tag_transaction_journal.tag_id')
- ->leftJoin('users', 'tags.user_id', '=', 'users.id')
- ->distinct()
- ->whereNull('tag_transaction_journal.tag_id')
- ->whereNull('tags.deleted_at')
- ->get(['tags.id', 'tags.tag', 'tags.user_id', 'users.email']);
+ ->leftJoin('users', 'tags.user_id', '=', 'users.id')
+ ->distinct()
+ ->whereNull('tag_transaction_journal.tag_id')
+ ->whereNull('tags.deleted_at')
+ ->get(['tags.id', 'tags.tag', 'tags.user_id', 'users.email'])
+ ;
- /** @var stdClass $entry */
+ /** @var \stdClass $entry */
foreach ($set as $entry) {
$line = sprintf(
'User #%d (%s) has tag #%d ("%s") which has no transaction journals.',
@@ -148,14 +136,15 @@ class ReportEmptyObjects extends Command
private function reportAccounts(): void
{
$set = Account::leftJoin('transactions', 'transactions.account_id', '=', 'accounts.id')
- ->leftJoin('users', 'accounts.user_id', '=', 'users.id')
- ->groupBy(['accounts.id', 'accounts.encrypted', 'accounts.name', 'accounts.user_id', 'users.email'])
- ->whereNull('transactions.account_id')
- ->get(
- ['accounts.id', 'accounts.encrypted', 'accounts.name', 'accounts.user_id', 'users.email']
- );
+ ->leftJoin('users', 'accounts.user_id', '=', 'users.id')
+ ->groupBy(['accounts.id', 'accounts.encrypted', 'accounts.name', 'accounts.user_id', 'users.email'])
+ ->whereNull('transactions.account_id')
+ ->get(
+ ['accounts.id', 'accounts.encrypted', 'accounts.name', 'accounts.user_id', 'users.email']
+ )
+ ;
- /** @var stdClass $entry */
+ /** @var \stdClass $entry */
foreach ($set as $entry) {
$line = 'User #%d (%s) has account #%d ("%s") which has no transactions.';
$line = sprintf($line, $entry->user_id, $entry->email, $entry->id, $entry->name);
@@ -169,10 +158,11 @@ class ReportEmptyObjects extends Command
private function reportBudgetLimits(): void
{
$set = Budget::leftJoin('budget_limits', 'budget_limits.budget_id', '=', 'budgets.id')
- ->leftJoin('users', 'budgets.user_id', '=', 'users.id')
- ->groupBy(['budgets.id', 'budgets.name', 'budgets.encrypted', 'budgets.user_id', 'users.email'])
- ->whereNull('budget_limits.id')
- ->get(['budgets.id', 'budgets.name', 'budgets.user_id', 'budgets.encrypted', 'users.email']);
+ ->leftJoin('users', 'budgets.user_id', '=', 'users.id')
+ ->groupBy(['budgets.id', 'budgets.name', 'budgets.encrypted', 'budgets.user_id', 'users.email'])
+ ->whereNull('budget_limits.id')
+ ->get(['budgets.id', 'budgets.name', 'budgets.user_id', 'budgets.encrypted', 'users.email'])
+ ;
/** @var Budget $entry */
foreach ($set as $entry) {
diff --git a/app/Console/Commands/Integrity/ReportIntegrity.php b/app/Console/Commands/Integrity/ReportIntegrity.php
index 5075e69ea9..5d4d48064e 100644
--- a/app/Console/Commands/Integrity/ReportIntegrity.php
+++ b/app/Console/Commands/Integrity/ReportIntegrity.php
@@ -23,32 +23,19 @@ declare(strict_types=1);
namespace FireflyIII\Console\Commands\Integrity;
-use Artisan;
use FireflyIII\Console\Commands\ShowsFriendlyMessages;
use Illuminate\Console\Command;
-use Schema;
/**
* Class ReportIntegrity
- *
-
*/
class ReportIntegrity extends Command
{
use ShowsFriendlyMessages;
- /**
- * The console command description.
- *
- * @var string
- */
protected $description = 'Will report on the integrity of your database.';
- /**
- * The name and signature of the console command.
- *
- * @var string
- */
- protected $signature = 'firefly-iii:report-integrity';
+
+ protected $signature = 'firefly-iii:report-integrity';
/**
* Execute the console command.
@@ -56,7 +43,7 @@ class ReportIntegrity extends Command
public function handle(): int
{
// if table does not exist, return false
- if (!Schema::hasTable('users')) {
+ if (!\Schema::hasTable('users')) {
return 1;
}
$commands = [
diff --git a/app/Console/Commands/Integrity/ReportSkeleton.php.stub b/app/Console/Commands/Integrity/ReportSkeleton.php.stub
index bf37df022f..fa771b24c9 100644
--- a/app/Console/Commands/Integrity/ReportSkeleton.php.stub
+++ b/app/Console/Commands/Integrity/ReportSkeleton.php.stub
@@ -10,17 +10,9 @@ use Illuminate\Console\Command;
*/
class ReportSkeleton extends Command
{
- /**
- * The console command description.
- *
- * @var string
- */
+
protected $description = 'DESCRIPTION HERE';
- /**
- * The name and signature of the console command.
- *
- * @var string
- */
+
protected $signature = 'firefly-iii:INT_COMMAND';
/**
diff --git a/app/Console/Commands/Integrity/ReportSum.php b/app/Console/Commands/Integrity/ReportSum.php
index 9dc5192edf..a586b9b507 100644
--- a/app/Console/Commands/Integrity/ReportSum.php
+++ b/app/Console/Commands/Integrity/ReportSum.php
@@ -40,8 +40,6 @@ class ReportSum extends Command
/**
* Execute the console command.
- *
- * @return int
*/
public function handle(): int
{
@@ -64,6 +62,7 @@ class ReportSum extends Command
if (!is_numeric($sum)) {
$message = sprintf('Error: Transactions for user #%d (%s) have an invalid sum ("%s").', $user->id, $user->email, $sum);
$this->friendlyError($message);
+
continue;
}
if (0 !== bccomp($sum, '0')) {
diff --git a/app/Console/Commands/Integrity/RestoreOAuthKeys.php b/app/Console/Commands/Integrity/RestoreOAuthKeys.php
index 463b270c91..b84a7eec14 100644
--- a/app/Console/Commands/Integrity/RestoreOAuthKeys.php
+++ b/app/Console/Commands/Integrity/RestoreOAuthKeys.php
@@ -40,8 +40,6 @@ class RestoreOAuthKeys extends Command
/**
* Execute the console command.
- *
- * @return int
*/
public function handle(): int
{
@@ -50,9 +48,6 @@ class RestoreOAuthKeys extends Command
return 0;
}
- /**
- *
- */
private function restoreOAuthKeys(): void
{
if (!$this->keysInDatabase() && !$this->keysOnDrive()) {
@@ -84,41 +79,26 @@ class RestoreOAuthKeys extends Command
$this->friendlyPositive('OAuth keys are OK');
}
- /**
- * @return bool
- */
private function keysInDatabase(): bool
{
return OAuthKeys::keysInDatabase();
}
- /**
- * @return bool
- */
private function keysOnDrive(): bool
{
return OAuthKeys::hasKeyFiles();
}
- /**
- *
- */
private function generateKeys(): void
{
OAuthKeys::generateKeys();
}
- /**
- *
- */
private function storeKeysInDB(): void
{
OAuthKeys::storeKeysInDB();
}
- /**
- *
- */
private function restoreKeysFromDB(): bool
{
return OAuthKeys::restoreKeysFromDB();
diff --git a/app/Console/Commands/Integrity/UpdateGroupInformation.php b/app/Console/Commands/Integrity/UpdateGroupInformation.php
index 305026d943..e3e8c5eaef 100644
--- a/app/Console/Commands/Integrity/UpdateGroupInformation.php
+++ b/app/Console/Commands/Integrity/UpdateGroupInformation.php
@@ -66,6 +66,7 @@ class UpdateGroupInformation extends Command
// recurrences, rule groups, rules, tags, transaction groups, transaction journals, webhooks
$users = User::get();
+
/** @var User $user */
foreach ($users as $user) {
$this->updateGroupInfo($user);
@@ -74,11 +75,6 @@ class UpdateGroupInformation extends Command
return 0;
}
- /**
- * @param User $user
- *
- * @return void
- */
private function updateGroupInfo(User $user): void
{
$group = $user->userGroup;
@@ -87,7 +83,7 @@ class UpdateGroupInformation extends Command
return;
}
- $set = [
+ $set = [
Account::class,
Attachment::class,
AvailableBudget::class,
@@ -109,13 +105,6 @@ class UpdateGroupInformation extends Command
}
}
- /**
- * @param User $user
- * @param UserGroup $group
- * @param string $className
- *
- * @return void
- */
private function updateGroupInfoForObject(User $user, UserGroup $group, string $className): void
{
try {
diff --git a/app/Console/Commands/ShowsFriendlyMessages.php b/app/Console/Commands/ShowsFriendlyMessages.php
index bc40b466d1..1046218d0f 100644
--- a/app/Console/Commands/ShowsFriendlyMessages.php
+++ b/app/Console/Commands/ShowsFriendlyMessages.php
@@ -1,6 +1,5 @@
error(sprintf(' [x] %s', trim($message)));
}
- /**
- * @param string $message
- *
- * @return void
- */
public function friendlyInfo(string $message): void
{
$this->friendlyNeutral($message);
}
- /**
- * @param string $message
- *
- * @return void
- */
public function friendlyNeutral(string $message): void
{
$this->line(sprintf(' [i] %s', trim($message)));
}
- /**
- * @param string $message
- *
- * @return void
- */
public function friendlyLine(string $message): void
{
$this->line(sprintf(' %s', trim($message)));
}
- /**
- * @param string $message
- *
- * @return void
- */
public function friendlyPositive(string $message): void
{
$this->info(sprintf(' [✓] %s', trim($message)));
}
- /**
- * @param string $message
- *
- * @return void
- */
public function friendlyWarning(string $message): void
{
$this->warn(sprintf(' [!] %s', trim($message)));
}
-
}
diff --git a/app/Console/Commands/System/CreateDatabase.php b/app/Console/Commands/System/CreateDatabase.php
index b34914e310..64b1c65895 100644
--- a/app/Console/Commands/System/CreateDatabase.php
+++ b/app/Console/Commands/System/CreateDatabase.php
@@ -27,7 +27,6 @@ namespace FireflyIII\Console\Commands\System;
use FireflyIII\Console\Commands\ShowsFriendlyMessages;
use Illuminate\Console\Command;
use PDO;
-use PDOException;
/**
* Class CreateDatabase
@@ -36,23 +35,14 @@ class CreateDatabase extends Command
{
use ShowsFriendlyMessages;
- /**
- * The console command description.
- *
- * @var string
- */
protected $description = 'Tries to create the database if it doesn\'t exist yet.';
- /**
- * The name and signature of the console command.
- *
- * @var string
- */
- protected $signature = 'firefly-iii:create-database';
+
+ protected $signature = 'firefly-iii:create-database';
/**
* Execute the console command.
*
- * @return int
+ * @suppressWarnings(PHPMD.MissingImport)
*/
public function handle(): int
{
@@ -62,9 +52,7 @@ class CreateDatabase extends Command
return 0;
}
// try to set up a raw connection:
- $pdo = false;
$exists = false;
- $checked = false; // checked for existence of DB?
$dsn = sprintf('mysql:host=%s;port=%d;charset=utf8mb4', env('DB_HOST', 'localhost'), env('DB_PORT', '3306'));
if ('' !== env('DB_SOCKET', '')) {
@@ -73,39 +61,39 @@ class CreateDatabase extends Command
$this->friendlyLine(sprintf('DSN is %s', $dsn));
$options = [
- PDO::ATTR_ERRMODE => PDO::ERRMODE_EXCEPTION,
- PDO::ATTR_DEFAULT_FETCH_MODE => PDO::FETCH_ASSOC,
- PDO::ATTR_EMULATE_PREPARES => false,
+ \PDO::ATTR_ERRMODE => \PDO::ERRMODE_EXCEPTION,
+ \PDO::ATTR_DEFAULT_FETCH_MODE => \PDO::FETCH_ASSOC,
+ \PDO::ATTR_EMULATE_PREPARES => false,
];
// when it fails, display error
try {
- $pdo = new PDO($dsn, env('DB_USERNAME'), env('DB_PASSWORD'), $options);
- } catch (PDOException $e) {
+ $pdo = new \PDO($dsn, env('DB_USERNAME'), env('DB_PASSWORD'), $options);
+ } catch (\PDOException $e) {
$this->friendlyError(sprintf('Error when connecting to DB: %s', $e->getMessage()));
+
+ return 1;
}
// only continue when no error.
- if (false !== $pdo) {
- // with PDO, try to list DB's (
- $stmt = $pdo->query('SHOW DATABASES;');
- $checked = true;
- // slightly more complex but less error prone.
- foreach ($stmt as $row) {
- $name = $row['Database'] ?? false;
- if ($name === env('DB_DATABASE')) {
- $exists = true;
- }
+ // with PDO, try to list DB's (
+ /** @var array $stmt */
+ $stmt = $pdo->query('SHOW DATABASES;');
+ // slightly more complex but less error-prone.
+ foreach ($stmt as $row) {
+ $name = $row['Database'] ?? false;
+ if ($name === env('DB_DATABASE')) {
+ $exists = true;
}
}
- if (false === $exists && true === $checked) {
+ if (false === $exists) {
$this->friendlyError(sprintf('Database "%s" does not exist.', env('DB_DATABASE')));
// try to create it.
$pdo->exec(sprintf('CREATE DATABASE `%s` CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci;', env('DB_DATABASE')));
$this->friendlyInfo(sprintf('Created database "%s"', env('DB_DATABASE')));
}
- if (true === $exists && true === $checked) {
+ if (true === $exists) {
$this->friendlyInfo(sprintf('Database "%s" exists.', env('DB_DATABASE')));
}
diff --git a/app/Console/Commands/System/CreateFirstUser.php b/app/Console/Commands/System/CreateFirstUser.php
index a547a3e47a..8a4d5dc882 100644
--- a/app/Console/Commands/System/CreateFirstUser.php
+++ b/app/Console/Commands/System/CreateFirstUser.php
@@ -28,35 +28,21 @@ use FireflyIII\Console\Commands\ShowsFriendlyMessages;
use FireflyIII\Repositories\User\UserRepositoryInterface;
use Illuminate\Console\Command;
use Illuminate\Support\Facades\Hash;
-use Str;
/**
* Class CreateFirstUser
- *
- * @package FireflyIII\Console\Commands
*/
class CreateFirstUser extends Command
{
use ShowsFriendlyMessages;
- /**
- * The console command description.
- *
- * @var string
- */
protected $description = 'Creates a new user and gives admin rights. Outputs the password on the command line. Strictly for testing.';
- /**
- * The name and signature of the console command.
- *
- * @var string
- */
- protected $signature = 'firefly-iii:create-first-user {email}';
+
+ protected $signature = 'firefly-iii:create-first-user {email}';
private UserRepositoryInterface $repository;
/**
* Execute the console command.
- *
- * @return int
*/
public function handle(): int
{
@@ -66,7 +52,7 @@ class CreateFirstUser extends Command
return 1;
}
$this->stupidLaravel();
- $count = $this->repository->count();
+ $count = $this->repository->count();
if ($count > 0) {
$this->friendlyError('Already have more than zero users in DB.');
@@ -78,11 +64,11 @@ class CreateFirstUser extends Command
'email' => $this->argument('email'),
'role' => 'owner',
];
- $password = Str::random(24);
+ $password = \Str::random(24);
$user = $this->repository->store($data);
$user->password = Hash::make($password);
$user->save();
- $user->setRememberToken(Str::random(60));
+ $user->setRememberToken(\Str::random(60));
$this->friendlyInfo(sprintf('Created new admin user (ID #%d) with email address "%s" and password "%s".', $user->id, $user->email, $password));
$this->friendlyWarning('Change this password.');
@@ -94,8 +80,6 @@ class CreateFirstUser extends Command
* Laravel will execute ALL __construct() methods for ALL commands whenever a SINGLE command is
* executed. This leads to noticeable slow-downs and class calls. To prevent this, this method should
* be called from the handle method instead of using the constructor to initialize the command.
- *
-
*/
private function stupidLaravel(): void
{
diff --git a/app/Console/Commands/System/ForceDecimalSize.php b/app/Console/Commands/System/ForceDecimalSize.php
index 70b2e7384d..19cda1faa2 100644
--- a/app/Console/Commands/System/ForceDecimalSize.php
+++ b/app/Console/Commands/System/ForceDecimalSize.php
@@ -41,7 +41,6 @@ use Illuminate\Database\Eloquent\Builder;
use Illuminate\Database\Eloquent\Model;
use Illuminate\Support\Collection;
use Illuminate\Support\Facades\DB;
-use Illuminate\Support\Facades\Log;
/**
* Class ForceDecimalSize
@@ -54,48 +53,47 @@ class ForceDecimalSize extends Command
{
use ShowsFriendlyMessages;
- protected $description = 'This command resizes DECIMAL columns in MySQL or PostgreSQL and correct amounts (only MySQL).';
- protected $signature = 'firefly-iii:force-decimal-size';
+ protected $description = 'This command resizes DECIMAL columns in MySQL or PostgreSQL and correct amounts (only MySQL).';
+ protected $signature = 'firefly-iii:force-decimal-size';
private string $cast;
private array $classes
= [
- 'accounts' => Account::class,
- 'auto_budgets' => AutoBudget::class,
- 'available_budgets' => AvailableBudget::class,
- 'bills' => Bill::class,
- 'budget_limits' => BudgetLimit::class,
- 'piggy_bank_events' => PiggyBankEvent::class,
- 'piggy_bank_repetitions' => PiggyBankRepetition::class,
- 'piggy_banks' => PiggyBank::class,
- 'recurrences_transactions' => RecurrenceTransaction::class,
- 'transactions' => Transaction::class,
- ];
+ 'accounts' => Account::class,
+ 'auto_budgets' => AutoBudget::class,
+ 'available_budgets' => AvailableBudget::class,
+ 'bills' => Bill::class,
+ 'budget_limits' => BudgetLimit::class,
+ 'piggy_bank_events' => PiggyBankEvent::class,
+ 'piggy_bank_repetitions' => PiggyBankRepetition::class,
+ 'piggy_banks' => PiggyBank::class,
+ 'recurrences_transactions' => RecurrenceTransaction::class,
+ 'transactions' => Transaction::class,
+ ];
private string $operator;
private string $regularExpression;
private array $tables
- = [
- 'accounts' => ['virtual_balance'],
- 'auto_budgets' => ['amount'],
- 'available_budgets' => ['amount'],
- 'bills' => ['amount_min', 'amount_max'],
- 'budget_limits' => ['amount'],
- 'currency_exchange_rates' => ['rate', 'user_rate'],
- 'limit_repetitions' => ['amount'],
- 'piggy_bank_events' => ['amount'],
- 'piggy_bank_repetitions' => ['currentamount'],
- 'piggy_banks' => ['targetamount'],
- 'recurrences_transactions' => ['amount', 'foreign_amount'],
- 'transactions' => ['amount', 'foreign_amount'],
- ];
+ = [
+ 'accounts' => ['virtual_balance'],
+ 'auto_budgets' => ['amount'],
+ 'available_budgets' => ['amount'],
+ 'bills' => ['amount_min', 'amount_max'],
+ 'budget_limits' => ['amount'],
+ 'currency_exchange_rates' => ['rate', 'user_rate'],
+ 'limit_repetitions' => ['amount'],
+ 'piggy_bank_events' => ['amount'],
+ 'piggy_bank_repetitions' => ['currentamount'],
+ 'piggy_banks' => ['targetamount'],
+ 'recurrences_transactions' => ['amount', 'foreign_amount'],
+ 'transactions' => ['amount', 'foreign_amount'],
+ ];
/**
* Execute the console command.
- *
*/
public function handle(): int
{
- Log::debug('Now in ForceDecimalSize::handle()');
+ app('log')->debug('Now in ForceDecimalSize::handle()');
$this->determineDatabaseType();
$this->friendlyError('Running this command is dangerous and can cause data loss.');
@@ -109,9 +107,6 @@ class ForceDecimalSize extends Command
return 0;
}
- /**
- * @return void
- */
private function determineDatabaseType(): void
{
// switch stuff based on database connection:
@@ -130,14 +125,12 @@ class ForceDecimalSize extends Command
/**
* This method checks if a basic check can be done or if it needs to be complicated.
- *
- * @return void
*/
private function correctAmounts(): void
{
// if sqlite, add function?
if ('sqlite' === (string)config('database.default')) {
- DB::connection()->getPdo()->sqliteCreateFunction('REGEXP', function ($pattern, $value) {
+ DB::connection()->getPdo()->sqliteCreateFunction('REGEXP', static function ($pattern, $value) {
mb_regex_encoding('UTF-8');
$pattern = trim($pattern, '"');
@@ -156,13 +149,13 @@ class ForceDecimalSize extends Command
/**
* This method loops all enabled currencies and then calls the method that will fix all objects in this currency.
*
- * @return void
* @throws FireflyException
*/
private function correctAmountsByCurrency(): void
{
/** @var Collection $enabled */
$enabled = TransactionCurrency::whereEnabled(1)->get();
+
/** @var TransactionCurrency $currency */
foreach ($enabled as $currency) {
$this->correctByCurrency($currency);
@@ -172,9 +165,6 @@ class ForceDecimalSize extends Command
/**
* This method loops the available tables that may need fixing, and calls for the right method that can fix them.
*
- * @param TransactionCurrency $currency
- *
- * @return void
* @throws FireflyException
*/
private function correctByCurrency(TransactionCurrency $currency): void
@@ -184,36 +174,50 @@ class ForceDecimalSize extends Command
* @var array $fields
*/
foreach ($this->tables as $name => $fields) {
- switch ($name) {
+ switch ($name) { // @phpstan-ignore-line
default:
$message = sprintf('Cannot handle table "%s"', $name);
$this->friendlyError($message);
+
throw new FireflyException($message);
+
case 'accounts':
$this->correctAccountAmounts($currency, $fields);
+
break;
+
case 'auto_budgets':
case 'available_budgets':
case 'bills':
case 'budget_limits':
case 'recurrences_transactions':
$this->correctGeneric($currency, $name);
+
break;
+
case 'currency_exchange_rates':
case 'limit_repetitions':
// do nothing
break;
+
case 'piggy_bank_events':
$this->correctPiggyEventAmounts($currency, $fields);
+
break;
+
case 'piggy_bank_repetitions':
$this->correctPiggyRepetitionAmounts($currency, $fields);
+
break;
+
case 'piggy_banks':
$this->correctPiggyAmounts($currency, $fields);
+
break;
+
case 'transactions':
$this->correctTransactionAmounts($currency);
+
break;
}
}
@@ -221,11 +225,6 @@ class ForceDecimalSize extends Command
/**
* This method loops over all accounts and validates the amounts.
- *
- * @param TransactionCurrency $currency
- * @param array $fields
- *
- * @return void
*/
private function correctAccountAmounts(TransactionCurrency $currency, array $fields): void
{
@@ -234,33 +233,36 @@ class ForceDecimalSize extends Command
$regularExpression = $this->regularExpression;
/** @var Builder $query */
- $query = Account::leftJoin('account_meta', 'accounts.id', '=', 'account_meta.account_id')
- ->where('account_meta.name', 'currency_id')
- ->where('account_meta.data', json_encode((string)$currency->id));
- $query->where(static function (Builder $q) use ($fields, $currency, $operator, $cast, $regularExpression) {
+ $query = Account::leftJoin('account_meta', 'accounts.id', '=', 'account_meta.account_id')
+ ->where('account_meta.name', 'currency_id')
+ ->where('account_meta.data', json_encode((string)$currency->id))
+ ;
+ $query->where(static function (Builder $q) use ($fields, $currency, $operator, $cast, $regularExpression): void {
foreach ($fields as $field) {
$q->orWhere(
- DB::raw(sprintf('CAST(accounts.%s AS %s)', $field, $cast)),
+ DB::raw(sprintf('CAST(accounts.%s AS %s)', $field, $cast)), // @phpstan-ignore-line
$operator,
DB::raw(sprintf($regularExpression, $currency->decimal_places))
);
}
});
- $result = $query->get(['accounts.*']);
+ $result = $query->get(['accounts.*']);
if (0 === $result->count()) {
$this->friendlyPositive(sprintf('All accounts in %s are OK', $currency->code));
return;
}
+
/** @var Account $account */
foreach ($result as $account) {
+ /** @var string $field */
foreach ($fields as $field) {
- $value = $account->$field;
+ $value = $account->{$field};
if (null === $value) {
continue;
}
// fix $field by rounding it down correctly.
- $pow = pow(10, (int)$currency->decimal_places);
+ $pow = 10 ** $currency->decimal_places;
$correct = bcdiv((string)round($value * $pow), (string)$pow, 12);
$this->friendlyInfo(sprintf('Account #%d has %s with value "%s", this has been corrected to "%s".', $account->id, $field, $value, $correct));
Account::find($account->id)->update([$field => $correct]);
@@ -270,11 +272,6 @@ class ForceDecimalSize extends Command
/**
* This method fixes all auto budgets in currency $currency.
- *
- * @param TransactionCurrency $currency
- * @param string $table
- *
- * @return void
*/
private function correctGeneric(TransactionCurrency $currency, string $table): void
{
@@ -285,11 +282,12 @@ class ForceDecimalSize extends Command
$regularExpression = $this->regularExpression;
/** @var Builder $query */
- $query = $class::where('transaction_currency_id', $currency->id)->where(
- static function (Builder $q) use ($fields, $currency, $operator, $cast, $regularExpression) {
+ $query = $class::where('transaction_currency_id', $currency->id)->where(
+ static function (Builder $q) use ($fields, $currency, $operator, $cast, $regularExpression): void {
+ /** @var string $field */
foreach ($fields as $field) {
$q->orWhere(
- DB::raw(sprintf('CAST(%s AS %s)', $field, $cast)),
+ DB::raw(sprintf('CAST(%s AS %s)', $field, $cast)), // @phpstan-ignore-line
$operator,
DB::raw(sprintf($regularExpression, $currency->decimal_places))
);
@@ -297,21 +295,23 @@ class ForceDecimalSize extends Command
}
);
- $result = $query->get(['*']);
+ $result = $query->get(['*']);
if (0 === $result->count()) {
$this->friendlyPositive(sprintf('All %s in %s are OK', $table, $currency->code));
return;
}
+
/** @var Model $item */
foreach ($result as $item) {
+ /** @var string $field */
foreach ($fields as $field) {
- $value = $item->$field;
+ $value = $item->{$field};
if (null === $value) {
continue;
}
// fix $field by rounding it down correctly.
- $pow = pow(10, (int)$currency->decimal_places);
+ $pow = 10 ** $currency->decimal_places;
$correct = bcdiv((string)round($value * $pow), (string)$pow, 12);
$this->friendlyWarning(sprintf('%s #%d has %s with value "%s", this has been corrected to "%s".', $table, $item->id, $field, $value, $correct));
$class::find($item->id)->update([$field => $correct]);
@@ -321,11 +321,6 @@ class ForceDecimalSize extends Command
/**
* This method fixes all piggy bank events in currency $currency.
- *
- * @param TransactionCurrency $currency
- * @param array $fields
- *
- * @return void
*/
private function correctPiggyEventAmounts(TransactionCurrency $currency, array $fields): void
{
@@ -334,36 +329,39 @@ class ForceDecimalSize extends Command
$regularExpression = $this->regularExpression;
/** @var Builder $query */
- $query = PiggyBankEvent::leftJoin('piggy_banks', 'piggy_bank_events.piggy_bank_id', '=', 'piggy_banks.id')
- ->leftJoin('accounts', 'piggy_banks.account_id', '=', 'accounts.id')
- ->leftJoin('account_meta', 'accounts.id', '=', 'account_meta.account_id')
- ->where('account_meta.name', 'currency_id')
- ->where('account_meta.data', json_encode((string)$currency->id))
- ->where(static function (Builder $q) use ($fields, $currency, $cast, $operator, $regularExpression) {
- foreach ($fields as $field) {
- $q->orWhere(
- DB::raw(sprintf('CAST(piggy_bank_events.%s AS %s)', $field, $cast)),
- $operator,
- DB::raw(sprintf($regularExpression, $currency->decimal_places))
- );
- }
- });
+ $query = PiggyBankEvent::leftJoin('piggy_banks', 'piggy_bank_events.piggy_bank_id', '=', 'piggy_banks.id')
+ ->leftJoin('accounts', 'piggy_banks.account_id', '=', 'accounts.id')
+ ->leftJoin('account_meta', 'accounts.id', '=', 'account_meta.account_id')
+ ->where('account_meta.name', 'currency_id')
+ ->where('account_meta.data', json_encode((string)$currency->id))
+ ->where(static function (Builder $q) use ($fields, $currency, $cast, $operator, $regularExpression): void {
+ foreach ($fields as $field) {
+ $q->orWhere(
+ DB::raw(sprintf('CAST(piggy_bank_events.%s AS %s)', $field, $cast)), // @phpstan-ignore-line
+ $operator,
+ DB::raw(sprintf($regularExpression, $currency->decimal_places))
+ );
+ }
+ })
+ ;
- $result = $query->get(['piggy_bank_events.*']);
+ $result = $query->get(['piggy_bank_events.*']);
if (0 === $result->count()) {
$this->friendlyPositive(sprintf('All piggy bank events in %s are OK', $currency->code));
return;
}
+
/** @var PiggyBankEvent $item */
foreach ($result as $item) {
+ /** @var string $field */
foreach ($fields as $field) {
- $value = $item->$field;
+ $value = $item->{$field};
if (null === $value) {
continue;
}
// fix $field by rounding it down correctly.
- $pow = pow(10, (int)$currency->decimal_places);
+ $pow = 10 ** $currency->decimal_places;
$correct = bcdiv((string)round($value * $pow), (string)$pow, 12);
$this->friendlyWarning(
sprintf('Piggy bank event #%d has %s with value "%s", this has been corrected to "%s".', $item->id, $field, $value, $correct)
@@ -375,49 +373,48 @@ class ForceDecimalSize extends Command
/**
* This method fixes all piggy bank repetitions in currency $currency.
- *
- * @param TransactionCurrency $currency
- * @param array $fields
- *
- * @return void
*/
- private function correctPiggyRepetitionAmounts(TransactionCurrency $currency, array $fields)
+ private function correctPiggyRepetitionAmounts(TransactionCurrency $currency, array $fields): void
{
$operator = $this->operator;
$cast = $this->cast;
$regularExpression = $this->regularExpression;
+
// select all piggy bank repetitions with this currency and issue.
/** @var Builder $query */
- $query = PiggyBankRepetition::leftJoin('piggy_banks', 'piggy_bank_repetitions.piggy_bank_id', '=', 'piggy_banks.id')
- ->leftJoin('accounts', 'piggy_banks.account_id', '=', 'accounts.id')
- ->leftJoin('account_meta', 'accounts.id', '=', 'account_meta.account_id')
- ->where('account_meta.name', 'currency_id')
- ->where('account_meta.data', json_encode((string)$currency->id))
- ->where(static function (Builder $q) use ($fields, $currency, $operator, $cast, $regularExpression) {
- foreach ($fields as $field) {
- $q->orWhere(
- DB::raw(sprintf('CAST(piggy_bank_repetitions.%s AS %s)', $field, $cast)),
- $operator,
- DB::raw(sprintf($regularExpression, $currency->decimal_places))
- );
- }
- });
+ $query = PiggyBankRepetition::leftJoin('piggy_banks', 'piggy_bank_repetitions.piggy_bank_id', '=', 'piggy_banks.id')
+ ->leftJoin('accounts', 'piggy_banks.account_id', '=', 'accounts.id')
+ ->leftJoin('account_meta', 'accounts.id', '=', 'account_meta.account_id')
+ ->where('account_meta.name', 'currency_id')
+ ->where('account_meta.data', json_encode((string)$currency->id))
+ ->where(static function (Builder $q) use ($fields, $currency, $operator, $cast, $regularExpression): void {
+ foreach ($fields as $field) {
+ $q->orWhere(
+ DB::raw(sprintf('CAST(piggy_bank_repetitions.%s AS %s)', $field, $cast)), // @phpstan-ignore-line
+ $operator,
+ DB::raw(sprintf($regularExpression, $currency->decimal_places))
+ );
+ }
+ })
+ ;
- $result = $query->get(['piggy_bank_repetitions.*']);
+ $result = $query->get(['piggy_bank_repetitions.*']);
if (0 === $result->count()) {
$this->friendlyPositive(sprintf('All piggy bank repetitions in %s', $currency->code));
return;
}
+
/** @var PiggyBankRepetition $item */
foreach ($result as $item) {
+ /** @var string $field */
foreach ($fields as $field) {
- $value = $item->$field;
+ $value = $item->{$field};
if (null === $value) {
continue;
}
// fix $field by rounding it down correctly.
- $pow = pow(10, (int)$currency->decimal_places);
+ $pow = 10 ** $currency->decimal_places;
$correct = bcdiv((string)round($value * $pow), (string)$pow, 12);
$this->friendlyWarning(
sprintf('Piggy bank repetition #%d has %s with value "%s", this has been corrected to "%s".', $item->id, $field, $value, $correct)
@@ -429,11 +426,6 @@ class ForceDecimalSize extends Command
/**
* This method fixes all piggy banks in currency $currency.
- *
- * @param TransactionCurrency $currency
- * @param array $fields
- *
- * @return void
*/
private function correctPiggyAmounts(TransactionCurrency $currency, array $fields): void
{
@@ -442,35 +434,38 @@ class ForceDecimalSize extends Command
$regularExpression = $this->regularExpression;
/** @var Builder $query */
- $query = PiggyBank::leftJoin('accounts', 'piggy_banks.account_id', '=', 'accounts.id')
- ->leftJoin('account_meta', 'accounts.id', '=', 'account_meta.account_id')
- ->where('account_meta.name', 'currency_id')
- ->where('account_meta.data', json_encode((string)$currency->id))
- ->where(static function (Builder $q) use ($fields, $currency, $operator, $cast, $regularExpression) {
- foreach ($fields as $field) {
- $q->orWhere(
- DB::raw(sprintf('CAST(piggy_banks.%s AS %s)', $field, $cast)),
- $operator,
- DB::raw(sprintf($regularExpression, $currency->decimal_places))
- );
- }
- });
+ $query = PiggyBank::leftJoin('accounts', 'piggy_banks.account_id', '=', 'accounts.id')
+ ->leftJoin('account_meta', 'accounts.id', '=', 'account_meta.account_id')
+ ->where('account_meta.name', 'currency_id')
+ ->where('account_meta.data', json_encode((string)$currency->id))
+ ->where(static function (Builder $q) use ($fields, $currency, $operator, $cast, $regularExpression): void {
+ foreach ($fields as $field) {
+ $q->orWhere(
+ DB::raw(sprintf('CAST(piggy_banks.%s AS %s)', $field, $cast)), // @phpstan-ignore-line
+ $operator,
+ DB::raw(sprintf($regularExpression, $currency->decimal_places))
+ );
+ }
+ })
+ ;
- $result = $query->get(['piggy_banks.*']);
+ $result = $query->get(['piggy_banks.*']);
if (0 === $result->count()) {
$this->friendlyPositive(sprintf('All piggy banks in %s are OK', $currency->code));
return;
}
+
/** @var PiggyBank $item */
foreach ($result as $item) {
+ /** @var string $field */
foreach ($fields as $field) {
- $value = $item->$field;
+ $value = $item->{$field};
if (null === $value) {
continue;
}
// fix $field by rounding it down correctly.
- $pow = pow(10, (int)$currency->decimal_places);
+ $pow = 10 ** $currency->decimal_places;
$correct = bcdiv((string)round($value * $pow), (string)$pow, 12);
$this->friendlyWarning(sprintf('Piggy bank #%d has %s with value "%s", this has been corrected to "%s".', $item->id, $field, $value, $correct));
PiggyBank::find($item->id)->update([$field => $correct]);
@@ -480,17 +475,13 @@ class ForceDecimalSize extends Command
/**
* This method fixes all transactions in currency $currency.
- *
- * @param TransactionCurrency $currency
- *
- * @return void
*/
private function correctTransactionAmounts(TransactionCurrency $currency): void
{
// select all transactions with this currency and issue.
/** @var Builder $query */
- $query = Transaction::where('transaction_currency_id', $currency->id)->where(
- DB::raw(sprintf('CAST(amount as %s)', $this->cast)),
+ $query = Transaction::where('transaction_currency_id', $currency->id)->where(
+ DB::raw(sprintf('CAST(amount as %s)', $this->cast)), // @phpstan-ignore-line
$this->operator,
DB::raw(sprintf($this->regularExpression, $currency->decimal_places))
);
@@ -502,21 +493,21 @@ class ForceDecimalSize extends Command
/** @var Transaction $item */
foreach ($result as $item) {
- $value = $item->amount;
- if (null === $value) {
+ $value = $item->amount;
+ if ('' === $value) {
continue;
}
// fix $field by rounding it down correctly.
- $pow = pow(10, (int)$currency->decimal_places);
- $correct = bcdiv((string)round($value * $pow), (string)$pow, 12);
+ $pow = (float)10 ** $currency->decimal_places;
+ $correct = bcdiv((string)round((float)$value * $pow), (string)$pow, 12);
$this->friendlyWarning(sprintf('Transaction #%d has amount with value "%s", this has been corrected to "%s".', $item->id, $value, $correct));
Transaction::find($item->id)->update(['amount' => $correct]);
}
// select all transactions with this FOREIGN currency and issue.
/** @var Builder $query */
- $query = Transaction::where('foreign_currency_id', $currency->id)->where(
- DB::raw(sprintf('CAST(foreign_amount as %s)', $this->cast)),
+ $query = Transaction::where('foreign_currency_id', $currency->id)->where(
+ DB::raw(sprintf('CAST(foreign_amount as %s)', $this->cast)), // @phpstan-ignore-line
$this->operator,
DB::raw(sprintf($this->regularExpression, $currency->decimal_places))
);
@@ -527,15 +518,16 @@ class ForceDecimalSize extends Command
return;
}
+
/** @var Transaction $item */
foreach ($result as $item) {
- $value = $item->foreign_amount;
+ $value = $item->foreign_amount;
if (null === $value) {
continue;
}
// fix $field by rounding it down correctly.
- $pow = pow(10, (int)$currency->decimal_places);
- $correct = bcdiv((string)round($value * $pow), (string)$pow, 12);
+ $pow = (float)10 ** $currency->decimal_places;
+ $correct = bcdiv((string)round((float)$value * $pow), (string)$pow, 12);
$this->friendlyWarning(
sprintf('Transaction #%d has foreign amount with value "%s", this has been corrected to "%s".', $item->id, $value, $correct)
);
@@ -543,9 +535,6 @@ class ForceDecimalSize extends Command
}
}
- /**
- * @return void
- */
private function updateDecimals(): void
{
$this->friendlyInfo('Going to force the size of DECIMAL columns. Please hold.');
@@ -559,22 +548,19 @@ class ForceDecimalSize extends Command
/** @var string $field */
foreach ($fields as $field) {
$this->friendlyLine(sprintf('Updating table "%s", field "%s"...', $name, $field));
+ if ('pgsql' === $type) {
+ DB::select(sprintf('ALTER TABLE %s ALTER COLUMN %s TYPE DECIMAL(32,12);', $name, $field));
+ sleep(1);
- switch ($type) {
- default:
- $this->friendlyError(sprintf('Cannot handle database type "%s".', $type));
-
- return;
- case 'pgsql':
- $query = sprintf('ALTER TABLE %s ALTER COLUMN %s TYPE DECIMAL(32,12);', $name, $field);
- break;
- case 'mysql':
- $query = sprintf('ALTER TABLE %s CHANGE COLUMN %s %s DECIMAL(32, 12);', $name, $field, $field);
- break;
+ return;
}
+ if ('mysql' === $type) {
+ DB::select(sprintf('ALTER TABLE %s CHANGE COLUMN %s %s DECIMAL(32, 12);', $name, $field, $field));
+ sleep(1);
- DB::select($query);
- sleep(1);
+ return;
+ }
+ $this->friendlyError(sprintf('Cannot handle database type "%s".', $type));
}
}
}
diff --git a/app/Console/Commands/System/ForceMigration.php b/app/Console/Commands/System/ForceMigration.php
index f437fa9482..5e63b0764e 100644
--- a/app/Console/Commands/System/ForceMigration.php
+++ b/app/Console/Commands/System/ForceMigration.php
@@ -40,18 +40,9 @@ class ForceMigration extends Command
use ShowsFriendlyMessages;
use VerifiesAccessToken;
- /**
- * The console command description.
- *
- * @var string
- */
protected $description = 'This command will force-run all database migrations.';
- /**
- * The name and signature of the console command.
- *
- * @var string
- */
- protected $signature = 'firefly-iii:force-migrations
+
+ protected $signature = 'firefly-iii:force-migrations
{--user=1 : The user ID.}
{--token= : The user\'s access token.}';
@@ -82,9 +73,6 @@ class ForceMigration extends Command
return 0;
}
- /**
- * @return void
- */
private function forceMigration(): void
{
DB::commit();
diff --git a/app/Console/Commands/System/OutputVersion.php b/app/Console/Commands/System/OutputVersion.php
index eea501b031..88835900b8 100644
--- a/app/Console/Commands/System/OutputVersion.php
+++ b/app/Console/Commands/System/OutputVersion.php
@@ -1,6 +1,5 @@
fileName();
$encryptedContent = $disk->get($fileName);
if (null === $encryptedContent) {
- Log::error(sprintf('No content for attachment #%d under filename "%s"', $attachment->id, $fileName));
+ app('log')->error(sprintf('No content for attachment #%d under filename "%s"', $attachment->id, $fileName));
+
continue;
}
+
try {
- $decryptedContent = Crypt::decrypt($encryptedContent); // verified
+ $decryptedContent = \Crypt::decrypt($encryptedContent); // verified
} catch (DecryptException $e) {
- Log::error(sprintf('Could not decrypt data of attachment #%d: %s', $attachment->id, $e->getMessage()));
+ app('log')->error(sprintf('Could not decrypt data of attachment #%d: %s', $attachment->id, $e->getMessage()));
$decryptedContent = $encryptedContent;
}
- $tempFileName = tempnam(sys_get_temp_dir(), 'FireflyIII');
+ $tempFileName = tempnam(sys_get_temp_dir(), 'FireflyIII');
+ if (false === $tempFileName) {
+ app('log')->error(sprintf('Could not create temporary file for attachment #%d', $attachment->id));
+
+ exit(1);
+ }
file_put_contents($tempFileName, $decryptedContent);
- $md5 = md5_file($tempFileName);
- $mime = mime_content_type($tempFileName);
- $attachment->md5 = $md5;
- $attachment->mime = $mime;
+ $attachment->md5 = (string)md5_file($tempFileName);
+ $attachment->mime = (string)mime_content_type($tempFileName);
$attachment->save();
$this->friendlyInfo(sprintf('Fixed attachment #%d', $attachment->id));
}
diff --git a/app/Console/Commands/System/SetLatestVersion.php b/app/Console/Commands/System/SetLatestVersion.php
index ab510eb394..71889bd0b0 100644
--- a/app/Console/Commands/System/SetLatestVersion.php
+++ b/app/Console/Commands/System/SetLatestVersion.php
@@ -34,23 +34,12 @@ class SetLatestVersion extends Command
{
use ShowsFriendlyMessages;
- /**
- * The console command description.
- *
- * @var string
- */
protected $description = 'Set latest version in DB.';
- /**
- * The name and signature of the console command.
- *
- * @var string
- */
- protected $signature = 'firefly-iii:set-latest-version {--james-is-cool}';
+
+ protected $signature = 'firefly-iii:set-latest-version {--james-is-cool}';
/**
* Execute the console command.
- *
- * @return int
*/
public function handle(): int
{
diff --git a/app/Console/Commands/System/UpgradeFireflyInstructions.php b/app/Console/Commands/System/UpgradeFireflyInstructions.php
index 3623a42956..525cd4eab8 100644
--- a/app/Console/Commands/System/UpgradeFireflyInstructions.php
+++ b/app/Console/Commands/System/UpgradeFireflyInstructions.php
@@ -26,29 +26,16 @@ namespace FireflyIII\Console\Commands\System;
use FireflyIII\Support\System\GeneratesInstallationId;
use Illuminate\Console\Command;
-use function FireflyIII\Console\Commands\str_starts_with;
-
/**
* Class UpgradeFireflyInstructions.
- *
-
*/
class UpgradeFireflyInstructions extends Command
{
use GeneratesInstallationId;
- /**
- * The console command description.
- *
- * @var string
- */
protected $description = 'Instructions in case of upgrade trouble.';
- /**
- * The name and signature of the console command.
- *
- * @var string
- */
- protected $signature = 'firefly:instructions {task}';
+
+ protected $signature = 'firefly:instructions {task}';
/**
* Execute the console command.
@@ -56,10 +43,10 @@ class UpgradeFireflyInstructions extends Command
public function handle(): int
{
$this->generateInstallationId();
- if ('update' === (string)$this->argument('task')) {
+ if ('update' === $this->argument('task')) {
$this->updateInstructions();
}
- if ('install' === (string)$this->argument('task')) {
+ if ('install' === $this->argument('task')) {
$this->installInstructions();
}
@@ -71,25 +58,38 @@ class UpgradeFireflyInstructions extends Command
*/
private function updateInstructions(): void
{
- /** @var string $version */
- $version = config('firefly.version');
+ $version = (string)config('firefly.version');
+
+ /** @var array $config */
$config = config('upgrade.text.upgrade');
$text = '';
+
+ /** @var string $compare */
foreach (array_keys($config) as $compare) {
// if string starts with:
- if (\str_starts_with($version, $compare)) {
- $text = $config[$compare];
+ if (str_starts_with($version, $compare)) {
+ $text = (string)$config[$compare];
}
}
+ // validate some settings.
+ if ('' === $text && 'local' === (string)config('app.env')) {
+ $text = 'Please set APP_ENV=production for a safer environment.';
+ }
+
+ $prefix = 'v';
+ if (str_starts_with($version, 'develop')) {
+ $prefix = '';
+ }
+
$this->newLine();
$this->showLogo();
$this->newLine();
$this->showLine();
$this->boxed('');
- if (null === $text || '' === $text) {
- $this->boxed(sprintf('Thank you for updating to Firefly III, v%s', $version));
+ if ('' === $text) {
+ $this->boxed(sprintf('Thank you for updating to Firefly III, %s%s', $prefix, $version));
$this->boxedInfo('There are no extra upgrade instructions.');
$this->boxed('Firefly III should be ready for use.');
$this->boxed('');
@@ -98,7 +98,7 @@ class UpgradeFireflyInstructions extends Command
return;
}
- $this->boxed(sprintf('Thank you for updating to Firefly III, v%s!', $version));
+ $this->boxed(sprintf('Thank you for updating to Firefly III, %s%s!', $prefix, $version));
$this->boxedInfo($text);
$this->boxed('');
$this->showLine();
@@ -106,13 +106,11 @@ class UpgradeFireflyInstructions extends Command
/**
* The logo takes up 8 lines of code. So 8 colors can be used.
- *
- * @return void
*/
private function showLogo(): void
{
- $today = date('m-d');
- $month = date('m');
+ $today = date('m-d');
+ $month = date('m');
// variation in colors and effects just because I can!
// default is Ukraine flag:
$colors = ['blue', 'blue', 'blue', 'yellow', 'yellow', 'yellow', 'default', 'default'];
@@ -155,27 +153,23 @@ class UpgradeFireflyInstructions extends Command
/**
* Show a nice box.
- *
- * @param string $text
*/
private function boxed(string $text): void
{
$parts = explode("\n", wordwrap($text));
foreach ($parts as $string) {
- $this->line('| ' . sprintf('%-77s', $string) . '|');
+ $this->line('| '.sprintf('%-77s', $string).'|');
}
}
/**
* Show a nice info box.
- *
- * @param string $text
*/
private function boxedInfo(string $text): void
{
$parts = explode("\n", wordwrap($text));
foreach ($parts as $string) {
- $this->info('| ' . sprintf('%-77s', $string) . '|');
+ $this->info('| '.sprintf('%-77s', $string).'|');
}
}
@@ -184,23 +178,37 @@ class UpgradeFireflyInstructions extends Command
*/
private function installInstructions(): void
{
- /** @var string $version */
- $version = config('firefly.version');
+ $version = (string)config('firefly.version');
+
+ /** @var array $config */
$config = config('upgrade.text.install');
$text = '';
+
+ /** @var string $compare */
foreach (array_keys($config) as $compare) {
// if string starts with:
- if (\str_starts_with($version, $compare)) {
- $text = $config[$compare];
+ if (str_starts_with($version, $compare)) {
+ $text = (string)$config[$compare];
}
}
+
+ // validate some settings.
+ if ('' === $text && 'local' === (string)config('app.env')) {
+ $text = 'Please set APP_ENV=production for a safer environment.';
+ }
+
+ $prefix = 'v';
+ if (str_starts_with($version, 'develop')) {
+ $prefix = '';
+ }
+
$this->newLine();
$this->showLogo();
$this->newLine();
$this->showLine();
$this->boxed('');
- if (null === $text || '' === $text) {
- $this->boxed(sprintf('Thank you for installing Firefly III, v%s!', $version));
+ if ('' === $text) {
+ $this->boxed(sprintf('Thank you for installing Firefly III, %s%s!', $prefix, $version));
$this->boxedInfo('There are no extra installation instructions.');
$this->boxed('Firefly III should be ready for use.');
$this->boxed('');
@@ -209,7 +217,7 @@ class UpgradeFireflyInstructions extends Command
return;
}
- $this->boxed(sprintf('Thank you for installing Firefly III, v%s!', $version));
+ $this->boxed(sprintf('Thank you for installing Firefly III, %s%s!', $prefix, $version));
$this->boxedInfo($text);
$this->boxed('');
$this->showLine();
diff --git a/app/Console/Commands/System/VerifySecurityAlerts.php b/app/Console/Commands/System/VerifySecurityAlerts.php
index 3c82bb45bd..aa60146808 100644
--- a/app/Console/Commands/System/VerifySecurityAlerts.php
+++ b/app/Console/Commands/System/VerifySecurityAlerts.php
@@ -27,9 +27,7 @@ namespace FireflyIII\Console\Commands\System;
use FireflyIII\Console\Commands\ShowsFriendlyMessages;
use Illuminate\Console\Command;
use Illuminate\Database\QueryException;
-use Illuminate\Support\Facades\Log;
use League\Flysystem\FilesystemException;
-use Storage;
/**
* Class VerifySecurityAlerts
@@ -38,23 +36,13 @@ class VerifySecurityAlerts extends Command
{
use ShowsFriendlyMessages;
- /**
- * The console command description.
- *
- * @var string
- */
protected $description = 'Verify security alerts';
- /**
- * The name and signature of the console command.
- *
- * @var string
- */
- protected $signature = 'firefly-iii:verify-security-alerts';
+
+ protected $signature = 'firefly-iii:verify-security-alerts';
/**
* Execute the console command.
*
- * @return int
* @throws FilesystemException
*/
public function handle(): int
@@ -63,10 +51,10 @@ class VerifySecurityAlerts extends Command
// check for security advisories.
$version = config('firefly.version');
- $disk = Storage::disk('resources');
+ $disk = \Storage::disk('resources');
// Next line is ignored because it's a Laravel Facade.
if (!$disk->has('alerts.json')) { // @phpstan-ignore-line
- Log::debug('No alerts.json file present.');
+ app('log')->debug('No alerts.json file present.');
return 0;
}
@@ -76,19 +64,19 @@ class VerifySecurityAlerts extends Command
/** @var array $array */
foreach ($json as $array) {
if ($version === $array['version'] && true === $array['advisory']) {
- Log::debug(sprintf('Version %s has an alert!', $array['version']));
+ app('log')->debug(sprintf('Version %s has an alert!', $array['version']));
// add advisory to configuration.
$this->saveSecurityAdvisory($array);
// depends on level
if ('info' === $array['level']) {
- Log::debug('INFO level alert');
+ app('log')->debug('INFO level alert');
$this->friendlyInfo($array['message']);
return 0;
}
if ('warning' === $array['level']) {
- Log::debug('WARNING level alert');
+ app('log')->debug('WARNING level alert');
$this->friendlyWarning('------------------------ :o');
$this->friendlyWarning($array['message']);
$this->friendlyWarning('------------------------ :o');
@@ -96,7 +84,7 @@ class VerifySecurityAlerts extends Command
return 0;
}
if ('danger' === $array['level']) {
- Log::debug('DANGER level alert');
+ app('log')->debug('DANGER level alert');
$this->friendlyError('------------------------ :-(');
$this->friendlyError($array['message']);
$this->friendlyError('------------------------ :-(');
@@ -107,36 +95,29 @@ class VerifySecurityAlerts extends Command
return 0;
}
}
- Log::debug(sprintf('No security alerts for version %s', $version));
+ app('log')->debug(sprintf('No security alerts for version %s', $version));
$this->friendlyPositive(sprintf('No security alerts for version %s', $version));
+
return 0;
}
- /**
- * @return void
- */
private function removeOldAdvisory(): void
{
try {
app('fireflyconfig')->delete('upgrade_security_message');
app('fireflyconfig')->delete('upgrade_security_level');
} catch (QueryException $e) {
- Log::debug(sprintf('Could not delete old security advisory, but thats OK: %s', $e->getMessage()));
+ app('log')->debug(sprintf('Could not delete old security advisory, but thats OK: %s', $e->getMessage()));
}
}
- /**
- * @param array $array
- *
- * @return void
- */
private function saveSecurityAdvisory(array $array): void
{
try {
app('fireflyconfig')->set('upgrade_security_message', $array['message']);
app('fireflyconfig')->set('upgrade_security_level', $array['level']);
} catch (QueryException $e) {
- Log::debug(sprintf('Could not save new security advisory, but thats OK: %s', $e->getMessage()));
+ app('log')->debug(sprintf('Could not save new security advisory, but thats OK: %s', $e->getMessage()));
}
}
}
diff --git a/app/Console/Commands/Tools/ApplyRules.php b/app/Console/Commands/Tools/ApplyRules.php
index 97b8b526b1..ee108f678a 100644
--- a/app/Console/Commands/Tools/ApplyRules.php
+++ b/app/Console/Commands/Tools/ApplyRules.php
@@ -47,19 +47,10 @@ class ApplyRules extends Command
use ShowsFriendlyMessages;
use VerifiesAccessToken;
- /**
- * The console command description.
- *
- * @var string
- */
protected $description = 'This command will apply your rules and rule groups on a selection of your transactions.';
- /**
- * The name and signature of the console command.
- *
- * @var string
- */
+
protected $signature
- = 'firefly-iii:apply-rules
+ = 'firefly-iii:apply-rules
{--user=1 : The user ID.}
{--token= : The user\'s access token.}
{--accounts= : A comma-separated list of asset accounts or liabilities to apply your rules to.}
@@ -82,12 +73,11 @@ class ApplyRules extends Command
/**
* Execute the console command.
*
- * @return int
* @throws FireflyException
*/
public function handle(): int
{
- $start = microtime(true);
+ $start = microtime(true);
$this->stupidLaravel();
if (!$this->verifyAccessToken()) {
$this->friendlyError('Invalid access token.');
@@ -99,19 +89,19 @@ class ApplyRules extends Command
$this->ruleRepository->setUser($this->getUser());
$this->ruleGroupRepository->setUser($this->getUser());
- $result = $this->verifyInput();
+ $result = $this->verifyInput();
if (false === $result) {
return 1;
}
- $this->allRules = $this->option('all_rules');
+ $this->allRules = $this->option('all_rules');
// always get all the rules of the user.
$this->grabAllRules();
// loop all groups and rules and indicate if they're included:
- $rulesToApply = $this->getRulesToApply();
- $count = $rulesToApply->count();
+ $rulesToApply = $this->getRulesToApply();
+ $count = $rulesToApply->count();
if (0 === $count) {
$this->friendlyError('No rules or rule groups have been included.');
$this->friendlyWarning('Make a selection using:');
@@ -124,7 +114,7 @@ class ApplyRules extends Command
// create new rule engine:
/** @var RuleEngineInterface $ruleEngine */
- $ruleEngine = app(RuleEngineInterface::class);
+ $ruleEngine = app(RuleEngineInterface::class);
$ruleEngine->setRules($rulesToApply);
$ruleEngine->setUser($this->getUser());
@@ -133,7 +123,7 @@ class ApplyRules extends Command
foreach ($this->accounts as $account) {
$filterAccountList[] = $account->id;
}
- $list = implode(',', $filterAccountList);
+ $list = implode(',', $filterAccountList);
$ruleEngine->addOperator(['type' => 'account_id', 'value' => $list]);
// add the date as a filter:
@@ -143,11 +133,11 @@ class ApplyRules extends Command
// start running rules.
$this->friendlyLine(sprintf('Will apply %d rule(s) to your transaction(s).', $count));
- // file the rule(s)
+ // fire the rule(s)
$ruleEngine->fire();
$this->friendlyLine('');
- $end = round(microtime(true) - $start, 2);
+ $end = round(microtime(true) - $start, 2);
$this->friendlyPositive(sprintf('Done in %s seconds!', $end));
return 0;
@@ -157,8 +147,6 @@ class ApplyRules extends Command
* Laravel will execute ALL __construct() methods for ALL commands whenever a SINGLE command is
* executed. This leads to noticeable slow-downs and class calls. To prevent this, this method should
* be called from the handle method instead of using the constructor to initialize the command.
- *
-
*/
private function stupidLaravel(): void
{
@@ -173,7 +161,6 @@ class ApplyRules extends Command
}
/**
- * @return bool
* @throws FireflyException
*/
private function verifyInput(): bool
@@ -196,19 +183,18 @@ class ApplyRules extends Command
}
/**
- * @return bool
* @throws FireflyException
*/
private function verifyInputAccounts(): bool
{
- $accountString = $this->option('accounts');
+ $accountString = $this->option('accounts');
if (null === $accountString || '' === $accountString) {
$this->friendlyError('Please use the --accounts option to indicate the accounts to apply rules to.');
return false;
}
- $finalList = new Collection();
- $accountList = explode(',', $accountString);
+ $finalList = new Collection();
+ $accountList = explode(',', $accountString);
/** @var AccountRepositoryInterface $accountRepository */
$accountRepository = app(AccountRepositoryInterface::class);
@@ -226,14 +212,11 @@ class ApplyRules extends Command
return false;
}
- $this->accounts = $finalList;
+ $this->accounts = $finalList;
return true;
}
- /**
- * @return bool
- */
private function verifyInputRuleGroups(): bool
{
$ruleGroupString = $this->option('rule_groups');
@@ -241,7 +224,7 @@ class ApplyRules extends Command
// can be empty.
return true;
}
- $ruleGroupList = explode(',', $ruleGroupString);
+ $ruleGroupList = explode(',', $ruleGroupString);
foreach ($ruleGroupList as $ruleGroupId) {
$ruleGroup = $this->ruleGroupRepository->find((int)$ruleGroupId);
@@ -256,9 +239,6 @@ class ApplyRules extends Command
return true;
}
- /**
- * @return bool
- */
private function verifyInputRules(): bool
{
$ruleString = $this->option('rules');
@@ -266,7 +246,7 @@ class ApplyRules extends Command
// can be empty.
return true;
}
- $ruleList = explode(',', $ruleString);
+ $ruleList = explode(',', $ruleString);
foreach ($ruleList as $ruleId) {
$rule = $this->ruleRepository->find((int)$ruleId);
@@ -284,13 +264,13 @@ class ApplyRules extends Command
private function verifyInputDates(): void
{
// parse start date.
- $inputStart = today(config('app.timezone'))->startOfMonth();
- $startString = $this->option('start_date');
+ $inputStart = today(config('app.timezone'))->startOfMonth();
+ $startString = $this->option('start_date');
if (null === $startString) {
/** @var JournalRepositoryInterface $repository */
$repository = app(JournalRepositoryInterface::class);
$repository->setUser($this->getUser());
- $first = $repository->firstNull();
+ $first = $repository->firstNull();
if (null !== $first) {
$inputStart = $first->date;
}
@@ -300,11 +280,16 @@ class ApplyRules extends Command
}
// parse end date
- $inputEnd = today(config('app.timezone'));
- $endString = $this->option('end_date');
+ $inputEnd = today(config('app.timezone'));
+ $endString = $this->option('end_date');
if (null !== $endString && '' !== $endString) {
$inputEnd = Carbon::createFromFormat('Y-m-d', $endString);
}
+ if (false === $inputEnd || false === $inputStart) {
+ Log::error('Could not parse start or end date in verifyInputDate().');
+
+ return;
+ }
if ($inputStart > $inputEnd) {
[$inputEnd, $inputStart] = [$inputStart, $inputEnd];
@@ -314,28 +299,25 @@ class ApplyRules extends Command
$this->endDate = $inputEnd;
}
- /**
- */
private function grabAllRules(): void
{
$this->groups = $this->ruleGroupRepository->getActiveGroups();
}
- /**
- * @return Collection
- */
private function getRulesToApply(): Collection
{
$rulesToApply = new Collection();
+
/** @var RuleGroup $group */
foreach ($this->groups as $group) {
$rules = $this->ruleGroupRepository->getActiveStoreRules($group);
+
/** @var Rule $rule */
foreach ($rules as $rule) {
// if in rule selection, or group in selection or all rules, it's included.
$test = $this->includeRule($rule, $group);
if (true === $test) {
- Log::debug(sprintf('Will include rule #%d "%s"', $rule->id, $rule->title));
+ app('log')->debug(sprintf('Will include rule #%d "%s"', $rule->id, $rule->title));
$rulesToApply->push($rule);
}
}
@@ -344,12 +326,6 @@ class ApplyRules extends Command
return $rulesToApply;
}
- /**
- * @param Rule $rule
- * @param RuleGroup $group
- *
- * @return bool
- */
private function includeRule(Rule $rule, RuleGroup $group): bool
{
return in_array($group->id, $this->ruleGroupSelection, true)
diff --git a/app/Console/Commands/Tools/Cron.php b/app/Console/Commands/Tools/Cron.php
index bf9d13ada0..4b3b0177b9 100644
--- a/app/Console/Commands/Tools/Cron.php
+++ b/app/Console/Commands/Tools/Cron.php
@@ -33,93 +33,67 @@ use FireflyIII\Support\Cronjobs\ExchangeRatesCronjob;
use FireflyIII\Support\Cronjobs\RecurringCronjob;
use Illuminate\Console\Command;
use Illuminate\Support\Facades\Log;
-use InvalidArgumentException;
-use Psr\Container\ContainerExceptionInterface;
-use Psr\Container\NotFoundExceptionInterface;
/**
* Class Cron
- *
-
*/
class Cron extends Command
{
use ShowsFriendlyMessages;
- /**
- * The console command description.
- *
- * @var string
- */
protected $description = 'Runs all Firefly III cron-job related commands. Configure a cron job according to the official Firefly III documentation.';
- /**
- * The name and signature of the console command.
- *
- * @var string
- */
- protected $signature = 'firefly-iii:cron
+
+ protected $signature = 'firefly-iii:cron
{--F|force : Force the cron job(s) to execute.}
{--date= : Set the date in YYYY-MM-DD to make Firefly III think that\'s the current date.}
';
- /**
- * @return int
- * @throws ContainerExceptionInterface
- * @throws NotFoundExceptionInterface
- */
public function handle(): int
{
- $date = null;
+ $date = null;
+
try {
$date = new Carbon($this->option('date'));
- } catch (InvalidArgumentException $e) {
+ } catch (\InvalidArgumentException $e) {
$this->friendlyError(sprintf('"%s" is not a valid date', $this->option('date')));
}
- $force = (bool)$this->option('force');
+ $force = (bool)$this->option('force'); // @phpstan-ignore-line
- /*
- * Fire exchange rates cron job.
- */
+ // Fire exchange rates cron job.
if (true === config('cer.download_enabled')) {
try {
$this->exchangeRatesCronJob($force, $date);
} catch (FireflyException $e) {
- Log::error($e->getMessage());
- Log::error($e->getTraceAsString());
+ app('log')->error($e->getMessage());
+ app('log')->error($e->getTraceAsString());
$this->friendlyError($e->getMessage());
}
}
- /*
- * Fire recurring transaction cron job.
- */
+ // Fire recurring transaction cron job.
try {
$this->recurringCronJob($force, $date);
} catch (FireflyException $e) {
- Log::error($e->getMessage());
- Log::error($e->getTraceAsString());
+ app('log')->error($e->getMessage());
+ app('log')->error($e->getTraceAsString());
$this->friendlyError($e->getMessage());
}
- /*
- * Fire auto-budget cron job:
- */
+ // Fire auto-budget cron job:
try {
$this->autoBudgetCronJob($force, $date);
} catch (FireflyException $e) {
- Log::error($e->getMessage());
- Log::error($e->getTraceAsString());
+ app('log')->error($e->getMessage());
+ app('log')->error($e->getTraceAsString());
$this->friendlyError($e->getMessage());
}
- /*
- * Fire bill warning cron job
- */
+ // Fire bill warning cron job
try {
$this->billWarningCronJob($force, $date);
} catch (FireflyException $e) {
- Log::error($e->getMessage());
- Log::error($e->getTraceAsString());
+ app('log')->error($e->getMessage());
+ app('log')->error($e->getTraceAsString());
$this->friendlyError($e->getMessage());
}
@@ -128,12 +102,9 @@ class Cron extends Command
return 0;
}
- /**
- * @param bool $force
- * @param Carbon|null $date
- */
private function exchangeRatesCronJob(bool $force, ?Carbon $date): void
{
+ Log::debug(sprintf('Created new ExchangeRateConverter in %s', __METHOD__));
$exchangeRates = new ExchangeRatesCronjob();
$exchangeRates->setForce($force);
// set date in cron job:
@@ -155,12 +126,7 @@ class Cron extends Command
}
/**
- * @param bool $force
- * @param Carbon|null $date
- *
- * @throws ContainerExceptionInterface
* @throws FireflyException
- * @throws NotFoundExceptionInterface
*/
private function recurringCronJob(bool $force, ?Carbon $date): void
{
@@ -184,11 +150,6 @@ class Cron extends Command
}
}
- /**
- * @param bool $force
- * @param Carbon|null $date
- *
- */
private function autoBudgetCronJob(bool $force, ?Carbon $date): void
{
$autoBudget = new AutoBudgetCronjob();
@@ -212,12 +173,7 @@ class Cron extends Command
}
/**
- * @param bool $force
- * @param Carbon|null $date
- *
* @throws FireflyException
- * @throws ContainerExceptionInterface
- * @throws NotFoundExceptionInterface
*/
private function billWarningCronJob(bool $force, ?Carbon $date): void
{
diff --git a/app/Console/Commands/Upgrade/AccountCurrencies.php b/app/Console/Commands/Upgrade/AccountCurrencies.php
index 73b6ffdf62..0ebe0d7b56 100644
--- a/app/Console/Commands/Upgrade/AccountCurrencies.php
+++ b/app/Console/Commands/Upgrade/AccountCurrencies.php
@@ -34,9 +34,6 @@ use FireflyIII\Repositories\Account\AccountRepositoryInterface;
use FireflyIII\Repositories\User\UserRepositoryInterface;
use FireflyIII\User;
use Illuminate\Console\Command;
-use Illuminate\Support\Facades\Log;
-use Psr\Container\ContainerExceptionInterface;
-use Psr\Container\NotFoundExceptionInterface;
/**
* Class AccountCurrencies
@@ -45,10 +42,10 @@ class AccountCurrencies extends Command
{
use ShowsFriendlyMessages;
- public const CONFIG_NAME = '480_account_currencies';
+ public const string CONFIG_NAME = '480_account_currencies';
- protected $description = 'Give all accounts proper currency info.';
- protected $signature = 'firefly-iii:account-currencies {--F|force : Force the execution of this command.}';
+ protected $description = 'Give all accounts proper currency info.';
+ protected $signature = 'firefly-iii:account-currencies {--F|force : Force the execution of this command.}';
private AccountRepositoryInterface $accountRepos;
private int $count;
private UserRepositoryInterface $userRepos;
@@ -56,8 +53,6 @@ class AccountCurrencies extends Command
/**
* Each (asset) account must have a reference to a preferred currency. If the account does not have one, it's
* forced upon the account.
- *
- * @return int
*/
public function handle(): int
{
@@ -85,7 +80,6 @@ class AccountCurrencies extends Command
* Laravel will execute ALL __construct() methods for ALL commands whenever a SINGLE command is
* executed. This leads to noticeable slow-downs and class calls. To prevent this, this method should
* be called from the handle method instead of using the constructor to initialize the command.
- *
*/
private function stupidLaravel(): void
{
@@ -94,55 +88,31 @@ class AccountCurrencies extends Command
$this->count = 0;
}
- /**
- * @return bool
- * @throws ContainerExceptionInterface
- * @throws NotFoundExceptionInterface
- */
private function isExecuted(): bool
{
$configVar = app('fireflyconfig')->get(self::CONFIG_NAME, false);
+
return (bool)$configVar?->data;
}
- /**
- *
- */
private function updateAccountCurrencies(): void
{
- $users = $this->userRepos->all();
- $defaultCurrencyCode = (string)config('firefly.default_currency', 'EUR');
+ $users = $this->userRepos->all();
foreach ($users as $user) {
- $this->updateCurrenciesForUser($user, $defaultCurrencyCode);
+ $this->updateCurrenciesForUser($user);
}
}
/**
- * @param User $user
- * @param string $systemCurrencyCode
- *
* @throws FireflyException
*/
- private function updateCurrenciesForUser(User $user, string $systemCurrencyCode): void
+ private function updateCurrenciesForUser(User $user): void
{
$this->accountRepos->setUser($user);
- $accounts = $this->accountRepos->getAccountsByType([AccountType::DEFAULT, AccountType::ASSET]);
+ $accounts = $this->accountRepos->getAccountsByType([AccountType::DEFAULT, AccountType::ASSET]);
// get user's currency preference:
- $defaultCurrencyCode = app('preferences')->getForUser($user, 'currencyPreference', $systemCurrencyCode)->data;
- if (!is_string($defaultCurrencyCode)) {
- $defaultCurrencyCode = $systemCurrencyCode;
- }
-
- /** @var TransactionCurrency|null $defaultCurrency */
- $defaultCurrency = TransactionCurrency::where('code', $defaultCurrencyCode)->first();
-
- if (null === $defaultCurrency) {
- Log::error(sprintf('Users currency pref "%s" does not exist!', $defaultCurrencyCode));
- $this->friendlyError(sprintf('User has a preference for "%s", but this currency does not exist.', $defaultCurrencyCode));
-
- return;
- }
+ $defaultCurrency = app('amount')->getDefaultCurrencyByUserGroup($user->userGroup);
/** @var Account $account */
foreach ($accounts as $account) {
@@ -150,10 +120,6 @@ class AccountCurrencies extends Command
}
}
- /**
- * @param Account $account
- * @param TransactionCurrency $currency
- */
private function updateAccount(Account $account, TransactionCurrency $currency): void
{
$this->accountRepos->setUser($account->user);
@@ -166,7 +132,7 @@ class AccountCurrencies extends Command
AccountMeta::where('account_id', $account->id)->where('name', 'currency_id')->forceDelete();
AccountMeta::create(['account_id' => $account->id, 'name' => 'currency_id', 'data' => $currency->id]);
$this->friendlyInfo(sprintf('Account #%d ("%s") now has a currency setting (%s).', $account->id, $account->name, $currency->code));
- $this->count++;
+ ++$this->count;
return;
}
@@ -175,7 +141,7 @@ class AccountCurrencies extends Command
if (0 === $accountCurrency && $obCurrency > 0) {
AccountMeta::create(['account_id' => $account->id, 'name' => 'currency_id', 'data' => $obCurrency]);
$this->friendlyInfo(sprintf('Account #%d ("%s") now has a currency setting (#%d).', $account->id, $account->name, $obCurrency));
- $this->count++;
+ ++$this->count;
return;
}
@@ -185,19 +151,16 @@ class AccountCurrencies extends Command
$openingBalance->transaction_currency_id = $accountCurrency;
$openingBalance->save();
$openingBalance->transactions->each(
- static function (Transaction $transaction) use ($accountCurrency) {
+ static function (Transaction $transaction) use ($accountCurrency): void {
$transaction->transaction_currency_id = $accountCurrency;
$transaction->save();
}
);
$this->friendlyInfo(sprintf('Account #%d ("%s") now has a correct currency for opening balance.', $account->id, $account->name));
- $this->count++;
+ ++$this->count;
}
}
- /**
- *
- */
private function markAsExecuted(): void
{
app('fireflyconfig')->set(self::CONFIG_NAME, true);
diff --git a/app/Console/Commands/Upgrade/AppendBudgetLimitPeriods.php b/app/Console/Commands/Upgrade/AppendBudgetLimitPeriods.php
index 12961e4843..39263ad0c6 100644
--- a/app/Console/Commands/Upgrade/AppendBudgetLimitPeriods.php
+++ b/app/Console/Commands/Upgrade/AppendBudgetLimitPeriods.php
@@ -26,9 +26,6 @@ namespace FireflyIII\Console\Commands\Upgrade;
use FireflyIII\Console\Commands\ShowsFriendlyMessages;
use FireflyIII\Models\BudgetLimit;
use Illuminate\Console\Command;
-use Illuminate\Support\Facades\Log;
-use Psr\Container\ContainerExceptionInterface;
-use Psr\Container\NotFoundExceptionInterface;
/**
* Class AppendBudgetLimitPeriods
@@ -37,26 +34,14 @@ class AppendBudgetLimitPeriods extends Command
{
use ShowsFriendlyMessages;
- public const CONFIG_NAME = '550_budget_limit_periods';
- /**
- * The console command description.
- *
- * @var string
- */
- protected $description = 'Append budget limits with their (estimated) timeframe.';
- /**
- * The name and signature of the console command.
- *
- * @var string
- */
- protected $signature = 'firefly-iii:budget-limit-periods {--F|force : Force the execution of this command.}';
+ public const string CONFIG_NAME = '550_budget_limit_periods';
+
+ protected $description = 'Append budget limits with their (estimated) timeframe.';
+
+ protected $signature = 'firefly-iii:budget-limit-periods {--F|force : Force the execution of this command.}';
/**
* Execute the console command.
- *
- * @return int
- * @throws ContainerExceptionInterface
- * @throws NotFoundExceptionInterface
*/
public function handle(): int
{
@@ -72,11 +57,6 @@ class AppendBudgetLimitPeriods extends Command
return 0;
}
- /**
- * @return bool
- * @throws ContainerExceptionInterface
- * @throws NotFoundExceptionInterface
- */
private function isExecuted(): bool
{
$configVar = app('fireflyconfig')->get(self::CONFIG_NAME, false);
@@ -84,24 +64,19 @@ class AppendBudgetLimitPeriods extends Command
return (bool)$configVar->data;
}
- /**
- *
- */
private function theresNoLimit(): void
{
$limits = BudgetLimit::whereNull('period')->get();
+
/** @var BudgetLimit $limit */
foreach ($limits as $limit) {
$this->fixLimit($limit);
}
}
- /**
- * @param BudgetLimit $limit
- */
- private function fixLimit(BudgetLimit $limit)
+ private function fixLimit(BudgetLimit $limit): void
{
- $period = $this->getLimitPeriod($limit);
+ $period = $this->getLimitPeriod($limit);
if (null === $period) {
$message = sprintf(
@@ -118,21 +93,16 @@ class AppendBudgetLimitPeriods extends Command
$limit->period = $period;
$limit->save();
- $msg = sprintf(
+ $msg = sprintf(
'Budget limit #%d (%s - %s) period is "%s".',
$limit->id,
$limit->start_date->format('Y-m-d'),
$limit->end_date->format('Y-m-d'),
$period
);
- Log::debug($msg);
+ app('log')->debug($msg);
}
- /**
- * @param BudgetLimit $limit
- *
- * @return string|null
- */
private function getLimitPeriod(BudgetLimit $limit): ?string
{
// is daily
@@ -181,9 +151,6 @@ class AppendBudgetLimitPeriods extends Command
return null;
}
- /**
- *
- */
private function markAsExecuted(): void
{
app('fireflyconfig')->set(self::CONFIG_NAME, true);
diff --git a/app/Console/Commands/Upgrade/BackToJournals.php b/app/Console/Commands/Upgrade/BackToJournals.php
index 3f6e2c5ca1..d3c3d29000 100644
--- a/app/Console/Commands/Upgrade/BackToJournals.php
+++ b/app/Console/Commands/Upgrade/BackToJournals.php
@@ -23,7 +23,6 @@ declare(strict_types=1);
namespace FireflyIII\Console\Commands\Upgrade;
-use DB;
use FireflyIII\Console\Commands\ShowsFriendlyMessages;
use FireflyIII\Models\Budget;
use FireflyIII\Models\Category;
@@ -31,8 +30,6 @@ use FireflyIII\Models\Transaction;
use FireflyIII\Models\TransactionJournal;
use Illuminate\Console\Command;
use Illuminate\Support\Collection;
-use Psr\Container\ContainerExceptionInterface;
-use Psr\Container\NotFoundExceptionInterface;
/**
* Class BackToJournals
@@ -41,26 +38,14 @@ class BackToJournals extends Command
{
use ShowsFriendlyMessages;
- public const CONFIG_NAME = '480_back_to_journals';
- /**
- * The console command description.
- *
- * @var string
- */
- protected $description = 'Move meta data back to journals, not individual transactions.';
- /**
- * The name and signature of the console command.
- *
- * @var string
- */
- protected $signature = 'firefly-iii:back-to-journals {--F|force : Force the execution of this command.}';
+ public const string CONFIG_NAME = '480_back_to_journals';
+
+ protected $description = 'Move meta data back to journals, not individual transactions.';
+
+ protected $signature = 'firefly-iii:back-to-journals {--F|force : Force the execution of this command.}';
/**
* Execute the console command.
- *
- * @return int
- * @throws ContainerExceptionInterface
- * @throws NotFoundExceptionInterface
*/
public function handle(): int
{
@@ -76,7 +61,6 @@ class BackToJournals extends Command
$this->friendlyWarning('Forcing the command.');
}
-
$this->migrateAll();
$this->friendlyInfo('Updated category and budget info for all transaction journals');
$this->markAsExecuted();
@@ -84,11 +68,6 @@ class BackToJournals extends Command
return 0;
}
- /**
- * @return bool
- * @throws ContainerExceptionInterface
- * @throws NotFoundExceptionInterface
- */
private function isMigrated(): bool
{
$configVar = app('fireflyconfig')->get(MigrateToGroups::CONFIG_NAME, false);
@@ -96,11 +75,6 @@ class BackToJournals extends Command
return (bool)$configVar->data;
}
- /**
- * @return bool
- * @throws ContainerExceptionInterface
- * @throws NotFoundExceptionInterface
- */
private function isExecuted(): bool
{
$configVar = app('fireflyconfig')->get(self::CONFIG_NAME, false);
@@ -108,22 +82,16 @@ class BackToJournals extends Command
return (bool)$configVar->data;
}
- /**
- *
- */
private function migrateAll(): void
{
$this->migrateBudgets();
$this->migrateCategories();
// empty tables
- DB::table('budget_transaction')->delete();
- DB::table('category_transaction')->delete();
+ \DB::table('budget_transaction')->delete();
+ \DB::table('category_transaction')->delete();
}
- /**
- *
- */
private function migrateBudgets(): void
{
$journals = new Collection();
@@ -133,51 +101,48 @@ class BackToJournals extends Command
$collected = TransactionJournal::whereIn('id', $journalIds)->with(['transactions', 'budgets', 'transactions.budgets'])->get();
$journals = $journals->merge($collected);
}
+
/** @var TransactionJournal $journal */
foreach ($journals as $journal) {
$this->migrateBudgetsForJournal($journal);
}
}
- /**
- * @return array
- */
private function getIdsForBudgets(): array
{
- $transactions = DB::table('budget_transaction')->distinct()->pluck('transaction_id')->toArray();
+ $transactions = \DB::table('budget_transaction')->distinct()->pluck('transaction_id')->toArray();
$array = [];
$chunks = array_chunk($transactions, 500);
foreach ($chunks as $chunk) {
- $set = DB::table('transactions')->whereIn('transactions.id', $chunk)->pluck('transaction_journal_id')->toArray();
+ $set = \DB::table('transactions')->whereIn('transactions.id', $chunk)->pluck('transaction_journal_id')->toArray();
$array = array_merge($array, $set);
}
return $array;
}
- /**
- * @param TransactionJournal $journal
- */
private function migrateBudgetsForJournal(TransactionJournal $journal): void
{
// grab category from first transaction
- /** @var Transaction|null $transaction */
- $transaction = $journal->transactions->first();
+ /** @var null|Transaction $transaction */
+ $transaction = $journal->transactions->first();
if (null === $transaction) {
$this->friendlyInfo(sprintf('Transaction journal #%d has no transactions. Will be fixed later.', $journal->id));
return;
}
- /** @var Budget|null $budget */
- $budget = $transaction->budgets->first();
- /** @var Budget|null $journalBudget */
+
+ /** @var null|Budget $budget */
+ $budget = $transaction->budgets->first();
+
+ /** @var null|Budget $journalBudget */
$journalBudget = $journal->budgets->first();
// both have a budget, but they don't match.
if (null !== $budget && null !== $journalBudget && $budget->id !== $journalBudget->id) {
// sync to journal:
- $journal->budgets()->sync([(int)$budget->id]);
+ $journal->budgets()->sync([$budget->id]);
return;
}
@@ -185,82 +150,73 @@ class BackToJournals extends Command
// transaction has a budget, but the journal doesn't.
if (null !== $budget && null === $journalBudget) {
// sync to journal:
- $journal->budgets()->sync([(int)$budget->id]);
+ $journal->budgets()->sync([$budget->id]);
}
}
- /**
- *
- */
private function migrateCategories(): void
{
$journals = new Collection();
$allIds = $this->getIdsForCategories();
-
- $chunks = array_chunk($allIds, 500);
+ $chunks = array_chunk($allIds, 500);
foreach ($chunks as $chunk) {
$collected = TransactionJournal::whereIn('id', $chunk)->with(['transactions', 'categories', 'transactions.categories'])->get();
$journals = $journals->merge($collected);
}
+
/** @var TransactionJournal $journal */
foreach ($journals as $journal) {
$this->migrateCategoriesForJournal($journal);
}
}
- /**
- * @return array
- */
private function getIdsForCategories(): array
{
- $transactions = DB::table('category_transaction')->distinct()->pluck('transaction_id')->toArray();
+ $transactions = \DB::table('category_transaction')->distinct()->pluck('transaction_id')->toArray();
$array = [];
$chunks = array_chunk($transactions, 500);
foreach ($chunks as $chunk) {
- $set = DB::table('transactions')
- ->whereIn('transactions.id', $chunk)
- ->pluck('transaction_journal_id')->toArray();
+ $set = \DB::table('transactions')
+ ->whereIn('transactions.id', $chunk)
+ ->pluck('transaction_journal_id')->toArray()
+ ;
$array = array_merge($array, $set);
}
return $array;
}
- /**
- * @param TransactionJournal $journal
- */
private function migrateCategoriesForJournal(TransactionJournal $journal): void
{
// grab category from first transaction
- /** @var Transaction|null $transaction */
- $transaction = $journal->transactions->first();
+ /** @var null|Transaction $transaction */
+ $transaction = $journal->transactions->first();
if (null === $transaction) {
$this->friendlyInfo(sprintf('Transaction journal #%d has no transactions. Will be fixed later.', $journal->id));
return;
}
- /** @var Category|null $category */
- $category = $transaction->categories->first();
- /** @var Category|null $journalCategory */
+
+ /** @var null|Category $category */
+ $category = $transaction->categories->first();
+
+ /** @var null|Category $journalCategory */
$journalCategory = $journal->categories->first();
// both have a category, but they don't match.
if (null !== $category && null !== $journalCategory && $category->id !== $journalCategory->id) {
// sync to journal:
- $journal->categories()->sync([(int)$category->id]);
+ $journal->categories()->sync([$category->id]);
}
// transaction has a category, but the journal doesn't.
if (null !== $category && null === $journalCategory) {
- $journal->categories()->sync([(int)$category->id]);
+ $journal->categories()->sync([$category->id]);
}
}
- /**
- *
- */
private function markAsExecuted(): void
{
app('fireflyconfig')->set(self::CONFIG_NAME, true);
diff --git a/app/Console/Commands/Upgrade/BudgetLimitCurrency.php b/app/Console/Commands/Upgrade/BudgetLimitCurrency.php
index 7cbd97aba6..f59008138b 100644
--- a/app/Console/Commands/Upgrade/BudgetLimitCurrency.php
+++ b/app/Console/Commands/Upgrade/BudgetLimitCurrency.php
@@ -25,10 +25,10 @@ namespace FireflyIII\Console\Commands\Upgrade;
use FireflyIII\Console\Commands\ShowsFriendlyMessages;
use FireflyIII\Exceptions\FireflyException;
+use FireflyIII\Models\Budget;
use FireflyIII\Models\BudgetLimit;
+use FireflyIII\User;
use Illuminate\Console\Command;
-use Psr\Container\ContainerExceptionInterface;
-use Psr\Container\NotFoundExceptionInterface;
/**
* Class BudgetLimitCurrency
@@ -37,27 +37,16 @@ class BudgetLimitCurrency extends Command
{
use ShowsFriendlyMessages;
- public const CONFIG_NAME = '480_bl_currency';
- /**
- * The console command description.
- *
- * @var string
- */
- protected $description = 'Give budget limits a currency';
- /**
- * The name and signature of the console command.
- *
- * @var string
- */
- protected $signature = 'firefly-iii:bl-currency {--F|force : Force the execution of this command.}';
+ public const string CONFIG_NAME = '480_bl_currency';
+
+ protected $description = 'Give budget limits a currency';
+
+ protected $signature = 'firefly-iii:bl-currency {--F|force : Force the execution of this command.}';
/**
* Execute the console command.
*
- * @return int
- * @throws ContainerExceptionInterface
* @throws FireflyException
- * @throws NotFoundExceptionInterface
*/
public function handle(): int
{
@@ -67,23 +56,25 @@ class BudgetLimitCurrency extends Command
return 0;
}
-
$count = 0;
$budgetLimits = BudgetLimit::get();
+
/** @var BudgetLimit $budgetLimit */
foreach ($budgetLimits as $budgetLimit) {
if (null === $budgetLimit->transaction_currency_id) {
+ /** @var null|Budget $budget */
$budget = $budgetLimit->budget;
if (null !== $budget) {
+ /** @var null|User $user */
$user = $budget->user;
if (null !== $user) {
- $currency = app('amount')->getDefaultCurrencyByUser($user);
+ $currency = app('amount')->getDefaultCurrencyByUserGroup($user->userGroup);
$budgetLimit->transaction_currency_id = $currency->id;
$budgetLimit->save();
$this->friendlyInfo(
sprintf('Budget limit #%d (part of budget "%s") now has a currency setting (%s).', $budgetLimit->id, $budget->name, $currency->name)
);
- $count++;
+ ++$count;
}
}
}
@@ -96,11 +87,6 @@ class BudgetLimitCurrency extends Command
return 0;
}
- /**
- * @return bool
- * @throws ContainerExceptionInterface
- * @throws NotFoundExceptionInterface
- */
private function isExecuted(): bool
{
$configVar = app('fireflyconfig')->get(self::CONFIG_NAME, false);
@@ -111,9 +97,6 @@ class BudgetLimitCurrency extends Command
return false;
}
- /**
- *
- */
private function markAsExecuted(): void
{
app('fireflyconfig')->set(self::CONFIG_NAME, true);
diff --git a/app/Console/Commands/Upgrade/CCLiabilities.php b/app/Console/Commands/Upgrade/CCLiabilities.php
index b41f41c9a5..78d6511d9d 100644
--- a/app/Console/Commands/Upgrade/CCLiabilities.php
+++ b/app/Console/Commands/Upgrade/CCLiabilities.php
@@ -29,8 +29,6 @@ use FireflyIII\Models\Account;
use FireflyIII\Models\AccountType;
use Illuminate\Console\Command;
use Illuminate\Support\Collection;
-use Psr\Container\ContainerExceptionInterface;
-use Psr\Container\NotFoundExceptionInterface;
/**
* Class CCLiabilities
@@ -39,17 +37,14 @@ class CCLiabilities extends Command
{
use ShowsFriendlyMessages;
- public const CONFIG_NAME = '480_cc_liabilities';
- protected $description = 'Convert old credit card liabilities.';
- protected $signature = 'firefly-iii:cc-liabilities {--F|force : Force the execution of this command.}';
+ public const string CONFIG_NAME = '480_cc_liabilities';
+ protected $description = 'Convert old credit card liabilities.';
+ protected $signature = 'firefly-iii:cc-liabilities {--F|force : Force the execution of this command.}';
/**
* Execute the console command.
*
- * @return int
- * @throws ContainerExceptionInterface
* @throws FireflyException
- * @throws NotFoundExceptionInterface
*/
public function handle(): int
{
@@ -59,7 +54,6 @@ class CCLiabilities extends Command
return 0;
}
-
$ccType = AccountType::where('type', AccountType::CREDITCARD)->first();
$debtType = AccountType::where('type', AccountType::DEBT)->first();
if (null === $ccType || null === $debtType) {
@@ -68,6 +62,7 @@ class CCLiabilities extends Command
return 0;
}
+
/** @var Collection $accounts */
$accounts = Account::where('account_type_id', $ccType->id)->get();
foreach ($accounts as $account) {
@@ -88,20 +83,13 @@ class CCLiabilities extends Command
return 0;
}
- /**
- * @return bool
- * @throws ContainerExceptionInterface
- * @throws NotFoundExceptionInterface
- */
private function isExecuted(): bool
{
$configVar = app('fireflyconfig')->get(self::CONFIG_NAME, false);
+
return (bool)$configVar?->data;
}
- /**
- *
- */
private function markAsExecuted(): void
{
app('fireflyconfig')->set(self::CONFIG_NAME, true);
diff --git a/app/Console/Commands/Upgrade/DecryptDatabase.php b/app/Console/Commands/Upgrade/DecryptDatabase.php
index 0f584f9296..e4332d5fd5 100644
--- a/app/Console/Commands/Upgrade/DecryptDatabase.php
+++ b/app/Console/Commands/Upgrade/DecryptDatabase.php
@@ -24,18 +24,11 @@ declare(strict_types=1);
namespace FireflyIII\Console\Commands\Upgrade;
-use Crypt;
-use DB;
use FireflyIII\Console\Commands\ShowsFriendlyMessages;
use FireflyIII\Exceptions\FireflyException;
use FireflyIII\Models\Preference;
use Illuminate\Console\Command;
use Illuminate\Contracts\Encryption\DecryptException;
-use Illuminate\Support\Facades\Log;
-use JsonException;
-use Psr\Container\ContainerExceptionInterface;
-use Psr\Container\NotFoundExceptionInterface;
-use stdClass;
/**
* Class DecryptDatabase
@@ -49,10 +42,6 @@ class DecryptDatabase extends Command
/**
* Execute the console command.
- *
- * @return int
- * @throws ContainerExceptionInterface
- * @throws NotFoundExceptionInterface
*/
public function handle(): int
{
@@ -69,6 +58,7 @@ class DecryptDatabase extends Command
'transactions' => ['description'],
'journal_links' => ['comment'],
];
+
/**
* @var string $table
* @var array $fields
@@ -76,16 +66,10 @@ class DecryptDatabase extends Command
foreach ($tables as $table => $fields) {
$this->decryptTable($table, $fields);
}
+
return 0;
}
- /**
- * @param string $table
- * @param array $fields
- *
- * @throws ContainerExceptionInterface
- * @throws NotFoundExceptionInterface
- */
private function decryptTable(string $table, array $fields): void
{
if ($this->isDecrypted($table)) {
@@ -102,21 +86,15 @@ class DecryptDatabase extends Command
app('fireflyconfig')->set($configName, true);
}
- /**
- * @param string $table
- *
- * @return bool
- * @throws ContainerExceptionInterface
- * @throws NotFoundExceptionInterface
- */
private function isDecrypted(string $table): bool
{
$configName = sprintf('is_decrypted_%s', $table);
$configVar = null;
+
try {
$configVar = app('fireflyconfig')->get($configName, false);
} catch (FireflyException $e) {
- Log::error($e->getMessage());
+ app('log')->error($e->getMessage());
}
if (null !== $configVar) {
return (bool)$configVar->data;
@@ -125,40 +103,32 @@ class DecryptDatabase extends Command
return false;
}
- /**
- * @param string $table
- * @param string $field
- */
private function decryptField(string $table, string $field): void
{
- $rows = DB::table($table)->get(['id', $field]);
- /** @var stdClass $row */
+ $rows = \DB::table($table)->get(['id', $field]);
+
+ /** @var \stdClass $row */
foreach ($rows as $row) {
$this->decryptRow($table, $field, $row);
}
}
- /**
- * @param string $table
- * @param string $field
- * @param stdClass $row
- */
- private function decryptRow(string $table, string $field, stdClass $row): void
+ private function decryptRow(string $table, string $field, \stdClass $row): void
{
- $original = $row->$field;
+ $original = $row->{$field};
if (null === $original) {
return;
}
- $id = (int)$row->id;
- $value = '';
+ $id = (int)$row->id;
+ $value = '';
try {
$value = $this->tryDecrypt($original);
} catch (FireflyException $e) {
$message = sprintf('Could not decrypt field "%s" in row #%d of table "%s": %s', $field, $id, $table, $e->getMessage());
$this->friendlyError($message);
- Log::error($message);
- Log::error($e->getTraceAsString());
+ app('log')->error($message);
+ app('log')->error($e->getTraceAsString());
}
// A separate routine for preferences table:
@@ -169,7 +139,7 @@ class DecryptDatabase extends Command
}
if ($value !== $original) {
- DB::table($table)->where('id', $id)->update([$field => $value]);
+ \DB::table($table)->where('id', $id)->update([$field => $value]);
}
}
@@ -179,12 +149,13 @@ class DecryptDatabase extends Command
* @param mixed $value
*
* @return string
+ *
* @throws FireflyException
*/
private function tryDecrypt($value)
{
try {
- $value = Crypt::decrypt($value);
+ $value = \Crypt::decrypt($value);
} catch (DecryptException $e) {
if ('The MAC is invalid.' === $e->getMessage()) {
throw new FireflyException($e->getMessage(), 0, $e);
@@ -194,16 +165,12 @@ class DecryptDatabase extends Command
return $value;
}
- /**
- * @param int $id
- * @param string $value
- */
private function decryptPreferencesRow(int $id, string $value): void
{
// try to json_decrypt the value.
try {
$newValue = json_decode($value, true, 512, JSON_THROW_ON_ERROR) ?? $value;
- } catch (JsonException $e) {
+ } catch (\JsonException $e) {
$message = sprintf('Could not JSON decode preference row #%d: %s. This does not have to be a problem.', $id, $e->getMessage());
$this->friendlyError($message);
app('log')->warning($message);
@@ -213,8 +180,8 @@ class DecryptDatabase extends Command
return;
}
- /** @var Preference $object */
- $object = Preference::find((int)$id);
+ /** @var null|Preference $object */
+ $object = Preference::find($id);
if (null !== $object) {
$object->data = $newValue;
$object->save();
diff --git a/app/Console/Commands/Upgrade/FixPostgresSequences.php b/app/Console/Commands/Upgrade/FixPostgresSequences.php
index 71399ebd29..3bbdc04464 100644
--- a/app/Console/Commands/Upgrade/FixPostgresSequences.php
+++ b/app/Console/Commands/Upgrade/FixPostgresSequences.php
@@ -24,7 +24,6 @@ declare(strict_types=1);
namespace FireflyIII\Console\Commands\Upgrade;
-use DB;
use FireflyIII\Console\Commands\ShowsFriendlyMessages;
use Illuminate\Console\Command;
@@ -35,104 +34,37 @@ class FixPostgresSequences extends Command
{
use ShowsFriendlyMessages;
- /**
- * The console command description.
- *
- * @var string
- */
protected $description = 'Fixes issues with PostgreSQL sequences.';
- /**
- * The name and signature of the console command.
- *
- * @var string
- */
- protected $signature = 'firefly-iii:fix-pgsql-sequences';
+
+ protected $signature = 'firefly-iii:fix-pgsql-sequences';
/**
* Execute the console command.
- *
- * @return int
*/
public function handle(): int
{
- if (DB::connection()->getName() !== 'pgsql') {
+ if ('pgsql' !== \DB::connection()->getName()) {
return 0;
}
$this->friendlyLine('Going to verify PostgreSQL table sequences.');
- $tablesToCheck = [
- '2fa_tokens',
- 'account_meta',
- 'account_types',
- 'accounts',
- 'attachments',
- 'auto_budgets',
- 'available_budgets',
- 'bills',
- 'budget_limits',
- 'budget_transaction',
- 'budget_transaction_journal',
- 'budgets',
- 'categories',
- 'category_transaction',
- 'category_transaction_journal',
- 'configuration',
- 'currency_exchange_rates',
- 'failed_jobs',
- 'group_journals',
- 'jobs',
- 'journal_links',
- 'journal_meta',
- 'limit_repetitions',
- 'link_types',
- 'locations',
- 'migrations',
- 'notes',
- 'oauth_clients',
- 'oauth_personal_access_clients',
- 'object_groups',
- 'permissions',
- 'piggy_bank_events',
- 'piggy_bank_repetitions',
- 'piggy_banks',
- 'preferences',
- 'recurrences',
- 'recurrences_meta',
- 'recurrences_repetitions',
- 'recurrences_transactions',
- 'roles',
- 'rt_meta',
- 'rule_actions',
- 'rule_groups',
- 'rule_triggers',
- 'rules',
- 'tag_transaction_journal',
- 'tags',
- 'transaction_currencies',
- 'transaction_groups',
- 'transaction_journals',
- 'transaction_types',
- 'transactions',
- 'users',
- 'webhook_attempts',
- 'webhook_messages',
- 'webhooks',
- ];
+ $tablesToCheck = ['2fa_tokens', 'account_meta', 'account_types', 'accounts', 'attachments', 'auto_budgets', 'available_budgets', 'bills', 'budget_limits', 'budget_transaction', 'budget_transaction_journal', 'budgets', 'categories', 'category_transaction', 'category_transaction_journal', 'configuration', 'currency_exchange_rates', 'failed_jobs', 'group_journals', 'jobs', 'journal_links', 'journal_meta', 'limit_repetitions', 'link_types', 'locations', 'migrations', 'notes', 'oauth_clients', 'oauth_personal_access_clients', 'object_groups', 'permissions', 'piggy_bank_events', 'piggy_bank_repetitions', 'piggy_banks', 'preferences', 'recurrences', 'recurrences_meta', 'recurrences_repetitions', 'recurrences_transactions', 'roles', 'rt_meta', 'rule_actions', 'rule_groups', 'rule_triggers', 'rules', 'tag_transaction_journal', 'tags', 'transaction_currencies', 'transaction_groups', 'transaction_journals', 'transaction_types', 'transactions', 'users', 'webhook_attempts', 'webhook_messages', 'webhooks'];
foreach ($tablesToCheck as $tableToCheck) {
$this->friendlyLine(sprintf('Checking the next id sequence for table "%s".', $tableToCheck));
- $highestId = DB::table($tableToCheck)->select(DB::raw('MAX(id)'))->first();
- $nextId = DB::table($tableToCheck)->select(DB::raw(sprintf('nextval(\'%s_id_seq\')', $tableToCheck)))->first();
+ $highestId = \DB::table($tableToCheck)->select(\DB::raw('MAX(id)'))->first();
+ $nextId = \DB::table($tableToCheck)->select(\DB::raw(sprintf('nextval(\'%s_id_seq\')', $tableToCheck)))->first();
if (null === $nextId) {
$this->friendlyInfo(sprintf('nextval is NULL for table "%s", go to next table.', $tableToCheck));
+
continue;
}
- if ($nextId->nextval < $highestId->max) {
- DB::select(sprintf('SELECT setval(\'%s_id_seq\', %d)', $tableToCheck, $highestId->max));
- $highestId = DB::table($tableToCheck)->select(DB::raw('MAX(id)'))->first();
- $nextId = DB::table($tableToCheck)->select(DB::raw(sprintf('nextval(\'%s_id_seq\')', $tableToCheck)))->first();
- if ($nextId->nextval > $highestId->max) {
+ if ($nextId->nextval < $highestId->max) { // @phpstan-ignore-line
+ \DB::select(sprintf('SELECT setval(\'%s_id_seq\', %d)', $tableToCheck, $highestId->max));
+ $highestId = \DB::table($tableToCheck)->select(\DB::raw('MAX(id)'))->first();
+ $nextId = \DB::table($tableToCheck)->select(\DB::raw(sprintf('nextval(\'%s_id_seq\')', $tableToCheck)))->first();
+ if ($nextId->nextval > $highestId->max) { // @phpstan-ignore-line
$this->friendlyInfo(sprintf('Table "%s" autoincrement corrected.', $tableToCheck));
}
if ($nextId->nextval <= $highestId->max) {
@@ -144,7 +76,6 @@ class FixPostgresSequences extends Command
}
}
-
return 0;
}
}
diff --git a/app/Console/Commands/Upgrade/MigrateAttachments.php b/app/Console/Commands/Upgrade/MigrateAttachments.php
index db0e4dedb0..08015d38c5 100644
--- a/app/Console/Commands/Upgrade/MigrateAttachments.php
+++ b/app/Console/Commands/Upgrade/MigrateAttachments.php
@@ -28,9 +28,6 @@ use FireflyIII\Exceptions\FireflyException;
use FireflyIII\Models\Attachment;
use FireflyIII\Models\Note;
use Illuminate\Console\Command;
-use Illuminate\Support\Facades\Log;
-use Psr\Container\ContainerExceptionInterface;
-use Psr\Container\NotFoundExceptionInterface;
/**
* Class MigrateAttachments
@@ -39,38 +36,26 @@ class MigrateAttachments extends Command
{
use ShowsFriendlyMessages;
- public const CONFIG_NAME = '480_migrate_attachments';
- /**
- * The console command description.
- *
- * @var string
- */
- protected $description = 'Migrates attachment meta-data.';
- /**
- * The name and signature of the console command.
- *
- * @var string
- */
- protected $signature = 'firefly-iii:migrate-attachments {--F|force : Force the execution of this command.}';
+ public const string CONFIG_NAME = '480_migrate_attachments';
+
+ protected $description = 'Migrates attachment meta-data.';
+
+ protected $signature = 'firefly-iii:migrate-attachments {--F|force : Force the execution of this command.}';
/**
* Execute the console command.
*
- * @return int
- * @throws ContainerExceptionInterface
* @throws FireflyException
- * @throws NotFoundExceptionInterface
*/
public function handle(): int
{
- $start = microtime(true);
+ $start = microtime(true);
if ($this->isExecuted() && true !== $this->option('force')) {
$this->friendlyInfo('This command has already been executed.');
return 0;
}
-
$attachments = Attachment::get();
$count = 0;
@@ -80,20 +65,20 @@ class MigrateAttachments extends Command
$attDescription = (string)$att->description;
if ('' !== $attDescription) {
// find or create note:
- $note = $att->notes()->first();
+ $note = $att->notes()->first();
if (null === $note) {
$note = new Note();
$note->noteable()->associate($att);
}
- $note->text = $attDescription;
+ $note->text = $attDescription;
$note->save();
// clear description:
$att->description = '';
$att->save();
- Log::debug(sprintf('Migrated attachment #%s description to note #%d.', $att->id, $note->id));
- $count++;
+ app('log')->debug(sprintf('Migrated attachment #%s description to note #%d.', $att->id, $note->id));
+ ++$count;
}
}
if (0 === $count) {
@@ -102,18 +87,13 @@ class MigrateAttachments extends Command
if (0 !== $count) {
$this->friendlyInfo(sprintf('Updated %d attachment(s).', $count));
}
- $end = round(microtime(true) - $start, 2);
+ $end = round(microtime(true) - $start, 2);
$this->friendlyInfo(sprintf('Migrated attachment notes in %s seconds.', $end));
$this->markAsExecuted();
return 0;
}
- /**
- * @return bool
- * @throws ContainerExceptionInterface
- * @throws NotFoundExceptionInterface
- */
private function isExecuted(): bool
{
$configVar = app('fireflyconfig')->get(self::CONFIG_NAME, false);
@@ -124,9 +104,6 @@ class MigrateAttachments extends Command
return false;
}
- /**
- *
- */
private function markAsExecuted(): void
{
app('fireflyconfig')->set(self::CONFIG_NAME, true);
diff --git a/app/Console/Commands/Upgrade/MigrateJournalNotes.php b/app/Console/Commands/Upgrade/MigrateJournalNotes.php
index 293ce3738c..960125b369 100644
--- a/app/Console/Commands/Upgrade/MigrateJournalNotes.php
+++ b/app/Console/Commands/Upgrade/MigrateJournalNotes.php
@@ -27,9 +27,6 @@ use FireflyIII\Console\Commands\ShowsFriendlyMessages;
use FireflyIII\Models\Note;
use FireflyIII\Models\TransactionJournalMeta;
use Illuminate\Console\Command;
-use Illuminate\Support\Facades\Log;
-use Psr\Container\ContainerExceptionInterface;
-use Psr\Container\NotFoundExceptionInterface;
/**
* Class MigrateJournalNotes
@@ -38,26 +35,14 @@ class MigrateJournalNotes extends Command
{
use ShowsFriendlyMessages;
- public const CONFIG_NAME = '480_migrate_notes';
- /**
- * The console command description.
- *
- * @var string
- */
- protected $description = 'Migrate notes for transaction journals.';
- /**
- * The name and signature of the console command.
- *
- * @var string
- */
- protected $signature = 'firefly-iii:migrate-notes {--F|force : Force the execution of this command.}';
+ public const string CONFIG_NAME = '480_migrate_notes';
+
+ protected $description = 'Migrate notes for transaction journals.';
+
+ protected $signature = 'firefly-iii:migrate-notes {--F|force : Force the execution of this command.}';
/**
* Execute the console command.
- *
- * @return int
- * @throws ContainerExceptionInterface
- * @throws NotFoundExceptionInterface
*/
public function handle(): int
{
@@ -71,10 +56,11 @@ class MigrateJournalNotes extends Command
$count = 0;
$set = TransactionJournalMeta::whereName('notes')->get();
+
/** @var TransactionJournalMeta $meta */
foreach ($set as $meta) {
- $journal = $meta->transactionJournal;
- $note = $journal->notes()->first();
+ $journal = $meta->transactionJournal;
+ $note = $journal->notes()->first();
if (null === $note) {
$note = new Note();
$note->noteable()->associate($journal);
@@ -82,10 +68,10 @@ class MigrateJournalNotes extends Command
$note->text = $meta->data;
$note->save();
- Log::debug(sprintf('Migrated meta note #%d to Note #%d', $meta->id, $note->id));
+ app('log')->debug(sprintf('Migrated meta note #%d to Note #%d', $meta->id, $note->id));
$meta->delete();
- $count++;
+ ++$count;
}
if (0 === $count) {
@@ -95,18 +81,13 @@ class MigrateJournalNotes extends Command
$this->friendlyInfo(sprintf('Migrated %d note(s).', $count));
}
- $end = round(microtime(true) - $start, 2);
+ $end = round(microtime(true) - $start, 2);
$this->friendlyInfo(sprintf('Migrated notes in %s seconds.', $end));
$this->markAsExecuted();
return 0;
}
- /**
- * @return bool
- * @throws ContainerExceptionInterface
- * @throws NotFoundExceptionInterface
- */
private function isExecuted(): bool
{
$configVar = app('fireflyconfig')->get(self::CONFIG_NAME, false);
@@ -117,9 +98,6 @@ class MigrateJournalNotes extends Command
return false;
}
- /**
- *
- */
private function markAsExecuted(): void
{
app('fireflyconfig')->set(self::CONFIG_NAME, true);
diff --git a/app/Console/Commands/Upgrade/MigrateRecurrenceMeta.php b/app/Console/Commands/Upgrade/MigrateRecurrenceMeta.php
index 10c1ebd0a5..207e45d1fa 100644
--- a/app/Console/Commands/Upgrade/MigrateRecurrenceMeta.php
+++ b/app/Console/Commands/Upgrade/MigrateRecurrenceMeta.php
@@ -29,9 +29,6 @@ use FireflyIII\Models\Recurrence;
use FireflyIII\Models\RecurrenceMeta;
use FireflyIII\Models\RecurrenceTransactionMeta;
use Illuminate\Console\Command;
-use JsonException;
-use Psr\Container\ContainerExceptionInterface;
-use Psr\Container\NotFoundExceptionInterface;
/**
* Class MigrateRecurrenceMeta
@@ -40,27 +37,14 @@ class MigrateRecurrenceMeta extends Command
{
use ShowsFriendlyMessages;
- public const CONFIG_NAME = '481_migrate_recurrence_meta';
- /**
- * The console command description.
- *
- * @var string
- */
- protected $description = 'Migrate recurrence meta data';
- /**
- * The name and signature of the console command.
- *
- * @var string
- */
- protected $signature = 'firefly-iii:migrate-recurrence-meta {--F|force : Force the execution of this command.}';
+ public const string CONFIG_NAME = '481_migrate_recurrence_meta';
+
+ protected $description = 'Migrate recurrence meta data';
+
+ protected $signature = 'firefly-iii:migrate-recurrence-meta {--F|force : Force the execution of this command.}';
/**
* Execute the console command.
- *
- * @return int
- * @throws ContainerExceptionInterface
- * @throws JsonException
- * @throws NotFoundExceptionInterface
*/
public function handle(): int
{
@@ -83,11 +67,6 @@ class MigrateRecurrenceMeta extends Command
return 0;
}
- /**
- * @return bool
- * @throws ContainerExceptionInterface
- * @throws NotFoundExceptionInterface
- */
private function isExecuted(): bool
{
$configVar = app('fireflyconfig')->get(self::CONFIG_NAME, false);
@@ -98,15 +77,12 @@ class MigrateRecurrenceMeta extends Command
return false;
}
- /**
- * @return int
- * @throws JsonException
- */
private function migrateMetaData(): int
{
- $count = 0;
+ $count = 0;
// get all recurrence meta data:
$collection = RecurrenceMeta::with('recurrence')->get();
+
/** @var RecurrenceMeta $meta */
foreach ($collection as $meta) {
$count += $this->migrateEntry($meta);
@@ -115,16 +91,10 @@ class MigrateRecurrenceMeta extends Command
return $count;
}
- /**
- * @param RecurrenceMeta $meta
- *
- * @return int
- * @throws JsonException
- */
private function migrateEntry(RecurrenceMeta $meta): int
{
- /** @var Recurrence|null $recurrence */
- $recurrence = $meta->recurrence;
+ /** @var null|Recurrence $recurrence */
+ $recurrence = $meta->recurrence;
if (null === $recurrence) {
return 0;
}
@@ -132,7 +102,7 @@ class MigrateRecurrenceMeta extends Command
if (null === $firstTransaction) {
return 0;
}
- $value = $meta->value;
+ $value = $meta->value;
if ('tags' === $meta->name) {
$array = explode(',', $meta->value);
@@ -151,9 +121,6 @@ class MigrateRecurrenceMeta extends Command
return 1;
}
- /**
- *
- */
private function markAsExecuted(): void
{
app('fireflyconfig')->set(self::CONFIG_NAME, true);
diff --git a/app/Console/Commands/Upgrade/MigrateRecurrenceType.php b/app/Console/Commands/Upgrade/MigrateRecurrenceType.php
index c6a509495b..7aec519d9c 100644
--- a/app/Console/Commands/Upgrade/MigrateRecurrenceType.php
+++ b/app/Console/Commands/Upgrade/MigrateRecurrenceType.php
@@ -25,12 +25,7 @@ declare(strict_types=1);
namespace FireflyIII\Console\Commands\Upgrade;
use FireflyIII\Console\Commands\ShowsFriendlyMessages;
-use FireflyIII\Models\Recurrence;
-use FireflyIII\Models\RecurrenceTransaction;
-use FireflyIII\Models\TransactionType;
use Illuminate\Console\Command;
-use Psr\Container\ContainerExceptionInterface;
-use Psr\Container\NotFoundExceptionInterface;
/**
* Class MigrateRecurrenceType
@@ -39,26 +34,14 @@ class MigrateRecurrenceType extends Command
{
use ShowsFriendlyMessages;
- public const CONFIG_NAME = '550_migrate_recurrence_type';
- /**
- * The console command description.
- *
- * @var string
- */
- protected $description = 'Migrate transaction type of recurring transaction.';
- /**
- * The name and signature of the console command.
- *
- * @var string
- */
- protected $signature = 'firefly-iii:migrate-recurrence-type {--F|force : Force the execution of this command.}';
+ public const string CONFIG_NAME = '550_migrate_recurrence_type';
+
+ protected $description = 'Migrate transaction type of recurring transaction.';
+
+ protected $signature = 'firefly-iii:migrate-recurrence-type {--F|force : Force the execution of this command.}';
/**
* Execute the console command.
- *
- * @return int
- * @throws ContainerExceptionInterface
- * @throws NotFoundExceptionInterface
*/
public function handle(): int
{
@@ -67,69 +50,19 @@ class MigrateRecurrenceType extends Command
return 0;
}
-
- $this->migrateTypes();
+ $this->friendlyWarning('This command has been disabled.');
$this->markAsExecuted();
-
return 0;
}
- /**
- * @return bool
- * @throws ContainerExceptionInterface
- * @throws NotFoundExceptionInterface
- */
private function isExecuted(): bool
{
$configVar = app('fireflyconfig')->get(self::CONFIG_NAME, false);
+
return (bool)$configVar?->data;
}
- /**
- *
- */
- private function migrateTypes(): void
- {
- $set = Recurrence::get();
- /** @var Recurrence $recurrence */
- foreach ($set as $recurrence) {
- if ($recurrence->transactionType->type !== TransactionType::INVALID) {
- $this->migrateRecurrence($recurrence);
- }
- }
- }
-
- /**
- * @param Recurrence $recurrence
- *
- * @return void
- */
- private function migrateRecurrence(Recurrence $recurrence): void
- {
- $originalType = (int)$recurrence->transaction_type_id;
- $newType = $this->getInvalidType();
- $recurrence->transaction_type_id = $newType->id;
- $recurrence->save();
- /** @var RecurrenceTransaction $transaction */
- foreach ($recurrence->recurrenceTransactions as $transaction) {
- $transaction->transaction_type_id = $originalType;
- $transaction->save();
- }
- $this->friendlyInfo(sprintf('Updated recurrence #%d to new transaction type model.', $recurrence->id));
- }
-
- /**
- *
- */
- private function getInvalidType(): TransactionType
- {
- return TransactionType::whereType(TransactionType::INVALID)->firstOrCreate(['type' => TransactionType::INVALID]);
- }
-
- /**
- *
- */
private function markAsExecuted(): void
{
app('fireflyconfig')->set(self::CONFIG_NAME, true);
diff --git a/app/Console/Commands/Upgrade/MigrateTagLocations.php b/app/Console/Commands/Upgrade/MigrateTagLocations.php
index c2d53c178e..76a7f81a9e 100644
--- a/app/Console/Commands/Upgrade/MigrateTagLocations.php
+++ b/app/Console/Commands/Upgrade/MigrateTagLocations.php
@@ -28,8 +28,6 @@ use FireflyIII\Console\Commands\ShowsFriendlyMessages;
use FireflyIII\Models\Location;
use FireflyIII\Models\Tag;
use Illuminate\Console\Command;
-use Psr\Container\ContainerExceptionInterface;
-use Psr\Container\NotFoundExceptionInterface;
/**
* Class MigrateTagLocations
@@ -38,26 +36,14 @@ class MigrateTagLocations extends Command
{
use ShowsFriendlyMessages;
- public const CONFIG_NAME = '500_migrate_tag_locations';
- /**
- * The console command description.
- *
- * @var string
- */
- protected $description = 'Migrate tag locations.';
- /**
- * The name and signature of the console command.
- *
- * @var string
- */
- protected $signature = 'firefly-iii:migrate-tag-locations {--F|force : Force the execution of this command.}';
+ public const string CONFIG_NAME = '500_migrate_tag_locations';
+
+ protected $description = 'Migrate tag locations.';
+
+ protected $signature = 'firefly-iii:migrate-tag-locations {--F|force : Force the execution of this command.}';
/**
* Execute the console command.
- *
- * @return int
- * @throws ContainerExceptionInterface
- * @throws NotFoundExceptionInterface
*/
public function handle(): int
{
@@ -72,11 +58,6 @@ class MigrateTagLocations extends Command
return 0;
}
- /**
- * @return bool
- * @throws ContainerExceptionInterface
- * @throws NotFoundExceptionInterface
- */
private function isExecuted(): bool
{
$configVar = app('fireflyconfig')->get(self::CONFIG_NAME, false);
@@ -87,12 +68,10 @@ class MigrateTagLocations extends Command
return false;
}
- /**
- * @return void
- */
private function migrateTagLocations(): void
{
$tags = Tag::get();
+
/** @var Tag $tag */
foreach ($tags as $tag) {
if ($this->hasLocationDetails($tag)) {
@@ -101,19 +80,11 @@ class MigrateTagLocations extends Command
}
}
- /**
- * @param Tag $tag
- *
- * @return bool
- */
private function hasLocationDetails(Tag $tag): bool
{
return null !== $tag->latitude && null !== $tag->longitude && null !== $tag->zoomLevel;
}
- /**
- * @param Tag $tag
- */
private function migrateLocationDetails(Tag $tag): void
{
$location = new Location();
@@ -123,15 +94,12 @@ class MigrateTagLocations extends Command
$location->locatable()->associate($tag);
$location->save();
- $tag->longitude = null;
- $tag->latitude = null;
- $tag->zoomLevel = null;
+ $tag->longitude = null;
+ $tag->latitude = null;
+ $tag->zoomLevel = null;
$tag->save();
}
- /**
- *
- */
private function markAsExecuted(): void
{
app('fireflyconfig')->set(self::CONFIG_NAME, true);
diff --git a/app/Console/Commands/Upgrade/MigrateToGroups.php b/app/Console/Commands/Upgrade/MigrateToGroups.php
index 78a364b4a9..e18ba489fd 100644
--- a/app/Console/Commands/Upgrade/MigrateToGroups.php
+++ b/app/Console/Commands/Upgrade/MigrateToGroups.php
@@ -23,8 +23,6 @@ declare(strict_types=1);
namespace FireflyIII\Console\Commands\Upgrade;
-use DB;
-use Exception;
use FireflyIII\Console\Commands\ShowsFriendlyMessages;
use FireflyIII\Factory\TransactionGroupFactory;
use FireflyIII\Models\Budget;
@@ -36,9 +34,6 @@ use FireflyIII\Repositories\Journal\JournalRepositoryInterface;
use FireflyIII\Services\Internal\Destroy\JournalDestroyService;
use Illuminate\Console\Command;
use Illuminate\Support\Collection;
-use Illuminate\Support\Facades\Log;
-use Psr\Container\ContainerExceptionInterface;
-use Psr\Container\NotFoundExceptionInterface;
/**
* This command will take split transactions and migrate them to "transaction groups".
@@ -51,9 +46,9 @@ class MigrateToGroups extends Command
{
use ShowsFriendlyMessages;
- public const CONFIG_NAME = '480_migrated_to_groups';
- protected $description = 'Migrates a pre-4.7.8 transaction structure to the 4.7.8+ transaction structure.';
- protected $signature = 'firefly-iii:migrate-to-groups {--F|force : Force the migration, even if it fired before.}';
+ public const string CONFIG_NAME = '480_migrated_to_groups';
+ protected $description = 'Migrates a pre-4.7.8 transaction structure to the 4.7.8+ transaction structure.';
+ protected $signature = 'firefly-iii:migrate-to-groups {--F|force : Force the migration, even if it fired before.}';
private JournalCLIRepositoryInterface $cliRepository;
private int $count;
private TransactionGroupFactory $groupFactory;
@@ -62,10 +57,6 @@ class MigrateToGroups extends Command
/**
* Execute the console command.
- *
- * @return int
- * @throws ContainerExceptionInterface
- * @throws NotFoundExceptionInterface
*/
public function handle(): int
{
@@ -81,7 +72,6 @@ class MigrateToGroups extends Command
$this->friendlyWarning('Forcing the migration.');
}
-
$this->makeGroupsFromSplitJournals();
$this->makeGroupsFromAll();
@@ -100,8 +90,6 @@ class MigrateToGroups extends Command
* Laravel will execute ALL __construct() methods for ALL commands whenever a SINGLE command is
* executed. This leads to noticeable slow-downs and class calls. To prevent this, this method should
* be called from the handle method instead of using the constructor to initialize the command.
- *
-
*/
private function stupidLaravel(): void
{
@@ -112,11 +100,6 @@ class MigrateToGroups extends Command
$this->cliRepository = app(JournalCLIRepositoryInterface::class);
}
- /**
- * @return bool
- * @throws ContainerExceptionInterface
- * @throws NotFoundExceptionInterface
- */
private function isMigrated(): bool
{
$configVar = app('fireflyconfig')->get(self::CONFIG_NAME, false);
@@ -128,13 +111,14 @@ class MigrateToGroups extends Command
}
/**
- * @throws Exception
+ * @throws \Exception
*/
private function makeGroupsFromSplitJournals(): void
{
$splitJournals = $this->cliRepository->getSplitJournals();
if ($splitJournals->count() > 0) {
$this->friendlyLine(sprintf('Going to convert %d split transaction(s). Please hold..', $splitJournals->count()));
+
/** @var TransactionJournal $journal */
foreach ($splitJournals as $journal) {
$this->makeMultiGroup($journal);
@@ -143,19 +127,17 @@ class MigrateToGroups extends Command
}
/**
- * @param TransactionJournal $journal
- *
- * @throws Exception
+ * @throws \Exception
*/
private function makeMultiGroup(TransactionJournal $journal): void
{
// double check transaction count.
if ($journal->transactions->count() <= 2) {
- Log::debug(sprintf('Will not try to convert journal #%d because it has 2 or less transactions.', $journal->id));
+ app('log')->debug(sprintf('Will not try to convert journal #%d because it has 2 or fewer transactions.', $journal->id));
return;
}
- Log::debug(sprintf('Will now try to convert journal #%d', $journal->id));
+ app('log')->debug(sprintf('Will now try to convert journal #%d', $journal->id));
$this->journalRepository->setUser($journal->user);
$this->groupFactory->setUser($journal->user);
@@ -167,106 +149,24 @@ class MigrateToGroups extends Command
'transactions' => [],
];
$destTransactions = $this->getDestinationTransactions($journal);
- $budgetId = $this->cliRepository->getJournalBudgetId($journal);
- $categoryId = $this->cliRepository->getJournalCategoryId($journal);
- $notes = $this->cliRepository->getNoteText($journal);
- $tags = $this->cliRepository->getTags($journal);
- $internalRef = $this->cliRepository->getMetaField($journal, 'internal-reference');
- $sepaCC = $this->cliRepository->getMetaField($journal, 'sepa_cc');
- $sepaCtOp = $this->cliRepository->getMetaField($journal, 'sepa_ct_op');
- $sepaCtId = $this->cliRepository->getMetaField($journal, 'sepa_ct_id');
- $sepaDb = $this->cliRepository->getMetaField($journal, 'sepa_db');
- $sepaCountry = $this->cliRepository->getMetaField($journal, 'sepa_country');
- $sepaEp = $this->cliRepository->getMetaField($journal, 'sepa_ep');
- $sepaCi = $this->cliRepository->getMetaField($journal, 'sepa_ci');
- $sepaBatchId = $this->cliRepository->getMetaField($journal, 'sepa_batch_id');
- $externalId = $this->cliRepository->getMetaField($journal, 'external-id');
- $originalSource = $this->cliRepository->getMetaField($journal, 'original-source');
- $recurrenceId = $this->cliRepository->getMetaField($journal, 'recurrence_id');
- $bunq = $this->cliRepository->getMetaField($journal, 'bunq_payment_id');
- $hash = $this->cliRepository->getMetaField($journal, 'import_hash');
- $hashTwo = $this->cliRepository->getMetaField($journal, 'import_hash_v2');
- $interestDate = $this->cliRepository->getMetaDate($journal, 'interest_date');
- $bookDate = $this->cliRepository->getMetaDate($journal, 'book_date');
- $processDate = $this->cliRepository->getMetaDate($journal, 'process_date');
- $dueDate = $this->cliRepository->getMetaDate($journal, 'due_date');
- $paymentDate = $this->cliRepository->getMetaDate($journal, 'payment_date');
- $invoiceDate = $this->cliRepository->getMetaDate($journal, 'invoice_date');
- Log::debug(sprintf('Will use %d positive transactions to create a new group.', $destTransactions->count()));
+ app('log')->debug(sprintf('Will use %d positive transactions to create a new group.', $destTransactions->count()));
/** @var Transaction $transaction */
foreach ($destTransactions as $transaction) {
- Log::debug(sprintf('Now going to add transaction #%d to the array.', $transaction->id));
- $opposingTr = $this->findOpposingTransaction($journal, $transaction);
-
- if (null === $opposingTr) {
- $this->friendlyError(
- sprintf(
- 'Journal #%d has no opposing transaction for transaction #%d. Cannot upgrade this entry.',
- $journal->id,
- $transaction->id
- )
- );
- continue;
- }
-
- // overrule journal category with transaction category.
- $budgetId = $this->getTransactionBudget($transaction, $opposingTr) ?? $budgetId;
- $categoryId = $this->getTransactionCategory($transaction, $opposingTr) ?? $categoryId;
-
- $tArray = [
- 'type' => strtolower($journal->transactionType->type),
- 'date' => $journal->date,
- 'user' => $journal->user_id,
- 'currency_id' => $transaction->transaction_currency_id,
- 'foreign_currency_id' => $transaction->foreign_currency_id,
- 'amount' => $transaction->amount,
- 'foreign_amount' => $transaction->foreign_amount,
- 'description' => $transaction->description ?? $journal->description,
- 'source_id' => $opposingTr->account_id,
- 'destination_id' => $transaction->account_id,
- 'budget_id' => $budgetId,
- 'category_id' => $categoryId,
- 'bill_id' => $journal->bill_id,
- 'notes' => $notes,
- 'tags' => $tags,
- 'internal_reference' => $internalRef,
- 'sepa_cc' => $sepaCC,
- 'sepa_ct_op' => $sepaCtOp,
- 'sepa_ct_id' => $sepaCtId,
- 'sepa_db' => $sepaDb,
- 'sepa_country' => $sepaCountry,
- 'sepa_ep' => $sepaEp,
- 'sepa_ci' => $sepaCi,
- 'sepa_batch_id' => $sepaBatchId,
- 'external_id' => $externalId,
- 'original-source' => $originalSource,
- 'recurrence_id' => $recurrenceId,
- 'bunq_payment_id' => $bunq,
- 'import_hash' => $hash,
- 'import_hash_v2' => $hashTwo,
- 'interest_date' => $interestDate,
- 'book_date' => $bookDate,
- 'process_date' => $processDate,
- 'due_date' => $dueDate,
- 'payment_date' => $paymentDate,
- 'invoice_date' => $invoiceDate,
- ];
-
- $data['transactions'][] = $tArray;
+ $data['transactions'][] = $this->generateTransaction($journal, $transaction);
}
- Log::debug(sprintf('Now calling transaction journal factory (%d transactions in array)', count($data['transactions'])));
- $group = $this->groupFactory->create($data);
- Log::debug('Done calling transaction journal factory');
+ app('log')->debug(sprintf('Now calling transaction journal factory (%d transactions in array)', count($data['transactions'])));
+ $group = $this->groupFactory->create($data);
+ app('log')->debug('Done calling transaction journal factory');
// delete the old transaction journal.
$this->service->destroy($journal);
- $this->count++;
+ ++$this->count;
// report on result:
- Log::debug(
+ app('log')->debug(
sprintf(
'Migrated journal #%d into group #%d with these journals: #%s',
$journal->id,
@@ -284,11 +184,6 @@ class MigrateToGroups extends Command
);
}
- /**
- * @param TransactionJournal $journal
- *
- * @return Collection
- */
private function getDestinationTransactions(TransactionJournal $journal): Collection
{
return $journal->transactions->filter(
@@ -299,19 +194,103 @@ class MigrateToGroups extends Command
}
/**
- * @param TransactionJournal $journal
- * @param Transaction $transaction
- *
- * @return Transaction|null
+ * @SuppressWarnings(PHPMD.ExcessiveMethodLength)
*/
+ private function generateTransaction(TransactionJournal $journal, Transaction $transaction): array
+ {
+ app('log')->debug(sprintf('Now going to add transaction #%d to the array.', $transaction->id));
+ $opposingTr = $this->findOpposingTransaction($journal, $transaction);
+
+ if (null === $opposingTr) {
+ $this->friendlyError(
+ sprintf(
+ 'Journal #%d has no opposing transaction for transaction #%d. Cannot upgrade this entry.',
+ $journal->id,
+ $transaction->id
+ )
+ );
+
+ return [];
+ }
+
+ $budgetId = $this->cliRepository->getJournalBudgetId($journal);
+ $categoryId = $this->cliRepository->getJournalCategoryId($journal);
+ $notes = $this->cliRepository->getNoteText($journal);
+ $tags = $this->cliRepository->getTags($journal);
+ $internalRef = $this->cliRepository->getMetaField($journal, 'internal-reference');
+ $sepaCC = $this->cliRepository->getMetaField($journal, 'sepa_cc');
+ $sepaCtOp = $this->cliRepository->getMetaField($journal, 'sepa_ct_op');
+ $sepaCtId = $this->cliRepository->getMetaField($journal, 'sepa_ct_id');
+ $sepaDb = $this->cliRepository->getMetaField($journal, 'sepa_db');
+ $sepaCountry = $this->cliRepository->getMetaField($journal, 'sepa_country');
+ $sepaEp = $this->cliRepository->getMetaField($journal, 'sepa_ep');
+ $sepaCi = $this->cliRepository->getMetaField($journal, 'sepa_ci');
+ $sepaBatchId = $this->cliRepository->getMetaField($journal, 'sepa_batch_id');
+ $externalId = $this->cliRepository->getMetaField($journal, 'external-id');
+ $originalSource = $this->cliRepository->getMetaField($journal, 'original-source');
+ $recurrenceId = $this->cliRepository->getMetaField($journal, 'recurrence_id');
+ $bunq = $this->cliRepository->getMetaField($journal, 'bunq_payment_id');
+ $hash = $this->cliRepository->getMetaField($journal, 'import_hash');
+ $hashTwo = $this->cliRepository->getMetaField($journal, 'import_hash_v2');
+ $interestDate = $this->cliRepository->getMetaDate($journal, 'interest_date');
+ $bookDate = $this->cliRepository->getMetaDate($journal, 'book_date');
+ $processDate = $this->cliRepository->getMetaDate($journal, 'process_date');
+ $dueDate = $this->cliRepository->getMetaDate($journal, 'due_date');
+ $paymentDate = $this->cliRepository->getMetaDate($journal, 'payment_date');
+ $invoiceDate = $this->cliRepository->getMetaDate($journal, 'invoice_date');
+
+ // overrule journal category with transaction category.
+ $budgetId = $this->getTransactionBudget($transaction, $opposingTr) ?? $budgetId;
+ $categoryId = $this->getTransactionCategory($transaction, $opposingTr) ?? $categoryId;
+
+ return [
+ 'type' => strtolower($journal->transactionType->type),
+ 'date' => $journal->date,
+ 'user' => $journal->user_id,
+ 'currency_id' => $transaction->transaction_currency_id,
+ 'foreign_currency_id' => $transaction->foreign_currency_id,
+ 'amount' => $transaction->amount,
+ 'foreign_amount' => $transaction->foreign_amount,
+ 'description' => $transaction->description ?? $journal->description,
+ 'source_id' => $opposingTr->account_id,
+ 'destination_id' => $transaction->account_id,
+ 'budget_id' => $budgetId,
+ 'category_id' => $categoryId,
+ 'bill_id' => $journal->bill_id,
+ 'notes' => $notes,
+ 'tags' => $tags,
+ 'internal_reference' => $internalRef,
+ 'sepa_cc' => $sepaCC,
+ 'sepa_ct_op' => $sepaCtOp,
+ 'sepa_ct_id' => $sepaCtId,
+ 'sepa_db' => $sepaDb,
+ 'sepa_country' => $sepaCountry,
+ 'sepa_ep' => $sepaEp,
+ 'sepa_ci' => $sepaCi,
+ 'sepa_batch_id' => $sepaBatchId,
+ 'external_id' => $externalId,
+ 'original-source' => $originalSource,
+ 'recurrence_id' => $recurrenceId,
+ 'bunq_payment_id' => $bunq,
+ 'import_hash' => $hash,
+ 'import_hash_v2' => $hashTwo,
+ 'interest_date' => $interestDate,
+ 'book_date' => $bookDate,
+ 'process_date' => $processDate,
+ 'due_date' => $dueDate,
+ 'payment_date' => $paymentDate,
+ 'invoice_date' => $invoiceDate,
+ ];
+ }
+
private function findOpposingTransaction(TransactionJournal $journal, Transaction $transaction): ?Transaction
{
$set = $journal->transactions->filter(
static function (Transaction $subject) use ($transaction) {
$amount = (float)$transaction->amount * -1 === (float)$subject->amount; // intentional float
$identifier = $transaction->identifier === $subject->identifier;
- Log::debug(sprintf('Amount the same? %s', var_export($amount, true)));
- Log::debug(sprintf('ID the same? %s', var_export($identifier, true)));
+ app('log')->debug(sprintf('Amount the same? %s', var_export($amount, true)));
+ app('log')->debug(sprintf('ID the same? %s', var_export($identifier, true)));
return $amount && $identifier;
}
@@ -320,67 +299,55 @@ class MigrateToGroups extends Command
return $set->first();
}
- /**
- * @param Transaction $left
- * @param Transaction $right
- *
- * @return int|null
- */
private function getTransactionBudget(Transaction $left, Transaction $right): ?int
{
- Log::debug('Now in getTransactionBudget()');
+ app('log')->debug('Now in getTransactionBudget()');
// try to get a budget ID from the left transaction:
- /** @var Budget|null $budget */
+ /** @var null|Budget $budget */
$budget = $left->budgets()->first();
if (null !== $budget) {
- Log::debug(sprintf('Return budget #%d, from transaction #%d', $budget->id, $left->id));
+ app('log')->debug(sprintf('Return budget #%d, from transaction #%d', $budget->id, $left->id));
- return (int)$budget->id;
+ return $budget->id;
}
// try to get a budget ID from the right transaction:
- /** @var Budget|null $budget */
+ /** @var null|Budget $budget */
$budget = $right->budgets()->first();
if (null !== $budget) {
- Log::debug(sprintf('Return budget #%d, from transaction #%d', $budget->id, $right->id));
+ app('log')->debug(sprintf('Return budget #%d, from transaction #%d', $budget->id, $right->id));
- return (int)$budget->id;
+ return $budget->id;
}
- Log::debug('Neither left or right have a budget, return NULL');
+ app('log')->debug('Neither left or right have a budget, return NULL');
// if all fails, return NULL.
return null;
}
- /**
- * @param Transaction $left
- * @param Transaction $right
- *
- * @return int|null
- */
private function getTransactionCategory(Transaction $left, Transaction $right): ?int
{
- Log::debug('Now in getTransactionCategory()');
+ app('log')->debug('Now in getTransactionCategory()');
// try to get a category ID from the left transaction:
- /** @var Category|null $category */
+ /** @var null|Category $category */
$category = $left->categories()->first();
if (null !== $category) {
- Log::debug(sprintf('Return category #%d, from transaction #%d', $category->id, $left->id));
+ app('log')->debug(sprintf('Return category #%d, from transaction #%d', $category->id, $left->id));
- return (int)$category->id;
+ return $category->id;
}
// try to get a category ID from the left transaction:
- /** @var Category|null $category */
+ /** @var null|Category $category */
$category = $right->categories()->first();
if (null !== $category) {
- Log::debug(sprintf('Return category #%d, from transaction #%d', $category->id, $category->id));
+ app('log')->debug(sprintf('Return category #%d, from transaction #%d', $category->id, $category->id));
- return (int)$category->id;
+ return $category->id;
}
- Log::debug('Neither left or right have a category, return NULL');
+ app('log')->debug('Neither left or right have a category, return NULL');
// if all fails, return NULL.
return null;
@@ -394,8 +361,9 @@ class MigrateToGroups extends Command
$orphanedJournals = $this->cliRepository->getJournalsWithoutGroup();
$total = count($orphanedJournals);
if ($total > 0) {
- Log::debug(sprintf('Going to convert %d transaction journals. Please hold..', $total));
+ app('log')->debug(sprintf('Going to convert %d transaction journals. Please hold..', $total));
$this->friendlyInfo(sprintf('Going to convert %d transaction journals. Please hold..', $total));
+
/** @var array $array */
foreach ($orphanedJournals as $array) {
$this->giveGroup($array);
@@ -406,12 +374,9 @@ class MigrateToGroups extends Command
}
}
- /**
- * @param array $array
- */
private function giveGroup(array $array): void
{
- $groupId = DB::table('transaction_groups')->insertGetId(
+ $groupId = \DB::table('transaction_groups')->insertGetId(
[
'created_at' => date('Y-m-d H:i:s'),
'updated_at' => date('Y-m-d H:i:s'),
@@ -419,13 +384,10 @@ class MigrateToGroups extends Command
'user_id' => $array['user_id'],
]
);
- DB::table('transaction_journals')->where('id', $array['id'])->update(['transaction_group_id' => $groupId]);
- $this->count++;
+ \DB::table('transaction_journals')->where('id', $array['id'])->update(['transaction_group_id' => $groupId]);
+ ++$this->count;
}
- /**
- *
- */
private function markAsMigrated(): void
{
app('fireflyconfig')->set(self::CONFIG_NAME, true);
diff --git a/app/Console/Commands/Upgrade/MigrateToRules.php b/app/Console/Commands/Upgrade/MigrateToRules.php
index 6e8c804894..34db0ce8f7 100644
--- a/app/Console/Commands/Upgrade/MigrateToRules.php
+++ b/app/Console/Commands/Upgrade/MigrateToRules.php
@@ -34,8 +34,6 @@ use FireflyIII\Repositories\RuleGroup\RuleGroupRepositoryInterface;
use FireflyIII\Repositories\User\UserRepositoryInterface;
use FireflyIII\User;
use Illuminate\Console\Command;
-use Psr\Container\ContainerExceptionInterface;
-use Psr\Container\NotFoundExceptionInterface;
/**
* Class MigrateToRules
@@ -44,36 +42,21 @@ class MigrateToRules extends Command
{
use ShowsFriendlyMessages;
- public const CONFIG_NAME = '480_bills_to_rules';
- /**
- * The console command description.
- *
- * @var string
- */
- protected $description = 'Migrate bills to rules.';
- /**
- * The name and signature of the console command.
- *
- * @var string
- */
- protected $signature = 'firefly-iii:bills-to-rules {--F|force : Force the execution of this command.}';
- /** @var BillRepositoryInterface */
- private $billRepository;
- private $count;
- /** @var RuleGroupRepositoryInterface */
- private $ruleGroupRepository;
- /** @var RuleRepositoryInterface */
- private $ruleRepository;
- /** @var UserRepositoryInterface */
- private $userRepository;
+ public const string CONFIG_NAME = '480_bills_to_rules';
+
+ protected $description = 'Migrate bills to rules.';
+
+ protected $signature = 'firefly-iii:bills-to-rules {--F|force : Force the execution of this command.}';
+ private BillRepositoryInterface $billRepository;
+ private int $count;
+ private RuleGroupRepositoryInterface $ruleGroupRepository;
+ private RuleRepositoryInterface $ruleRepository;
+ private UserRepositoryInterface $userRepository;
/**
* Execute the console command.
*
- * @return int
- * @throws ContainerExceptionInterface
* @throws FireflyException
- * @throws NotFoundExceptionInterface
*/
public function handle(): int
{
@@ -85,8 +68,8 @@ class MigrateToRules extends Command
return 0;
}
-
$users = $this->userRepository->all();
+
/** @var User $user */
foreach ($users as $user) {
$this->migrateUser($user);
@@ -108,8 +91,6 @@ class MigrateToRules extends Command
* Laravel will execute ALL __construct() methods for ALL commands whenever a SINGLE command is
* executed. This leads to noticeable slow-downs and class calls. To prevent this, this method should
* be called from the handle method instead of using the constructor to initialize the command.
- *
-
*/
private function stupidLaravel(): void
{
@@ -120,11 +101,6 @@ class MigrateToRules extends Command
$this->ruleRepository = app(RuleRepositoryInterface::class);
}
- /**
- * @return bool
- * @throws ContainerExceptionInterface
- * @throws NotFoundExceptionInterface
- */
private function isExecuted(): bool
{
$configVar = app('fireflyconfig')->get(self::CONFIG_NAME, false);
@@ -138,8 +114,6 @@ class MigrateToRules extends Command
/**
* Migrate bills to new rule structure for a specific user.
*
- * @param User $user
- *
* @throws FireflyException
*/
private function migrateUser(User $user): void
@@ -150,19 +124,20 @@ class MigrateToRules extends Command
/** @var Preference $lang */
$lang = app('preferences')->getForUser($user, 'language', 'en_US');
- $groupTitle = (string)trans('firefly.rulegroup_for_bills_title', [], $lang->data);
+ $language = null !== $lang->data && !is_array($lang->data) ? (string)$lang->data : 'en_US';
+ $groupTitle = (string)trans('firefly.rulegroup_for_bills_title', [], $language);
$ruleGroup = $this->ruleGroupRepository->findByTitle($groupTitle);
if (null === $ruleGroup) {
$ruleGroup = $this->ruleGroupRepository->store(
[
- 'title' => (string)trans('firefly.rulegroup_for_bills_title', [], $lang->data),
- 'description' => (string)trans('firefly.rulegroup_for_bills_description', [], $lang->data),
+ 'title' => (string)trans('firefly.rulegroup_for_bills_title', [], $language),
+ 'description' => (string)trans('firefly.rulegroup_for_bills_description', [], $language),
'active' => true,
]
);
}
- $bills = $this->billRepository->getBills();
+ $bills = $this->billRepository->getBills();
/** @var Bill $bill */
foreach ($bills as $bill) {
@@ -170,26 +145,22 @@ class MigrateToRules extends Command
}
}
- /**
- * @param RuleGroup $ruleGroup
- * @param Bill $bill
- * @param Preference $language
- */
private function migrateBill(RuleGroup $ruleGroup, Bill $bill, Preference $language): void
{
if ('MIGRATED_TO_RULES' === $bill->match) {
return;
}
+ $languageString = null !== $language->data && !is_array($language->data) ? (string)$language->data : 'en_US';
// get match thing:
- $match = implode(' ', explode(',', $bill->match));
- $newRule = [
+ $match = implode(' ', explode(',', $bill->match));
+ $newRule = [
'rule_group_id' => $ruleGroup->id,
'active' => true,
'strict' => false,
'stop_processing' => false, // field is no longer used.
- 'title' => (string)trans('firefly.rule_for_bill_title', ['name' => $bill->name], $language->data),
- 'description' => (string)trans('firefly.rule_for_bill_description', ['name' => $bill->name], $language->data),
+ 'title' => (string)trans('firefly.rule_for_bill_title', ['name' => $bill->name], $languageString),
+ 'description' => (string)trans('firefly.rule_for_bill_description', ['name' => $bill->name], $languageString),
'trigger' => 'store-journal',
'triggers' => [
[
@@ -226,7 +197,7 @@ class MigrateToRules extends Command
$this->ruleRepository->store($newRule);
// update bill:
- $newBillData = [
+ $newBillData = [
'currency_id' => $bill->transaction_currency_id,
'name' => $bill->name,
'match' => 'MIGRATED_TO_RULES',
@@ -238,12 +209,9 @@ class MigrateToRules extends Command
'active' => $bill->active,
];
$this->billRepository->update($bill, $newBillData);
- $this->count++;
+ ++$this->count;
}
- /**
- *
- */
private function markAsExecuted(): void
{
app('fireflyconfig')->set(self::CONFIG_NAME, true);
diff --git a/app/Console/Commands/Upgrade/OtherCurrenciesCorrections.php b/app/Console/Commands/Upgrade/OtherCurrenciesCorrections.php
index 093223fe36..a6dba4b748 100644
--- a/app/Console/Commands/Upgrade/OtherCurrenciesCorrections.php
+++ b/app/Console/Commands/Upgrade/OtherCurrenciesCorrections.php
@@ -31,12 +31,9 @@ use FireflyIII\Models\TransactionCurrency;
use FireflyIII\Models\TransactionJournal;
use FireflyIII\Models\TransactionType;
use FireflyIII\Repositories\Account\AccountRepositoryInterface;
-use FireflyIII\Repositories\Currency\CurrencyRepositoryInterface;
use FireflyIII\Repositories\Journal\JournalCLIRepositoryInterface;
use FireflyIII\Repositories\Journal\JournalRepositoryInterface;
use Illuminate\Console\Command;
-use Psr\Container\ContainerExceptionInterface;
-use Psr\Container\NotFoundExceptionInterface;
/**
* Class OtherCurrenciesCorrections
@@ -45,22 +42,17 @@ class OtherCurrenciesCorrections extends Command
{
use ShowsFriendlyMessages;
- public const CONFIG_NAME = '480_other_currencies';
- protected $description = 'Update all journal currency information.';
- protected $signature = 'firefly-iii:other-currencies {--F|force : Force the execution of this command.}';
+ public const string CONFIG_NAME = '480_other_currencies';
+ protected $description = 'Update all journal currency information.';
+ protected $signature = 'firefly-iii:other-currencies {--F|force : Force the execution of this command.}';
private array $accountCurrencies;
private AccountRepositoryInterface $accountRepos;
private JournalCLIRepositoryInterface $cliRepos;
private int $count;
- private CurrencyRepositoryInterface $currencyRepos;
private JournalRepositoryInterface $journalRepos;
/**
* Execute the console command.
- *
- * @return int
- * @throws ContainerExceptionInterface
- * @throws NotFoundExceptionInterface
*/
public function handle(): int
{
@@ -72,7 +64,6 @@ class OtherCurrenciesCorrections extends Command
return 0;
}
-
$this->updateOtherJournalsCurrencies();
$this->markAsExecuted();
@@ -85,24 +76,16 @@ class OtherCurrenciesCorrections extends Command
* Laravel will execute ALL __construct() methods for ALL commands whenever a SINGLE command is
* executed. This leads to noticeable slow-downs and class calls. To prevent this, this method should
* be called from the handle method instead of using the constructor to initialize the command.
- *
-
*/
private function stupidLaravel(): void
{
$this->count = 0;
$this->accountCurrencies = [];
$this->accountRepos = app(AccountRepositoryInterface::class);
- $this->currencyRepos = app(CurrencyRepositoryInterface::class);
$this->journalRepos = app(JournalRepositoryInterface::class);
$this->cliRepos = app(JournalCLIRepositoryInterface::class);
}
- /**
- * @return bool
- * @throws ContainerExceptionInterface
- * @throws NotFoundExceptionInterface
- */
private function isExecuted(): bool
{
$configVar = app('fireflyconfig')->get(self::CONFIG_NAME, false);
@@ -122,7 +105,7 @@ class OtherCurrenciesCorrections extends Command
private function updateOtherJournalsCurrencies(): void
{
$set = $this->cliRepos->getAllJournals(
- [TransactionType::WITHDRAWAL, TransactionType::DEPOSIT, TransactionType::OPENING_BALANCE, TransactionType::RECONCILIATION,]
+ [TransactionType::WITHDRAWAL, TransactionType::DEPOSIT, TransactionType::OPENING_BALANCE, TransactionType::RECONCILIATION]
);
/** @var TransactionJournal $journal */
@@ -131,17 +114,13 @@ class OtherCurrenciesCorrections extends Command
}
}
- /**
- * @param TransactionJournal $journal
- */
private function updateJournalCurrency(TransactionJournal $journal): void
{
$this->accountRepos->setUser($journal->user);
$this->journalRepos->setUser($journal->user);
- $this->currencyRepos->setUser($journal->user);
$this->cliRepos->setUser($journal->user);
- $leadTransaction = $this->getLeadTransaction($journal);
+ $leadTransaction = $this->getLeadTransaction($journal);
if (null === $leadTransaction) {
$this->friendlyError(sprintf('Could not reliably determine which transaction is in the lead for transaction journal #%d.', $journal->id));
@@ -149,8 +128,8 @@ class OtherCurrenciesCorrections extends Command
return;
}
- $account = $leadTransaction->account;
- $currency = $this->getCurrency($account);
+ $account = $leadTransaction->account;
+ $currency = $this->getCurrency($account);
if (null === $currency) {
$this->friendlyError(
sprintf(
@@ -160,21 +139,21 @@ class OtherCurrenciesCorrections extends Command
$journal->id
)
);
- $this->count++;
+ ++$this->count;
return;
}
// fix each transaction:
$journal->transactions->each(
- static function (Transaction $transaction) use ($currency) {
+ static function (Transaction $transaction) use ($currency): void {
if (null === $transaction->transaction_currency_id) {
$transaction->transaction_currency_id = $currency->id;
$transaction->save();
}
// when mismatch in transaction:
- if ((int)$transaction->transaction_currency_id !== (int)$currency->id) {
- $transaction->foreign_currency_id = (int)$transaction->transaction_currency_id;
+ if ($transaction->transaction_currency_id !== $currency->id) {
+ $transaction->foreign_currency_id = $transaction->transaction_currency_id;
$transaction->foreign_amount = $transaction->amount;
$transaction->transaction_currency_id = $currency->id;
$transaction->save();
@@ -183,31 +162,33 @@ class OtherCurrenciesCorrections extends Command
);
// also update the journal, of course:
$journal->transaction_currency_id = $currency->id;
- $this->count++;
+ ++$this->count;
$journal->save();
}
/**
* Gets the transaction that determines the transaction that "leads" and will determine
* the currency to be used by all transactions, and the journal itself.
- *
- * @param TransactionJournal $journal
- *
- * @return Transaction|null
*/
private function getLeadTransaction(TransactionJournal $journal): ?Transaction
{
/** @var Transaction $lead */
$lead = null;
+
switch ($journal->transactionType->type) {
default:
break;
+
case TransactionType::WITHDRAWAL:
$lead = $journal->transactions()->where('amount', '<', 0)->first();
+
break;
+
case TransactionType::DEPOSIT:
$lead = $journal->transactions()->where('amount', '>', 0)->first();
+
break;
+
case TransactionType::OPENING_BALANCE:
// whichever isn't an initial balance account:
$lead = $journal->transactions()->leftJoin('accounts', 'transactions.account_id', '=', 'accounts.id')->leftJoin(
@@ -216,7 +197,9 @@ class OtherCurrenciesCorrections extends Command
'=',
'account_types.id'
)->where('account_types.type', '!=', AccountType::INITIAL_BALANCE)->first(['transactions.*']);
+
break;
+
case TransactionType::RECONCILIATION:
// whichever isn't the reconciliation account:
$lead = $journal->transactions()->leftJoin('accounts', 'transactions.account_id', '=', 'accounts.id')->leftJoin(
@@ -225,27 +208,23 @@ class OtherCurrenciesCorrections extends Command
'=',
'account_types.id'
)->where('account_types.type', '!=', AccountType::RECONCILIATION)->first(['transactions.*']);
+
break;
}
return $lead;
}
- /**
- * @param Account $account
- *
- * @return TransactionCurrency|null
- */
private function getCurrency(Account $account): ?TransactionCurrency
{
- $accountId = $account->id;
+ $accountId = $account->id;
if (array_key_exists($accountId, $this->accountCurrencies) && 0 === $this->accountCurrencies[$accountId]) {
return null;
}
if (array_key_exists($accountId, $this->accountCurrencies) && $this->accountCurrencies[$accountId] instanceof TransactionCurrency) {
return $this->accountCurrencies[$accountId];
}
- $currency = $this->accountRepos->getAccountCurrency($account);
+ $currency = $this->accountRepos->getAccountCurrency($account);
if (null === $currency) {
$this->accountCurrencies[$accountId] = 0;
@@ -256,9 +235,6 @@ class OtherCurrenciesCorrections extends Command
return $currency;
}
- /**
- *
- */
private function markAsExecuted(): void
{
app('fireflyconfig')->set(self::CONFIG_NAME, true);
diff --git a/app/Console/Commands/Upgrade/RenameAccountMeta.php b/app/Console/Commands/Upgrade/RenameAccountMeta.php
index 8451c88f0c..e62899a19c 100644
--- a/app/Console/Commands/Upgrade/RenameAccountMeta.php
+++ b/app/Console/Commands/Upgrade/RenameAccountMeta.php
@@ -27,8 +27,6 @@ use FireflyIII\Console\Commands\ShowsFriendlyMessages;
use FireflyIII\Exceptions\FireflyException;
use FireflyIII\Models\AccountMeta;
use Illuminate\Console\Command;
-use Psr\Container\ContainerExceptionInterface;
-use Psr\Container\NotFoundExceptionInterface;
/**
* Class RenameAccountMeta
@@ -37,27 +35,16 @@ class RenameAccountMeta extends Command
{
use ShowsFriendlyMessages;
- public const CONFIG_NAME = '480_rename_account_meta';
- /**
- * The console command description.
- *
- * @var string
- */
- protected $description = 'Rename account meta-data to new format.';
- /**
- * The name and signature of the console command.
- *
- * @var string
- */
- protected $signature = 'firefly-iii:rename-account-meta {--F|force : Force the execution of this command.}';
+ public const string CONFIG_NAME = '480_rename_account_meta';
+
+ protected $description = 'Rename account meta-data to new format.';
+
+ protected $signature = 'firefly-iii:rename-account-meta {--F|force : Force the execution of this command.}';
/**
* Execute the console command.
*
- * @return int
- * @throws ContainerExceptionInterface
* @throws FireflyException
- * @throws NotFoundExceptionInterface
*/
public function handle(): int
{
@@ -98,11 +85,6 @@ class RenameAccountMeta extends Command
return 0;
}
- /**
- * @return bool
- * @throws ContainerExceptionInterface
- * @throws NotFoundExceptionInterface
- */
private function isExecuted(): bool
{
$configVar = app('fireflyconfig')->get(self::CONFIG_NAME, false);
@@ -113,9 +95,6 @@ class RenameAccountMeta extends Command
return false;
}
- /**
- *
- */
private function markAsExecuted(): void
{
app('fireflyconfig')->set(self::CONFIG_NAME, true);
diff --git a/app/Console/Commands/Upgrade/TransactionIdentifier.php b/app/Console/Commands/Upgrade/TransactionIdentifier.php
index 4f27a372ca..b241c6d394 100644
--- a/app/Console/Commands/Upgrade/TransactionIdentifier.php
+++ b/app/Console/Commands/Upgrade/TransactionIdentifier.php
@@ -30,10 +30,6 @@ use FireflyIII\Models\TransactionJournal;
use FireflyIII\Repositories\Journal\JournalCLIRepositoryInterface;
use Illuminate\Console\Command;
use Illuminate\Database\QueryException;
-use Illuminate\Support\Facades\Log;
-use Psr\Container\ContainerExceptionInterface;
-use Psr\Container\NotFoundExceptionInterface;
-use Schema;
/**
* Class TransactionIdentifier
@@ -42,9 +38,9 @@ class TransactionIdentifier extends Command
{
use ShowsFriendlyMessages;
- public const CONFIG_NAME = '480_transaction_identifier';
- protected $description = 'Fixes transaction identifiers.';
- protected $signature = 'firefly-iii:transaction-identifiers {--F|force : Force the execution of this command.}';
+ public const string CONFIG_NAME = '480_transaction_identifier';
+ protected $description = 'Fixes transaction identifiers.';
+ protected $signature = 'firefly-iii:transaction-identifiers {--F|force : Force the execution of this command.}';
private JournalCLIRepositoryInterface $cliRepository;
private int $count;
@@ -58,10 +54,7 @@ class TransactionIdentifier extends Command
* When either of these are the same amount, FF3 can't keep them apart: +3/-3, +3/-3, +3/-3. This happens more
* often than you would think. So each set gets a number (1,2,3) to keep them apart.
*
- * @return int
- * @throws ContainerExceptionInterface
* @throws FireflyException
- * @throws NotFoundExceptionInterface
*/
public function handle(): int
{
@@ -74,11 +67,12 @@ class TransactionIdentifier extends Command
}
// if table does not exist, return false
- if (!Schema::hasTable('transaction_journals')) {
+ if (!\Schema::hasTable('transaction_journals')) {
return 0;
}
$journals = $this->cliRepository->getSplitJournals();
+
/** @var TransactionJournal $journal */
foreach ($journals as $journal) {
$this->updateJournalIdentifiers($journal);
@@ -100,8 +94,6 @@ class TransactionIdentifier extends Command
* Laravel will execute ALL __construct() methods for ALL commands whenever a SINGLE command is
* executed. This leads to noticeable slow-downs and class calls. To prevent this, this method should
* be called from the handle method instead of using the constructor to initialize the command.
- *
-
*/
private function stupidLaravel(): void
{
@@ -109,11 +101,6 @@ class TransactionIdentifier extends Command
$this->count = 0;
}
- /**
- * @return bool
- * @throws ContainerExceptionInterface
- * @throws NotFoundExceptionInterface
- */
private function isExecuted(): bool
{
$configVar = app('fireflyconfig')->get(self::CONFIG_NAME, false);
@@ -127,8 +114,6 @@ class TransactionIdentifier extends Command
/**
* Grab all positive transactions from this journal that are not deleted. for each one, grab the negative opposing
* one which has 0 as an identifier and give it the same identifier.
- *
- * @param TransactionJournal $transactionJournal
*/
private function updateJournalIdentifiers(TransactionJournal $transactionJournal): void
{
@@ -145,33 +130,28 @@ class TransactionIdentifier extends Command
$opposing->identifier = $identifier;
$transaction->save();
$opposing->save();
- $exclude[] = $transaction->id;
- $exclude[] = $opposing->id;
- $this->count++;
+ $exclude[] = $transaction->id;
+ $exclude[] = $opposing->id;
+ ++$this->count;
}
++$identifier;
}
}
- /**
- * @param Transaction $transaction
- * @param array $exclude
- *
- * @return Transaction|null
- */
private function findOpposing(Transaction $transaction, array $exclude): ?Transaction
{
// find opposing:
- $amount = bcmul((string)$transaction->amount, '-1');
+ $amount = bcmul($transaction->amount, '-1');
try {
/** @var Transaction $opposing */
$opposing = Transaction::where('transaction_journal_id', $transaction->transaction_journal_id)
- ->where('amount', $amount)->where('identifier', '=', 0)
- ->whereNotIn('id', $exclude)
- ->first();
+ ->where('amount', $amount)->where('identifier', '=', 0)
+ ->whereNotIn('id', $exclude)
+ ->first()
+ ;
} catch (QueryException $e) {
- Log::error($e->getMessage());
+ app('log')->error($e->getMessage());
$this->friendlyError('Firefly III could not find the "identifier" field in the "transactions" table.');
$this->friendlyError(sprintf('This field is required for Firefly III version %s to run.', config('firefly.version')));
$this->friendlyError('Please run "php artisan migrate" to add this field to the table.');
@@ -183,9 +163,6 @@ class TransactionIdentifier extends Command
return $opposing;
}
- /**
- *
- */
private function markAsExecuted(): void
{
app('fireflyconfig')->set(self::CONFIG_NAME, true);
diff --git a/app/Console/Commands/Upgrade/TransferCurrenciesCorrections.php b/app/Console/Commands/Upgrade/TransferCurrenciesCorrections.php
index 556994f292..5733fa365f 100644
--- a/app/Console/Commands/Upgrade/TransferCurrenciesCorrections.php
+++ b/app/Console/Commands/Upgrade/TransferCurrenciesCorrections.php
@@ -32,9 +32,6 @@ use FireflyIII\Models\TransactionType;
use FireflyIII\Repositories\Account\AccountRepositoryInterface;
use FireflyIII\Repositories\Journal\JournalCLIRepositoryInterface;
use Illuminate\Console\Command;
-use Illuminate\Support\Facades\Log;
-use Psr\Container\ContainerExceptionInterface;
-use Psr\Container\NotFoundExceptionInterface;
/**
* Class TransferCurrenciesCorrections
@@ -43,9 +40,9 @@ class TransferCurrenciesCorrections extends Command
{
use ShowsFriendlyMessages;
- public const CONFIG_NAME = '480_transfer_currencies';
- protected $description = 'Updates transfer currency information.';
- protected $signature = 'firefly-iii:transfer-currencies {--F|force : Force the execution of this command.}';
+ public const string CONFIG_NAME = '480_transfer_currencies';
+ protected $description = 'Updates transfer currency information.';
+ protected $signature = 'firefly-iii:transfer-currencies {--F|force : Force the execution of this command.}';
private array $accountCurrencies;
private AccountRepositoryInterface $accountRepos;
private JournalCLIRepositoryInterface $cliRepos;
@@ -60,10 +57,6 @@ class TransferCurrenciesCorrections extends Command
/**
* Execute the console command.
- *
- * @return int
- * @throws ContainerExceptionInterface
- * @throws NotFoundExceptionInterface
*/
public function handle(): int
{
@@ -75,16 +68,17 @@ class TransferCurrenciesCorrections extends Command
return 0;
}
-
$this->startUpdateRoutine();
$this->markAsExecuted();
if (0 === $this->count) {
$this->friendlyPositive('All transfers have correct currency information.');
+
return 0;
}
$this->friendlyInfo(sprintf('Verified currency information of %d transfer(s).', $this->count));
+
return 0;
}
@@ -92,8 +86,6 @@ class TransferCurrenciesCorrections extends Command
* Laravel will execute ALL __construct() methods for ALL commands whenever a SINGLE command is
* executed. This leads to noticeable slow-downs and class calls. To prevent this, this method should
* be called from the handle method instead of using the constructor to initialize the command.
- *
-
*/
private function stupidLaravel(): void
{
@@ -106,8 +98,6 @@ class TransferCurrenciesCorrections extends Command
/**
* Reset all the class fields for the current transfer.
- *
-
*/
private function resetInformation(): void
{
@@ -119,11 +109,6 @@ class TransferCurrenciesCorrections extends Command
$this->destinationCurrency = null;
}
- /**
- * @return bool
- * @throws ContainerExceptionInterface
- * @throws NotFoundExceptionInterface
- */
private function isExecuted(): bool
{
$configVar = app('fireflyconfig')->get(self::CONFIG_NAME, false);
@@ -145,27 +130,23 @@ class TransferCurrenciesCorrections extends Command
private function startUpdateRoutine(): void
{
$set = $this->cliRepos->getAllJournals([TransactionType::TRANSFER]);
+
/** @var TransactionJournal $journal */
foreach ($set as $journal) {
$this->updateTransferCurrency($journal);
}
}
- /**
- * @param TransactionJournal $transfer
- */
private function updateTransferCurrency(TransactionJournal $transfer): void
{
$this->resetInformation();
-
if ($this->isSplitJournal($transfer)) {
$this->friendlyWarning(sprintf('Transaction journal #%d is a split journal. Cannot continue.', $transfer->id));
return;
}
-
$this->getSourceInformation($transfer);
$this->getDestinationInformation($transfer);
@@ -187,7 +168,6 @@ class TransferCurrenciesCorrections extends Command
return;
}
-
// fix source transaction having no currency.
$this->fixSourceNoCurrency();
@@ -216,10 +196,6 @@ class TransferCurrenciesCorrections extends Command
/**
* Is this a split transaction journal?
- *
- * @param TransactionJournal $transfer
- *
- * @return bool
*/
private function isSplitJournal(TransactionJournal $transfer): bool
{
@@ -228,10 +204,6 @@ class TransferCurrenciesCorrections extends Command
/**
* Extract source transaction, source account + source account currency from the journal.
- *
- * @param TransactionJournal $journal
- *
-
*/
private function getSourceInformation(TransactionJournal $journal): void
{
@@ -240,31 +212,21 @@ class TransferCurrenciesCorrections extends Command
$this->sourceCurrency = null === $this->sourceAccount ? null : $this->getCurrency($this->sourceAccount);
}
- /**
- * @param TransactionJournal $transfer
- *
- * @return Transaction|null
- */
private function getSourceTransaction(TransactionJournal $transfer): ?Transaction
{
return $transfer->transactions()->where('amount', '<', 0)->first();
}
- /**
- * @param Account $account
- *
- * @return TransactionCurrency|null
- */
private function getCurrency(Account $account): ?TransactionCurrency
{
- $accountId = $account->id;
+ $accountId = $account->id;
if (array_key_exists($accountId, $this->accountCurrencies) && 0 === $this->accountCurrencies[$accountId]) {
return null;
}
if (array_key_exists($accountId, $this->accountCurrencies) && $this->accountCurrencies[$accountId] instanceof TransactionCurrency) {
return $this->accountCurrencies[$accountId];
}
- $currency = $this->accountRepos->getAccountCurrency($account);
+ $currency = $this->accountRepos->getAccountCurrency($account);
if (null === $currency) {
$this->accountCurrencies[$accountId] = 0;
@@ -277,10 +239,6 @@ class TransferCurrenciesCorrections extends Command
/**
* Extract destination transaction, destination account + destination account currency from the journal.
- *
- * @param TransactionJournal $journal
- *
-
*/
private function getDestinationInformation(TransactionJournal $journal): void
{
@@ -289,11 +247,6 @@ class TransferCurrenciesCorrections extends Command
$this->destinationCurrency = null === $this->destinationAccount ? null : $this->getCurrency($this->destinationAccount);
}
- /**
- * @param TransactionJournal $transfer
- *
- * @return Transaction|null
- */
private function getDestinationTransaction(TransactionJournal $transfer): ?Transaction
{
return $transfer->transactions()->where('amount', '>', 0)->first();
@@ -301,8 +254,6 @@ class TransferCurrenciesCorrections extends Command
/**
* Is either the source or destination transaction NULL?
- *
- * @return bool
*/
private function isEmptyTransactions(): bool
{
@@ -311,15 +262,12 @@ class TransferCurrenciesCorrections extends Command
|| null === $this->destinationAccount;
}
- /**
- * @return bool
- */
private function isNoCurrencyPresent(): bool
{
// source account must have a currency preference.
if (null === $this->sourceCurrency) {
$message = sprintf('Account #%d ("%s") must have currency preference but has none.', $this->sourceAccount->id, $this->sourceAccount->name);
- Log::error($message);
+ app('log')->error($message);
$this->friendlyError($message);
return true;
@@ -332,7 +280,7 @@ class TransferCurrenciesCorrections extends Command
$this->destinationAccount->id,
$this->destinationAccount->name
);
- Log::error($message);
+ app('log')->error($message);
$this->friendlyError($message);
return true;
@@ -350,14 +298,15 @@ class TransferCurrenciesCorrections extends Command
if (null === $this->sourceTransaction->transaction_currency_id && null !== $this->sourceCurrency) {
$this->sourceTransaction
->transaction_currency_id
- = (int)$this->sourceCurrency->id;
+ = $this->sourceCurrency->id
+ ;
$message = sprintf(
'Transaction #%d has no currency setting, now set to %s.',
$this->sourceTransaction->id,
$this->sourceCurrency->code
);
$this->friendlyInfo($message);
- $this->count++;
+ ++$this->count;
$this->sourceTransaction->save();
}
}
@@ -370,9 +319,9 @@ class TransferCurrenciesCorrections extends Command
{
if (null !== $this->sourceCurrency
&& null === $this->sourceTransaction->foreign_amount
- && (int)$this->sourceTransaction->transaction_currency_id !== (int)$this->sourceCurrency->id
+ && (int)$this->sourceTransaction->transaction_currency_id !== $this->sourceCurrency->id
) {
- $message = sprintf(
+ $message = sprintf(
'Transaction #%d has a currency setting #%d that should be #%d. Amount remains %s, currency is changed.',
$this->sourceTransaction->id,
$this->sourceTransaction->transaction_currency_id,
@@ -380,8 +329,8 @@ class TransferCurrenciesCorrections extends Command
$this->sourceTransaction->amount
);
$this->friendlyWarning($message);
- $this->count++;
- $this->sourceTransaction->transaction_currency_id = (int)$this->sourceCurrency->id;
+ ++$this->count;
+ $this->sourceTransaction->transaction_currency_id = $this->sourceCurrency->id;
$this->sourceTransaction->save();
}
}
@@ -395,14 +344,15 @@ class TransferCurrenciesCorrections extends Command
if (null === $this->destinationTransaction->transaction_currency_id && null !== $this->destinationCurrency) {
$this->destinationTransaction
->transaction_currency_id
- = (int)$this->destinationCurrency->id;
+ = $this->destinationCurrency->id
+ ;
$message = sprintf(
'Transaction #%d has no currency setting, now set to %s.',
$this->destinationTransaction->id,
$this->destinationCurrency->code
);
$this->friendlyInfo($message);
- $this->count++;
+ ++$this->count;
$this->destinationTransaction->save();
}
}
@@ -415,9 +365,9 @@ class TransferCurrenciesCorrections extends Command
{
if (null !== $this->destinationCurrency
&& null === $this->destinationTransaction->foreign_amount
- && (int)$this->destinationTransaction->transaction_currency_id !== (int)$this->destinationCurrency->id
+ && (int)$this->destinationTransaction->transaction_currency_id !== $this->destinationCurrency->id
) {
- $message = sprintf(
+ $message = sprintf(
'Transaction #%d has a currency setting #%d that should be #%d. Amount remains %s, currency is changed.',
$this->destinationTransaction->id,
$this->destinationTransaction->transaction_currency_id,
@@ -425,8 +375,8 @@ class TransferCurrenciesCorrections extends Command
$this->destinationTransaction->amount
);
$this->friendlyWarning($message);
- $this->count++;
- $this->destinationTransaction->transaction_currency_id = (int)$this->destinationCurrency->id;
+ ++$this->count;
+ $this->destinationTransaction->transaction_currency_id = $this->destinationCurrency->id;
$this->destinationTransaction->save();
}
}
@@ -438,10 +388,10 @@ class TransferCurrenciesCorrections extends Command
*/
private function fixInvalidForeignCurrency(): void
{
- if ((int)$this->destinationCurrency->id === (int)$this->sourceCurrency->id) {
+ if ($this->destinationCurrency->id === $this->sourceCurrency->id) {
// update both transactions to match:
- $this->sourceTransaction->foreign_amount = null;
- $this->sourceTransaction->foreign_currency_id = null;
+ $this->sourceTransaction->foreign_amount = null;
+ $this->sourceTransaction->foreign_currency_id = null;
$this->destinationTransaction->foreign_amount = null;
$this->destinationTransaction->foreign_currency_id = null;
@@ -458,7 +408,7 @@ class TransferCurrenciesCorrections extends Command
*/
private function fixMismatchedForeignCurrency(): void
{
- if ((int)$this->sourceCurrency->id !== (int)$this->destinationCurrency->id) {
+ if ($this->sourceCurrency->id !== $this->destinationCurrency->id) {
$this->sourceTransaction->transaction_currency_id = $this->sourceCurrency->id;
$this->sourceTransaction->foreign_currency_id = $this->destinationCurrency->id;
$this->destinationTransaction->transaction_currency_id = $this->sourceCurrency->id;
@@ -466,7 +416,7 @@ class TransferCurrenciesCorrections extends Command
$this->sourceTransaction->save();
$this->destinationTransaction->save();
- $this->count++;
+ ++$this->count;
$this->friendlyInfo(
sprintf('Verified foreign currency ID of transaction #%d and #%d', $this->sourceTransaction->id, $this->destinationTransaction->id)
);
@@ -480,9 +430,9 @@ class TransferCurrenciesCorrections extends Command
private function fixSourceNullForeignAmount(): void
{
if (null === $this->sourceTransaction->foreign_amount && null !== $this->destinationTransaction->foreign_amount) {
- $this->sourceTransaction->foreign_amount = bcmul((string)$this->destinationTransaction->foreign_amount, '-1');
+ $this->sourceTransaction->foreign_amount = bcmul($this->destinationTransaction->foreign_amount, '-1');
$this->sourceTransaction->save();
- $this->count++;
+ ++$this->count;
$this->friendlyInfo(
sprintf(
'Restored foreign amount of source transaction #%d to %s',
@@ -500,9 +450,9 @@ class TransferCurrenciesCorrections extends Command
private function fixDestNullForeignAmount(): void
{
if (null === $this->destinationTransaction->foreign_amount && null !== $this->sourceTransaction->foreign_amount) {
- $this->destinationTransaction->foreign_amount = bcmul((string)$this->sourceTransaction->foreign_amount, '-1');
+ $this->destinationTransaction->foreign_amount = bcmul($this->sourceTransaction->foreign_amount, '-1');
$this->destinationTransaction->save();
- $this->count++;
+ ++$this->count;
$this->friendlyInfo(
sprintf(
'Restored foreign amount of destination transaction #%d to %s',
@@ -515,12 +465,10 @@ class TransferCurrenciesCorrections extends Command
/**
* This method makes sure that the transaction journal uses the currency given in the source transaction.
- *
- * @param TransactionJournal $journal
*/
private function fixTransactionJournalCurrency(TransactionJournal $journal): void
{
- if ((int)$journal->transaction_currency_id !== (int)$this->sourceCurrency->id) {
+ if ((int)$journal->transaction_currency_id !== $this->sourceCurrency->id) {
$oldCurrencyCode = $journal->transactionCurrency->code ?? '(nothing)';
$journal->transaction_currency_id = $this->sourceCurrency->id;
$message = sprintf(
@@ -530,15 +478,12 @@ class TransferCurrenciesCorrections extends Command
$this->sourceCurrency->code,
$oldCurrencyCode
);
- $this->count++;
+ ++$this->count;
$this->friendlyInfo($message);
$journal->save();
}
}
- /**
- *
- */
private function markAsExecuted(): void
{
app('fireflyconfig')->set(self::CONFIG_NAME, true);
diff --git a/app/Console/Commands/Upgrade/UpgradeCurrencyPreferences.php b/app/Console/Commands/Upgrade/UpgradeCurrencyPreferences.php
new file mode 100644
index 0000000000..ff59b5169c
--- /dev/null
+++ b/app/Console/Commands/Upgrade/UpgradeCurrencyPreferences.php
@@ -0,0 +1,151 @@
+.
+ */
+
+declare(strict_types=1);
+
+namespace FireflyIII\Console\Commands\Upgrade;
+
+use FireflyIII\Console\Commands\ShowsFriendlyMessages;
+use FireflyIII\Models\Preference;
+use FireflyIII\Models\TransactionCurrency;
+use FireflyIII\Models\UserGroup;
+use FireflyIII\User;
+use Illuminate\Console\Command;
+use Illuminate\Support\Collection;
+
+/**
+ * Class UpgradeCurrencyPreferences
+ */
+class UpgradeCurrencyPreferences extends Command
+{
+ use ShowsFriendlyMessages;
+
+ public const string CONFIG_NAME = '610_upgrade_currency_prefs';
+
+ protected $description = 'Upgrade user currency preferences';
+
+ protected $signature = 'firefly-iii:upgrade-currency-preferences {--F|force : Force the execution of this command.}';
+
+ /**
+ * Execute the console command.
+ */
+ public function handle(): int
+ {
+ if ($this->isExecuted() && true !== $this->option('force')) {
+ $this->friendlyInfo('This command has already been executed.');
+
+ return 0;
+ }
+ $this->runUpgrade();
+
+ $this->friendlyPositive('Currency preferences migrated.');
+
+ $this->markAsExecuted();
+
+ return 0;
+ }
+
+ private function isExecuted(): bool
+ {
+ $configVar = app('fireflyconfig')->get(self::CONFIG_NAME, false);
+ if (null !== $configVar) {
+ return (bool)$configVar->data;
+ }
+
+ return false;
+ }
+
+ private function runUpgrade(): void
+ {
+ $groups = UserGroup::get();
+
+ /** @var UserGroup $group */
+ foreach ($groups as $group) {
+ $this->upgradeGroupPreferences($group);
+ }
+
+ $users = User::get();
+
+ /** @var User $user */
+ foreach ($users as $user) {
+ $this->upgradeUserPreferences($user);
+ }
+ }
+
+ private function upgradeGroupPreferences(UserGroup $group): void
+ {
+ $currencies = TransactionCurrency::get();
+ $enabled = new Collection();
+
+ /** @var TransactionCurrency $currency */
+ foreach ($currencies as $currency) {
+ if ($currency->enabled) {
+ $enabled->push($currency);
+ }
+ }
+ $group->currencies()->sync($enabled->pluck('id')->toArray());
+ }
+
+ private function upgradeUserPreferences(User $user): void
+ {
+ $currencies = TransactionCurrency::get();
+ $enabled = new Collection();
+
+ /** @var TransactionCurrency $currency */
+ foreach ($currencies as $currency) {
+ if ($currency->enabled) {
+ $enabled->push($currency);
+ }
+ }
+ $user->currencies()->sync($enabled->pluck('id')->toArray());
+
+ // set the default currency for the user and for the group:
+ $preference = $this->getPreference($user);
+ $defaultCurrency = TransactionCurrency::where('code', $preference)->first();
+ if (null === $defaultCurrency) {
+ // get EUR
+ $defaultCurrency = TransactionCurrency::where('code', 'EUR')->first();
+ }
+ $user->currencies()->updateExistingPivot($defaultCurrency->id, ['user_default' => true]);
+ $user->userGroup->currencies()->updateExistingPivot($defaultCurrency->id, ['group_default' => true]);
+ }
+
+ private function getPreference(User $user): string
+ {
+ $preference = Preference::where('user_id', $user->id)->where('name', 'currencyPreference')->first(['id', 'user_id', 'name', 'data', 'updated_at', 'created_at']);
+
+ if (null === $preference) {
+ return 'EUR';
+ }
+
+ if (null !== $preference->data && !is_array($preference->data)) {
+ return (string)$preference->data;
+ }
+
+ return 'EUR';
+ }
+
+ private function markAsExecuted(): void
+ {
+ app('fireflyconfig')->set(self::CONFIG_NAME, true);
+ }
+}
diff --git a/app/Console/Commands/Upgrade/UpgradeDatabase.php b/app/Console/Commands/Upgrade/UpgradeDatabase.php
index 45f073768f..bf701b585b 100644
--- a/app/Console/Commands/Upgrade/UpgradeDatabase.php
+++ b/app/Console/Commands/Upgrade/UpgradeDatabase.php
@@ -25,14 +25,11 @@ namespace FireflyIII\Console\Commands\Upgrade;
set_time_limit(0);
-use Artisan;
use FireflyIII\Console\Commands\ShowsFriendlyMessages;
use Illuminate\Console\Command;
/**
* Class UpgradeDatabase
- *
-
*/
class UpgradeDatabase extends Command
{
@@ -43,8 +40,6 @@ class UpgradeDatabase extends Command
/**
* Execute the console command.
- *
- * @return int
*/
public function handle(): int
{
@@ -72,6 +67,7 @@ class UpgradeDatabase extends Command
// also just in case, some integrity commands:
'firefly-iii:create-group-memberships',
'firefly-iii:upgrade-group-information',
+ 'firefly-iii:upgrade-currency-preferences',
];
$args = [];
if ($this->option('force')) {
@@ -89,9 +85,6 @@ class UpgradeDatabase extends Command
return 0;
}
- /**
- * @return void
- */
private function callInitialCommands(): void
{
$this->call('migrate', ['--seed' => true, '--force' => true, '--no-interaction' => true]);
diff --git a/app/Console/Commands/Upgrade/UpgradeLiabilities.php b/app/Console/Commands/Upgrade/UpgradeLiabilities.php
index 3723b2858d..0f36506a8e 100644
--- a/app/Console/Commands/Upgrade/UpgradeLiabilities.php
+++ b/app/Console/Commands/Upgrade/UpgradeLiabilities.php
@@ -33,8 +33,6 @@ use FireflyIII\Repositories\Account\AccountRepositoryInterface;
use FireflyIII\Services\Internal\Support\CreditRecalculateService;
use FireflyIII\User;
use Illuminate\Console\Command;
-use Psr\Container\ContainerExceptionInterface;
-use Psr\Container\NotFoundExceptionInterface;
/**
* Class UpgradeLiabilities
@@ -43,16 +41,12 @@ class UpgradeLiabilities extends Command
{
use ShowsFriendlyMessages;
- public const CONFIG_NAME = '560_upgrade_liabilities';
- protected $description = 'Upgrade liabilities to new 5.6.0 structure.';
- protected $signature = 'firefly-iii:upgrade-liabilities {--F|force : Force the execution of this command.}';
+ public const string CONFIG_NAME = '560_upgrade_liabilities';
+ protected $description = 'Upgrade liabilities to new 5.6.0 structure.';
+ protected $signature = 'firefly-iii:upgrade-liabilities {--F|force : Force the execution of this command.}';
/**
* Execute the console command.
- *
- * @return int
- * @throws ContainerExceptionInterface
- * @throws NotFoundExceptionInterface
*/
public function handle(): int
{
@@ -64,14 +58,10 @@ class UpgradeLiabilities extends Command
$this->upgradeLiabilities();
$this->markAsExecuted();
+
return 0;
}
- /**
- * @return bool
- * @throws ContainerExceptionInterface
- * @throws NotFoundExceptionInterface
- */
private function isExecuted(): bool
{
$configVar = app('fireflyconfig')->get(self::CONFIG_NAME, false);
@@ -82,27 +72,24 @@ class UpgradeLiabilities extends Command
return false;
}
- /**
- *
- */
private function upgradeLiabilities(): void
{
$users = User::get();
+
/** @var User $user */
foreach ($users as $user) {
$this->upgradeForUser($user);
}
}
- /**
- * @param User $user
- */
private function upgradeForUser(User $user): void
{
$accounts = $user->accounts()
- ->leftJoin('account_types', 'account_types.id', '=', 'accounts.account_type_id')
- ->whereIn('account_types.type', config('firefly.valid_liabilities'))
- ->get(['accounts.*']);
+ ->leftJoin('account_types', 'account_types.id', '=', 'accounts.account_type_id')
+ ->whereIn('account_types.type', config('firefly.valid_liabilities'))
+ ->get(['accounts.*'])
+ ;
+
/** @var Account $account */
foreach ($accounts as $account) {
$this->upgradeLiability($account);
@@ -112,13 +99,10 @@ class UpgradeLiabilities extends Command
}
}
- /**
- * @param Account $account
- */
private function upgradeLiability(Account $account): void
{
/** @var AccountRepositoryInterface $repository */
- $repository = app(AccountRepositoryInterface::class);
+ $repository = app(AccountRepositoryInterface::class);
$repository->setUser($account->user);
// get opening balance, and correct if necessary.
@@ -129,7 +113,7 @@ class UpgradeLiabilities extends Command
}
// add liability direction property (if it does not yet exist!)
- $value = $repository->getMetaValue($account, 'liability_direction');
+ $value = $repository->getMetaValue($account, 'liability_direction');
if (null === $value) {
/** @var AccountMetaFactory $factory */
$factory = app(AccountMetaFactory::class);
@@ -137,10 +121,6 @@ class UpgradeLiabilities extends Command
}
}
- /**
- * @param Account $account
- * @param TransactionJournal $openingBalance
- */
private function correctOpeningBalance(Account $account, TransactionJournal $openingBalance): void
{
$source = $this->getSourceTransaction($openingBalance);
@@ -149,9 +129,9 @@ class UpgradeLiabilities extends Command
return;
}
// source MUST be the liability.
- if ((int)$destination->account_id === (int)$account->id) {
+ if ($destination->account_id === $account->id) {
// so if not, switch things around:
- $sourceAccountId = (int)$source->account_id;
+ $sourceAccountId = $source->account_id;
$source->account_id = $destination->account_id;
$destination->account_id = $sourceAccountId;
$source->save();
@@ -159,29 +139,16 @@ class UpgradeLiabilities extends Command
}
}
- /**
- * @param TransactionJournal $journal
- *
- * @return Transaction|null
- */
private function getSourceTransaction(TransactionJournal $journal): ?Transaction
{
return $journal->transactions()->where('amount', '<', 0)->first();
}
- /**
- * @param TransactionJournal $journal
- *
- * @return Transaction|null
- */
private function getDestinationTransaction(TransactionJournal $journal): ?Transaction
{
return $journal->transactions()->where('amount', '>', 0)->first();
}
- /**
- *
- */
private function markAsExecuted(): void
{
app('fireflyconfig')->set(self::CONFIG_NAME, true);
diff --git a/app/Console/Commands/Upgrade/UpgradeLiabilitiesEight.php b/app/Console/Commands/Upgrade/UpgradeLiabilitiesEight.php
index ccd8e4721b..0fb2c9bb84 100644
--- a/app/Console/Commands/Upgrade/UpgradeLiabilitiesEight.php
+++ b/app/Console/Commands/Upgrade/UpgradeLiabilitiesEight.php
@@ -26,7 +26,6 @@ namespace FireflyIII\Console\Commands\Upgrade;
use FireflyIII\Console\Commands\ShowsFriendlyMessages;
use FireflyIII\Models\Account;
-use FireflyIII\Models\AccountType;
use FireflyIII\Models\Transaction;
use FireflyIII\Models\TransactionJournal;
use FireflyIII\Models\TransactionType;
@@ -35,9 +34,6 @@ use FireflyIII\Services\Internal\Destroy\TransactionGroupDestroyService;
use FireflyIII\Services\Internal\Support\CreditRecalculateService;
use FireflyIII\User;
use Illuminate\Console\Command;
-use Illuminate\Support\Facades\Log;
-use Psr\Container\ContainerExceptionInterface;
-use Psr\Container\NotFoundExceptionInterface;
/**
* Class UpgradeLiabilitiesEight
@@ -46,16 +42,12 @@ class UpgradeLiabilitiesEight extends Command
{
use ShowsFriendlyMessages;
- public const CONFIG_NAME = '600_upgrade_liabilities';
- protected $description = 'Upgrade liabilities to new 6.0.0 structure.';
- protected $signature = 'firefly-iii:liabilities-600 {--F|force : Force the execution of this command.}';
+ public const string CONFIG_NAME = '600_upgrade_liabilities';
+ protected $description = 'Upgrade liabilities to new 6.0.0 structure.';
+ protected $signature = 'firefly-iii:liabilities-600 {--F|force : Force the execution of this command.}';
/**
* Execute the console command.
- *
- * @return int
- * @throws ContainerExceptionInterface
- * @throws NotFoundExceptionInterface
*/
public function handle(): int
{
@@ -70,11 +62,6 @@ class UpgradeLiabilitiesEight extends Command
return 0;
}
- /**
- * @return bool
- * @throws ContainerExceptionInterface
- * @throws NotFoundExceptionInterface
- */
private function isExecuted(): bool
{
$configVar = app('fireflyconfig')->get(self::CONFIG_NAME, false);
@@ -85,27 +72,24 @@ class UpgradeLiabilitiesEight extends Command
return false;
}
- /**
- *
- */
private function upgradeLiabilities(): void
{
$users = User::get();
+
/** @var User $user */
foreach ($users as $user) {
$this->upgradeForUser($user);
}
}
- /**
- * @param User $user
- */
private function upgradeForUser(User $user): void
{
$accounts = $user->accounts()
- ->leftJoin('account_types', 'account_types.id', '=', 'accounts.account_type_id')
- ->whereIn('account_types.type', config('firefly.valid_liabilities'))
- ->get(['accounts.*']);
+ ->leftJoin('account_types', 'account_types.id', '=', 'accounts.account_type_id')
+ ->whereIn('account_types.type', config('firefly.valid_liabilities'))
+ ->get(['accounts.*'])
+ ;
+
/** @var Account $account */
foreach ($accounts as $account) {
$this->upgradeLiability($account);
@@ -115,16 +99,13 @@ class UpgradeLiabilitiesEight extends Command
}
}
- /**
- * @param Account $account
- */
private function upgradeLiability(Account $account): void
{
/** @var AccountRepositoryInterface $repository */
$repository = app(AccountRepositoryInterface::class);
$repository->setUser($account->user);
- $direction = $repository->getMetaValue($account, 'liability_direction');
+ $direction = $repository->getMetaValue($account, 'liability_direction');
if ('credit' === $direction && $this->hasBadOpening($account)) {
$this->deleteCreditTransaction($account);
$this->reverseOpeningBalance($account);
@@ -138,26 +119,23 @@ class UpgradeLiabilitiesEight extends Command
}
}
- /**
- * @param Account $account
- *
- * @return bool
- */
private function hasBadOpening(Account $account): bool
{
$openingBalanceType = TransactionType::whereType(TransactionType::OPENING_BALANCE)->first();
$liabilityType = TransactionType::whereType(TransactionType::LIABILITY_CREDIT)->first();
$openingJournal = TransactionJournal::leftJoin('transactions', 'transactions.transaction_journal_id', '=', 'transaction_journals.id')
- ->where('transactions.account_id', $account->id)
- ->where('transaction_journals.transaction_type_id', $openingBalanceType->id)
- ->first(['transaction_journals.*']);
+ ->where('transactions.account_id', $account->id)
+ ->where('transaction_journals.transaction_type_id', $openingBalanceType->id)
+ ->first(['transaction_journals.*'])
+ ;
if (null === $openingJournal) {
return false;
}
- $liabilityJournal = TransactionJournal::leftJoin('transactions', 'transactions.transaction_journal_id', '=', 'transaction_journals.id')
- ->where('transactions.account_id', $account->id)
- ->where('transaction_journals.transaction_type_id', $liabilityType->id)
- ->first(['transaction_journals.*']);
+ $liabilityJournal = TransactionJournal::leftJoin('transactions', 'transactions.transaction_journal_id', '=', 'transaction_journals.id')
+ ->where('transactions.account_id', $account->id)
+ ->where('transaction_journals.transaction_type_id', $liabilityType->id)
+ ->first(['transaction_journals.*'])
+ ;
if (null === $liabilityJournal) {
return false;
}
@@ -168,18 +146,14 @@ class UpgradeLiabilitiesEight extends Command
return true;
}
- /**
- * @param Account $account
- *
- * @return void
- */
private function deleteCreditTransaction(Account $account): void
{
$liabilityType = TransactionType::whereType(TransactionType::LIABILITY_CREDIT)->first();
$liabilityJournal = TransactionJournal::leftJoin('transactions', 'transactions.transaction_journal_id', '=', 'transaction_journals.id')
- ->where('transactions.account_id', $account->id)
- ->where('transaction_journals.transaction_type_id', $liabilityType->id)
- ->first(['transaction_journals.*']);
+ ->where('transactions.account_id', $account->id)
+ ->where('transaction_journals.transaction_type_id', $liabilityType->id)
+ ->first(['transaction_journals.*'])
+ ;
if (null !== $liabilityJournal) {
$group = $liabilityJournal->transactionGroup;
$service = new TransactionGroupDestroyService();
@@ -189,24 +163,23 @@ class UpgradeLiabilitiesEight extends Command
}
}
- /**
- * @param Account $account
- *
- * @return void
- */
private function reverseOpeningBalance(Account $account): void
{
$openingBalanceType = TransactionType::whereType(TransactionType::OPENING_BALANCE)->first();
+
/** @var TransactionJournal $openingJournal */
- $openingJournal = TransactionJournal::leftJoin('transactions', 'transactions.transaction_journal_id', '=', 'transaction_journals.id')
- ->where('transactions.account_id', $account->id)
- ->where('transaction_journals.transaction_type_id', $openingBalanceType->id)
- ->first(['transaction_journals.*']);
- /** @var Transaction|null $source */
- $source = $openingJournal->transactions()->where('amount', '<', 0)->first();
- /** @var Transaction|null $dest */
- $dest = $openingJournal->transactions()->where('amount', '>', 0)->first();
- if ($source && $dest) {
+ $openingJournal = TransactionJournal::leftJoin('transactions', 'transactions.transaction_journal_id', '=', 'transaction_journals.id')
+ ->where('transactions.account_id', $account->id)
+ ->where('transaction_journals.transaction_type_id', $openingBalanceType->id)
+ ->first(['transaction_journals.*'])
+ ;
+
+ /** @var null|Transaction $source */
+ $source = $openingJournal->transactions()->where('amount', '<', 0)->first();
+
+ /** @var null|Transaction $dest */
+ $dest = $openingJournal->transactions()->where('amount', '>', 0)->first();
+ if (null !== $source && null !== $dest) {
$sourceId = $source->account_id;
$destId = $dest->account_id;
$dest->account_id = $sourceId;
@@ -216,53 +189,49 @@ class UpgradeLiabilitiesEight extends Command
return;
}
- Log::warning('Did not find opening balance.');
+ app('log')->warning('Did not find opening balance.');
}
- /**
- * @param $account
- *
- * @return int
- */
- private function deleteTransactions($account): int
+ private function deleteTransactions(Account $account): int
{
$count = 0;
$journals = TransactionJournal::leftJoin('transactions', 'transaction_journals.id', '=', 'transactions.transaction_journal_id')
- ->where('transactions.account_id', $account->id)->get(['transaction_journals.*']);
+ ->where('transactions.account_id', $account->id)->get(['transaction_journals.*'])
+ ;
+
/** @var TransactionJournal $journal */
foreach ($journals as $journal) {
- $delete = false;
- /** @var Transaction $source */
- $source = $journal->transactions()->where('amount', '<', 0)->first();
- /** @var Transaction $dest */
- $dest = $journal->transactions()->where('amount', '>', 0)->first();
+ // $delete = false;
+ // /** @var Transaction $source */
+ // $source = $journal->transactions()->where('amount', '<', 0)->first();
+ // /** @var Transaction $dest */
+ // $dest = $journal->transactions()->where('amount', '>', 0)->first();
- // if source is this liability and destination is expense, remove transaction.
- // if source is revenue and destination is liability, remove transaction.
- if ((int)$source->account_id === (int)$account->id && $dest->account->accountType->type === AccountType::EXPENSE) {
- $delete = true;
- }
- if ((int)$dest->account_id === (int)$account->id && $source->account->accountType->type === AccountType::REVENUE) {
- $delete = true;
- }
+ /**
+ * // if source is this liability and destination is expense, remove transaction.
+ * // if source is revenue and destination is liability, remove transaction.
+ * if ($source->account_id === $account->id && $dest->account->accountType->type === AccountType::EXPENSE) {
+ * $delete = true;
+ * }
+ * if ($dest->account_id === $account->id && $source->account->accountType->type === AccountType::REVENUE) {
+ * $delete = true;
+ * }
+ *
+ * // overruled. No transaction will be deleted, ever.
+ * // code is kept in place, so I can revisit my reasoning.
+ * $delete = false;
+ */
- // overruled. No transaction will be deleted, ever.
- // code is kept in place so i can revisit my reasoning.
- $delete = false;
-
- if ($delete) {
- $service = app(TransactionGroupDestroyService::class);
- $service->destroy($journal->transactionGroup);
- $count++;
- }
+ // if ($delete) {
+ $service = app(TransactionGroupDestroyService::class);
+ $service->destroy($journal->transactionGroup);
+ ++$count;
+ // }
}
return $count;
}
- /**
- *
- */
private function markAsExecuted(): void
{
app('fireflyconfig')->set(self::CONFIG_NAME, true);
diff --git a/app/Console/Commands/Upgrade/UpgradeSkeleton.php.stub b/app/Console/Commands/Upgrade/UpgradeSkeleton.php.stub
index 4ba6803d78..437c42e220 100644
--- a/app/Console/Commands/Upgrade/UpgradeSkeleton.php.stub
+++ b/app/Console/Commands/Upgrade/UpgradeSkeleton.php.stub
@@ -10,18 +10,11 @@ use Illuminate\Console\Command;
*/
class UpgradeSkeleton extends Command
{
- public const CONFIG_NAME = '480_some_name';
- /**
- * The console command description.
- *
- * @var string
- */
+ use ShowsFriendlyMessages;
+ public const string CONFIG_NAME = '480_some_name';
+
protected $description = 'SOME DESCRIPTION';
- /**
- * The name and signature of the console command.
- *
- * @var string
- */
+
protected $signature = 'firefly-iii:UPGRSKELETON {--F|force : Force the execution of this command.}';
/**
diff --git a/app/Console/Commands/VerifiesAccessToken.php b/app/Console/Commands/VerifiesAccessToken.php
index d6c45610c3..47ddcf88fa 100644
--- a/app/Console/Commands/VerifiesAccessToken.php
+++ b/app/Console/Commands/VerifiesAccessToken.php
@@ -26,24 +26,21 @@ namespace FireflyIII\Console\Commands;
use FireflyIII\Exceptions\FireflyException;
use FireflyIII\Repositories\User\UserRepositoryInterface;
use FireflyIII\User;
-use Illuminate\Support\Facades\Log;
/**
* Trait VerifiesAccessToken.
*
* Verifies user access token for sensitive commands.
- *
-
*/
trait VerifiesAccessToken
{
/**
- * @return User
* @throws FireflyException
*/
public function getUser(): User
{
- $userId = (int)$this->option('user');
+ $userId = (int)$this->option('user');
+
/** @var UserRepositoryInterface $repository */
$repository = app(UserRepositoryInterface::class);
$user = $repository->find($userId);
@@ -57,7 +54,7 @@ trait VerifiesAccessToken
/**
* Abstract method to make sure trait knows about method "option".
*
- * @param string|null $key
+ * @param null|string $key
*
* @return mixed
*/
@@ -66,31 +63,31 @@ trait VerifiesAccessToken
/**
* Returns false when given token does not match given user token.
*
- * @return bool
* @throws FireflyException
*/
protected function verifyAccessToken(): bool
{
- $userId = (int)$this->option('user');
- $token = (string)$this->option('token');
+ $userId = (int)$this->option('user');
+ $token = (string)$this->option('token');
+
/** @var UserRepositoryInterface $repository */
- $repository = app(UserRepositoryInterface::class);
- $user = $repository->find($userId);
+ $repository = app(UserRepositoryInterface::class);
+ $user = $repository->find($userId);
if (null === $user) {
- Log::error(sprintf('verifyAccessToken(): no such user for input "%d"', $userId));
+ app('log')->error(sprintf('verifyAccessToken(): no such user for input "%d"', $userId));
return false;
}
$accessToken = app('preferences')->getForUser($user, 'access_token');
if (null === $accessToken) {
- Log::error(sprintf('User #%d has no access token, so cannot access command line options.', $userId));
+ app('log')->error(sprintf('User #%d has no access token, so cannot access command line options.', $userId));
return false;
}
if ($accessToken->data !== $token) {
- Log::error(sprintf('Invalid access token for user #%d.', $userId));
- Log::error(sprintf('Token given is "%s", expected something else.', $token));
+ app('log')->error(sprintf('Invalid access token for user #%d.', $userId));
+ app('log')->error(sprintf('Token given is "%s", expected something else.', $token));
return false;
}
diff --git a/app/Console/Kernel.php b/app/Console/Kernel.php
index 3282712a95..8e2776a54e 100644
--- a/app/Console/Kernel.php
+++ b/app/Console/Kernel.php
@@ -26,12 +26,9 @@ namespace FireflyIII\Console;
use Illuminate\Console\Scheduling\Schedule;
use Illuminate\Foundation\Console\Kernel as ConsoleKernel;
-use Illuminate\Support\Facades\Log;
/**
* File to make sure commands work.
- *
-
*/
class Kernel extends ConsoleKernel
{
@@ -40,21 +37,19 @@ class Kernel extends ConsoleKernel
*/
protected function commands(): void
{
- $this->load(__DIR__ . '/Commands');
+ $this->load(__DIR__.'/Commands');
require base_path('routes/console.php');
}
/**
* Define the application's command schedule.
- *
- * @param Schedule $schedule
*/
protected function schedule(Schedule $schedule): void
{
$schedule->call(
- static function () {
- Log::error(
+ static function (): void {
+ app('log')->error(
'Firefly III no longer users the Laravel scheduler to do cron jobs! Please read the instructions at https://docs.firefly-iii.org/'
);
echo "\n";
diff --git a/app/Enums/ClauseType.php b/app/Enums/ClauseType.php
index 6b78943a0e..47f50192f8 100644
--- a/app/Enums/ClauseType.php
+++ b/app/Enums/ClauseType.php
@@ -29,7 +29,7 @@ namespace FireflyIII\Enums;
*/
class ClauseType
{
- public const TRANSACTION = 'transaction';
- public const UPDATE = 'update';
- public const WHERE = 'where';
+ public const string TRANSACTION = 'transaction';
+ public const string UPDATE = 'update';
+ public const string WHERE = 'where';
}
diff --git a/frontend/src/components/models.ts b/app/Enums/SearchDirection.php
similarity index 78%
rename from frontend/src/components/models.ts
rename to app/Enums/SearchDirection.php
index 440b03cfdc..ea87e1d481 100644
--- a/frontend/src/components/models.ts
+++ b/app/Enums/SearchDirection.php
@@ -1,6 +1,7 @@
+.
*/
-export interface Todo {
- id: number;
- content: string;
-}
+declare(strict_types=1);
-export interface Meta {
- totalCount: number;
+namespace FireflyIII\Enums;
+
+enum SearchDirection
+{
+ case SOURCE;
+ case DESTINATION;
+ case BOTH;
}
diff --git a/frontend/src/api/preferences/index.js b/app/Enums/StringPosition.php
similarity index 70%
rename from frontend/src/api/preferences/index.js
rename to app/Enums/StringPosition.php
index fac50967d5..19745d0f8a 100644
--- a/frontend/src/api/preferences/index.js
+++ b/app/Enums/StringPosition.php
@@ -1,6 +1,7 @@
+.
*/
-import {api} from "boot/axios";
+declare(strict_types=1);
-export default class Preferences {
- getByName(name) {
- return api.get('/api/v1/preferences/' + name);
- }
+namespace FireflyIII\Enums;
- postByName(name, value) {
- return api.post('/api/v1/preferences', {name: name, data: value});
- }
+/**
+ * Class StringPosition
+ *
+ * stringPosition: 1 = start (default), 2 = end, 3 = contains, 4 = is
+ */
+enum StringPosition
+{
+ case STARTS;
+ case ENDS;
+ case CONTAINS;
+ case IS;
}
diff --git a/app/Enums/UserRoleEnum.php b/app/Enums/UserRoleEnum.php
index af98413c55..8906fb3535 100644
--- a/app/Enums/UserRoleEnum.php
+++ b/app/Enums/UserRoleEnum.php
@@ -30,13 +30,13 @@ namespace FireflyIII\Enums;
enum UserRoleEnum: string
{
// most basic rights, cannot see other members, can see everything else.
- case READ_ONLY = 'ro';
+ case READ_ONLY = 'ro';
// required to even USE the group properly (in this order)
- case MANAGE_TRANSACTIONS = 'mng_trx';
+ case MANAGE_TRANSACTIONS = 'mng_trx';
// required to edit, add or change categories/tags/object-groups
- case MANAGE_META = 'mng_meta';
+ case MANAGE_META = 'mng_meta';
// manage other financial objects:
case MANAGE_BUDGETS = 'mng_budgets';
@@ -49,14 +49,14 @@ enum UserRoleEnum: string
case MANAGE_CURRENCIES = 'mng_currencies';
// view and generate reports
- case VIEW_REPORTS = 'view_reports';
+ case VIEW_REPORTS = 'view_reports';
// view memberships. needs FULL to manage them.
- case VIEW_MEMBERSHIPS = 'view_memberships';
+ case VIEW_MEMBERSHIPS = 'view_memberships';
// everything the creator can, except remove/change original creator and delete group
- case FULL = 'full';
+ case FULL = 'full';
// reserved for original creator
- case OWNER = 'owner';
+ case OWNER = 'owner';
}
diff --git a/app/Enums/WebhookDelivery.php b/app/Enums/WebhookDelivery.php
index c09f3b1b07..3322d761e8 100644
--- a/app/Enums/WebhookDelivery.php
+++ b/app/Enums/WebhookDelivery.php
@@ -29,6 +29,6 @@ namespace FireflyIII\Enums;
*/
enum WebhookDelivery: int
{
- //case XML = 200;
+ // case XML = 200;
case JSON = 300;
}
diff --git a/app/Enums/WebhookTrigger.php b/app/Enums/WebhookTrigger.php
index 4e48851ba1..bdb2a58bf2 100644
--- a/app/Enums/WebhookTrigger.php
+++ b/app/Enums/WebhookTrigger.php
@@ -29,10 +29,10 @@ namespace FireflyIII\Enums;
*/
enum WebhookTrigger: int
{
- case STORE_TRANSACTION = 100;
- //case BEFORE_STORE_TRANSACTION = 101;
- case UPDATE_TRANSACTION = 110;
- //case BEFORE_UPDATE_TRANSACTION = 111;
+ case STORE_TRANSACTION = 100;
+ // case BEFORE_STORE_TRANSACTION = 101;
+ case UPDATE_TRANSACTION = 110;
+ // case BEFORE_UPDATE_TRANSACTION = 111;
case DESTROY_TRANSACTION = 120;
- //case BEFORE_DESTROY_TRANSACTION = 121;
+ // case BEFORE_DESTROY_TRANSACTION = 121;
}
diff --git a/app/Events/ActuallyLoggedIn.php b/app/Events/ActuallyLoggedIn.php
index 557dad3b38..6bb21a5a04 100644
--- a/app/Events/ActuallyLoggedIn.php
+++ b/app/Events/ActuallyLoggedIn.php
@@ -25,6 +25,7 @@ declare(strict_types=1);
namespace FireflyIII\Events;
use FireflyIII\User;
+use Illuminate\Contracts\Auth\Authenticatable;
use Illuminate\Queue\SerializesModels;
/**
@@ -36,11 +37,10 @@ class ActuallyLoggedIn extends Event
public User $user;
- /**
- * @param User $user
- */
- public function __construct(User $user)
+ public function __construct(null|Authenticatable|User $user)
{
- $this->user = $user;
+ if ($user instanceof User) {
+ $this->user = $user;
+ }
}
}
diff --git a/app/Events/Admin/InvitationCreated.php b/app/Events/Admin/InvitationCreated.php
index 3df959e956..c057b35b06 100644
--- a/app/Events/Admin/InvitationCreated.php
+++ b/app/Events/Admin/InvitationCreated.php
@@ -42,8 +42,6 @@ class InvitationCreated extends Event
/**
* Create a new event instance.
- *
- * @param InvitedUser $invitee
*/
public function __construct(InvitedUser $invitee)
{
diff --git a/app/Events/AdminRequestedTestMessage.php b/app/Events/AdminRequestedTestMessage.php
index 1c8d0fa1de..4f32c7841c 100644
--- a/app/Events/AdminRequestedTestMessage.php
+++ b/app/Events/AdminRequestedTestMessage.php
@@ -26,12 +26,9 @@ namespace FireflyIII\Events;
use FireflyIII\User;
use Illuminate\Queue\SerializesModels;
-use Illuminate\Support\Facades\Log;
/**
* Class AdminRequestedTestMessage.
- *
-
*/
class AdminRequestedTestMessage extends Event
{
@@ -41,12 +38,10 @@ class AdminRequestedTestMessage extends Event
/**
* Create a new event instance.
- *
- * @param User $user
*/
public function __construct(User $user)
{
- Log::debug(sprintf('Triggered AdminRequestedTestMessage for user #%d (%s)', $user->id, $user->email));
+ app('log')->debug(sprintf('Triggered AdminRequestedTestMessage for user #%d (%s)', $user->id, $user->email));
$this->user = $user;
}
}
diff --git a/app/Events/DestroyedTransactionGroup.php b/app/Events/DestroyedTransactionGroup.php
index febad99260..9911864c1e 100644
--- a/app/Events/DestroyedTransactionGroup.php
+++ b/app/Events/DestroyedTransactionGroup.php
@@ -26,12 +26,9 @@ namespace FireflyIII\Events;
use FireflyIII\Models\TransactionGroup;
use Illuminate\Queue\SerializesModels;
-use Illuminate\Support\Facades\Log;
/**
* Class DestroyedTransactionGroup.
- *
-
*/
class DestroyedTransactionGroup extends Event
{
@@ -41,12 +38,10 @@ class DestroyedTransactionGroup extends Event
/**
* Create a new event instance.
- *
- * @param TransactionGroup $transactionGroup
*/
public function __construct(TransactionGroup $transactionGroup)
{
- Log::debug(sprintf('Now in %s', __METHOD__));
+ app('log')->debug(sprintf('Now in %s', __METHOD__));
$this->transactionGroup = $transactionGroup;
}
}
diff --git a/app/Events/DestroyedTransactionLink.php b/app/Events/DestroyedTransactionLink.php
index fee5c47c9e..c4b748c83b 100644
--- a/app/Events/DestroyedTransactionLink.php
+++ b/app/Events/DestroyedTransactionLink.php
@@ -33,12 +33,10 @@ class DestroyedTransactionLink extends Event
{
use SerializesModels;
- private TransactionJournalLink $link; /// @phpstan-ignore-line PHPStan thinks this property is never read.
+ private TransactionJournalLink $link; // @phpstan-ignore-line
/**
* DestroyedTransactionLink constructor.
- *
- * @param TransactionJournalLink $link
*/
public function __construct(TransactionJournalLink $link)
{
diff --git a/app/Events/DetectedNewIPAddress.php b/app/Events/DetectedNewIPAddress.php
index 567bba32cc..3b2ba133be 100644
--- a/app/Events/DetectedNewIPAddress.php
+++ b/app/Events/DetectedNewIPAddress.php
@@ -38,9 +38,6 @@ class DetectedNewIPAddress extends Event
/**
* Create a new event instance. This event is triggered when a new user registers.
- *
- * @param User $user
- * @param string $ipAddress
*/
public function __construct(User $user, string $ipAddress)
{
diff --git a/app/Events/Event.php b/app/Events/Event.php
index ff329a8c3a..12c302afdb 100644
--- a/app/Events/Event.php
+++ b/app/Events/Event.php
@@ -26,9 +26,5 @@ namespace FireflyIII\Events;
/**
* Class Event.
- *
-
*/
-abstract class Event
-{
-}
+abstract class Event {}
diff --git a/app/Events/Model/BudgetLimit/Created.php b/app/Events/Model/BudgetLimit/Created.php
index e0133a3f21..2600c41632 100644
--- a/app/Events/Model/BudgetLimit/Created.php
+++ b/app/Events/Model/BudgetLimit/Created.php
@@ -1,6 +1,5 @@
budgetLimit = $budgetLimit;
diff --git a/app/Events/Model/BudgetLimit/Deleted.php b/app/Events/Model/BudgetLimit/Deleted.php
index 059d594ab5..06aab6e0ca 100644
--- a/app/Events/Model/BudgetLimit/Deleted.php
+++ b/app/Events/Model/BudgetLimit/Deleted.php
@@ -1,6 +1,5 @@
budgetLimit = $budgetLimit;
diff --git a/app/Events/Model/BudgetLimit/Updated.php b/app/Events/Model/BudgetLimit/Updated.php
index 828ae98a07..6429635ea0 100644
--- a/app/Events/Model/BudgetLimit/Updated.php
+++ b/app/Events/Model/BudgetLimit/Updated.php
@@ -1,6 +1,5 @@
budgetLimit = $budgetLimit;
diff --git a/app/Events/Model/PiggyBank/ChangedAmount.php b/app/Events/Model/PiggyBank/ChangedAmount.php
index 79d2068c30..9521641ab3 100644
--- a/app/Events/Model/PiggyBank/ChangedAmount.php
+++ b/app/Events/Model/PiggyBank/ChangedAmount.php
@@ -29,7 +29,6 @@ use FireflyIII\Models\PiggyBank;
use FireflyIII\Models\TransactionGroup;
use FireflyIII\Models\TransactionJournal;
use Illuminate\Queue\SerializesModels;
-use Illuminate\Support\Facades\Log;
/**
* Class ChangedAmount
@@ -45,15 +44,10 @@ class ChangedAmount extends Event
/**
* Create a new event instance.
- *
- * @param PiggyBank $piggyBank
- * @param string $amount
- * @param TransactionJournal|null $transactionJournal
- * @param TransactionGroup|null $transactionGroup
*/
public function __construct(PiggyBank $piggyBank, string $amount, ?TransactionJournal $transactionJournal, ?TransactionGroup $transactionGroup)
{
- Log::debug(sprintf('Created piggy bank event for piggy bank #%d with amount %s', $piggyBank->id, $amount));
+ app('log')->debug(sprintf('Created piggy bank event for piggy bank #%d with amount %s', $piggyBank->id, $amount));
$this->piggyBank = $piggyBank;
$this->transactionJournal = $transactionJournal;
$this->transactionGroup = $transactionGroup;
diff --git a/app/Events/Model/Rule/RuleActionFailedOnArray.php b/app/Events/Model/Rule/RuleActionFailedOnArray.php
index fe11bf9a0b..8c6ca6aa9d 100644
--- a/app/Events/Model/Rule/RuleActionFailedOnArray.php
+++ b/app/Events/Model/Rule/RuleActionFailedOnArray.php
@@ -1,6 +1,5 @@
debug('Created new RuleActionFailedOnArray');
diff --git a/app/Events/Model/Rule/RuleActionFailedOnObject.php b/app/Events/Model/Rule/RuleActionFailedOnObject.php
index a9df1869ee..bfc14bd78d 100644
--- a/app/Events/Model/Rule/RuleActionFailedOnObject.php
+++ b/app/Events/Model/Rule/RuleActionFailedOnObject.php
@@ -1,6 +1,5 @@
debug('Created new RuleActionFailedOnObject');
diff --git a/app/Events/NewVersionAvailable.php b/app/Events/NewVersionAvailable.php
index 9051f76e9c..db3626b490 100644
--- a/app/Events/NewVersionAvailable.php
+++ b/app/Events/NewVersionAvailable.php
@@ -37,8 +37,6 @@ class NewVersionAvailable extends Event
/**
* Create a new event instance. This event is triggered when a new version is available.
- *
- * @param string $message
*/
public function __construct(string $message)
{
diff --git a/app/Events/RegisteredUser.php b/app/Events/RegisteredUser.php
index 16e29abfd2..0a4d116d8f 100644
--- a/app/Events/RegisteredUser.php
+++ b/app/Events/RegisteredUser.php
@@ -29,8 +29,6 @@ use Illuminate\Queue\SerializesModels;
/**
* Class RegisteredUser.
- *
-
*/
class RegisteredUser extends Event
{
@@ -40,8 +38,6 @@ class RegisteredUser extends Event
/**
* Create a new event instance. This event is triggered when a new user registers.
- *
- * @param User $user
*/
public function __construct(User $user)
{
diff --git a/app/Events/RequestedNewPassword.php b/app/Events/RequestedNewPassword.php
index 5967426dcd..71634ce001 100644
--- a/app/Events/RequestedNewPassword.php
+++ b/app/Events/RequestedNewPassword.php
@@ -29,8 +29,6 @@ use Illuminate\Queue\SerializesModels;
/**
* Class RequestedNewPassword.
- *
-
*/
class RequestedNewPassword extends Event
{
@@ -38,17 +36,15 @@ class RequestedNewPassword extends Event
/** @var string The users IP address */
public $ipAddress;
+
/** @var string The token */
public $token;
+
/** @var User The user */
public $user;
/**
* Create a new event instance. This event is triggered when a users tries to reset his or her password.
- *
- * @param User $user
- * @param string $token
- * @param string $ipAddress
*/
public function __construct(User $user, string $token, string $ipAddress)
{
diff --git a/app/Events/RequestedReportOnJournals.php b/app/Events/RequestedReportOnJournals.php
index 8b9edbd7eb..01ed141159 100644
--- a/app/Events/RequestedReportOnJournals.php
+++ b/app/Events/RequestedReportOnJournals.php
@@ -29,12 +29,9 @@ use Illuminate\Broadcasting\PrivateChannel;
use Illuminate\Foundation\Events\Dispatchable;
use Illuminate\Queue\SerializesModels;
use Illuminate\Support\Collection;
-use Illuminate\Support\Facades\Log;
/**
* Class RequestedReportOnJournals
- *
-
*/
class RequestedReportOnJournals
{
@@ -47,13 +44,10 @@ class RequestedReportOnJournals
/**
* Create a new event instance.
- *
- * @param int $userId
- * @param Collection $groups
*/
public function __construct(int $userId, Collection $groups)
{
- Log::debug('In event RequestedReportOnJournals.');
+ app('log')->debug('In event RequestedReportOnJournals.');
$this->userId = $userId;
$this->groups = $groups;
}
diff --git a/app/Events/RequestedVersionCheckStatus.php b/app/Events/RequestedVersionCheckStatus.php
index 9379beacb3..63b9f4f898 100644
--- a/app/Events/RequestedVersionCheckStatus.php
+++ b/app/Events/RequestedVersionCheckStatus.php
@@ -29,21 +29,16 @@ use Illuminate\Queue\SerializesModels;
/**
* Class RequestedVersionCheckStatus
- *
-
*/
class RequestedVersionCheckStatus extends Event
{
use SerializesModels;
- /** @var User The user */
- public $user;
+ public User $user;
/**
* Create a new event instance. This event is triggered when Firefly III wants to know
* what the deal is with the version checker.
- *
- * @param User $user
*/
public function __construct(User $user)
{
diff --git a/app/Events/StoredAccount.php b/app/Events/StoredAccount.php
index d126dd3468..441afed64a 100644
--- a/app/Events/StoredAccount.php
+++ b/app/Events/StoredAccount.php
@@ -38,8 +38,6 @@ class StoredAccount extends Event
/**
* Create a new event instance.
- *
- * @param Account $account
*/
public function __construct(Account $account)
{
diff --git a/app/Events/StoredTransactionGroup.php b/app/Events/StoredTransactionGroup.php
index 40d65bf776..268525635f 100644
--- a/app/Events/StoredTransactionGroup.php
+++ b/app/Events/StoredTransactionGroup.php
@@ -29,8 +29,6 @@ use Illuminate\Queue\SerializesModels;
/**
* Class StoredTransactionGroup.
- *
-
*/
class StoredTransactionGroup extends Event
{
@@ -42,10 +40,6 @@ class StoredTransactionGroup extends Event
/**
* Create a new event instance.
- *
- * @param TransactionGroup $transactionGroup
- * @param bool $applyRules
- * @param bool $fireWebhooks
*/
public function __construct(TransactionGroup $transactionGroup, bool $applyRules, bool $fireWebhooks)
{
diff --git a/app/Events/TriggeredAuditLog.php b/app/Events/TriggeredAuditLog.php
index 95f7fe5b71..19d66b07da 100644
--- a/app/Events/TriggeredAuditLog.php
+++ b/app/Events/TriggeredAuditLog.php
@@ -42,6 +42,8 @@ class TriggeredAuditLog extends Event
/**
* Create a new event instance.
+ *
+ * @SuppressWarnings(PHPMD.ExcessiveParameterList)
*/
public function __construct(Model $changer, Model $auditable, string $field, mixed $before, mixed $after)
{
diff --git a/app/Events/UpdatedAccount.php b/app/Events/UpdatedAccount.php
index 66640720b2..3deceba692 100644
--- a/app/Events/UpdatedAccount.php
+++ b/app/Events/UpdatedAccount.php
@@ -38,8 +38,6 @@ class UpdatedAccount extends Event
/**
* Create a new event instance.
- *
- * @param Account $account
*/
public function __construct(Account $account)
{
diff --git a/app/Events/UpdatedTransactionGroup.php b/app/Events/UpdatedTransactionGroup.php
index b3a79a56f2..9827d81d06 100644
--- a/app/Events/UpdatedTransactionGroup.php
+++ b/app/Events/UpdatedTransactionGroup.php
@@ -29,8 +29,6 @@ use Illuminate\Queue\SerializesModels;
/**
* Class UpdatedTransactionGroup.
- *
-
*/
class UpdatedTransactionGroup extends Event
{
@@ -42,10 +40,6 @@ class UpdatedTransactionGroup extends Event
/**
* Create a new event instance.
- *
- * @param TransactionGroup $transactionGroup
- * @param bool $applyRules
- * @param bool $fireWebhooks
*/
public function __construct(TransactionGroup $transactionGroup, bool $applyRules, bool $fireWebhooks)
{
diff --git a/app/Events/UserChangedEmail.php b/app/Events/UserChangedEmail.php
index a71a4b7580..1d2e11fcf7 100644
--- a/app/Events/UserChangedEmail.php
+++ b/app/Events/UserChangedEmail.php
@@ -29,8 +29,6 @@ use Illuminate\Queue\SerializesModels;
/**
* Class UserChangedEmail.
- *
-
*/
class UserChangedEmail extends Event
{
@@ -42,10 +40,6 @@ class UserChangedEmail extends Event
/**
* UserChangedEmail constructor.
- *
- * @param User $user
- * @param string $newEmail
- * @param string $oldEmail
*/
public function __construct(User $user, string $newEmail, string $oldEmail)
{
diff --git a/app/Events/WarnUserAboutBill.php b/app/Events/WarnUserAboutBill.php
index d0673f5755..98b7d5c449 100644
--- a/app/Events/WarnUserAboutBill.php
+++ b/app/Events/WarnUserAboutBill.php
@@ -29,8 +29,6 @@ use Illuminate\Queue\SerializesModels;
/**
* Class WarnUserAboutBill.
- *
-
*/
class WarnUserAboutBill extends Event
{
@@ -40,11 +38,6 @@ class WarnUserAboutBill extends Event
public int $diff;
public string $field;
- /**
- * @param Bill $bill
- * @param string $field
- * @param int $diff
- */
public function __construct(Bill $bill, string $field, int $diff)
{
$this->bill = $bill;
diff --git a/app/Exceptions/BadHttpHeaderException.php b/app/Exceptions/BadHttpHeaderException.php
index 1ac5a5359c..19e1e5a7af 100644
--- a/app/Exceptions/BadHttpHeaderException.php
+++ b/app/Exceptions/BadHttpHeaderException.php
@@ -24,12 +24,7 @@ declare(strict_types=1);
namespace FireflyIII\Exceptions;
-use Exception;
-
-/**
- *
- */
-class BadHttpHeaderException extends Exception
+class BadHttpHeaderException extends \Exception
{
public int $statusCode = 406;
}
diff --git a/app/Exceptions/DuplicateTransactionException.php b/app/Exceptions/DuplicateTransactionException.php
index 28c614f53c..b8d6ece025 100644
--- a/app/Exceptions/DuplicateTransactionException.php
+++ b/app/Exceptions/DuplicateTransactionException.php
@@ -24,11 +24,7 @@ declare(strict_types=1);
namespace FireflyIII\Exceptions;
-use Exception;
-
/**
* Class DuplicateTransactionException
*/
-class DuplicateTransactionException extends Exception
-{
-}
+class DuplicateTransactionException extends \Exception {}
diff --git a/app/Exceptions/FireflyException.php b/app/Exceptions/FireflyException.php
index 9d57980b0e..18b3fb0a35 100644
--- a/app/Exceptions/FireflyException.php
+++ b/app/Exceptions/FireflyException.php
@@ -24,13 +24,7 @@ declare(strict_types=1);
namespace FireflyIII\Exceptions;
-use Exception;
-
/**
* Class FireflyException.
- *
-
*/
-class FireflyException extends Exception
-{
-}
+class FireflyException extends \Exception {}
diff --git a/app/Exceptions/GracefulNotFoundHandler.php b/app/Exceptions/GracefulNotFoundHandler.php
index 94ba81ec38..2f9ca2abf1 100644
--- a/app/Exceptions/GracefulNotFoundHandler.php
+++ b/app/Exceptions/GracefulNotFoundHandler.php
@@ -30,15 +30,9 @@ use FireflyIII\Models\TransactionGroup;
use FireflyIII\Models\TransactionJournal;
use FireflyIII\Models\TransactionType;
use FireflyIII\User;
-use Illuminate\Contracts\Foundation\Application;
use Illuminate\Foundation\Exceptions\Handler as ExceptionHandler;
-use Illuminate\Http\JsonResponse;
-use Illuminate\Http\RedirectResponse;
use Illuminate\Http\Request;
-use Illuminate\Routing\Redirector;
-use Illuminate\Support\Facades\Log;
use Symfony\Component\HttpFoundation\Response;
-use Throwable;
/**
* Class GracefulNotFoundHandler
@@ -48,19 +42,19 @@ class GracefulNotFoundHandler extends ExceptionHandler
/**
* Render an exception into an HTTP response.
*
- * @param Request $request
- * @param Throwable $e
+ * @param Request $request
*
- * @return Application|JsonResponse|\Illuminate\Http\Response|Redirector|RedirectResponse|Response
- * @throws Throwable
+ * @throws \Throwable
+ *
+ * @SuppressWarnings(PHPMD.CyclomaticComplexity)
*/
- public function render($request, Throwable $e)
+ public function render($request, \Throwable $e): Response
{
$route = $request->route();
if (null === $route) {
return parent::render($request, $e);
}
- $name = $route->getName();
+ $name = $route->getName();
if (!auth()->check()) {
return parent::render($request, $e);
}
@@ -70,57 +64,69 @@ class GracefulNotFoundHandler extends ExceptionHandler
app('log')->warning(sprintf('GracefulNotFoundHandler cannot handle route with name "%s"', $name));
return parent::render($request, $e);
+
case 'accounts.show':
case 'accounts.edit':
case 'accounts.show.all':
return $this->handleAccount($request, $e);
+
case 'transactions.show':
case 'transactions.edit':
return $this->handleGroup($request, $e);
+
case 'attachments.show':
case 'attachments.edit':
case 'attachments.download':
case 'attachments.view':
// redirect to original attachment holder.
return $this->handleAttachment($request, $e);
+
case 'bills.show':
$request->session()->reflash();
return redirect(route('bills.index'));
+
case 'currencies.show':
$request->session()->reflash();
return redirect(route('currencies.index'));
+
case 'budgets.show':
case 'budgets.edit':
case 'budgets.show.limit':
$request->session()->reflash();
return redirect(route('budgets.index'));
+
case 'piggy-banks.show':
$request->session()->reflash();
return redirect(route('piggy-banks.index'));
+
case 'recurring.show':
case 'recurring.edit':
$request->session()->reflash();
return redirect(route('recurring.index'));
+
case 'tags.show.all':
case 'tags.show':
case 'tags.edit':
$request->session()->reflash();
return redirect(route('tags.index'));
+
case 'categories.show':
case 'categories.show.all':
$request->session()->reflash();
return redirect(route('categories.index'));
+
case 'rules.edit':
$request->session()->reflash();
return redirect(route('rules.index'));
+
case 'transactions.mass.edit':
case 'transactions.mass.delete':
case 'transactions.bulk.edit':
@@ -135,29 +141,28 @@ class GracefulNotFoundHandler extends ExceptionHandler
}
/**
- * @param Request $request
- * @param Throwable $exception
- *
- * @return Response
- * @throws Throwable
+ * @throws \Throwable
*/
- private function handleAccount(Request $request, Throwable $exception)
+ private function handleAccount(Request $request, \Throwable $exception): Response
{
- Log::debug('404 page is probably a deleted account. Redirect to overview of account types.');
+ app('log')->debug('404 page is probably a deleted account. Redirect to overview of account types.');
+
/** @var User $user */
- $user = auth()->user();
- $route = $request->route();
- $param = $route->parameter('account');
+ $user = auth()->user();
+ $route = $request->route();
+ $param = $route->parameter('account');
+ $accountId = 0;
if ($param instanceof Account) {
- $accountId = (int)$param->id;
+ $accountId = $param->id;
}
- if (!($param instanceof Account)) {
+ if (!($param instanceof Account) && !is_object($param)) {
$accountId = (int)$param;
}
- /** @var Account|null $account */
- $account = $user->accounts()->with(['accountType'])->withTrashed()->find($accountId);
+
+ /** @var null|Account $account */
+ $account = $user->accounts()->with(['accountType'])->withTrashed()->find($accountId);
if (null === $account) {
- Log::error(sprintf('Could not find account %d, so give big fat error.', $accountId));
+ app('log')->error(sprintf('Could not find account %d, so give big fat error.', $accountId));
return parent::render($request, $exception);
}
@@ -169,35 +174,36 @@ class GracefulNotFoundHandler extends ExceptionHandler
}
/**
- * @param Request $request
- * @param Throwable $exception
- *
* @return Response
- * @throws Throwable
+ *
+ * @throws \Throwable
*/
- private function handleGroup(Request $request, Throwable $exception)
+ private function handleGroup(Request $request, \Throwable $exception)
{
- Log::debug('404 page is probably a deleted group. Redirect to overview of group types.');
+ app('log')->debug('404 page is probably a deleted group. Redirect to overview of group types.');
+
/** @var User $user */
$user = auth()->user();
$route = $request->route();
- $groupId = (int)$route->parameter('transactionGroup');
+ $param = $route->parameter('transactionGroup');
+ $groupId = !is_object($param) ? (int)$param : 0;
- /** @var TransactionGroup|null $group */
- $group = $user->transactionGroups()->withTrashed()->find($groupId);
+ /** @var null|TransactionGroup $group */
+ $group = $user->transactionGroups()->withTrashed()->find($groupId);
if (null === $group) {
- Log::error(sprintf('Could not find group %d, so give big fat error.', $groupId));
+ app('log')->error(sprintf('Could not find group %d, so give big fat error.', $groupId));
return parent::render($request, $exception);
}
- /** @var TransactionJournal|null $journal */
+
+ /** @var null|TransactionJournal $journal */
$journal = $group->transactionJournals()->withTrashed()->first();
if (null === $journal) {
- Log::error(sprintf('Could not find journal for group %d, so give big fat error.', $groupId));
+ app('log')->error(sprintf('Could not find journal for group %d, so give big fat error.', $groupId));
return parent::render($request, $exception);
}
- $type = $journal->transactionType->type;
+ $type = $journal->transactionType->type;
$request->session()->reflash();
if (TransactionType::RECONCILIATION === $type) {
@@ -208,30 +214,31 @@ class GracefulNotFoundHandler extends ExceptionHandler
}
/**
- * @param Request $request
- * @param Throwable $exception
- *
* @return Response
- * @throws Throwable
+ *
+ * @throws \Throwable
*/
- private function handleAttachment(Request $request, Throwable $exception)
+ private function handleAttachment(Request $request, \Throwable $exception)
{
- Log::debug('404 page is probably a deleted attachment. Redirect to parent object.');
+ app('log')->debug('404 page is probably a deleted attachment. Redirect to parent object.');
+
/** @var User $user */
$user = auth()->user();
$route = $request->route();
- $attachmentId = (int)$route->parameter('attachment');
- /** @var Attachment|null $attachment */
- $attachment = $user->attachments()->withTrashed()->find($attachmentId);
+ $param = $route->parameter('attachment');
+ $attachmentId = is_object($param) ? 0 : (int)$param;
+
+ /** @var null|Attachment $attachment */
+ $attachment = $user->attachments()->withTrashed()->find($attachmentId);
if (null === $attachment) {
- Log::error(sprintf('Could not find attachment %d, so give big fat error.', $attachmentId));
+ app('log')->error(sprintf('Could not find attachment %d, so give big fat error.', $attachmentId));
return parent::render($request, $exception);
}
// get bindable.
if (TransactionJournal::class === $attachment->attachable_type) {
// is linked to journal, get group of journal (if not also deleted)
- /** @var TransactionJournal $journal */
+ /** @var null|TransactionJournal $journal */
$journal = $user->transactionJournals()->withTrashed()->find($attachment->attachable_id);
if (null !== $journal) {
return redirect(route('transactions.show', [$journal->transaction_group_id]));
@@ -239,14 +246,14 @@ class GracefulNotFoundHandler extends ExceptionHandler
}
if (Bill::class === $attachment->attachable_type) {
// is linked to bill.
- /** @var Bill $bill */
+ /** @var null|Bill $bill */
$bill = $user->bills()->withTrashed()->find($attachment->attachable_id);
if (null !== $bill) {
return redirect(route('bills.show', [$bill->id]));
}
}
- Log::error(sprintf('Could not redirect attachment %d, its linked to a %s.', $attachmentId, $attachment->attachable_type));
+ app('log')->error(sprintf('Could not redirect attachment %d, its linked to a %s.', $attachmentId, $attachment->attachable_type));
return parent::render($request, $exception);
}
diff --git a/app/Exceptions/Handler.php b/app/Exceptions/Handler.php
index b9bf1e6a36..f43d151f90 100644
--- a/app/Exceptions/Handler.php
+++ b/app/Exceptions/Handler.php
@@ -24,37 +24,32 @@ declare(strict_types=1);
namespace FireflyIII\Exceptions;
-use ErrorException;
use FireflyIII\Jobs\MailError;
use Illuminate\Auth\AuthenticationException;
-use Illuminate\Contracts\Foundation\Application;
use Illuminate\Database\QueryException;
use Illuminate\Foundation\Exceptions\Handler as ExceptionHandler;
+use Illuminate\Http\JsonResponse;
use Illuminate\Http\RedirectResponse;
use Illuminate\Http\Request;
-use Illuminate\Routing\Redirector;
use Illuminate\Session\TokenMismatchException;
use Illuminate\Support\Arr;
-use Illuminate\Support\Facades\Log;
use Illuminate\Validation\ValidationException as LaravelValidationException;
use Laravel\Passport\Exceptions\OAuthServerException as LaravelOAuthException;
use League\OAuth2\Server\Exception\OAuthServerException;
use Symfony\Component\HttpFoundation\Exception\SuspiciousOperationException;
+use Symfony\Component\HttpFoundation\Response;
use Symfony\Component\HttpKernel\Exception\BadRequestHttpException;
use Symfony\Component\HttpKernel\Exception\HttpException;
use Symfony\Component\HttpKernel\Exception\MethodNotAllowedHttpException;
use Symfony\Component\HttpKernel\Exception\NotFoundHttpException;
-use Throwable;
/**
* Class Handler
- *
-
*/
class Handler extends ExceptionHandler
{
/**
- * @var array>
+ * @var array>
*/
protected $dontReport
= [
@@ -70,54 +65,62 @@ class Handler extends ExceptionHandler
];
/**
- * Render an exception into an HTTP response.
+ * Render an exception into an HTTP response. It's complex but lucky for us, we never use it because
+ * Firefly III never crashes.
*
- * @param Request $request
- * @param Throwable $e
+ * @param Request $request
*
- * @return mixed
- * @throws Throwable
+ * @throws \Throwable
+ *
+ * @SuppressWarnings(PHPMD.NPathComplexity)
+ * @SuppressWarnings(PHPMD.CyclomaticComplexity)
*/
- public function render($request, Throwable $e)
+ public function render($request, \Throwable $e): Response
{
$expectsJson = $request->expectsJson();
// if the user requests anything /api/, assume the user wants to see JSON.
if (str_starts_with($request->getRequestUri(), '/api/')) {
- Log::debug('API endpoint, always assume user wants JSON.');
+ app('log')->debug('API endpoint, always assume user wants JSON.');
$expectsJson = true;
}
- Log::debug('Now in Handler::render()');
+ app('log')->debug('Now in Handler::render()');
if ($e instanceof LaravelValidationException && $expectsJson) {
// ignore it: controller will handle it.
- Log::debug(sprintf('Return to parent to handle LaravelValidationException(%d)', $e->status));
+ app('log')->debug(sprintf('Return to parent to handle LaravelValidationException(%d)', $e->status));
+
return parent::render($request, $e);
}
if ($e instanceof NotFoundHttpException && $expectsJson) {
// JSON error:
- Log::debug('Return JSON not found error.');
+ app('log')->debug('Return JSON not found error.');
+
return response()->json(['message' => 'Resource not found', 'exception' => 'NotFoundHttpException'], 404);
}
if ($e instanceof AuthenticationException && $expectsJson) {
// somehow Laravel handler does not catch this:
- Log::debug('Return JSON unauthenticated error.');
+ app('log')->debug('Return JSON unauthenticated error.');
+
return response()->json(['message' => 'Unauthenticated', 'exception' => 'AuthenticationException'], 401);
}
if ($e instanceof OAuthServerException && $expectsJson) {
- Log::debug('Return JSON OAuthServerException.');
+ app('log')->debug('Return JSON OAuthServerException.');
+
// somehow Laravel handler does not catch this:
return response()->json(['message' => $e->getMessage(), 'exception' => 'OAuthServerException'], 401);
}
if ($e instanceof BadRequestHttpException) {
- Log::debug('Return JSON BadRequestHttpException.');
+ app('log')->debug('Return JSON BadRequestHttpException.');
+
return response()->json(['message' => $e->getMessage(), 'exception' => 'BadRequestHttpException'], 400);
}
if ($e instanceof BadHttpHeaderException) {
// is always API exception.
- Log::debug('Return JSON BadHttpHeaderException.');
+ app('log')->debug('Return JSON BadHttpHeaderException.');
+
return response()->json(['message' => $e->getMessage(), 'exception' => 'BadHttpHeaderException'], $e->statusCode);
}
@@ -125,9 +128,10 @@ class Handler extends ExceptionHandler
$errorCode = 500;
$errorCode = $e instanceof MethodNotAllowedHttpException ? 405 : $errorCode;
- $isDebug = config('app.debug', false);
+ $isDebug = (bool)config('app.debug', false);
if ($isDebug) {
- Log::debug(sprintf('Return JSON %s with debug.', get_class($e)));
+ app('log')->debug(sprintf('Return JSON %s with debug.', get_class($e)));
+
return response()->json(
[
'message' => $e->getMessage(),
@@ -139,7 +143,8 @@ class Handler extends ExceptionHandler
$errorCode
);
}
- Log::debug(sprintf('Return JSON %s.', get_class($e)));
+ app('log')->debug(sprintf('Return JSON %s.', get_class($e)));
+
return response()->json(
['message' => sprintf('Internal Firefly III Exception: %s', $e->getMessage()), 'exception' => get_class($e)],
$errorCode
@@ -147,7 +152,7 @@ class Handler extends ExceptionHandler
}
if ($e instanceof NotFoundHttpException) {
- Log::debug('Refer to GracefulNotFoundHandler');
+ app('log')->debug('Refer to GracefulNotFoundHandler');
$handler = app(GracefulNotFoundHandler::class);
return $handler->render($request, $e);
@@ -155,20 +160,20 @@ class Handler extends ExceptionHandler
// special view for database errors with extra instructions
if ($e instanceof QueryException) {
- Log::debug('Return Firefly III database exception view.');
+ app('log')->debug('Return Firefly III database exception view.');
$isDebug = config('app.debug');
return response()->view('errors.DatabaseException', ['exception' => $e, 'debug' => $isDebug], 500);
}
- if ($e instanceof FireflyException || $e instanceof ErrorException || $e instanceof OAuthServerException) {
- Log::debug('Return Firefly III error view.');
+ if ($e instanceof FireflyException || $e instanceof \ErrorException || $e instanceof OAuthServerException) {
+ app('log')->debug('Return Firefly III error view.');
$isDebug = config('app.debug');
return response()->view('errors.FireflyException', ['exception' => $e, 'debug' => $isDebug], 500);
}
- Log::debug(sprintf('Error "%s" has no Firefly III treatment, parent will handle.', get_class($e)));
+ app('log')->debug(sprintf('Error "%s" has no Firefly III treatment, parent will handle.', get_class($e)));
return parent::render($request, $e);
}
@@ -176,21 +181,17 @@ class Handler extends ExceptionHandler
/**
* Report or log an exception.
*
- * @param Throwable $e
- *
- * @return void
- * @throws Throwable
- *
+ * @throws \Throwable
*/
- public function report(Throwable $e)
+ public function report(\Throwable $e): void
{
- $doMailError = config('firefly.send_error_message');
+ $doMailError = (bool)config('firefly.send_error_message');
if ($this->shouldntReportLocal($e) || !$doMailError) {
parent::report($e);
return;
}
- $userData = [
+ $userData = [
'id' => 0,
'email' => 'unknown@example.com',
];
@@ -199,9 +200,9 @@ class Handler extends ExceptionHandler
$userData['email'] = auth()->user()->email;
}
- $headers = request()->headers->all();
+ $headers = request()->headers->all();
- $data = [
+ $data = [
'class' => get_class($e),
'errorMessage' => $e->getMessage(),
'time' => date('r'),
@@ -215,42 +216,33 @@ class Handler extends ExceptionHandler
'json' => request()->acceptsJson(),
'method' => request()->method(),
'headers' => $headers,
+ 'post' => 'POST' === request()->method() ? json_encode(request()->all()) : '',
];
// create job that will mail.
- $ipAddress = request()->ip() ?? '0.0.0.0';
- $job = new MailError($userData, (string)config('firefly.site_owner'), $ipAddress, $data);
+ $ipAddress = request()->ip() ?? '0.0.0.0';
+ $job = new MailError($userData, (string)config('firefly.site_owner'), $ipAddress, $data);
dispatch($job);
parent::report($e);
}
- /**
- * @param Throwable $e
- *
- * @return bool
- */
- private function shouldntReportLocal(Throwable $e): bool
+ private function shouldntReportLocal(\Throwable $e): bool
{
- return !is_null(
- Arr::first(
- $this->dontReport,
- function ($type) use ($e) {
- return $e instanceof $type;
- }
- )
+ return null !== Arr::first(
+ $this->dontReport,
+ static function ($type) use ($e) {
+ return $e instanceof $type;
+ }
);
}
/**
* Convert a validation exception into a response.
*
- * @param Request $request
- * @param LaravelValidationException $exception
- *
- * @return Application|RedirectResponse|Redirector
+ * @param Request $request
*/
- protected function invalid($request, LaravelValidationException $exception): Application | RedirectResponse | Redirector
+ protected function invalid($request, LaravelValidationException $exception): \Illuminate\Http\Response|JsonResponse|RedirectResponse
{
// protect against open redirect when submitting invalid forms.
$previous = app('steam')->getSafePreviousUrl();
@@ -258,15 +250,12 @@ class Handler extends ExceptionHandler
return redirect($redirect ?? $previous)
->withInput(Arr::except($request->input(), $this->dontFlash))
- ->withErrors($exception->errors(), $request->input('_error_bag', $exception->errorBag));
+ ->withErrors($exception->errors(), $request->input('_error_bag', $exception->errorBag))
+ ;
}
/**
* Only return the redirectTo property from the exception if it is a valid URL. Return NULL otherwise.
- *
- * @param LaravelValidationException $exception
- *
- * @return string|null
*/
private function getRedirectUrl(LaravelValidationException $exception): ?string
{
diff --git a/app/Support/Calendar/Exceptions/IntervalException.php b/app/Exceptions/IntervalException.php
similarity index 65%
rename from app/Support/Calendar/Exceptions/IntervalException.php
rename to app/Exceptions/IntervalException.php
index 6192dcc51e..c411b2dd1c 100644
--- a/app/Support/Calendar/Exceptions/IntervalException.php
+++ b/app/Exceptions/IntervalException.php
@@ -1,9 +1,8 @@
availableIntervals = [];
+ $this->periodicity = Periodicity::Monthly;
+ }
+
public static function unavailable(
Periodicity $periodicity,
array $intervals,
int $code = 0,
- ?Throwable $previous = null
- ): IntervalException {
- $message = sprintf(
+ ?\Throwable $previous = null
+ ): self {
+ $message = sprintf(
'The periodicity %s is unknown. Choose one of available periodicity: %s',
$periodicity->name,
- join(', ', $intervals)
+ implode(', ', $intervals)
);
- $exception = new IntervalException($message, $code, $previous);
+ $exception = new self($message, $code, $previous);
$exception->periodicity = $periodicity;
$exception->availableIntervals = $intervals;
+
return $exception;
}
}
diff --git a/app/Exceptions/NotImplementedException.php b/app/Exceptions/NotImplementedException.php
index 31ce17a23f..37bc63c0bb 100644
--- a/app/Exceptions/NotImplementedException.php
+++ b/app/Exceptions/NotImplementedException.php
@@ -24,13 +24,7 @@ declare(strict_types=1);
namespace FireflyIII\Exceptions;
-use Exception;
-
/**
* Class NotImplementedException.
- *
-
*/
-class NotImplementedException extends Exception
-{
-}
+class NotImplementedException extends \Exception {}
diff --git a/app/Exceptions/ValidationException.php b/app/Exceptions/ValidationException.php
index f8f3db344f..1927df03ef 100644
--- a/app/Exceptions/ValidationException.php
+++ b/app/Exceptions/ValidationException.php
@@ -24,13 +24,7 @@ declare(strict_types=1);
namespace FireflyIII\Exceptions;
-use Exception;
-
/**
* Class ValidationExceptions.
- *
-
*/
-class ValidationException extends Exception
-{
-}
+class ValidationException extends \Exception {}
diff --git a/app/Factory/AccountFactory.php b/app/Factory/AccountFactory.php
index 080da2d31b..faaaaa6c52 100644
--- a/app/Factory/AccountFactory.php
+++ b/app/Factory/AccountFactory.php
@@ -34,7 +34,6 @@ use FireflyIII\Services\Internal\Support\LocationServiceTrait;
use FireflyIII\Services\Internal\Update\AccountUpdateService;
use FireflyIII\User;
use Illuminate\Support\Facades\Log;
-use JsonException;
/**
* Factory to create or return accounts.
@@ -56,8 +55,6 @@ class AccountFactory
/**
* AccountFactory constructor.
- *
-
*/
public function __construct()
{
@@ -70,25 +67,20 @@ class AccountFactory
}
/**
- * @param string $accountName
- * @param string $accountType
- *
- * @return Account
* @throws FireflyException
- * @throws JsonException
*/
public function findOrCreate(string $accountName, string $accountType): Account
{
- Log::debug(sprintf('findOrCreate("%s", "%s")', $accountName, $accountType));
+ app('log')->debug(sprintf('findOrCreate("%s", "%s")', $accountName, $accountType));
- $type = $this->accountRepository->getAccountTypeByType($accountType);
+ $type = $this->accountRepository->getAccountTypeByType($accountType);
if (null === $type) {
throw new FireflyException(sprintf('Cannot find account type "%s"', $accountType));
}
$return = $this->user->accounts->where('account_type_id', $type->id)->where('name', $accountName)->first();
if (null === $return) {
- Log::debug('Found nothing. Will create a new one.');
+ app('log')->debug('Found nothing. Will create a new one.');
$return = $this->create(
[
'user_id' => $this->user->id,
@@ -107,26 +99,22 @@ class AccountFactory
}
/**
- * @param array $data
- *
- * @return Account
* @throws FireflyException
- * @throws JsonException
*/
public function create(array $data): Account
{
- Log::debug('Now in AccountFactory::create()');
+ app('log')->debug('Now in AccountFactory::create()');
$type = $this->getAccountType($data);
$data['iban'] = $this->filterIban($data['iban'] ?? null);
// account may exist already:
- $return = $this->find($data['name'], $type->type);
+ $return = $this->find($data['name'], $type->type);
if (null !== $return) {
return $return;
}
- $return = $this->createAccount($type, $data);
+ $return = $this->createAccount($type, $data);
event(new StoredAccount($return));
@@ -134,9 +122,6 @@ class AccountFactory
}
/**
- * @param array $data
- *
- * @return AccountType|null
* @throws FireflyException
*/
protected function getAccountType(array $data): ?AccountType
@@ -161,35 +146,25 @@ class AccountFactory
}
if (null === $result) {
app('log')->warning(sprintf('Found NO account type based on %d and "%s"', $accountTypeId, $accountTypeName));
+
throw new FireflyException(sprintf('AccountFactory::create() was unable to find account type #%d ("%s").', $accountTypeId, $accountTypeName));
}
- Log::debug(sprintf('Found account type based on %d and "%s": "%s"', $accountTypeId, $accountTypeName, $result->type));
+ app('log')->debug(sprintf('Found account type based on %d and "%s": "%s"', $accountTypeId, $accountTypeName, $result->type));
return $result;
}
- /**
- * @param string $accountName
- * @param string $accountType
- *
- * @return Account|null
- */
public function find(string $accountName, string $accountType): ?Account
{
- Log::debug(sprintf('Now in AccountFactory::find("%s", "%s")', $accountName, $accountType));
+ app('log')->debug(sprintf('Now in AccountFactory::find("%s", "%s")', $accountName, $accountType));
$type = AccountType::whereType($accountType)->first();
- /** @var Account|null */
+ // @var Account|null
return $this->user->accounts()->where('account_type_id', $type->id)->where('name', $accountName)->first();
}
/**
- * @param AccountType $type
- * @param array $data
- *
- * @return Account
* @throws FireflyException
- * @throws JsonException
*/
private function createAccount(AccountType $type, array $data): Account
{
@@ -217,31 +192,31 @@ class AccountFactory
$databaseData['virtual_balance'] = null;
}
// create account!
- $account = Account::create($databaseData);
+ $account = Account::create($databaseData);
Log::channel('audit')->info(sprintf('Account #%d ("%s") has been created.', $account->id, $account->name));
// update meta data:
- $data = $this->cleanMetaDataArray($account, $data);
+ $data = $this->cleanMetaDataArray($account, $data);
$this->storeMetaData($account, $data);
// create opening balance (only asset accounts)
try {
$this->storeOpeningBalance($account, $data);
} catch (FireflyException $e) {
- Log::error($e->getMessage());
- Log::error($e->getTraceAsString());
+ app('log')->error($e->getMessage());
+ app('log')->error($e->getTraceAsString());
}
// create credit liability data (only liabilities)
try {
$this->storeCreditLiability($account, $data);
} catch (FireflyException $e) {
- Log::error($e->getMessage());
- Log::error($e->getTraceAsString());
+ app('log')->error($e->getMessage());
+ app('log')->error($e->getTraceAsString());
}
// create notes
- $notes = array_key_exists('notes', $data) ? $data['notes'] : '';
+ $notes = array_key_exists('notes', $data) ? $data['notes'] : '';
$this->updateNote($account, $notes);
// create location
@@ -257,22 +232,17 @@ class AccountFactory
}
/**
- * @param Account $account
- * @param array $data
- *
- * @return array
* @throws FireflyException
- * @throws JsonException
*/
private function cleanMetaDataArray(Account $account, array $data): array
{
- $currencyId = array_key_exists('currency_id', $data) ? (int)$data['currency_id'] : 0;
- $currencyCode = array_key_exists('currency_code', $data) ? (string)$data['currency_code'] : '';
- $accountRole = array_key_exists('account_role', $data) ? (string)$data['account_role'] : null;
- $currency = $this->getCurrency($currencyId, $currencyCode);
+ $currencyId = array_key_exists('currency_id', $data) ? (int)$data['currency_id'] : 0;
+ $currencyCode = array_key_exists('currency_code', $data) ? (string)$data['currency_code'] : '';
+ $accountRole = array_key_exists('account_role', $data) ? (string)$data['account_role'] : null;
+ $currency = $this->getCurrency($currencyId, $currencyCode);
// only asset account may have a role:
- if ($account->accountType->type !== AccountType::ASSET) {
+ if (AccountType::ASSET !== $account->accountType->type) {
$accountRole = '';
}
// only liability may have direction:
@@ -285,26 +255,22 @@ class AccountFactory
return $data;
}
- /**
- * @param Account $account
- * @param array $data
- */
private function storeMetaData(Account $account, array $data): void
{
- $fields = $this->validFields;
- if ($account->accountType->type === AccountType::ASSET) {
+ $fields = $this->validFields;
+ if (AccountType::ASSET === $account->accountType->type) {
$fields = $this->validAssetFields;
}
- if ($account->accountType->type === AccountType::ASSET && 'ccAsset' === $data['account_role']) {
+ if (AccountType::ASSET === $account->accountType->type && 'ccAsset' === $data['account_role']) {
$fields = $this->validCCFields;
}
// remove currency_id if necessary.
- $type = $account->accountType->type;
- $list = config('firefly.valid_currency_account_types');
+ $type = $account->accountType->type;
+ $list = config('firefly.valid_currency_account_types');
if (!in_array($type, $list, true)) {
$pos = array_search('currency_id', $fields, true);
- if ($pos !== false) {
+ if (false !== $pos) {
unset($fields[$pos]);
}
}
@@ -329,9 +295,6 @@ class AccountFactory
}
/**
- * @param Account $account
- * @param array $data
- *
* @throws FireflyException
*/
private function storeOpeningBalance(Account $account, array $data): void
@@ -351,45 +314,39 @@ class AccountFactory
}
/**
- * @param Account $account
- * @param array $data
- *
* @throws FireflyException
*/
private function storeCreditLiability(Account $account, array $data): void
{
- Log::debug('storeCreditLiability');
+ app('log')->debug('storeCreditLiability');
$account->refresh();
$accountType = $account->accountType->type;
$direction = $this->accountRepository->getMetaValue($account, 'liability_direction');
$valid = config('firefly.valid_liabilities');
if (in_array($accountType, $valid, true)) {
- Log::debug('Is a liability with credit ("i am owed") direction.');
+ app('log')->debug('Is a liability with credit ("i am owed") direction.');
if ($this->validOBData($data)) {
- Log::debug('Has valid CL data.');
+ app('log')->debug('Has valid CL data.');
$openingBalance = $data['opening_balance'];
$openingBalanceDate = $data['opening_balance_date'];
// store credit transaction.
$this->updateCreditTransaction($account, $direction, $openingBalance, $openingBalanceDate);
}
if (!$this->validOBData($data)) {
- Log::debug('Does NOT have valid CL data, deletr any CL transaction.');
+ app('log')->debug('Does NOT have valid CL data, deletr any CL transaction.');
$this->deleteCreditTransaction($account);
}
}
}
/**
- * @param Account $account
- * @param array $data
- *
* @throws FireflyException
*/
private function storeOrder(Account $account, array $data): void
{
- $accountType = $account->accountType->type;
- $maxOrder = $this->accountRepository->maxOrder($accountType);
- $order = null;
+ $accountType = $account->accountType->type;
+ $maxOrder = $this->accountRepository->maxOrder($accountType);
+ $order = null;
if (!array_key_exists('order', $data)) {
$order = $maxOrder + 1;
}
@@ -403,9 +360,6 @@ class AccountFactory
$updateService->update($account, ['order' => $order]);
}
- /**
- * @param User $user
- */
public function setUser(User $user): void
{
$this->user = $user;
diff --git a/app/Factory/AccountMetaFactory.php b/app/Factory/AccountMetaFactory.php
index e92b88a6cc..cad3bdddb6 100644
--- a/app/Factory/AccountMetaFactory.php
+++ b/app/Factory/AccountMetaFactory.php
@@ -26,7 +26,6 @@ namespace FireflyIII\Factory;
use FireflyIII\Models\Account;
use FireflyIII\Models\AccountMeta;
-use Illuminate\Support\Facades\Log;
/**
* Class AccountMetaFactory
@@ -35,16 +34,10 @@ class AccountMetaFactory
{
/**
* Create update or delete meta data.
- *
- * @param Account $account
- * @param string $field
- * @param string $value
- *
- * @return AccountMeta|null
*/
public function crud(Account $account, string $field, string $value): ?AccountMeta
{
- /** @var AccountMeta|null $entry */
+ /** @var null|AccountMeta $entry */
$entry = $account->accountMeta()->where('name', $field)->first();
// must not be an empty string:
if ('' !== $value) {
@@ -66,11 +59,6 @@ class AccountMetaFactory
return $entry;
}
- /**
- * @param array $data
- *
- * @return AccountMeta|null
- */
public function create(array $data): ?AccountMeta
{
return AccountMeta::create($data);
diff --git a/app/Factory/AttachmentFactory.php b/app/Factory/AttachmentFactory.php
index bf4f63da5a..75b60e8738 100644
--- a/app/Factory/AttachmentFactory.php
+++ b/app/Factory/AttachmentFactory.php
@@ -38,21 +38,18 @@ class AttachmentFactory
private User $user;
/**
- * @param array $data
- *
- * @return Attachment|null
* @throws FireflyException
*/
public function create(array $data): ?Attachment
{
// append if necessary.
- $model = !str_contains($data['attachable_type'], 'FireflyIII') ? sprintf('FireflyIII\\Models\\%s', $data['attachable_type'])
+ $model = !str_contains($data['attachable_type'], 'FireflyIII') ? sprintf('FireflyIII\\Models\\%s', $data['attachable_type'])
: $data['attachable_type'];
// get journal instead of transaction.
if (Transaction::class === $model) {
- /** @var Transaction|null $transaction */
- $transaction = $this->user->transactions()->find((int)$data['attachable_id']);
+ /** @var null|Transaction $transaction */
+ $transaction = $this->user->transactions()->find((int)$data['attachable_id']);
if (null === $transaction) {
throw new FireflyException('Unexpectedly could not find transaction');
}
@@ -77,7 +74,7 @@ class AttachmentFactory
);
$notes = (string)($data['notes'] ?? '');
if ('' !== $notes) {
- $note = new Note();
+ $note = new Note();
$note->noteable()->associate($attachment);
$note->text = $notes;
$note->save();
@@ -86,9 +83,6 @@ class AttachmentFactory
return $attachment;
}
- /**
- * @param User $user
- */
public function setUser(User $user): void
{
$this->user = $user;
diff --git a/app/Factory/BillFactory.php b/app/Factory/BillFactory.php
index c2bf305d3a..cc359db009 100644
--- a/app/Factory/BillFactory.php
+++ b/app/Factory/BillFactory.php
@@ -30,8 +30,6 @@ use FireflyIII\Repositories\ObjectGroup\CreatesObjectGroups;
use FireflyIII\Services\Internal\Support\BillServiceTrait;
use FireflyIII\User;
use Illuminate\Database\QueryException;
-use Illuminate\Support\Facades\Log;
-use JsonException;
/**
* Class BillFactory
@@ -44,24 +42,21 @@ class BillFactory
private User $user;
/**
- * @param array $data
- *
- * @return Bill|null
* @throws FireflyException
- * @throws JsonException
*/
public function create(array $data): ?Bill
{
- Log::debug(sprintf('Now in %s', __METHOD__), $data);
- $factory = app(TransactionCurrencyFactory::class);
- $currency = $factory->find((int)($data['currency_id'] ?? null), (string)($data['currency_code'] ?? null)) ??
- app('amount')->getDefaultCurrencyByUser($this->user);
+ app('log')->debug(sprintf('Now in %s', __METHOD__), $data);
+ $factory = app(TransactionCurrencyFactory::class);
+ $currency = $factory->find((int)($data['currency_id'] ?? null), (string)($data['currency_code'] ?? null)) ??
+ app('amount')->getDefaultCurrencyByUserGroup($this->user->userGroup);
try {
$skip = array_key_exists('skip', $data) ? $data['skip'] : 0;
$active = array_key_exists('active', $data) ? $data['active'] : 0;
+
/** @var Bill $bill */
- $bill = Bill::create(
+ $bill = Bill::create(
[
'name' => $data['name'],
'match' => 'MIGRATED_TO_RULES',
@@ -80,8 +75,9 @@ class BillFactory
]
);
} catch (QueryException $e) {
- Log::error($e->getMessage());
- Log::error($e->getTraceAsString());
+ app('log')->error($e->getMessage());
+ app('log')->error($e->getTraceAsString());
+
throw new FireflyException('400000: Could not store bill.', 0, $e);
}
@@ -97,7 +93,7 @@ class BillFactory
}
}
// try also with ID:
- $objectGroupId = (int)($data['object_group_id'] ?? 0);
+ $objectGroupId = (int)($data['object_group_id'] ?? 0);
if (0 !== $objectGroupId) {
$objectGroup = $this->findObjectGroupById($objectGroupId);
if (null !== $objectGroup) {
@@ -109,12 +105,6 @@ class BillFactory
return $bill;
}
- /**
- * @param int|null $billId
- * @param null|string $billName
- *
- * @return Bill|null
- */
public function find(?int $billId, ?string $billName): ?Bill
{
$billId = (int)$billId;
@@ -134,19 +124,11 @@ class BillFactory
return $bill;
}
- /**
- * @param string $name
- *
- * @return Bill|null
- */
public function findByName(string $name): ?Bill
{
return $this->user->bills()->where('name', 'LIKE', sprintf('%%%s%%', $name))->first();
}
- /**
- * @param User $user
- */
public function setUser(User $user): void
{
$this->user = $user;
diff --git a/app/Factory/BudgetFactory.php b/app/Factory/BudgetFactory.php
index 728f69c51f..f5b438b714 100644
--- a/app/Factory/BudgetFactory.php
+++ b/app/Factory/BudgetFactory.php
@@ -33,12 +33,6 @@ class BudgetFactory
{
private User $user;
- /**
- * @param int|null $budgetId
- * @param null|string $budgetName
- *
- * @return Budget|null
- */
public function find(?int $budgetId, ?string $budgetName): ?Budget
{
$budgetId = (int)$budgetId;
@@ -50,7 +44,7 @@ class BudgetFactory
// first by ID:
if ($budgetId > 0) {
- /** @var Budget $budget */
+ /** @var null|Budget $budget */
$budget = $this->user->budgets()->find($budgetId);
if (null !== $budget) {
return $budget;
@@ -67,19 +61,11 @@ class BudgetFactory
return null;
}
- /**
- * @param string $name
- *
- * @return Budget|null
- */
public function findByName(string $name): ?Budget
{
return $this->user->budgets()->where('name', $name)->first();
}
- /**
- * @param User $user
- */
public function setUser(User $user): void
{
$this->user = $user;
diff --git a/app/Factory/CategoryFactory.php b/app/Factory/CategoryFactory.php
index e94ad3f50e..b5adc0d7e6 100644
--- a/app/Factory/CategoryFactory.php
+++ b/app/Factory/CategoryFactory.php
@@ -27,7 +27,6 @@ use FireflyIII\Exceptions\FireflyException;
use FireflyIII\Models\Category;
use FireflyIII\User;
use Illuminate\Database\QueryException;
-use Illuminate\Support\Facades\Log;
/**
* Class CategoryFactory
@@ -37,10 +36,6 @@ class CategoryFactory
private User $user;
/**
- * @param int|null $categoryId
- * @param null|string $categoryName
- *
- * @return Category|null
* @throws FireflyException
*/
public function findOrCreate(?int $categoryId, ?string $categoryName): ?Category
@@ -48,14 +43,14 @@ class CategoryFactory
$categoryId = (int)$categoryId;
$categoryName = (string)$categoryName;
- Log::debug(sprintf('Going to find category with ID %d and name "%s"', $categoryId, $categoryName));
+ app('log')->debug(sprintf('Going to find category with ID %d and name "%s"', $categoryId, $categoryName));
if ('' === $categoryName && 0 === $categoryId) {
return null;
}
// first by ID:
if ($categoryId > 0) {
- /** @var Category $category */
+ /** @var null|Category $category */
$category = $this->user->categories()->find($categoryId);
if (null !== $category) {
return $category;
@@ -67,6 +62,7 @@ class CategoryFactory
if (null !== $category) {
return $category;
}
+
try {
return Category::create(
[
@@ -76,8 +72,9 @@ class CategoryFactory
]
);
} catch (QueryException $e) {
- Log::error($e->getMessage());
- Log::error($e->getTraceAsString());
+ app('log')->error($e->getMessage());
+ app('log')->error($e->getTraceAsString());
+
throw new FireflyException('400003: Could not store new category.', 0, $e);
}
}
@@ -85,19 +82,11 @@ class CategoryFactory
return null;
}
- /**
- * @param string $name
- *
- * @return Category|null
- */
public function findByName(string $name): ?Category
{
return $this->user->categories()->where('name', $name)->first();
}
- /**
- * @param User $user
- */
public function setUser(User $user): void
{
$this->user = $user;
diff --git a/app/Factory/PiggyBankEventFactory.php b/app/Factory/PiggyBankEventFactory.php
index 3489ef96ec..5ae8ed384e 100644
--- a/app/Factory/PiggyBankEventFactory.php
+++ b/app/Factory/PiggyBankEventFactory.php
@@ -26,7 +26,6 @@ namespace FireflyIII\Factory;
use FireflyIII\Models\PiggyBank;
use FireflyIII\Models\TransactionJournal;
use FireflyIII\Repositories\PiggyBank\PiggyBankRepositoryInterface;
-use Illuminate\Support\Facades\Log;
/**
* Create piggy bank events.
@@ -35,15 +34,11 @@ use Illuminate\Support\Facades\Log;
*/
class PiggyBankEventFactory
{
- /**
- * @param TransactionJournal $journal
- * @param PiggyBank|null $piggyBank
- */
public function create(TransactionJournal $journal, ?PiggyBank $piggyBank): void
{
- Log::debug(sprintf('Now in PiggyBankEventCreate for a %s', $journal->transactionType->type));
+ app('log')->debug(sprintf('Now in PiggyBankEventCreate for a %s', $journal->transactionType->type));
if (null === $piggyBank) {
- Log::debug('Piggy bank is null');
+ app('log')->debug('Piggy bank is null');
return;
}
@@ -54,14 +49,14 @@ class PiggyBankEventFactory
$repetition = $piggyRepos->getRepetition($piggyBank);
if (null === $repetition) {
- Log::error(sprintf('No piggy bank repetition on %s!', $journal->date->format('Y-m-d')));
+ app('log')->error(sprintf('No piggy bank repetition on %s!', $journal->date->format('Y-m-d')));
return;
}
- Log::debug('Found repetition');
- $amount = $piggyRepos->getExactAmount($piggyBank, $repetition, $journal);
+ app('log')->debug('Found repetition');
+ $amount = $piggyRepos->getExactAmount($piggyBank, $repetition, $journal);
if (0 === bccomp($amount, '0')) {
- Log::debug('Amount is zero, will not create event.');
+ app('log')->debug('Amount is zero, will not create event.');
return;
}
diff --git a/app/Factory/PiggyBankFactory.php b/app/Factory/PiggyBankFactory.php
index 7d6d85fe2d..505c92d0da 100644
--- a/app/Factory/PiggyBankFactory.php
+++ b/app/Factory/PiggyBankFactory.php
@@ -33,12 +33,6 @@ class PiggyBankFactory
{
private User $user;
- /**
- * @param int|null $piggyBankId
- * @param null|string $piggyBankName
- *
- * @return PiggyBank|null
- */
public function find(?int $piggyBankId, ?string $piggyBankName): ?PiggyBank
{
$piggyBankId = (int)$piggyBankId;
@@ -48,7 +42,7 @@ class PiggyBankFactory
}
// first find by ID:
if ($piggyBankId > 0) {
- /** @var PiggyBank $piggyBank */
+ /** @var null|PiggyBank $piggyBank */
$piggyBank = $this->user->piggyBanks()->find($piggyBankId);
if (null !== $piggyBank) {
return $piggyBank;
@@ -57,7 +51,7 @@ class PiggyBankFactory
// then find by name:
if ('' !== $piggyBankName) {
- /** @var PiggyBank $piggyBank */
+ /** @var null|PiggyBank $piggyBank */
$piggyBank = $this->findByName($piggyBankName);
if (null !== $piggyBank) {
return $piggyBank;
@@ -67,19 +61,11 @@ class PiggyBankFactory
return null;
}
- /**
- * @param string $name
- *
- * @return PiggyBank|null
- */
public function findByName(string $name): ?PiggyBank
{
return $this->user->piggyBanks()->where('piggy_banks.name', $name)->first();
}
- /**
- * @param User $user
- */
public function setUser(User $user): void
{
$this->user = $user;
diff --git a/app/Factory/RecurrenceFactory.php b/app/Factory/RecurrenceFactory.php
index a826b06a66..fc9769ab0a 100644
--- a/app/Factory/RecurrenceFactory.php
+++ b/app/Factory/RecurrenceFactory.php
@@ -29,25 +29,21 @@ use FireflyIII\Models\Recurrence;
use FireflyIII\Services\Internal\Support\RecurringTransactionTrait;
use FireflyIII\Services\Internal\Support\TransactionTypeTrait;
use FireflyIII\User;
-use Illuminate\Support\Facades\Log;
use Illuminate\Support\MessageBag;
-use JsonException;
/**
* Class RecurrenceFactory
*/
class RecurrenceFactory
{
- use TransactionTypeTrait;
use RecurringTransactionTrait;
+ use TransactionTypeTrait;
private MessageBag $errors;
private User $user;
/**
* Constructor.
- *
-
*/
public function __construct()
{
@@ -55,11 +51,9 @@ class RecurrenceFactory
}
/**
- * @param array $data
- *
- * @return Recurrence
* @throws FireflyException
- * @throws JsonException
+ *
+ * @SuppressWarnings(PHPMD.NPathComplexity)
*/
public function create(array $data): Recurrence
{
@@ -67,8 +61,8 @@ class RecurrenceFactory
$type = $this->findTransactionType(ucfirst($data['recurrence']['type']));
} catch (FireflyException $e) {
$message = sprintf('Cannot make a recurring transaction of type "%s"', $data['recurrence']['type']);
- Log::error($message);
- Log::error($e->getTraceAsString());
+ app('log')->error($message);
+ app('log')->error($e->getTraceAsString());
throw new FireflyException($message, 0, $e);
}
@@ -104,7 +98,7 @@ class RecurrenceFactory
}
$repeatUntilString = $repeatUntil?->format('Y-m-d');
- $recurrence = new Recurrence(
+ $recurrence = new Recurrence(
[
'user_id' => $this->user->id,
'user_group_id' => $this->user->user_group_id,
@@ -126,32 +120,27 @@ class RecurrenceFactory
}
$this->createRepetitions($recurrence, $data['repetitions'] ?? []);
+
try {
$this->createTransactions($recurrence, $data['transactions'] ?? []);
} catch (FireflyException $e) {
- Log::error($e->getMessage());
- Log::error($e->getTraceAsString());
+ app('log')->error($e->getMessage());
+ app('log')->error($e->getTraceAsString());
$recurrence->forceDelete();
$message = sprintf('Could not create recurring transaction: %s', $e->getMessage());
$this->errors->add('store', $message);
+
throw new FireflyException($message, 0, $e);
}
-
return $recurrence;
}
- /**
- * @return MessageBag
- */
public function getErrors(): MessageBag
{
return $this->errors;
}
- /**
- * @param User $user
- */
public function setUser(User $user): void
{
$this->user = $user;
diff --git a/app/Factory/TagFactory.php b/app/Factory/TagFactory.php
index dcfd9b8741..efe89c3d22 100644
--- a/app/Factory/TagFactory.php
+++ b/app/Factory/TagFactory.php
@@ -26,7 +26,6 @@ namespace FireflyIII\Factory;
use FireflyIII\Models\Location;
use FireflyIII\Models\Tag;
use FireflyIII\User;
-use Illuminate\Support\Facades\Log;
/**
* Class TagFactory
@@ -35,20 +34,15 @@ class TagFactory
{
private User $user;
- /**
- * @param string $tag
- *
- * @return Tag|null
- */
public function findOrCreate(string $tag): ?Tag
{
- $tag = trim($tag);
- Log::debug(sprintf('Now in TagFactory::findOrCreate("%s")', $tag));
+ $tag = trim($tag);
+ app('log')->debug(sprintf('Now in TagFactory::findOrCreate("%s")', $tag));
- /** @var Tag|null $dbTag */
- $dbTag = $this->user->tags()->where('tag', $tag)->first();
+ /** @var null|Tag $dbTag */
+ $dbTag = $this->user->tags()->where('tag', $tag)->first();
if (null !== $dbTag) {
- Log::debug(sprintf('Tag exists (#%d), return it.', $dbTag->id));
+ app('log')->debug(sprintf('Tag exists (#%d), return it.', $dbTag->id));
return $dbTag;
}
@@ -63,20 +57,15 @@ class TagFactory
]
);
if (null === $newTag) {
- Log::error(sprintf('TagFactory::findOrCreate("%s") but tag is unexpectedly NULL!', $tag));
+ app('log')->error(sprintf('TagFactory::findOrCreate("%s") but tag is unexpectedly NULL!', $tag));
return null;
}
- Log::debug(sprintf('Created new tag #%d ("%s")', $newTag->id, $newTag->tag));
+ app('log')->debug(sprintf('Created new tag #%d ("%s")', $newTag->id, $newTag->tag));
return $newTag;
}
- /**
- * @param array $data
- *
- * @return Tag|null
- */
public function create(array $data): ?Tag
{
$zoomLevel = 0 === (int)$data['zoom_level'] ? null : (int)$data['zoom_level'];
@@ -93,6 +82,8 @@ class TagFactory
'longitude' => null,
'zoomLevel' => null,
];
+
+ /** @var null|Tag $tag */
$tag = Tag::create($array);
if (null !== $tag && null !== $latitude && null !== $longitude) {
// create location object.
@@ -107,9 +98,6 @@ class TagFactory
return $tag;
}
- /**
- * @param User $user
- */
public function setUser(User $user): void
{
$this->user = $user;
diff --git a/app/Factory/TransactionCurrencyFactory.php b/app/Factory/TransactionCurrencyFactory.php
index f1d61b7e20..6c03fde0d8 100644
--- a/app/Factory/TransactionCurrencyFactory.php
+++ b/app/Factory/TransactionCurrencyFactory.php
@@ -26,7 +26,6 @@ namespace FireflyIII\Factory;
use FireflyIII\Exceptions\FireflyException;
use FireflyIII\Models\TransactionCurrency;
use Illuminate\Database\QueryException;
-use Illuminate\Support\Facades\Log;
/**
* Class TransactionCurrencyFactory
@@ -34,9 +33,6 @@ use Illuminate\Support\Facades\Log;
class TransactionCurrencyFactory
{
/**
- * @param array $data
- *
- * @return TransactionCurrency
* @throws FireflyException
*/
public function create(array $data): TransactionCurrency
@@ -45,10 +41,9 @@ class TransactionCurrencyFactory
$data['symbol'] = e($data['symbol']);
$data['name'] = e($data['name']);
$data['decimal_places'] = (int)$data['decimal_places'];
- $data['enabled'] = (bool)$data['enabled'];
// if the code already exists (deleted)
// force delete it and then create the transaction:
- $count = TransactionCurrency::withTrashed()->whereCode($data['code'])->count();
+ $count = TransactionCurrency::withTrashed()->whereCode($data['code'])->count();
if (1 === $count) {
$old = TransactionCurrency::withTrashed()->whereCode($data['code'])->first();
$old->forceDelete();
@@ -63,32 +58,27 @@ class TransactionCurrencyFactory
'code' => $data['code'],
'symbol' => $data['symbol'],
'decimal_places' => $data['decimal_places'],
- 'enabled' => $data['enabled'],
+ 'enabled' => false,
]
);
} catch (QueryException $e) {
$result = null;
- Log::error(sprintf('Could not create new currency: %s', $e->getMessage()));
- Log::error($e->getTraceAsString());
+ app('log')->error(sprintf('Could not create new currency: %s', $e->getMessage()));
+ app('log')->error($e->getTraceAsString());
+
throw new FireflyException('400004: Could not store new currency.', 0, $e);
}
return $result;
}
- /**
- * @param int|null $currencyId
- * @param null|string $currencyCode
- *
- * @return TransactionCurrency|null
- */
public function find(?int $currencyId, ?string $currencyCode): ?TransactionCurrency
{
- $currencyCode = (string)e($currencyCode);
+ $currencyCode = e($currencyCode);
$currencyId = (int)$currencyId;
if ('' === $currencyCode && 0 === $currencyId) {
- Log::debug('Cannot find anything on empty currency code and empty currency ID!');
+ app('log')->debug('Cannot find anything on empty currency code and empty currency ID!');
return null;
}
diff --git a/app/Factory/TransactionFactory.php b/app/Factory/TransactionFactory.php
index cc63aa1fc0..15308c674f 100644
--- a/app/Factory/TransactionFactory.php
+++ b/app/Factory/TransactionFactory.php
@@ -33,8 +33,6 @@ use FireflyIII\Rules\UniqueIban;
use FireflyIII\Services\Internal\Update\AccountUpdateService;
use FireflyIII\User;
use Illuminate\Database\QueryException;
-use Illuminate\Support\Facades\Log;
-use Validator;
/**
* Class TransactionFactory
@@ -50,8 +48,6 @@ class TransactionFactory
/**
* Constructor.
- *
-
*/
public function __construct()
{
@@ -62,10 +58,6 @@ class TransactionFactory
/**
* Create transaction with negative amount (for source accounts).
*
- * @param string $amount
- * @param string|null $foreignAmount
- *
- * @return Transaction
* @throws FireflyException
*/
public function createNegative(string $amount, ?string $foreignAmount): Transaction
@@ -81,10 +73,6 @@ class TransactionFactory
}
/**
- * @param string $amount
- * @param string|null $foreignAmount
- *
- * @return Transaction
* @throws FireflyException
*/
private function create(string $amount, ?string $foreignAmount): Transaction
@@ -103,20 +91,22 @@ class TransactionFactory
'foreign_currency_id' => null,
'identifier' => 0,
];
+
try {
- /** @var Transaction|null $result */
+ /** @var null|Transaction $result */
$result = Transaction::create($data);
} catch (QueryException $e) {
- Log::error(sprintf('Could not create transaction: %s', $e->getMessage()), $data);
- Log::error($e->getMessage());
- Log::error($e->getTraceAsString());
+ app('log')->error(sprintf('Could not create transaction: %s', $e->getMessage()), $data);
+ app('log')->error($e->getMessage());
+ app('log')->error($e->getTraceAsString());
+
throw new FireflyException(sprintf('Query exception when creating transaction: %s', $e->getMessage()), 0, $e);
}
if (null === $result) {
throw new FireflyException('Transaction is NULL.');
}
- Log::debug(
+ app('log')->debug(
sprintf(
'Created transaction #%d (%s %s, account %s), part of journal #%d',
$result->id,
@@ -128,7 +118,9 @@ class TransactionFactory
);
// do foreign currency thing: add foreign currency info to $one and $two if necessary.
- if (null !== $this->foreignCurrency && null !== $foreignAmount && $this->foreignCurrency->id !== $this->currency->id && '' !== $foreignAmount) {
+ if (null !== $this->foreignCurrency
+ && null !== $foreignAmount
+ && $this->foreignCurrency->id !== $this->currency->id) {
$result->foreign_currency_id = $this->foreignCurrency->id;
$result->foreign_amount = $foreignAmount;
}
@@ -141,44 +133,43 @@ class TransactionFactory
}
/**
- * @return void
* @throws FireflyException
*/
private function updateAccountInformation(): void
{
if (!array_key_exists('iban', $this->accountInformation)) {
- Log::debug('No IBAN information in array, will not update.');
+ app('log')->debug('No IBAN information in array, will not update.');
+
return;
}
if ('' !== (string)$this->account->iban) {
- Log::debug('Account already has IBAN information, will not update.');
+ app('log')->debug('Account already has IBAN information, will not update.');
+
return;
}
if ($this->account->iban === $this->accountInformation['iban']) {
- Log::debug('Account already has this IBAN, will not update.');
+ app('log')->debug('Account already has this IBAN, will not update.');
+
return;
}
// validate info:
- $validator = Validator::make(['iban' => $this->accountInformation['iban']], [
+ $validator = \Validator::make(['iban' => $this->accountInformation['iban']], [
'iban' => ['required', new UniqueIban($this->account, $this->account->accountType->type)],
]);
if ($validator->fails()) {
- Log::debug('Invalid or non-unique IBAN, will not update.');
+ app('log')->debug('Invalid or non-unique IBAN, will not update.');
+
return;
}
- Log::debug('Will update account with IBAN information.');
- $service = app(AccountUpdateService::class);
+ app('log')->debug('Will update account with IBAN information.');
+ $service = app(AccountUpdateService::class);
$service->update($this->account, ['iban' => $this->accountInformation['iban']]);
}
/**
* Create transaction with positive amount (for destination accounts).
*
- * @param string $amount
- * @param string|null $foreignAmount
- *
- * @return Transaction
* @throws FireflyException
*/
public function createPositive(string $amount, ?string $foreignAmount): Transaction
@@ -193,68 +184,41 @@ class TransactionFactory
return $this->create(app('steam')->positive($amount), $foreignAmount);
}
- /**
- * @param Account $account
- *
-
- */
public function setAccount(Account $account): void
{
$this->account = $account;
}
- /**
- * @param array $accountInformation
- */
public function setAccountInformation(array $accountInformation): void
{
$this->accountInformation = $accountInformation;
}
- /**
- * @param TransactionCurrency $currency
- *
-
- */
public function setCurrency(TransactionCurrency $currency): void
{
$this->currency = $currency;
}
/**
- * @param TransactionCurrency|null $foreignCurrency |null
- *
-
+ * @param null|TransactionCurrency $foreignCurrency |null
*/
public function setForeignCurrency(?TransactionCurrency $foreignCurrency): void
{
$this->foreignCurrency = $foreignCurrency;
}
- /**
- * @param TransactionJournal $journal
- *
-
- */
public function setJournal(TransactionJournal $journal): void
{
$this->journal = $journal;
}
- /**
- * @param bool $reconciled
- *
-
- */
public function setReconciled(bool $reconciled): void
{
$this->reconciled = $reconciled;
}
/**
- * @param User $user
- *
-
+ * @SuppressWarnings(PHPMD.UnusedFormalParameter)
*/
public function setUser(User $user): void
{
diff --git a/app/Factory/TransactionGroupFactory.php b/app/Factory/TransactionGroupFactory.php
index 9304a24650..d75a170c59 100644
--- a/app/Factory/TransactionGroupFactory.php
+++ b/app/Factory/TransactionGroupFactory.php
@@ -27,13 +27,9 @@ use FireflyIII\Exceptions\DuplicateTransactionException;
use FireflyIII\Exceptions\FireflyException;
use FireflyIII\Models\TransactionGroup;
use FireflyIII\User;
-use Illuminate\Support\Facades\Log;
-use JsonException;
/**
* Class TransactionGroupFactory
- *
-
*/
class TransactionGroupFactory
{
@@ -51,26 +47,24 @@ class TransactionGroupFactory
/**
* Store a new transaction journal.
*
- * @param array $data
- *
- * @return TransactionGroup
* @throws DuplicateTransactionException
* @throws FireflyException
- * @throws JsonException
*/
public function create(array $data): TransactionGroup
{
- Log::debug('Now in TransactionGroupFactory::create()');
+ app('log')->debug('Now in TransactionGroupFactory::create()');
$this->journalFactory->setUser($this->user);
$this->journalFactory->setErrorOnHash($data['error_if_duplicate_hash'] ?? false);
+
try {
$collection = $this->journalFactory->create($data);
} catch (DuplicateTransactionException $e) {
app('log')->warning('GroupFactory::create() caught journalFactory::create() with a duplicate!');
+
throw new DuplicateTransactionException($e->getMessage(), 0, $e);
}
- $title = $data['group_title'] ?? null;
- $title = '' === $title ? null : $title;
+ $title = $data['group_title'] ?? null;
+ $title = '' === $title ? null : $title;
if (null !== $title) {
$title = substr($title, 0, 1000);
@@ -79,7 +73,7 @@ class TransactionGroupFactory
throw new FireflyException('Created zero transaction journals.');
}
- $group = new TransactionGroup();
+ $group = new TransactionGroup();
$group->user()->associate($this->user);
$group->userGroup()->associate($data['user_group'] ?? $this->user->userGroup);
$group->title = $title;
@@ -92,8 +86,6 @@ class TransactionGroupFactory
/**
* Set the user.
- *
- * @param User $user
*/
public function setUser(User $user): void
{
diff --git a/app/Factory/TransactionJournalFactory.php b/app/Factory/TransactionJournalFactory.php
index 7321c86b81..bbe9ce33b1 100644
--- a/app/Factory/TransactionJournalFactory.php
+++ b/app/Factory/TransactionJournalFactory.php
@@ -25,11 +25,10 @@ declare(strict_types=1);
namespace FireflyIII\Factory;
use Carbon\Carbon;
-use Exception;
use FireflyIII\Exceptions\DuplicateTransactionException;
use FireflyIII\Exceptions\FireflyException;
use FireflyIII\Models\Account;
-use FireflyIII\Models\Preference;
+use FireflyIII\Models\Location;
use FireflyIII\Models\Transaction;
use FireflyIII\Models\TransactionCurrency;
use FireflyIII\Models\TransactionJournal;
@@ -39,20 +38,20 @@ 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\PiggyBank\PiggyBankRepositoryInterface;
use FireflyIII\Repositories\TransactionType\TransactionTypeRepositoryInterface;
+use FireflyIII\Repositories\UserGroups\Currency\CurrencyRepositoryInterface;
use FireflyIII\Services\Internal\Destroy\JournalDestroyService;
use FireflyIII\Services\Internal\Support\JournalServiceTrait;
use FireflyIII\Support\NullArrayObject;
use FireflyIII\User;
use FireflyIII\Validation\AccountValidator;
use Illuminate\Support\Collection;
-use Illuminate\Support\Facades\Log;
-use JsonException;
/**
* Class TransactionJournalFactory
+ *
+ * @SuppressWarnings(PHPMD.CouplingBetweenObjects)
*/
class TransactionJournalFactory
{
@@ -72,7 +71,7 @@ class TransactionJournalFactory
/**
* Constructor.
*
- * @throws Exception
+ * @throws \Exception
*/
public function __construct()
{
@@ -93,50 +92,49 @@ class TransactionJournalFactory
/**
* Store a new (set of) transaction journals.
*
- * @param array $data
- *
- * @return Collection
* @throws DuplicateTransactionException
* @throws FireflyException
- * @throws JsonException
*/
public function create(array $data): Collection
{
- Log::debug('Now in TransactionJournalFactory::create()');
+ app('log')->debug('Now in TransactionJournalFactory::create()');
// convert to special object.
- $dataObject = new NullArrayObject($data);
+ $dataObject = new NullArrayObject($data);
- Log::debug('Start of TransactionJournalFactory::create()');
+ app('log')->debug('Start of TransactionJournalFactory::create()');
$collection = new Collection();
$transactions = $dataObject['transactions'] ?? [];
if (0 === count($transactions)) {
- Log::error('There are no transactions in the array, the TransactionJournalFactory cannot continue.');
+ app('log')->error('There are no transactions in the array, the TransactionJournalFactory cannot continue.');
return new Collection();
}
+
try {
/** @var array $row */
foreach ($transactions as $index => $row) {
- Log::debug(sprintf('Now creating journal %d/%d', $index + 1, count($transactions)));
+ app('log')->debug(sprintf('Now creating journal %d/%d', $index + 1, count($transactions)));
$journal = $this->createJournal(new NullArrayObject($row));
if (null !== $journal) {
$collection->push($journal);
}
if (null === $journal) {
- Log::error('The createJournal() method returned NULL. This may indicate an error.');
+ app('log')->error('The createJournal() method returned NULL. This may indicate an error.');
}
}
} catch (DuplicateTransactionException $e) {
app('log')->warning('TransactionJournalFactory::create() caught a duplicate journal in createJournal()');
- Log::error($e->getMessage());
- Log::error($e->getTraceAsString());
+ app('log')->error($e->getMessage());
+ app('log')->error($e->getTraceAsString());
$this->forceDeleteOnError($collection);
+
throw new DuplicateTransactionException($e->getMessage(), 0, $e);
} catch (FireflyException $e) {
app('log')->warning('TransactionJournalFactory::create() caught an exception.');
- Log::error($e->getMessage());
- Log::error($e->getTraceAsString());
+ app('log')->error($e->getMessage());
+ app('log')->error($e->getTraceAsString());
$this->forceDeleteOnError($collection);
+
throw new FireflyException($e->getMessage(), 0, $e);
}
@@ -144,12 +142,13 @@ class TransactionJournalFactory
}
/**
- * @param NullArrayObject $row
+ * TODO typeOverrule: the account validator may have another opinion on the transaction type. not sure what to do
+ * with this.
*
- * @return TransactionJournal|null
* @throws DuplicateTransactionException
* @throws FireflyException
- * @throws JsonException
+ *
+ * @SuppressWarnings(PHPMD.ExcessiveMethodLength)
*/
private function createJournal(NullArrayObject $row): ?TransactionJournal
{
@@ -158,33 +157,30 @@ class TransactionJournalFactory
$this->errorIfDuplicate($row['import_hash_v2']);
/** Some basic fields */
- $type = $this->typeRepository->findTransactionType(null, $row['type']);
- $carbon = $row['date'] ?? today(config('app.timezone'));
- $order = $row['order'] ?? 0;
- $currency = $this->currencyRepository->findCurrency((int)$row['currency_id'], $row['currency_code']);
- $foreignCurrency = $this->currencyRepository->findCurrencyNull($row['foreign_currency_id'], $row['foreign_currency_code']);
- $bill = $this->billRepository->findBill((int)$row['bill_id'], $row['bill_name']);
- $billId = TransactionType::WITHDRAWAL === $type->type && null !== $bill ? $bill->id : null;
- $description = (string)$row['description'];
+ $type = $this->typeRepository->findTransactionType(null, $row['type']);
+ $carbon = $row['date'] ?? today(config('app.timezone'));
+ $order = $row['order'] ?? 0;
+ $currency = $this->currencyRepository->findCurrency((int)$row['currency_id'], $row['currency_code']);
+ $foreignCurrency = $this->currencyRepository->findCurrencyNull($row['foreign_currency_id'], $row['foreign_currency_code']);
+ $bill = $this->billRepository->findBill((int)$row['bill_id'], $row['bill_name']);
+ $billId = TransactionType::WITHDRAWAL === $type->type && null !== $bill ? $bill->id : null;
+ $description = (string)$row['description'];
- /** Manipulate basic fields */
+ // Manipulate basic fields
$carbon->setTimezone(config('app.timezone'));
try {
// validate source and destination using a new Validator.
$this->validateAccounts($row);
} catch (FireflyException $e) {
- Log::error('Could not validate source or destination.');
- Log::error($e->getMessage());
+ app('log')->error('Could not validate source or destination.');
+ app('log')->error($e->getMessage());
return null;
}
- // typeOverrule: the account validator may have another opinion on the transaction type.
- // not sure what to do with this.
-
/** create or get source and destination accounts */
- $sourceInfo = [
+ $sourceInfo = [
'id' => $row['source_id'],
'name' => $row['source_name'],
'iban' => $row['source_iban'],
@@ -193,7 +189,7 @@ class TransactionJournalFactory
'currency_id' => $currency->id,
];
- $destInfo = [
+ $destInfo = [
'id' => $row['destination_id'],
'name' => $row['destination_name'],
'iban' => $row['destination_iban'],
@@ -201,28 +197,26 @@ class TransactionJournalFactory
'bic' => $row['destination_bic'],
'currency_id' => $currency->id,
];
- Log::debug('Source info:', $sourceInfo);
- Log::debug('Destination info:', $destInfo);
- Log::debug('Now calling getAccount for the source.');
- $sourceAccount = $this->getAccount($type->type, 'source', $sourceInfo);
- Log::debug('Now calling getAccount for the destination.');
- $destinationAccount = $this->getAccount($type->type, 'destination', $destInfo);
- Log::debug('Done with getAccount(2x)');
+ app('log')->debug('Source info:', $sourceInfo);
+ app('log')->debug('Destination info:', $destInfo);
+ $sourceAccount = $this->getAccount($type->type, 'source', $sourceInfo);
+ $destinationAccount = $this->getAccount($type->type, 'destination', $destInfo);
+ app('log')->debug('Done with getAccount(2x)');
// this is the moment for a reconciliation sanity check (again).
if (TransactionType::RECONCILIATION === $type->type) {
[$sourceAccount, $destinationAccount] = $this->reconciliationSanityCheck($sourceAccount, $destinationAccount);
}
- $currency = $this->getCurrencyByAccount($type->type, $currency, $sourceAccount, $destinationAccount);
- $foreignCurrency = $this->compareCurrencies($currency, $foreignCurrency);
- $foreignCurrency = $this->getForeignByAccount($type->type, $foreignCurrency, $destinationAccount);
- $description = $this->getDescription($description);
+ $currency = $this->getCurrencyByAccount($type->type, $currency, $sourceAccount, $destinationAccount);
+ $foreignCurrency = $this->compareCurrencies($currency, $foreignCurrency);
+ $foreignCurrency = $this->getForeignByAccount($type->type, $foreignCurrency, $destinationAccount);
+ $description = $this->getDescription($description);
- Log::debug(sprintf('Date: %s (%s)', $carbon->toW3cString(), $carbon->getTimezone()->getName()));
+ app('log')->debug(sprintf('Date: %s (%s)', $carbon->toW3cString(), $carbon->getTimezone()->getName()));
/** Create a basic journal. */
- $journal = TransactionJournal::create(
+ $journal = TransactionJournal::create(
[
'user_id' => $this->user->id,
'user_group_id' => $this->user->user_group_id,
@@ -236,10 +230,10 @@ class TransactionJournalFactory
'completed' => 0,
]
);
- Log::debug(sprintf('Created new journal #%d: "%s"', $journal->id, $journal->description));
+ app('log')->debug(sprintf('Created new journal #%d: "%s"', $journal->id, $journal->description));
/** Create two transactions. */
- $transactionFactory = app(TransactionFactory::class);
+ $transactionFactory = app(TransactionFactory::class);
$transactionFactory->setUser($this->user);
$transactionFactory->setJournal($journal);
$transactionFactory->setAccount($sourceAccount);
@@ -247,19 +241,18 @@ class TransactionJournalFactory
$transactionFactory->setAccountInformation($sourceInfo);
$transactionFactory->setForeignCurrency($foreignCurrency);
$transactionFactory->setReconciled($row['reconciled'] ?? false);
+
try {
$negative = $transactionFactory->createNegative((string)$row['amount'], (string)$row['foreign_amount']);
} catch (FireflyException $e) {
- Log::error('Exception creating negative transaction.');
- Log::error($e->getMessage());
- Log::error($e->getTraceAsString());
+ app('log')->error(sprintf('Exception creating negative transaction: %s', $e->getMessage()));
$this->forceDeleteOnError(new Collection([$journal]));
+
throw new FireflyException($e->getMessage(), 0, $e);
}
- // and the destination one:
/** @var TransactionFactory $transactionFactory */
- $transactionFactory = app(TransactionFactory::class);
+ $transactionFactory = app(TransactionFactory::class);
$transactionFactory->setUser($this->user);
$transactionFactory->setJournal($journal);
$transactionFactory->setAccount($destinationAccount);
@@ -267,58 +260,43 @@ class TransactionJournalFactory
$transactionFactory->setCurrency($currency);
$transactionFactory->setForeignCurrency($foreignCurrency);
$transactionFactory->setReconciled($row['reconciled'] ?? false);
+
try {
$transactionFactory->createPositive((string)$row['amount'], (string)$row['foreign_amount']);
} catch (FireflyException $e) {
- Log::error('Exception creating positive transaction.');
- Log::error($e->getMessage());
- Log::error($e->getTraceAsString());
- app('log')->warning('Delete negative transaction.');
+ app('log')->error(sprintf('Exception creating positive transaction: %s', $e->getMessage()));
$this->forceTrDelete($negative);
$this->forceDeleteOnError(new Collection([$journal]));
+
throw new FireflyException($e->getMessage(), 0, $e);
}
- // verify that journal has two transactions. Otherwise, delete and cancel.
- $journal->completed = true;
+ $journal->completed = true;
$journal->save();
-
- /** Link all other data to the journal. */
-
- /** Link budget */
$this->storeBudget($journal, $row);
-
- /** Link category */
$this->storeCategory($journal, $row);
-
- /** Set notes */
$this->storeNotes($journal, $row['notes']);
-
- /** Set piggy bank */
$this->storePiggyEvent($journal, $row);
-
- /** Set tags */
$this->storeTags($journal, $row['tags']);
-
- /** set all meta fields */
$this->storeMetaFields($journal, $row);
+ $this->storeLocation($journal, $row);
return $journal;
}
- /**
- * @param NullArrayObject $row
- *
- * @return string
- * @throws JsonException
- */
private function hashArray(NullArrayObject $row): string
{
$dataRow = $row->getArrayCopy();
unset($dataRow['import_hash_v2'], $dataRow['original_source']);
- $json = json_encode($dataRow, JSON_THROW_ON_ERROR);
- $hash = hash('sha256', $json);
- Log::debug(sprintf('The hash is: %s', $hash), $dataRow);
+
+ try {
+ $json = json_encode($dataRow, JSON_THROW_ON_ERROR);
+ } catch (\JsonException $e) {
+ app('log')->error(sprintf('Could not encode dataRow: %s', $e->getMessage()));
+ $json = microtime();
+ }
+ $hash = hash('sha256', $json);
+ app('log')->debug(sprintf('The hash is: %s', $hash), $dataRow);
return $hash;
}
@@ -326,68 +304,66 @@ class TransactionJournalFactory
/**
* If this transaction already exists, throw an error.
*
- * @param string $hash
- *
* @throws DuplicateTransactionException
- * @throws JsonException
*/
private function errorIfDuplicate(string $hash): void
{
- Log::debug(sprintf('In errorIfDuplicate(%s)', $hash));
+ app('log')->debug(sprintf('In errorIfDuplicate(%s)', $hash));
if (false === $this->errorOnHash) {
return;
}
- Log::debug('Will verify duplicate!');
- /** @var TransactionJournalMeta|null $result */
+ app('log')->debug('Will verify duplicate!');
+
+ /** @var null|TransactionJournalMeta $result */
$result = TransactionJournalMeta::withTrashed()
- ->where('data', json_encode($hash, JSON_THROW_ON_ERROR))
- ->with(['transactionJournal', 'transactionJournal.transactionGroup'])
- ->first();
+ ->leftJoin('transaction_journals', 'transaction_journals.id', '=', 'journal_meta.transaction_journal_id')
+ ->whereNotNull('transaction_journals.id')
+ ->where('transaction_journals.user_id', $this->user->id)
+ ->where('data', json_encode($hash, JSON_THROW_ON_ERROR))
+ ->with(['transactionJournal', 'transactionJournal.transactionGroup'])
+ ->first(['journal_meta.*'])
+ ;
if (null !== $result) {
app('log')->warning(sprintf('Found a duplicate in errorIfDuplicate because hash %s is not unique!', $hash));
$journal = $result->transactionJournal()->withTrashed()->first();
$group = $journal?->transactionGroup()->withTrashed()->first();
- $groupId = $group?->id;
- if (null === $group) {
- $groupId = 0;
- }
+ $groupId = (int)$group?->id;
+
throw new DuplicateTransactionException(sprintf('Duplicate of transaction #%d.', $groupId));
}
}
/**
- * @param NullArrayObject $data
- *
* @throws FireflyException
*/
private function validateAccounts(NullArrayObject $data): void
{
- Log::debug(sprintf('Now in %s', __METHOD__));
- $transactionType = $data['type'] ?? 'invalid';
+ app('log')->debug(sprintf('Now in %s', __METHOD__));
+ $transactionType = $data['type'] ?? 'invalid';
$this->accountValidator->setUser($this->user);
$this->accountValidator->setTransactionType($transactionType);
// validate source account.
- $array = [
- 'id' => $data['source_id'] ? (int)$data['source_id'] : null,
- 'name' => $data['source_name'] ? (string)$data['source_name'] : null,
- 'iban' => $data['source_iban'] ? (string)$data['source_iban'] : null,
- 'number' => $data['source_number'] ? (string)$data['source_number'] : null,
+ $array = [
+ 'id' => null !== $data['source_id'] ? (int)$data['source_id'] : null,
+ 'name' => null !== $data['source_name'] ? (string)$data['source_name'] : null,
+ 'iban' => null !== $data['source_iban'] ? (string)$data['source_iban'] : null,
+ 'number' => null !== $data['source_number'] ? (string)$data['source_number'] : null,
];
- $validSource = $this->accountValidator->validateSource($array);
+ $validSource = $this->accountValidator->validateSource($array);
// do something with result:
if (false === $validSource) {
throw new FireflyException(sprintf('Source: %s', $this->accountValidator->sourceError));
}
- Log::debug('Source seems valid.');
+ app('log')->debug('Source seems valid.');
// validate destination account
- $array = [
- 'id' => $data['destination_id'] ? (int)$data['destination_id'] : null,
- 'name' => $data['destination_name'] ? (string)$data['destination_name'] : null,
- 'iban' => $data['destination_iban'] ? (string)$data['destination_iban'] : null,
- 'number' => $data['destination_number'] ? (string)$data['destination_number'] : null,
+ $array = [
+ 'id' => null !== $data['destination_id'] ? (int)$data['destination_id'] : null,
+ 'name' => null !== $data['destination_name'] ? (string)$data['destination_name'] : null,
+ 'iban' => null !== $data['destination_iban'] ? (string)$data['destination_iban'] : null,
+ 'number' => null !== $data['destination_number'] ? (string)$data['destination_number'] : null,
];
$validDestination = $this->accountValidator->validateDestination($array);
@@ -399,8 +375,6 @@ class TransactionJournalFactory
/**
* Set the user.
- *
- * @param User $user
*/
public function setUser(User $user): void
{
@@ -414,49 +388,40 @@ class TransactionJournalFactory
$this->accountRepository->setUser($this->user);
}
- /**
- * @param Account|null $sourceAccount
- * @param Account|null $destinationAccount
- *
- * @return array
- */
private function reconciliationSanityCheck(?Account $sourceAccount, ?Account $destinationAccount): array
{
- Log::debug(sprintf('Now in %s', __METHOD__));
+ app('log')->debug(sprintf('Now in %s', __METHOD__));
if (null !== $sourceAccount && null !== $destinationAccount) {
- Log::debug('Both accounts exist, simply return them.');
+ app('log')->debug('Both accounts exist, simply return them.');
+
return [$sourceAccount, $destinationAccount];
}
- if (null !== $sourceAccount && null === $destinationAccount) {
- Log::debug('Destination account is NULL, source account is not.');
+ if (null === $destinationAccount) { // @phpstan-ignore-line
+ app('log')->debug('Destination account is NULL, source account is not.');
$account = $this->accountRepository->getReconciliation($sourceAccount);
- Log::debug(sprintf('Will return account #%d ("%s") of type "%s"', $account->id, $account->name, $account->accountType->type));
+ app('log')->debug(sprintf('Will return account #%d ("%s") of type "%s"', $account->id, $account->name, $account->accountType->type));
+
return [$sourceAccount, $account];
}
- if (null === $sourceAccount && null !== $destinationAccount) {
- Log::debug('Source account is NULL, destination account is not.');
+ if (null === $sourceAccount) { // @phpstan-ignore-line
+ app('log')->debug('Source account is NULL, destination account is not.');
$account = $this->accountRepository->getReconciliation($destinationAccount);
- Log::debug(sprintf('Will return account #%d ("%s") of type "%s"', $account->id, $account->name, $account->accountType->type));
+ app('log')->debug(sprintf('Will return account #%d ("%s") of type "%s"', $account->id, $account->name, $account->accountType->type));
+
return [$account, $destinationAccount];
}
- Log::debug('Unused fallback');
+ app('log')->debug('Unused fallback'); // @phpstan-ignore-line
+
return [$sourceAccount, $destinationAccount];
}
/**
- * @param string $type
- * @param TransactionCurrency|null $currency
- * @param Account $source
- * @param Account $destination
- *
- * @return TransactionCurrency
* @throws FireflyException
- * @throws JsonException
*/
private function getCurrencyByAccount(string $type, ?TransactionCurrency $currency, Account $source, Account $destination): TransactionCurrency
{
- Log::debug('Now in getCurrencyByAccount()');
+ app('log')->debug('Now in getCurrencyByAccount()');
return match ($type) {
default => $this->getCurrency($currency, $source),
@@ -465,35 +430,26 @@ class TransactionJournalFactory
}
/**
- * @param TransactionCurrency|null $currency
- * @param Account $account
- *
- * @return TransactionCurrency
* @throws FireflyException
- * @throws JsonException
*/
private function getCurrency(?TransactionCurrency $currency, Account $account): TransactionCurrency
{
- Log::debug('Now in getCurrency()');
- /** @var Preference|null $preference */
+ app('log')->debug('Now in getCurrency()');
+
+ /** @var null|TransactionCurrency $preference */
$preference = $this->accountRepository->getAccountCurrency($account);
if (null === $preference && null === $currency) {
// return user's default:
- return app('amount')->getDefaultCurrencyByUser($this->user);
+ return app('amount')->getDefaultCurrencyByUserGroup($this->user->userGroup);
}
- $result = ($preference ?? $currency) ?? app('amount')->getSystemCurrency();
- Log::debug(sprintf('Currency is now #%d (%s) because of account #%d (%s)', $result->id, $result->code, $account->id, $account->name));
+ $result = $preference ?? $currency;
+ app('log')->debug(sprintf('Currency is now #%d (%s) because of account #%d (%s)', $result->id, $result->code, $account->id, $account->name));
return $result;
}
/**
* Set foreign currency to NULL if it's the same as the normal currency:
- *
- * @param TransactionCurrency|null $currency
- * @param TransactionCurrency|null $foreignCurrency
- *
- * @return TransactionCurrency|null
*/
private function compareCurrencies(?TransactionCurrency $currency, ?TransactionCurrency $foreignCurrency): ?TransactionCurrency
{
@@ -508,13 +464,7 @@ class TransactionJournalFactory
}
/**
- * @param string $type
- * @param TransactionCurrency|null $foreignCurrency
- * @param Account $destination
- *
- * @return TransactionCurrency|null
* @throws FireflyException
- * @throws JsonException
*/
private function getForeignByAccount(string $type, ?TransactionCurrency $foreignCurrency, Account $destination): ?TransactionCurrency
{
@@ -525,11 +475,6 @@ class TransactionJournalFactory
return $foreignCurrency;
}
- /**
- * @param string $description
- *
- * @return string
- */
private function getDescription(string $description): string
{
$description = '' === $description ? '(empty description)' : $description;
@@ -540,23 +485,19 @@ class TransactionJournalFactory
/**
* Force the deletion of an entire set of transaction journals and their meta object in case of
* an error creating a group.
- *
- * @param Collection $collection
*/
private function forceDeleteOnError(Collection $collection): void
{
- Log::debug(sprintf('forceDeleteOnError on collection size %d item(s)', $collection->count()));
+ app('log')->debug(sprintf('forceDeleteOnError on collection size %d item(s)', $collection->count()));
$service = app(JournalDestroyService::class);
+
/** @var TransactionJournal $journal */
foreach ($collection as $journal) {
- Log::debug(sprintf('forceDeleteOnError on journal #%d', $journal->id));
+ app('log')->debug(sprintf('forceDeleteOnError on journal #%d', $journal->id));
$service->destroy($journal);
}
}
- /**
- * @param Transaction $transaction
- */
private function forceTrDelete(Transaction $transaction): void
{
$transaction->delete();
@@ -564,29 +505,22 @@ class TransactionJournalFactory
/**
* Link a piggy bank to this journal.
- *
- * @param TransactionJournal $journal
- * @param NullArrayObject $data
*/
private function storePiggyEvent(TransactionJournal $journal, NullArrayObject $data): void
{
- Log::debug('Will now store piggy event.');
+ app('log')->debug('Will now store piggy event.');
$piggyBank = $this->piggyRepository->findPiggyBank((int)$data['piggy_bank_id'], $data['piggy_bank_name']);
if (null !== $piggyBank) {
$this->piggyEventFactory->create($journal, $piggyBank);
- Log::debug('Create piggy event.');
+ app('log')->debug('Create piggy event.');
return;
}
- Log::debug('Create no piggy event');
+ app('log')->debug('Create no piggy event');
}
- /**
- * @param TransactionJournal $journal
- * @param NullArrayObject $transaction
- */
private function storeMetaFields(TransactionJournal $journal, NullArrayObject $transaction): void
{
foreach ($this->fields as $field) {
@@ -594,39 +528,43 @@ class TransactionJournalFactory
}
}
- /**
- * @param TransactionJournal $journal
- * @param NullArrayObject $data
- * @param string $field
- */
protected function storeMeta(TransactionJournal $journal, NullArrayObject $data, string $field): void
{
- $set = [
+ $set = [
'journal' => $journal,
'name' => $field,
'data' => (string)($data[$field] ?? ''),
];
if ($data[$field] instanceof Carbon) {
$data[$field]->setTimezone(config('app.timezone'));
- Log::debug(sprintf('%s Date: %s (%s)', $field, $data[$field], $data[$field]->timezone->getName()));
+ app('log')->debug(sprintf('%s Date: %s (%s)', $field, $data[$field], $data[$field]->timezone->getName()));
$set['data'] = $data[$field]->format('Y-m-d H:i:s');
}
- Log::debug(sprintf('Going to store meta-field "%s", with value "%s".', $set['name'], $set['data']));
+ app('log')->debug(sprintf('Going to store meta-field "%s", with value "%s".', $set['name'], $set['data']));
/** @var TransactionJournalMetaFactory $factory */
$factory = app(TransactionJournalMetaFactory::class);
$factory->updateOrCreate($set);
}
- /**
- * @param bool $errorOnHash
- */
+ private function storeLocation(TransactionJournal $journal, NullArrayObject $data): void
+ {
+ if (true === $data['store_location']) {
+ $location = new Location();
+ $location->longitude = $data['longitude'];
+ $location->latitude = $data['latitude'];
+ $location->zoom_level = $data['zoom_level'];
+ $location->locatable()->associate($journal);
+ $location->save();
+ }
+ }
+
public function setErrorOnHash(bool $errorOnHash): void
{
$this->errorOnHash = $errorOnHash;
if (true === $errorOnHash) {
- Log::info('Will trigger duplication alert for this journal.');
+ app('log')->info('Will trigger duplication alert for this journal.');
}
}
}
diff --git a/app/Factory/TransactionJournalMetaFactory.php b/app/Factory/TransactionJournalMetaFactory.php
index 41cfe13971..28f3516609 100644
--- a/app/Factory/TransactionJournalMetaFactory.php
+++ b/app/Factory/TransactionJournalMetaFactory.php
@@ -25,40 +25,35 @@ namespace FireflyIII\Factory;
use Carbon\Carbon;
use FireflyIII\Models\TransactionJournalMeta;
-use Illuminate\Support\Facades\Log;
/**
* Class TransactionJournalMetaFactory
*/
class TransactionJournalMetaFactory
{
- /**
- * @param array $data
- *
- * @return TransactionJournalMeta|null
- */
public function updateOrCreate(array $data): ?TransactionJournalMeta
{
- //Log::debug('In updateOrCreate()');
- $value = $data['data'];
- /** @var TransactionJournalMeta|null $entry */
- $entry = $data['journal']->transactionJournalMeta()->where('name', $data['name'])->first();
+ // app('log')->debug('In updateOrCreate()');
+ $value = $data['data'];
+
+ /** @var null|TransactionJournalMeta $entry */
+ $entry = $data['journal']->transactionJournalMeta()->where('name', $data['name'])->first();
if (null === $value && null !== $entry) {
- //Log::debug('Value is empty, delete meta value.');
+ // app('log')->debug('Value is empty, delete meta value.');
$entry->delete();
return null;
}
if ($data['data'] instanceof Carbon) {
- Log::debug('Is a carbon object.');
+ app('log')->debug('Is a carbon object.');
$value = $data['data']->toW3cString();
}
if ('' === (string)$value) {
- // Log::debug('Is an empty string.');
+ // app('log')->debug('Is an empty string.');
// don't store blank strings.
if (null !== $entry) {
- Log::debug('Will not store empty strings, delete meta value');
+ app('log')->debug('Will not store empty strings, delete meta value');
$entry->delete();
}
@@ -66,13 +61,13 @@ class TransactionJournalMetaFactory
}
if (null === $entry) {
- //Log::debug('Will create new object.');
- Log::debug(sprintf('Going to create new meta-data entry to store "%s".', $data['name']));
- $entry = new TransactionJournalMeta();
+ // app('log')->debug('Will create new object.');
+ app('log')->debug(sprintf('Going to create new meta-data entry to store "%s".', $data['name']));
+ $entry = new TransactionJournalMeta();
$entry->transactionJournal()->associate($data['journal']);
$entry->name = $data['name'];
}
- Log::debug('Will update value and return.');
+ app('log')->debug('Will update value and return.');
$entry->data = $value;
$entry->save();
diff --git a/app/Factory/TransactionTypeFactory.php b/app/Factory/TransactionTypeFactory.php
index 64294ef1ee..b7bde85c90 100644
--- a/app/Factory/TransactionTypeFactory.php
+++ b/app/Factory/TransactionTypeFactory.php
@@ -31,11 +31,6 @@ use FireflyIII\Models\TransactionType;
*/
class TransactionTypeFactory
{
- /**
- * @param string $type
- *
- * @return TransactionType|null
- */
public function find(string $type): ?TransactionType
{
return TransactionType::whereType(ucfirst($type))->first();
diff --git a/app/Factory/UserGroupFactory.php b/app/Factory/UserGroupFactory.php
index f4d3169772..d392b69832 100644
--- a/app/Factory/UserGroupFactory.php
+++ b/app/Factory/UserGroupFactory.php
@@ -1,6 +1,5 @@
title = $data['title'];
+ $userGroup = new UserGroup();
+ $userGroup->title = $data['title'];
$userGroup->save();
// grab the OWNER role:
- $role = UserRole::whereTitle(UserRoleEnum::OWNER->value)->first();
+ $role = UserRole::whereTitle(UserRoleEnum::OWNER->value)->first();
if (null === $role) {
throw new FireflyException('Role "owner" does not exist.');
}
@@ -62,5 +58,4 @@ class UserGroupFactory
return $userGroup;
}
-
}
diff --git a/app/Generator/Chart/Basic/ChartJsGenerator.php b/app/Generator/Chart/Basic/ChartJsGenerator.php
index 0662b6200a..3675871dec 100644
--- a/app/Generator/Chart/Basic/ChartJsGenerator.php
+++ b/app/Generator/Chart/Basic/ChartJsGenerator.php
@@ -34,10 +34,6 @@ class ChartJsGenerator implements GeneratorInterface
* Expects data as:.
*
* key => [value => x, 'currency_symbol' => 'x']
- *
- * @param array $data
- *
- * @return array
*/
public function multiCurrencyPieChart(array $data): array
{
@@ -48,16 +44,16 @@ class ChartJsGenerator implements GeneratorInterface
'labels' => [],
];
- $amounts = array_column($data, 'amount');
- $next = next($amounts);
- $sortFlag = SORT_ASC;
+ $amounts = array_column($data, 'amount');
+ $next = next($amounts);
+ $sortFlag = SORT_ASC;
if (!is_bool($next) && 1 === bccomp((string)$next, '0')) {
$sortFlag = SORT_DESC;
}
array_multisort($amounts, $sortFlag, $data);
unset($next, $sortFlag, $amounts);
- $index = 0;
+ $index = 0;
foreach ($data as $key => $valueArray) {
// make larger than 0
$chartData['datasets'][0]['data'][] = app('steam')->positive((string)$valueArray['amount']);
@@ -99,19 +95,15 @@ class ChartJsGenerator implements GeneratorInterface
* ]
*
* // it's five.
- *
- * @param array $data
- *
- * @return array
*/
public function multiSet(array $data): array
{
reset($data);
- $first = current($data);
+ $first = current($data);
if (!is_array($first)) {
return [];
}
- $labels = is_array($first['entries']) ? array_keys($first['entries']) : [];
+ $labels = is_array($first['entries']) ? array_keys($first['entries']) : [];
$chartData = [
'count' => count($data),
@@ -121,7 +113,7 @@ class ChartJsGenerator implements GeneratorInterface
unset($first, $labels);
foreach ($data as $set) {
- $currentSet = [
+ $currentSet = [
'label' => $set['label'] ?? '(no label)',
'type' => $set['type'] ?? 'line',
'data' => array_values($set['entries']),
@@ -148,10 +140,6 @@ class ChartJsGenerator implements GeneratorInterface
* Expects data as:.
*
* key => value
- *
- * @param array $data
- *
- * @return array
*/
public function pieChart(array $data): array
{
@@ -165,20 +153,20 @@ class ChartJsGenerator implements GeneratorInterface
// sort by value, keep keys.
// different sort when values are positive and when they're negative.
asort($data);
- $next = next($data);
+ $next = next($data);
if (!is_bool($next) && 1 === bccomp((string)$next, '0')) {
// next is positive, sort other way around.
arsort($data);
}
unset($next);
- $index = 0;
+ $index = 0;
foreach ($data as $key => $value) {
// make larger than 0
$chartData['datasets'][0]['data'][] = app('steam')->positive((string)$value);
$chartData['datasets'][0]['backgroundColor'][] = ChartColour::getColour($index);
- $chartData['labels'][] = $key;
+ $chartData['labels'][] = $key;
++$index;
}
@@ -189,11 +177,6 @@ class ChartJsGenerator implements GeneratorInterface
* Will generate a (ChartJS) compatible array from the given input. Expects this format:.
*
* 'label-of-entry' => value
- *
- * @param string $setLabel
- * @param array $data
- *
- * @return array
*/
public function singleSet(string $setLabel, array $data): array
{
diff --git a/app/Generator/Chart/Basic/GeneratorInterface.php b/app/Generator/Chart/Basic/GeneratorInterface.php
index a43c85bba9..f55193b96c 100644
--- a/app/Generator/Chart/Basic/GeneratorInterface.php
+++ b/app/Generator/Chart/Basic/GeneratorInterface.php
@@ -28,11 +28,6 @@ namespace FireflyIII\Generator\Chart\Basic;
*/
interface GeneratorInterface
{
- /**
- * @param array $data
- *
- * @return array
- */
public function multiCurrencyPieChart(array $data): array;
/**
@@ -62,10 +57,6 @@ interface GeneratorInterface
* ]
*
* // it's five.
- *
- * @param array $data
- *
- * @return array
*/
public function multiSet(array $data): array;
@@ -73,10 +64,6 @@ interface GeneratorInterface
* Expects data as:.
*
* key => value
- *
- * @param array $data
- *
- * @return array
*/
public function pieChart(array $data): array;
@@ -84,11 +71,6 @@ interface GeneratorInterface
* Will generate a (ChartJS) compatible array from the given input. Expects this format:.
*
* 'label-of-entry' => value
- *
- * @param string $setLabel
- * @param array $data
- *
- * @return array
*/
public function singleSet(string $setLabel, array $data): array;
}
diff --git a/app/Generator/Report/Account/MonthReportGenerator.php b/app/Generator/Report/Account/MonthReportGenerator.php
index 8275835d8c..49487a84b5 100644
--- a/app/Generator/Report/Account/MonthReportGenerator.php
+++ b/app/Generator/Report/Account/MonthReportGenerator.php
@@ -27,13 +27,9 @@ use Carbon\Carbon;
use FireflyIII\Exceptions\FireflyException;
use FireflyIII\Generator\Report\ReportGeneratorInterface;
use Illuminate\Support\Collection;
-use Illuminate\Support\Facades\Log;
-use Throwable;
/**
* Class MonthReportGenerator.
- *
-
*/
class MonthReportGenerator implements ReportGeneratorInterface
{
@@ -45,7 +41,6 @@ class MonthReportGenerator implements ReportGeneratorInterface
/**
* Generate the report.
*
- * @return string
* @throws FireflyException
*/
public function generate(): string
@@ -54,15 +49,18 @@ class MonthReportGenerator implements ReportGeneratorInterface
$doubleIds = implode(',', $this->expense->pluck('id')->toArray());
$reportType = 'account';
$preferredPeriod = $this->preferredPeriod();
+
try {
$result = view('reports.double.report', compact('accountIds', 'reportType', 'doubleIds', 'preferredPeriod'))
->with('start', $this->start)->with('end', $this->end)
->with('doubles', $this->expense)
- ->render();
- } catch (Throwable $e) {
- Log::error(sprintf('Cannot render reports.double.report: %s', $e->getMessage()));
- Log::error($e->getTraceAsString());
+ ->render()
+ ;
+ } catch (\Throwable $e) {
+ app('log')->error(sprintf('Cannot render reports.double.report: %s', $e->getMessage()));
+ app('log')->error($e->getTraceAsString());
$result = sprintf('Could not render report view: %s', $e->getMessage());
+
throw new FireflyException($result, 0, $e);
}
@@ -71,8 +69,6 @@ class MonthReportGenerator implements ReportGeneratorInterface
/**
* Return the preferred period.
- *
- * @return string
*/
protected function preferredPeriod(): string
{
@@ -81,10 +77,6 @@ class MonthReportGenerator implements ReportGeneratorInterface
/**
* Set accounts.
- *
- * @param Collection $accounts
- *
- * @return ReportGeneratorInterface
*/
public function setAccounts(Collection $accounts): ReportGeneratorInterface
{
@@ -95,10 +87,6 @@ class MonthReportGenerator implements ReportGeneratorInterface
/**
* Set budgets.
- *
- * @param Collection $budgets
- *
- * @return ReportGeneratorInterface
*/
public function setBudgets(Collection $budgets): ReportGeneratorInterface
{
@@ -107,10 +95,6 @@ class MonthReportGenerator implements ReportGeneratorInterface
/**
* Set categories.
- *
- * @param Collection $categories
- *
- * @return ReportGeneratorInterface
*/
public function setCategories(Collection $categories): ReportGeneratorInterface
{
@@ -119,10 +103,6 @@ class MonthReportGenerator implements ReportGeneratorInterface
/**
* Set end date.
- *
- * @param Carbon $date
- *
- * @return ReportGeneratorInterface
*/
public function setEndDate(Carbon $date): ReportGeneratorInterface
{
@@ -133,10 +113,6 @@ class MonthReportGenerator implements ReportGeneratorInterface
/**
* Set expense collection.
- *
- * @param Collection $expense
- *
- * @return ReportGeneratorInterface
*/
public function setExpense(Collection $expense): ReportGeneratorInterface
{
@@ -147,10 +123,6 @@ class MonthReportGenerator implements ReportGeneratorInterface
/**
* Set start date.
- *
- * @param Carbon $date
- *
- * @return ReportGeneratorInterface
*/
public function setStartDate(Carbon $date): ReportGeneratorInterface
{
@@ -161,10 +133,6 @@ class MonthReportGenerator implements ReportGeneratorInterface
/**
* Set collection of tags.
- *
- * @param Collection $tags
- *
- * @return ReportGeneratorInterface
*/
public function setTags(Collection $tags): ReportGeneratorInterface
{
diff --git a/app/Generator/Report/Account/MultiYearReportGenerator.php b/app/Generator/Report/Account/MultiYearReportGenerator.php
index 8ac4322348..06619ce900 100644
--- a/app/Generator/Report/Account/MultiYearReportGenerator.php
+++ b/app/Generator/Report/Account/MultiYearReportGenerator.php
@@ -25,15 +25,11 @@ namespace FireflyIII\Generator\Report\Account;
/**
* Class MultiYearReportGenerator.
- *
-
*/
class MultiYearReportGenerator extends MonthReportGenerator
{
/**
* Returns the preferred period.
- *
- * @return string
*/
protected function preferredPeriod(): string
{
diff --git a/app/Generator/Report/Account/YearReportGenerator.php b/app/Generator/Report/Account/YearReportGenerator.php
index 0f73b14d13..e911928c85 100644
--- a/app/Generator/Report/Account/YearReportGenerator.php
+++ b/app/Generator/Report/Account/YearReportGenerator.php
@@ -25,15 +25,11 @@ namespace FireflyIII\Generator\Report\Account;
/**
* Class YearReportGenerator.
- *
-
*/
class YearReportGenerator extends MonthReportGenerator
{
/**
* Returns the preferred period.
- *
- * @return string
*/
protected function preferredPeriod(): string
{
diff --git a/app/Generator/Report/Audit/MonthReportGenerator.php b/app/Generator/Report/Audit/MonthReportGenerator.php
index 30f5c162c9..8e12fbea01 100644
--- a/app/Generator/Report/Audit/MonthReportGenerator.php
+++ b/app/Generator/Report/Audit/MonthReportGenerator.php
@@ -31,9 +31,6 @@ use FireflyIII\Models\Account;
use FireflyIII\Repositories\Account\AccountRepositoryInterface;
use FireflyIII\Repositories\Journal\JournalRepositoryInterface;
use Illuminate\Support\Collection;
-use Illuminate\Support\Facades\Log;
-use JsonException;
-use Throwable;
/**
* Class MonthReportGenerator.
@@ -47,15 +44,14 @@ class MonthReportGenerator implements ReportGeneratorInterface
/**
* Generates the report.
*
- * @return string
* @throws FireflyException
- * @throws JsonException
*/
public function generate(): string
{
- $auditData = [];
- $dayBefore = clone $this->start;
+ $auditData = [];
+ $dayBefore = clone $this->start;
$dayBefore->subDay();
+
/** @var Account $account */
foreach ($this->accounts as $account) {
// balance the day before:
@@ -93,14 +89,17 @@ class MonthReportGenerator implements ReportGeneratorInterface
'payment_date',
'invoice_date',
];
+
try {
$result = view('reports.audit.report', compact('reportType', 'accountIds', 'auditData', 'hideable', 'defaultShow'))
->with('start', $this->start)->with('end', $this->end)->with('accounts', $this->accounts)
- ->render();
- } catch (Throwable $e) {
- Log::error(sprintf('Cannot render reports.audit.report: %s', $e->getMessage()));
- Log::error($e->getTraceAsString());
+ ->render()
+ ;
+ } catch (\Throwable $e) {
+ app('log')->error(sprintf('Cannot render reports.audit.report: %s', $e->getMessage()));
+ app('log')->error($e->getTraceAsString());
$result = sprintf('Could not render report view: %s', $e->getMessage());
+
throw new FireflyException($result, 0, $e);
}
@@ -110,12 +109,7 @@ class MonthReportGenerator implements ReportGeneratorInterface
/**
* Get the audit report.
*
- * @param Account $account
- * @param Carbon $date
- *
- * @return array
* @throws FireflyException
- * @throws JsonException
*/
public function getAuditReport(Account $account, Carbon $date): array
{
@@ -128,15 +122,16 @@ class MonthReportGenerator implements ReportGeneratorInterface
$journalRepository->setUser($account->user);
/** @var GroupCollectorInterface $collector */
- $collector = app(GroupCollectorInterface::class);
+ $collector = app(GroupCollectorInterface::class);
$collector->setAccounts(new Collection([$account]))->setRange($this->start, $this->end)->withAccountInformation()
- ->withBudgetInformation()->withCategoryInformation()->withBillInformation();
- $journals = $collector->getExtractedJournals();
- $journals = array_reverse($journals, true);
- $dayBeforeBalance = app('steam')->balance($account, $date);
- $startBalance = $dayBeforeBalance;
- $defaultCurrency = app('amount')->getDefaultCurrencyByUser($account->user);
- $currency = $accountRepository->getAccountCurrency($account) ?? $defaultCurrency;
+ ->withBudgetInformation()->withCategoryInformation()->withBillInformation()
+ ;
+ $journals = $collector->getExtractedJournals();
+ $journals = array_reverse($journals, true);
+ $dayBeforeBalance = app('steam')->balance($account, $date);
+ $startBalance = $dayBeforeBalance;
+ $defaultCurrency = app('amount')->getDefaultCurrencyByUserGroup($account->user->userGroup);
+ $currency = $accountRepository->getAccountCurrency($account) ?? $defaultCurrency;
foreach ($journals as $index => $journal) {
$journals[$index]['balance_before'] = $startBalance;
@@ -154,19 +149,19 @@ class MonthReportGenerator implements ReportGeneratorInterface
}
}
- $newBalance = bcadd($startBalance, $transactionAmount);
- $journals[$index]['balance_after'] = $newBalance;
- $startBalance = $newBalance;
+ $newBalance = bcadd($startBalance, $transactionAmount);
+ $journals[$index]['balance_after'] = $newBalance;
+ $startBalance = $newBalance;
// add meta dates for each journal.
- $journals[$index]['interest_date'] = $journalRepository->getMetaDateById($journal['transaction_journal_id'], 'interest_date');
- $journals[$index]['book_date'] = $journalRepository->getMetaDateById($journal['transaction_journal_id'], 'book_date');
- $journals[$index]['process_date'] = $journalRepository->getMetaDateById($journal['transaction_journal_id'], 'process_date');
- $journals[$index]['due_date'] = $journalRepository->getMetaDateById($journal['transaction_journal_id'], 'due_date');
- $journals[$index]['payment_date'] = $journalRepository->getMetaDateById($journal['transaction_journal_id'], 'payment_date');
- $journals[$index]['invoice_date'] = $journalRepository->getMetaDateById($journal['transaction_journal_id'], 'invoice_date');
+ $journals[$index]['interest_date'] = $journalRepository->getMetaDateById($journal['transaction_journal_id'], 'interest_date');
+ $journals[$index]['book_date'] = $journalRepository->getMetaDateById($journal['transaction_journal_id'], 'book_date');
+ $journals[$index]['process_date'] = $journalRepository->getMetaDateById($journal['transaction_journal_id'], 'process_date');
+ $journals[$index]['due_date'] = $journalRepository->getMetaDateById($journal['transaction_journal_id'], 'due_date');
+ $journals[$index]['payment_date'] = $journalRepository->getMetaDateById($journal['transaction_journal_id'], 'payment_date');
+ $journals[$index]['invoice_date'] = $journalRepository->getMetaDateById($journal['transaction_journal_id'], 'invoice_date');
}
- $locale = app('steam')->getLocale();
+ $locale = app('steam')->getLocale();
return [
'journals' => $journals,
@@ -181,10 +176,6 @@ class MonthReportGenerator implements ReportGeneratorInterface
/**
* Account collection setter.
- *
- * @param Collection $accounts
- *
- * @return ReportGeneratorInterface
*/
public function setAccounts(Collection $accounts): ReportGeneratorInterface
{
@@ -195,10 +186,6 @@ class MonthReportGenerator implements ReportGeneratorInterface
/**
* Budget collection setter.
- *
- * @param Collection $budgets
- *
- * @return ReportGeneratorInterface
*/
public function setBudgets(Collection $budgets): ReportGeneratorInterface
{
@@ -207,10 +194,6 @@ class MonthReportGenerator implements ReportGeneratorInterface
/**
* Category collection setter.
- *
- * @param Collection $categories
- *
- * @return ReportGeneratorInterface
*/
public function setCategories(Collection $categories): ReportGeneratorInterface
{
@@ -219,10 +202,6 @@ class MonthReportGenerator implements ReportGeneratorInterface
/**
* End date setter.
- *
- * @param Carbon $date
- *
- * @return ReportGeneratorInterface
*/
public function setEndDate(Carbon $date): ReportGeneratorInterface
{
@@ -233,10 +212,6 @@ class MonthReportGenerator implements ReportGeneratorInterface
/**
* Expenses collection setter.
- *
- * @param Collection $expense
- *
- * @return ReportGeneratorInterface
*/
public function setExpense(Collection $expense): ReportGeneratorInterface
{
@@ -246,10 +221,6 @@ class MonthReportGenerator implements ReportGeneratorInterface
/**
* Start date collection setter.
- *
- * @param Carbon $date
- *
- * @return ReportGeneratorInterface
*/
public function setStartDate(Carbon $date): ReportGeneratorInterface
{
@@ -260,10 +231,6 @@ class MonthReportGenerator implements ReportGeneratorInterface
/**
* Tags collection setter.
- *
- * @param Collection $tags
- *
- * @return ReportGeneratorInterface
*/
public function setTags(Collection $tags): ReportGeneratorInterface
{
diff --git a/app/Generator/Report/Audit/MultiYearReportGenerator.php b/app/Generator/Report/Audit/MultiYearReportGenerator.php
index 1677320748..2dde9586a0 100644
--- a/app/Generator/Report/Audit/MultiYearReportGenerator.php
+++ b/app/Generator/Report/Audit/MultiYearReportGenerator.php
@@ -25,9 +25,5 @@ namespace FireflyIII\Generator\Report\Audit;
/**
* Class MultiYearReportGenerator.
- *
-
*/
-class MultiYearReportGenerator extends MonthReportGenerator
-{
-}
+class MultiYearReportGenerator extends MonthReportGenerator {}
diff --git a/app/Generator/Report/Audit/YearReportGenerator.php b/app/Generator/Report/Audit/YearReportGenerator.php
index df7144b367..6357823820 100644
--- a/app/Generator/Report/Audit/YearReportGenerator.php
+++ b/app/Generator/Report/Audit/YearReportGenerator.php
@@ -25,9 +25,5 @@ namespace FireflyIII\Generator\Report\Audit;
/**
* Class YearReportGenerator.
- *
-
*/
-class YearReportGenerator extends MonthReportGenerator
-{
-}
+class YearReportGenerator extends MonthReportGenerator {}
diff --git a/app/Generator/Report/Budget/MonthReportGenerator.php b/app/Generator/Report/Budget/MonthReportGenerator.php
index 477c2e1f68..7ec1cad458 100644
--- a/app/Generator/Report/Budget/MonthReportGenerator.php
+++ b/app/Generator/Report/Budget/MonthReportGenerator.php
@@ -29,14 +29,10 @@ use FireflyIII\Generator\Report\ReportGeneratorInterface;
use FireflyIII\Helpers\Collector\GroupCollectorInterface;
use FireflyIII\Models\TransactionType;
use Illuminate\Support\Collection;
-use Illuminate\Support\Facades\Log;
-use Throwable;
/**
* Class MonthReportGenerator.
* TODO include info about tags.
- *
-
*/
class MonthReportGenerator implements ReportGeneratorInterface
{
@@ -57,13 +53,13 @@ class MonthReportGenerator implements ReportGeneratorInterface
/**
* Generates the report.
*
- * @return string
* @throws FireflyException
*/
public function generate(): string
{
$accountIds = implode(',', $this->accounts->pluck('id')->toArray());
$budgetIds = implode(',', $this->budgets->pluck('id')->toArray());
+
try {
$result = view(
'reports.budget.month',
@@ -72,11 +68,13 @@ class MonthReportGenerator implements ReportGeneratorInterface
->with('start', $this->start)->with('end', $this->end)
->with('budgets', $this->budgets)
->with('accounts', $this->accounts)
- ->render();
- } catch (Throwable $e) {
- Log::error(sprintf('Cannot render reports.account.report: %s', $e->getMessage()));
- Log::error($e->getTraceAsString());
+ ->render()
+ ;
+ } catch (\Throwable $e) {
+ app('log')->error(sprintf('Cannot render reports.account.report: %s', $e->getMessage()));
+ app('log')->error($e->getTraceAsString());
$result = sprintf('Could not render report view: %s', $e->getMessage());
+
throw new FireflyException($result, 0, $e);
}
@@ -85,10 +83,6 @@ class MonthReportGenerator implements ReportGeneratorInterface
/**
* Unused category setter.
- *
- * @param Collection $categories
- *
- * @return ReportGeneratorInterface
*/
public function setCategories(Collection $categories): ReportGeneratorInterface
{
@@ -97,10 +91,6 @@ class MonthReportGenerator implements ReportGeneratorInterface
/**
* Set the end date of the report.
- *
- * @param Carbon $date
- *
- * @return ReportGeneratorInterface
*/
public function setEndDate(Carbon $date): ReportGeneratorInterface
{
@@ -111,10 +101,6 @@ class MonthReportGenerator implements ReportGeneratorInterface
/**
* Unused expense setter.
- *
- * @param Collection $expense
- *
- * @return ReportGeneratorInterface
*/
public function setExpense(Collection $expense): ReportGeneratorInterface
{
@@ -123,10 +109,6 @@ class MonthReportGenerator implements ReportGeneratorInterface
/**
* Set the start date of the report.
- *
- * @param Carbon $date
- *
- * @return ReportGeneratorInterface
*/
public function setStartDate(Carbon $date): ReportGeneratorInterface
{
@@ -137,10 +119,6 @@ class MonthReportGenerator implements ReportGeneratorInterface
/**
* Unused tags setter.
- *
- * @param Collection $tags
- *
- * @return ReportGeneratorInterface
*/
public function setTags(Collection $tags): ReportGeneratorInterface
{
@@ -149,24 +127,23 @@ class MonthReportGenerator implements ReportGeneratorInterface
/**
* Get the expenses.
- *
- * @return array
*/
protected function getExpenses(): array
{
if (0 !== count($this->expenses)) {
- Log::debug('Return previous set of expenses.');
+ app('log')->debug('Return previous set of expenses.');
return $this->expenses;
}
/** @var GroupCollectorInterface $collector */
- $collector = app(GroupCollectorInterface::class);
+ $collector = app(GroupCollectorInterface::class);
$collector->setAccounts($this->accounts)->setRange($this->start, $this->end)
- ->setTypes([TransactionType::WITHDRAWAL])
- ->withAccountInformation()
- ->withBudgetInformation()
- ->setBudgets($this->budgets);
+ ->setTypes([TransactionType::WITHDRAWAL])
+ ->withAccountInformation()
+ ->withBudgetInformation()
+ ->setBudgets($this->budgets)
+ ;
$journals = $collector->getExtractedJournals();
$this->expenses = $journals;
@@ -176,10 +153,6 @@ class MonthReportGenerator implements ReportGeneratorInterface
/**
* Set the involved budgets.
- *
- * @param Collection $budgets
- *
- * @return ReportGeneratorInterface
*/
public function setBudgets(Collection $budgets): ReportGeneratorInterface
{
@@ -190,10 +163,6 @@ class MonthReportGenerator implements ReportGeneratorInterface
/**
* Set the involved accounts.
- *
- * @param Collection $accounts
- *
- * @return ReportGeneratorInterface
*/
public function setAccounts(Collection $accounts): ReportGeneratorInterface
{
diff --git a/app/Generator/Report/Budget/MultiYearReportGenerator.php b/app/Generator/Report/Budget/MultiYearReportGenerator.php
index a470db9a99..77a8579374 100644
--- a/app/Generator/Report/Budget/MultiYearReportGenerator.php
+++ b/app/Generator/Report/Budget/MultiYearReportGenerator.php
@@ -25,9 +25,5 @@ namespace FireflyIII\Generator\Report\Budget;
/**
* Class MultiYearReportGenerator.
- *
-
*/
-class MultiYearReportGenerator extends MonthReportGenerator
-{
-}
+class MultiYearReportGenerator extends MonthReportGenerator {}
diff --git a/app/Generator/Report/Budget/YearReportGenerator.php b/app/Generator/Report/Budget/YearReportGenerator.php
index 8b0cd930b7..4251a99e49 100644
--- a/app/Generator/Report/Budget/YearReportGenerator.php
+++ b/app/Generator/Report/Budget/YearReportGenerator.php
@@ -25,9 +25,5 @@ namespace FireflyIII\Generator\Report\Budget;
/**
* Class YearReportGenerator.
- *
-
*/
-class YearReportGenerator extends MonthReportGenerator
-{
-}
+class YearReportGenerator extends MonthReportGenerator {}
diff --git a/app/Generator/Report/Category/MonthReportGenerator.php b/app/Generator/Report/Category/MonthReportGenerator.php
index b7ed3cd4e5..b840358ccf 100644
--- a/app/Generator/Report/Category/MonthReportGenerator.php
+++ b/app/Generator/Report/Category/MonthReportGenerator.php
@@ -29,14 +29,10 @@ use FireflyIII\Generator\Report\ReportGeneratorInterface;
use FireflyIII\Helpers\Collector\GroupCollectorInterface;
use FireflyIII\Models\TransactionType;
use Illuminate\Support\Collection;
-use Illuminate\Support\Facades\Log;
-use Throwable;
/**
* Class MonthReportGenerator.
* TODO include info about tags
- *
-
*/
class MonthReportGenerator implements ReportGeneratorInterface
{
@@ -59,7 +55,6 @@ class MonthReportGenerator implements ReportGeneratorInterface
/**
* Generates the report.
*
- * @return string
* @throws FireflyException
*/
public function generate(): string
@@ -74,21 +69,19 @@ class MonthReportGenerator implements ReportGeneratorInterface
->with('start', $this->start)->with('end', $this->end)
->with('categories', $this->categories)
->with('accounts', $this->accounts)
- ->render();
- } catch (Throwable $e) {
- Log::error(sprintf('Cannot render reports.category.month: %s', $e->getMessage()));
- Log::error($e->getTraceAsString());
+ ->render()
+ ;
+ } catch (\Throwable $e) {
+ app('log')->error(sprintf('Cannot render reports.category.month: %s', $e->getMessage()));
+ app('log')->error($e->getTraceAsString());
$result = sprintf('Could not render report view: %s', $e->getMessage());
+
throw new FireflyException($result, 0, $e);
}
}
/**
* Empty budget setter.
- *
- * @param Collection $budgets
- *
- * @return ReportGeneratorInterface
*/
public function setBudgets(Collection $budgets): ReportGeneratorInterface
{
@@ -97,10 +90,6 @@ class MonthReportGenerator implements ReportGeneratorInterface
/**
* Set the end date for this report.
- *
- * @param Carbon $date
- *
- * @return ReportGeneratorInterface
*/
public function setEndDate(Carbon $date): ReportGeneratorInterface
{
@@ -111,10 +100,6 @@ class MonthReportGenerator implements ReportGeneratorInterface
/**
* Set the expenses involved in this report.
- *
- * @param Collection $expense
- *
- * @return ReportGeneratorInterface
*/
public function setExpense(Collection $expense): ReportGeneratorInterface
{
@@ -123,10 +108,6 @@ class MonthReportGenerator implements ReportGeneratorInterface
/**
* Set the start date for this report.
- *
- * @param Carbon $date
- *
- * @return ReportGeneratorInterface
*/
public function setStartDate(Carbon $date): ReportGeneratorInterface
{
@@ -137,10 +118,6 @@ class MonthReportGenerator implements ReportGeneratorInterface
/**
* Unused tag setter.
- *
- * @param Collection $tags
- *
- * @return ReportGeneratorInterface
*/
public function setTags(Collection $tags): ReportGeneratorInterface
{
@@ -149,22 +126,21 @@ class MonthReportGenerator implements ReportGeneratorInterface
/**
* Get the expenses for this report.
- *
- * @return array
*/
protected function getExpenses(): array
{
if (0 !== count($this->expenses)) {
- Log::debug('Return previous set of expenses.');
+ app('log')->debug('Return previous set of expenses.');
return $this->expenses;
}
/** @var GroupCollectorInterface $collector */
- $collector = app(GroupCollectorInterface::class);
+ $collector = app(GroupCollectorInterface::class);
$collector->setAccounts($this->accounts)->setRange($this->start, $this->end)
- ->setTypes([TransactionType::WITHDRAWAL, TransactionType::TRANSFER])
- ->setCategories($this->categories)->withAccountInformation();
+ ->setTypes([TransactionType::WITHDRAWAL, TransactionType::TRANSFER])
+ ->setCategories($this->categories)->withAccountInformation()
+ ;
$transactions = $collector->getExtractedJournals();
$this->expenses = $transactions;
@@ -174,10 +150,6 @@ class MonthReportGenerator implements ReportGeneratorInterface
/**
* Set the categories involved in this report.
- *
- * @param Collection $categories
- *
- * @return ReportGeneratorInterface
*/
public function setCategories(Collection $categories): ReportGeneratorInterface
{
@@ -188,10 +160,6 @@ class MonthReportGenerator implements ReportGeneratorInterface
/**
* Set the involved accounts.
- *
- * @param Collection $accounts
- *
- * @return ReportGeneratorInterface
*/
public function setAccounts(Collection $accounts): ReportGeneratorInterface
{
@@ -202,8 +170,6 @@ class MonthReportGenerator implements ReportGeneratorInterface
/**
* Get the income for this report.
- *
- * @return array
*/
protected function getIncome(): array
{
@@ -212,11 +178,12 @@ class MonthReportGenerator implements ReportGeneratorInterface
}
/** @var GroupCollectorInterface $collector */
- $collector = app(GroupCollectorInterface::class);
+ $collector = app(GroupCollectorInterface::class);
$collector->setAccounts($this->accounts)->setRange($this->start, $this->end)
- ->setTypes([TransactionType::DEPOSIT, TransactionType::TRANSFER])
- ->setCategories($this->categories)->withAccountInformation();
+ ->setTypes([TransactionType::DEPOSIT, TransactionType::TRANSFER])
+ ->setCategories($this->categories)->withAccountInformation()
+ ;
$transactions = $collector->getExtractedJournals();
$this->income = $transactions;
diff --git a/app/Generator/Report/Category/MultiYearReportGenerator.php b/app/Generator/Report/Category/MultiYearReportGenerator.php
index f8525587c0..c7fb20662a 100644
--- a/app/Generator/Report/Category/MultiYearReportGenerator.php
+++ b/app/Generator/Report/Category/MultiYearReportGenerator.php
@@ -25,9 +25,5 @@ namespace FireflyIII\Generator\Report\Category;
/**
* Class MultiYearReportGenerator.
- *
-
*/
-class MultiYearReportGenerator extends MonthReportGenerator
-{
-}
+class MultiYearReportGenerator extends MonthReportGenerator {}
diff --git a/app/Generator/Report/Category/YearReportGenerator.php b/app/Generator/Report/Category/YearReportGenerator.php
index 982ef37fe5..49f3d2f84f 100644
--- a/app/Generator/Report/Category/YearReportGenerator.php
+++ b/app/Generator/Report/Category/YearReportGenerator.php
@@ -25,9 +25,5 @@ namespace FireflyIII\Generator\Report\Category;
/**
* Class YearReportGenerator.
- *
-
*/
-class YearReportGenerator extends MonthReportGenerator
-{
-}
+class YearReportGenerator extends MonthReportGenerator {}
diff --git a/app/Generator/Report/ReportGeneratorFactory.php b/app/Generator/Report/ReportGeneratorFactory.php
index a577f8f076..fcb97f979f 100644
--- a/app/Generator/Report/ReportGeneratorFactory.php
+++ b/app/Generator/Report/ReportGeneratorFactory.php
@@ -28,20 +28,12 @@ use FireflyIII\Exceptions\FireflyException;
/**
* Class ReportGeneratorFactory.
- *
-
*/
class ReportGeneratorFactory
{
/**
* Static report generator class.
*
- * @param string $type
- * @param Carbon $start
- * @param Carbon $end
- *
- * @return ReportGeneratorInterface
- *
* @throws FireflyException
*/
public static function reportGenerator(string $type, Carbon $start, Carbon $end): ReportGeneratorInterface
@@ -57,7 +49,7 @@ class ReportGeneratorFactory
$period = 'MultiYear';
}
- $class = sprintf('FireflyIII\Generator\Report\%s\%sReportGenerator', $type, $period);
+ $class = sprintf('FireflyIII\Generator\Report\%s\%sReportGenerator', $type, $period);
if (class_exists($class)) {
/** @var ReportGeneratorInterface $obj */
$obj = app($class);
@@ -66,6 +58,7 @@ class ReportGeneratorFactory
return $obj;
}
+
throw new FireflyException(sprintf('Cannot generate report. There is no "%s"-report for period "%s".', $type, $period));
}
}
diff --git a/app/Generator/Report/ReportGeneratorInterface.php b/app/Generator/Report/ReportGeneratorInterface.php
index c56c71afbd..67a0991e4e 100644
--- a/app/Generator/Report/ReportGeneratorInterface.php
+++ b/app/Generator/Report/ReportGeneratorInterface.php
@@ -33,71 +33,41 @@ interface ReportGeneratorInterface
{
/**
* Generate the report.
- *
- * @return string
*/
public function generate(): string;
/**
* Set the involved accounts.
- *
- * @param Collection $accounts
- *
- * @return ReportGeneratorInterface
*/
- public function setAccounts(Collection $accounts): ReportGeneratorInterface;
+ public function setAccounts(Collection $accounts): self;
/**
* Set the involved budgets.
- *
- * @param Collection $budgets
- *
- * @return ReportGeneratorInterface
*/
- public function setBudgets(Collection $budgets): ReportGeneratorInterface;
+ public function setBudgets(Collection $budgets): self;
/**
* Set the involved categories.
- *
- * @param Collection $categories
- *
- * @return ReportGeneratorInterface
*/
- public function setCategories(Collection $categories): ReportGeneratorInterface;
+ public function setCategories(Collection $categories): self;
/**
* Set the end date.
- *
- * @param Carbon $date
- *
- * @return ReportGeneratorInterface
*/
- public function setEndDate(Carbon $date): ReportGeneratorInterface;
+ public function setEndDate(Carbon $date): self;
/**
* Set the expense accounts.
- *
- * @param Collection $expense
- *
- * @return ReportGeneratorInterface
*/
- public function setExpense(Collection $expense): ReportGeneratorInterface;
+ public function setExpense(Collection $expense): self;
/**
* Set the start date.
- *
- * @param Carbon $date
- *
- * @return ReportGeneratorInterface
*/
- public function setStartDate(Carbon $date): ReportGeneratorInterface;
+ public function setStartDate(Carbon $date): self;
/**
* Set the tags.
- *
- * @param Collection $tags
- *
- * @return ReportGeneratorInterface
*/
- public function setTags(Collection $tags): ReportGeneratorInterface;
+ public function setTags(Collection $tags): self;
}
diff --git a/app/Generator/Report/Standard/MonthReportGenerator.php b/app/Generator/Report/Standard/MonthReportGenerator.php
index a79956d9b1..fe70dc3041 100644
--- a/app/Generator/Report/Standard/MonthReportGenerator.php
+++ b/app/Generator/Report/Standard/MonthReportGenerator.php
@@ -27,27 +27,24 @@ use Carbon\Carbon;
use FireflyIII\Exceptions\FireflyException;
use FireflyIII\Generator\Report\ReportGeneratorInterface;
use Illuminate\Support\Collection;
-use Illuminate\Support\Facades\Log;
-use Throwable;
/**
* Class MonthReportGenerator.
- *
-
*/
class MonthReportGenerator implements ReportGeneratorInterface
{
/** @var Collection The accounts involved in the report. */
private $accounts;
+
/** @var Carbon The end date. */
private $end;
+
/** @var Carbon The start date. */
private $start;
/**
* Generates the report.
*
- * @return string
* @throws FireflyException
*/
public function generate(): string
@@ -57,20 +54,17 @@ class MonthReportGenerator implements ReportGeneratorInterface
try {
return view('reports.default.month', compact('accountIds', 'reportType'))->with('start', $this->start)->with('end', $this->end)->render();
- } catch (Throwable $e) {
- Log::error(sprintf('Cannot render reports.default.month: %s', $e->getMessage()));
- Log::error($e->getTraceAsString());
+ } catch (\Throwable $e) {
+ app('log')->error(sprintf('Cannot render reports.default.month: %s', $e->getMessage()));
+ app('log')->error($e->getTraceAsString());
$result = 'Could not render report view.';
+
throw new FireflyException($result, 0, $e);
}
}
/**
* Sets the accounts involved in the report.
- *
- * @param Collection $accounts
- *
- * @return ReportGeneratorInterface
*/
public function setAccounts(Collection $accounts): ReportGeneratorInterface
{
@@ -81,10 +75,6 @@ class MonthReportGenerator implements ReportGeneratorInterface
/**
* Unused budget setter.
- *
- * @param Collection $budgets
- *
- * @return ReportGeneratorInterface
*/
public function setBudgets(Collection $budgets): ReportGeneratorInterface
{
@@ -93,10 +83,6 @@ class MonthReportGenerator implements ReportGeneratorInterface
/**
* Unused category setter.
- *
- * @param Collection $categories
- *
- * @return ReportGeneratorInterface
*/
public function setCategories(Collection $categories): ReportGeneratorInterface
{
@@ -105,10 +91,6 @@ class MonthReportGenerator implements ReportGeneratorInterface
/**
* Set the end date of the report.
- *
- * @param Carbon $date
- *
- * @return ReportGeneratorInterface
*/
public function setEndDate(Carbon $date): ReportGeneratorInterface
{
@@ -119,10 +101,6 @@ class MonthReportGenerator implements ReportGeneratorInterface
/**
* Set the expenses used in this report.
- *
- * @param Collection $expense
- *
- * @return ReportGeneratorInterface
*/
public function setExpense(Collection $expense): ReportGeneratorInterface
{
@@ -131,10 +109,6 @@ class MonthReportGenerator implements ReportGeneratorInterface
/**
* Set the start date of this report.
- *
- * @param Carbon $date
- *
- * @return ReportGeneratorInterface
*/
public function setStartDate(Carbon $date): ReportGeneratorInterface
{
@@ -145,10 +119,6 @@ class MonthReportGenerator implements ReportGeneratorInterface
/**
* Set the tags used in this report.
- *
- * @param Collection $tags
- *
- * @return ReportGeneratorInterface
*/
public function setTags(Collection $tags): ReportGeneratorInterface
{
diff --git a/app/Generator/Report/Standard/MultiYearReportGenerator.php b/app/Generator/Report/Standard/MultiYearReportGenerator.php
index 9647dfd555..f40dcfe8eb 100644
--- a/app/Generator/Report/Standard/MultiYearReportGenerator.php
+++ b/app/Generator/Report/Standard/MultiYearReportGenerator.php
@@ -27,27 +27,24 @@ use Carbon\Carbon;
use FireflyIII\Exceptions\FireflyException;
use FireflyIII\Generator\Report\ReportGeneratorInterface;
use Illuminate\Support\Collection;
-use Illuminate\Support\Facades\Log;
-use Throwable;
/**
* Class MonthReportGenerator.
- *
-
*/
class MultiYearReportGenerator implements ReportGeneratorInterface
{
/** @var Collection The accounts involved. */
private $accounts;
+
/** @var Carbon The end date. */
private $end;
+
/** @var Carbon The start date. */
private $start;
/**
* Generates the report.
*
- * @return string
* @throws FireflyException
*/
public function generate(): string
@@ -61,20 +58,17 @@ class MultiYearReportGenerator implements ReportGeneratorInterface
'reports.default.multi-year',
compact('accountIds', 'reportType')
)->with('start', $this->start)->with('end', $this->end)->render();
- } catch (Throwable $e) {
- Log::error(sprintf('Cannot render reports.default.multi-year: %s', $e->getMessage()));
- Log::error($e->getTraceAsString());
+ } catch (\Throwable $e) {
+ app('log')->error(sprintf('Cannot render reports.default.multi-year: %s', $e->getMessage()));
+ app('log')->error($e->getTraceAsString());
$result = sprintf('Could not render report view: %s', $e->getMessage());
+
throw new FireflyException($result, 0, $e);
}
}
/**
* Sets the accounts used in the report.
- *
- * @param Collection $accounts
- *
- * @return ReportGeneratorInterface
*/
public function setAccounts(Collection $accounts): ReportGeneratorInterface
{
@@ -85,10 +79,6 @@ class MultiYearReportGenerator implements ReportGeneratorInterface
/**
* Sets the budgets used in the report.
- *
- * @param Collection $budgets
- *
- * @return ReportGeneratorInterface
*/
public function setBudgets(Collection $budgets): ReportGeneratorInterface
{
@@ -97,10 +87,6 @@ class MultiYearReportGenerator implements ReportGeneratorInterface
/**
* Sets the categories used in the report.
- *
- * @param Collection $categories
- *
- * @return ReportGeneratorInterface
*/
public function setCategories(Collection $categories): ReportGeneratorInterface
{
@@ -109,10 +95,6 @@ class MultiYearReportGenerator implements ReportGeneratorInterface
/**
* Sets the end date used in the report.
- *
- * @param Carbon $date
- *
- * @return ReportGeneratorInterface
*/
public function setEndDate(Carbon $date): ReportGeneratorInterface
{
@@ -123,10 +105,6 @@ class MultiYearReportGenerator implements ReportGeneratorInterface
/**
* Unused setter for expenses.
- *
- * @param Collection $expense
- *
- * @return ReportGeneratorInterface
*/
public function setExpense(Collection $expense): ReportGeneratorInterface
{
@@ -135,10 +113,6 @@ class MultiYearReportGenerator implements ReportGeneratorInterface
/**
* Set the start date of the report.
- *
- * @param Carbon $date
- *
- * @return ReportGeneratorInterface
*/
public function setStartDate(Carbon $date): ReportGeneratorInterface
{
@@ -149,10 +123,6 @@ class MultiYearReportGenerator implements ReportGeneratorInterface
/**
* Set the tags for the report.
- *
- * @param Collection $tags
- *
- * @return ReportGeneratorInterface
*/
public function setTags(Collection $tags): ReportGeneratorInterface
{
diff --git a/app/Generator/Report/Standard/YearReportGenerator.php b/app/Generator/Report/Standard/YearReportGenerator.php
index 8cd9c768eb..74b3b57ea9 100644
--- a/app/Generator/Report/Standard/YearReportGenerator.php
+++ b/app/Generator/Report/Standard/YearReportGenerator.php
@@ -27,27 +27,24 @@ use Carbon\Carbon;
use FireflyIII\Exceptions\FireflyException;
use FireflyIII\Generator\Report\ReportGeneratorInterface;
use Illuminate\Support\Collection;
-use Illuminate\Support\Facades\Log;
-use Throwable;
/**
* Class MonthReportGenerator.
- *
-
*/
class YearReportGenerator implements ReportGeneratorInterface
{
/** @var Collection The accounts involved. */
private $accounts;
+
/** @var Carbon The end date. */
private $end;
+
/** @var Carbon The start date. */
private $start;
/**
* Generates the report.
*
- * @return string
* @throws FireflyException
*/
public function generate(): string
@@ -61,10 +58,11 @@ class YearReportGenerator implements ReportGeneratorInterface
'reports.default.year',
compact('accountIds', 'reportType')
)->with('start', $this->start)->with('end', $this->end)->render();
- } catch (Throwable $e) {
- Log::error(sprintf('Cannot render reports.account.report: %s', $e->getMessage()));
- Log::error($e->getTraceAsString());
+ } catch (\Throwable $e) {
+ app('log')->error(sprintf('Cannot render reports.account.report: %s', $e->getMessage()));
+ app('log')->error($e->getTraceAsString());
$result = 'Could not render report view.';
+
throw new FireflyException($result, 0, $e);
}
@@ -73,10 +71,6 @@ class YearReportGenerator implements ReportGeneratorInterface
/**
* Set the accounts.
- *
- * @param Collection $accounts
- *
- * @return ReportGeneratorInterface
*/
public function setAccounts(Collection $accounts): ReportGeneratorInterface
{
@@ -87,10 +81,6 @@ class YearReportGenerator implements ReportGeneratorInterface
/**
* Unused budget setter.
- *
- * @param Collection $budgets
- *
- * @return ReportGeneratorInterface
*/
public function setBudgets(Collection $budgets): ReportGeneratorInterface
{
@@ -99,10 +89,6 @@ class YearReportGenerator implements ReportGeneratorInterface
/**
* Unused categories setter.
- *
- * @param Collection $categories
- *
- * @return ReportGeneratorInterface
*/
public function setCategories(Collection $categories): ReportGeneratorInterface
{
@@ -111,10 +97,6 @@ class YearReportGenerator implements ReportGeneratorInterface
/**
* Set the end date.
- *
- * @param Carbon $date
- *
- * @return ReportGeneratorInterface
*/
public function setEndDate(Carbon $date): ReportGeneratorInterface
{
@@ -125,10 +107,6 @@ class YearReportGenerator implements ReportGeneratorInterface
/**
* Set the expenses used.
- *
- * @param Collection $expense
- *
- * @return ReportGeneratorInterface
*/
public function setExpense(Collection $expense): ReportGeneratorInterface
{
@@ -137,10 +115,6 @@ class YearReportGenerator implements ReportGeneratorInterface
/**
* Set the start date.
- *
- * @param Carbon $date
- *
- * @return ReportGeneratorInterface
*/
public function setStartDate(Carbon $date): ReportGeneratorInterface
{
@@ -151,10 +125,6 @@ class YearReportGenerator implements ReportGeneratorInterface
/**
* Unused tags setter.
- *
- * @param Collection $tags
- *
- * @return ReportGeneratorInterface
*/
public function setTags(Collection $tags): ReportGeneratorInterface
{
diff --git a/app/Generator/Report/Tag/MonthReportGenerator.php b/app/Generator/Report/Tag/MonthReportGenerator.php
index 29ffb4ce91..23149855f0 100644
--- a/app/Generator/Report/Tag/MonthReportGenerator.php
+++ b/app/Generator/Report/Tag/MonthReportGenerator.php
@@ -27,13 +27,9 @@ use Carbon\Carbon;
use FireflyIII\Exceptions\FireflyException;
use FireflyIII\Generator\Report\ReportGeneratorInterface;
use Illuminate\Support\Collection;
-use Illuminate\Support\Facades\Log;
-use Throwable;
/**
* Class MonthReportGenerator.
- *
-
*/
class MonthReportGenerator implements ReportGeneratorInterface
{
@@ -54,7 +50,6 @@ class MonthReportGenerator implements ReportGeneratorInterface
/**
* Generate the report.
*
- * @return string
* @throws FireflyException
*/
public function generate(): string
@@ -69,10 +64,11 @@ class MonthReportGenerator implements ReportGeneratorInterface
'reports.tag.month',
compact('accountIds', 'reportType', 'tagIds')
)->with('start', $this->start)->with('end', $this->end)->with('tags', $this->tags)->with('accounts', $this->accounts)->render();
- } catch (Throwable $e) {
- Log::error(sprintf('Cannot render reports.tag.month: %s', $e->getMessage()));
- Log::error($e->getTraceAsString());
+ } catch (\Throwable $e) {
+ app('log')->error(sprintf('Cannot render reports.tag.month: %s', $e->getMessage()));
+ app('log')->error($e->getTraceAsString());
$result = sprintf('Could not render report view: %s', $e->getMessage());
+
throw new FireflyException($result, 0, $e);
}
@@ -81,10 +77,6 @@ class MonthReportGenerator implements ReportGeneratorInterface
/**
* Set the accounts.
- *
- * @param Collection $accounts
- *
- * @return ReportGeneratorInterface
*/
public function setAccounts(Collection $accounts): ReportGeneratorInterface
{
@@ -95,10 +87,6 @@ class MonthReportGenerator implements ReportGeneratorInterface
/**
* Unused budget setter.
- *
- * @param Collection $budgets
- *
- * @return ReportGeneratorInterface
*/
public function setBudgets(Collection $budgets): ReportGeneratorInterface
{
@@ -107,10 +95,6 @@ class MonthReportGenerator implements ReportGeneratorInterface
/**
* Unused category setter.
- *
- * @param Collection $categories
- *
- * @return ReportGeneratorInterface
*/
public function setCategories(Collection $categories): ReportGeneratorInterface
{
@@ -119,10 +103,6 @@ class MonthReportGenerator implements ReportGeneratorInterface
/**
* Set the end date of the report.
- *
- * @param Carbon $date
- *
- * @return ReportGeneratorInterface
*/
public function setEndDate(Carbon $date): ReportGeneratorInterface
{
@@ -133,10 +113,6 @@ class MonthReportGenerator implements ReportGeneratorInterface
/**
* Set the expenses in this report.
- *
- * @param Collection $expense
- *
- * @return ReportGeneratorInterface
*/
public function setExpense(Collection $expense): ReportGeneratorInterface
{
@@ -145,10 +121,6 @@ class MonthReportGenerator implements ReportGeneratorInterface
/**
* Set the start date.
- *
- * @param Carbon $date
- *
- * @return ReportGeneratorInterface
*/
public function setStartDate(Carbon $date): ReportGeneratorInterface
{
@@ -159,10 +131,6 @@ class MonthReportGenerator implements ReportGeneratorInterface
/**
* Set the tags used in this report.
- *
- * @param Collection $tags
- *
- * @return ReportGeneratorInterface
*/
public function setTags(Collection $tags): ReportGeneratorInterface
{
diff --git a/app/Generator/Report/Tag/MultiYearReportGenerator.php b/app/Generator/Report/Tag/MultiYearReportGenerator.php
index 6830d8aea2..f4f4b3eca3 100644
--- a/app/Generator/Report/Tag/MultiYearReportGenerator.php
+++ b/app/Generator/Report/Tag/MultiYearReportGenerator.php
@@ -25,9 +25,5 @@ namespace FireflyIII\Generator\Report\Tag;
/**
* Class MultiYearReportGenerator.
- *
-
*/
-class MultiYearReportGenerator extends MonthReportGenerator
-{
-}
+class MultiYearReportGenerator extends MonthReportGenerator {}
diff --git a/app/Generator/Report/Tag/YearReportGenerator.php b/app/Generator/Report/Tag/YearReportGenerator.php
index 0dd2aaa36f..91b94cdd7d 100644
--- a/app/Generator/Report/Tag/YearReportGenerator.php
+++ b/app/Generator/Report/Tag/YearReportGenerator.php
@@ -25,9 +25,5 @@ namespace FireflyIII\Generator\Report\Tag;
/**
* Class YearReportGenerator.
- *
-
*/
-class YearReportGenerator extends MonthReportGenerator
-{
-}
+class YearReportGenerator extends MonthReportGenerator {}
diff --git a/app/Generator/Webhook/MessageGeneratorInterface.php b/app/Generator/Webhook/MessageGeneratorInterface.php
index 1437122341..fbe441bad4 100644
--- a/app/Generator/Webhook/MessageGeneratorInterface.php
+++ b/app/Generator/Webhook/MessageGeneratorInterface.php
@@ -31,35 +31,15 @@ use Illuminate\Support\Collection;
*/
interface MessageGeneratorInterface
{
- /**
- *
- */
public function generateMessages(): void;
- /**
- * @return int
- */
public function getVersion(): int;
- /**
- * @param Collection $objects
- */
public function setObjects(Collection $objects): void;
- /**
- * @param int $trigger
- */
public function setTrigger(int $trigger): void;
- /**
- * @param User $user
- */
public function setUser(User $user): void;
- /**
- * @param Collection $webhooks
- *
- * @return void
- */
public function setWebhooks(Collection $webhooks): void;
}
diff --git a/app/Generator/Webhook/StandardMessageGenerator.php b/app/Generator/Webhook/StandardMessageGenerator.php
index f71c0a8ecb..0a8302710a 100644
--- a/app/Generator/Webhook/StandardMessageGenerator.php
+++ b/app/Generator/Webhook/StandardMessageGenerator.php
@@ -37,8 +37,6 @@ use FireflyIII\Transformers\TransactionGroupTransformer;
use FireflyIII\User;
use Illuminate\Database\Eloquent\Model;
use Illuminate\Support\Collection;
-use Illuminate\Support\Facades\Log;
-use JsonException;
use Ramsey\Uuid\Uuid;
use Symfony\Component\HttpFoundation\ParameterBag;
@@ -53,63 +51,75 @@ class StandardMessageGenerator implements MessageGeneratorInterface
private int $version = 0;
private Collection $webhooks;
- /**
- *
- */
public function __construct()
{
$this->objects = new Collection();
$this->webhooks = new Collection();
}
- /**
- *
- */
public function generateMessages(): void
{
- Log::debug(__METHOD__);
+ app('log')->debug(__METHOD__);
// get the webhooks:
if (0 === $this->webhooks->count()) {
$this->webhooks = $this->getWebhooks();
}
// do some debugging
- Log::debug(
+ app('log')->debug(
sprintf('StandardMessageGenerator will generate messages for %d object(s) and %d webhook(s).', $this->objects->count(), $this->webhooks->count())
);
$this->run();
}
- /**
- * @return Collection
- */
+ public function getVersion(): int
+ {
+ return $this->version;
+ }
+
+ public function setObjects(Collection $objects): void
+ {
+ $this->objects = $objects;
+ }
+
+ public function setTrigger(int $trigger): void
+ {
+ $this->trigger = $trigger;
+ }
+
+ public function setUser(User $user): void
+ {
+ $this->user = $user;
+ }
+
+ public function setWebhooks(Collection $webhooks): void
+ {
+ $this->webhooks = $webhooks;
+ }
+
private function getWebhooks(): Collection
{
return $this->user->webhooks()->where('active', true)->where('trigger', $this->trigger)->get(['webhooks.*']);
}
- /**
- *
- */
private function run(): void
{
- Log::debug('Now in StandardMessageGenerator::run');
+ app('log')->debug('Now in StandardMessageGenerator::run');
+
/** @var Webhook $webhook */
foreach ($this->webhooks as $webhook) {
$this->runWebhook($webhook);
}
- Log::debug('Done with StandardMessageGenerator::run');
+ app('log')->debug('Done with StandardMessageGenerator::run');
}
/**
- * @param Webhook $webhook
- *
* @throws FireflyException
- * @throws JsonException
*/
private function runWebhook(Webhook $webhook): void
{
- Log::debug(sprintf('Now in runWebhook(#%d)', $webhook->id));
+ app('log')->debug(sprintf('Now in runWebhook(#%d)', $webhook->id));
+
/** @var Model $object */
foreach ($this->objects as $object) {
$this->generateMessage($webhook, $object);
@@ -117,17 +127,13 @@ class StandardMessageGenerator implements MessageGeneratorInterface
}
/**
- * @param Webhook $webhook
- * @param Model $model
- *
* @throws FireflyException
- * @throws JsonException
*/
private function generateMessage(Webhook $webhook, Model $model): void
{
- $class = get_class($model);
+ $class = get_class($model);
// Line is ignored because all of Firefly III's Models have an id property.
- Log::debug(sprintf('Now in generateMessage(#%d, %s#%d)', $webhook->id, $class, $model->id)); // @phpstan-ignore-line
+ app('log')->debug(sprintf('Now in generateMessage(#%d, %s#%d)', $webhook->id, $class, $model->id));
$uuid = Uuid::uuid4();
$basicMessage = [
@@ -144,45 +150,55 @@ class StandardMessageGenerator implements MessageGeneratorInterface
switch ($class) {
default:
// Line is ignored because all of Firefly III's Models have an id property.
- Log::error(
+ app('log')->error(
sprintf('Webhook #%d was given %s#%d to deal with but can\'t extract user ID from it.', $webhook->id, $class, $model->id)
- ); // @phpstan-ignore-line
+ );
return;
+
case TransactionGroup::class:
- /** @var TransactionGroup $model */
+ // @var TransactionGroup $model
$basicMessage['user_id'] = $model->user->id;
+
break;
}
// then depends on the response what to put in the message:
switch ($webhook->response) {
default:
- Log::error(
+ app('log')->error(
sprintf('The response code for webhook #%d is "%d" and the message generator cant handle it. Soft fail.', $webhook->id, $webhook->response)
);
return;
+
case WebhookResponse::NONE->value:
$basicMessage['content'] = [];
+
break;
+
case WebhookResponse::TRANSACTIONS->value:
- $transformer = new TransactionGroupTransformer();
+ /** @var TransactionGroup $model */
+ $transformer = new TransactionGroupTransformer();
+
try {
$basicMessage['content'] = $transformer->transformObject($model);
} catch (FireflyException $e) {
- Log::error(
+ app('log')->error(
sprintf('The transformer could not include the requested transaction group for webhook #%d: %s', $webhook->id, $e->getMessage())
);
- Log::error($e->getTraceAsString());
+ app('log')->error($e->getTraceAsString());
return;
}
+
break;
+
case WebhookResponse::ACCOUNTS->value:
- $accounts = $this->collectAccounts($model);
+ /** @var TransactionGroup $model */
+ $accounts = $this->collectAccounts($model);
foreach ($accounts as $account) {
- $transformer = new AccountTransformer();
+ $transformer = new AccountTransformer();
$transformer->setParameters(new ParameterBag());
$basicMessage['content'][] = $transformer->transform($account);
}
@@ -190,22 +206,10 @@ class StandardMessageGenerator implements MessageGeneratorInterface
$this->storeMessage($webhook, $basicMessage);
}
- /**
- * @inheritDoc
- */
- public function getVersion(): int
- {
- return $this->version;
- }
-
- /**
- * @param TransactionGroup $transactionGroup
- *
- * @return Collection
- */
private function collectAccounts(TransactionGroup $transactionGroup): Collection
{
$accounts = new Collection();
+
/** @var TransactionJournal $journal */
foreach ($transactionGroup->transactionJournals as $journal) {
/** @var Transaction $transaction */
@@ -217,53 +221,15 @@ class StandardMessageGenerator implements MessageGeneratorInterface
return $accounts->unique();
}
- /**
- * @param Webhook $webhook
- * @param array $message
- *
- * @return void
- */
private function storeMessage(Webhook $webhook, array $message): void
{
- $webhookMessage = new WebhookMessage();
+ $webhookMessage = new WebhookMessage();
$webhookMessage->webhook()->associate($webhook);
$webhookMessage->sent = false;
$webhookMessage->errored = false;
$webhookMessage->uuid = $message['uuid'];
$webhookMessage->message = $message;
$webhookMessage->save();
- Log::debug(sprintf('Stored new webhook message #%d', $webhookMessage->id));
- }
-
- /**
- * @param Collection $objects
- */
- public function setObjects(Collection $objects): void
- {
- $this->objects = $objects;
- }
-
- /**
- * @param int $trigger
- */
- public function setTrigger(int $trigger): void
- {
- $this->trigger = $trigger;
- }
-
- /**
- * @param User $user
- */
- public function setUser(User $user): void
- {
- $this->user = $user;
- }
-
- /**
- * @inheritDoc
- */
- public function setWebhooks(Collection $webhooks): void
- {
- $this->webhooks = $webhooks;
+ app('log')->debug(sprintf('Stored new webhook message #%d', $webhookMessage->id));
}
}
diff --git a/app/Handlers/Events/APIEventHandler.php b/app/Handlers/Events/APIEventHandler.php
index c1d78be08e..bbe989922c 100644
--- a/app/Handlers/Events/APIEventHandler.php
+++ b/app/Handlers/Events/APIEventHandler.php
@@ -23,10 +23,8 @@ declare(strict_types=1);
namespace FireflyIII\Handlers\Events;
-use Exception;
use FireflyIII\Notifications\User\NewAccessToken;
use FireflyIII\Repositories\User\UserRepositoryInterface;
-use Illuminate\Support\Facades\Log;
use Illuminate\Support\Facades\Notification;
use Laravel\Passport\Events\AccessTokenCreated;
@@ -37,13 +35,11 @@ class APIEventHandler
{
/**
* Respond to the creation of an access token.
- *
- * @param AccessTokenCreated $event
- *
*/
public function accessTokenCreated(AccessTokenCreated $event): void
{
- Log::debug(__METHOD__);
+ app('log')->debug(__METHOD__);
+
/** @var UserRepositoryInterface $repository */
$repository = app(UserRepositoryInterface::class);
$user = $repository->find((int)$event->userId);
@@ -51,18 +47,20 @@ class APIEventHandler
if (null !== $user) {
try {
Notification::send($user, new NewAccessToken());
- } catch (Exception $e) {
+ } catch (\Exception $e) { // @phpstan-ignore-line
$message = $e->getMessage();
if (str_contains($message, 'Bcc')) {
- Log::warning('[Bcc] Could not send notification. Please validate your email settings, use the .env.example file as a guide.');
+ app('log')->warning('[Bcc] Could not send notification. Please validate your email settings, use the .env.example file as a guide.');
+
return;
}
if (str_contains($message, 'RFC 2822')) {
- Log::warning('[RFC] Could not send notification. Please validate your email settings, use the .env.example file as a guide.');
+ app('log')->warning('[RFC] Could not send notification. Please validate your email settings, use the .env.example file as a guide.');
+
return;
}
- Log::error($e->getMessage());
- Log::error($e->getTraceAsString());
+ app('log')->error($e->getMessage());
+ app('log')->error($e->getTraceAsString());
}
}
}
diff --git a/app/Handlers/Events/AdminEventHandler.php b/app/Handlers/Events/AdminEventHandler.php
index acf73ff5a4..fb8565b137 100644
--- a/app/Handlers/Events/AdminEventHandler.php
+++ b/app/Handlers/Events/AdminEventHandler.php
@@ -23,7 +23,6 @@ declare(strict_types=1);
namespace FireflyIII\Handlers\Events;
-use Exception;
use FireflyIII\Events\Admin\InvitationCreated;
use FireflyIII\Events\AdminRequestedTestMessage;
use FireflyIII\Events\NewVersionAvailable;
@@ -31,8 +30,6 @@ use FireflyIII\Notifications\Admin\TestNotification;
use FireflyIII\Notifications\Admin\UserInvitation;
use FireflyIII\Notifications\Admin\VersionCheckResult;
use FireflyIII\Repositories\User\UserRepositoryInterface;
-use FireflyIII\Support\Facades\FireflyConfig;
-use Illuminate\Support\Facades\Log;
use Illuminate\Support\Facades\Notification;
/**
@@ -40,14 +37,9 @@ use Illuminate\Support\Facades\Notification;
*/
class AdminEventHandler
{
- /**
- * @param InvitationCreated $event
- *
- * @return void
- */
public function sendInvitationNotification(InvitationCreated $event): void
{
- $sendMail = FireflyConfig::get('notification_invite_created', true)->data;
+ $sendMail = app('fireflyconfig')->get('notification_invite_created', true)->data;
if (false === $sendMail) {
return;
}
@@ -59,18 +51,20 @@ class AdminEventHandler
if ($repository->hasRole($user, 'owner')) {
try {
Notification::send($user, new UserInvitation($event->invitee));
- } catch (Exception $e) {
+ } catch (\Exception $e) { // @phpstan-ignore-line
$message = $e->getMessage();
if (str_contains($message, 'Bcc')) {
- Log::warning('[Bcc] Could not send notification. Please validate your email settings, use the .env.example file as a guide.');
+ app('log')->warning('[Bcc] Could not send notification. Please validate your email settings, use the .env.example file as a guide.');
+
return;
}
if (str_contains($message, 'RFC 2822')) {
- Log::warning('[RFC] Could not send notification. Please validate your email settings, use the .env.example file as a guide.');
+ app('log')->warning('[RFC] Could not send notification. Please validate your email settings, use the .env.example file as a guide.');
+
return;
}
- Log::error($e->getMessage());
- Log::error($e->getTraceAsString());
+ app('log')->error($e->getMessage());
+ app('log')->error($e->getTraceAsString());
}
}
}
@@ -78,14 +72,10 @@ class AdminEventHandler
/**
* Send new version message to admin.
- *
- * @param NewVersionAvailable $event
- *
- * @return void
*/
public function sendNewVersion(NewVersionAvailable $event): void
{
- $sendMail = FireflyConfig::get('notification_new_version', true)->data;
+ $sendMail = app('fireflyconfig')->get('notification_new_version', true)->data;
if (false === $sendMail) {
return;
}
@@ -97,18 +87,20 @@ class AdminEventHandler
if ($repository->hasRole($user, 'owner')) {
try {
Notification::send($user, new VersionCheckResult($event->message));
- } catch (Exception $e) {
+ } catch (\Exception $e) {// @phpstan-ignore-line
$message = $e->getMessage();
if (str_contains($message, 'Bcc')) {
- Log::warning('[Bcc] Could not send notification. Please validate your email settings, use the .env.example file as a guide.');
+ app('log')->warning('[Bcc] Could not send notification. Please validate your email settings, use the .env.example file as a guide.');
+
return;
}
if (str_contains($message, 'RFC 2822')) {
- Log::warning('[RFC] Could not send notification. Please validate your email settings, use the .env.example file as a guide.');
+ app('log')->warning('[RFC] Could not send notification. Please validate your email settings, use the .env.example file as a guide.');
+
return;
}
- Log::error($e->getMessage());
- Log::error($e->getTraceAsString());
+ app('log')->error($e->getMessage());
+ app('log')->error($e->getTraceAsString());
}
}
}
@@ -116,10 +108,6 @@ class AdminEventHandler
/**
* Sends a test message to an administrator.
- *
- * @param AdminRequestedTestMessage $event
- *
- * @return void
*/
public function sendTestMessage(AdminRequestedTestMessage $event): void
{
@@ -129,20 +117,23 @@ class AdminEventHandler
if (!$repository->hasRole($event->user, 'owner')) {
return;
}
+
try {
Notification::send($event->user, new TestNotification($event->user->email));
- } catch (Exception $e) {
+ } catch (\Exception $e) { // @phpstan-ignore-line
$message = $e->getMessage();
if (str_contains($message, 'Bcc')) {
- Log::warning('[Bcc] Could not send notification. Please validate your email settings, use the .env.example file as a guide.');
+ app('log')->warning('[Bcc] Could not send notification. Please validate your email settings, use the .env.example file as a guide.');
+
return;
}
if (str_contains($message, 'RFC 2822')) {
- Log::warning('[RFC] Could not send notification. Please validate your email settings, use the .env.example file as a guide.');
+ app('log')->warning('[RFC] Could not send notification. Please validate your email settings, use the .env.example file as a guide.');
+
return;
}
- Log::error($e->getMessage());
- Log::error($e->getTraceAsString());
+ app('log')->error($e->getMessage());
+ app('log')->error($e->getTraceAsString());
}
}
}
diff --git a/app/Handlers/Events/AuditEventHandler.php b/app/Handlers/Events/AuditEventHandler.php
index a0edd222bd..d881b19ed4 100644
--- a/app/Handlers/Events/AuditEventHandler.php
+++ b/app/Handlers/Events/AuditEventHandler.php
@@ -33,14 +33,9 @@ use FireflyIII\Repositories\AuditLogEntry\ALERepositoryInterface;
*/
class AuditEventHandler
{
- /**
- * @param TriggeredAuditLog $event
- *
- * @return void
- */
public function storeAuditEvent(TriggeredAuditLog $event): void
{
- $array = [
+ $array = [
'auditable' => $event->auditable,
'changer' => $event->changer,
'action' => $event->field,
diff --git a/app/Handlers/Events/AutomationHandler.php b/app/Handlers/Events/AutomationHandler.php
index defb50f90f..d3f5bc8631 100644
--- a/app/Handlers/Events/AutomationHandler.php
+++ b/app/Handlers/Events/AutomationHandler.php
@@ -23,14 +23,12 @@ declare(strict_types=1);
namespace FireflyIII\Handlers\Events;
-use Exception;
use FireflyIII\Events\RequestedReportOnJournals;
use FireflyIII\Exceptions\FireflyException;
use FireflyIII\Models\TransactionGroup;
use FireflyIII\Notifications\User\TransactionCreation;
use FireflyIII\Repositories\User\UserRepositoryInterface;
use FireflyIII\Transformers\TransactionGroupTransformer;
-use Illuminate\Support\Facades\Log;
use Illuminate\Support\Facades\Notification;
/**
@@ -41,53 +39,59 @@ class AutomationHandler
/**
* Respond to the creation of X journals.
*
- * @param RequestedReportOnJournals $event
- *
* @throws FireflyException
*/
public function reportJournals(RequestedReportOnJournals $event): void
{
- Log::debug('In reportJournals.');
+ app('log')->debug('In reportJournals.');
+
/** @var UserRepositoryInterface $repository */
- $repository = app(UserRepositoryInterface::class);
- $user = $repository->find($event->userId);
- $sendReport = app('preferences')->getForUser($user, 'notification_transaction_creation', false)->data;
+ $repository = app(UserRepositoryInterface::class);
+ $user = $repository->find($event->userId);
+
+ /** @var bool $sendReport */
+ $sendReport = app('preferences')->getForUser($user, 'notification_transaction_creation', false)->data;
if (false === $sendReport) {
- Log::debug('Not sending report, because config says so.');
+ app('log')->debug('Not sending report, because config says so.');
+
return;
}
-
if (null === $user || 0 === $event->groups->count()) {
- Log::debug('No transaction groups in event, nothing to email about.');
+ app('log')->debug('No transaction groups in event, nothing to email about.');
+
return;
}
- Log::debug('Continue with message!');
+ app('log')->debug('Continue with message!');
// transform groups into array:
/** @var TransactionGroupTransformer $transformer */
$transformer = app(TransactionGroupTransformer::class);
$groups = [];
+
/** @var TransactionGroup $group */
foreach ($event->groups as $group) {
$groups[] = $transformer->transformObject($group);
}
+
try {
Notification::send($user, new TransactionCreation($groups));
- } catch (Exception $e) {
+ } catch (\Exception $e) { // @phpstan-ignore-line
$message = $e->getMessage();
if (str_contains($message, 'Bcc')) {
- Log::warning('[Bcc] Could not send notification. Please validate your email settings, use the .env.example file as a guide.');
+ app('log')->warning('[Bcc] Could not send notification. Please validate your email settings, use the .env.example file as a guide.');
+
return;
}
if (str_contains($message, 'RFC 2822')) {
- Log::warning('[RFC] Could not send notification. Please validate your email settings, use the .env.example file as a guide.');
+ app('log')->warning('[RFC] Could not send notification. Please validate your email settings, use the .env.example file as a guide.');
+
return;
}
- Log::error($e->getMessage());
- Log::error($e->getTraceAsString());
+ app('log')->error($e->getMessage());
+ app('log')->error($e->getTraceAsString());
}
- Log::debug('If there is no error above this line, message was sent.');
+ app('log')->debug('If there is no error above this line, message was sent.');
}
}
diff --git a/app/Handlers/Events/BillEventHandler.php b/app/Handlers/Events/BillEventHandler.php
index f360c1e4a6..7d87e6727f 100644
--- a/app/Handlers/Events/BillEventHandler.php
+++ b/app/Handlers/Events/BillEventHandler.php
@@ -24,11 +24,8 @@ declare(strict_types=1);
namespace FireflyIII\Handlers\Events;
-use Exception;
use FireflyIII\Events\WarnUserAboutBill;
use FireflyIII\Notifications\User\BillReminder;
-use FireflyIII\Support\Facades\Preferences;
-use Illuminate\Support\Facades\Log;
use Illuminate\Support\Facades\Notification;
/**
@@ -36,39 +33,38 @@ use Illuminate\Support\Facades\Notification;
*/
class BillEventHandler
{
- /**
- * @param WarnUserAboutBill $event
- *
- * @return void
- */
public function warnAboutBill(WarnUserAboutBill $event): void
{
- Log::debug(sprintf('Now in %s', __METHOD__));
+ app('log')->debug(sprintf('Now in %s', __METHOD__));
+
+ $bill = $event->bill;
- $bill = $event->bill;
/** @var bool $preference */
- $preference = Preferences::getForUser($bill->user, 'notification_bill_reminder', true)->data;
+ $preference = app('preferences')->getForUser($bill->user, 'notification_bill_reminder', true)->data;
if (true === $preference) {
- Log::debug('Bill reminder is true!');
+ app('log')->debug('Bill reminder is true!');
+
try {
Notification::send($bill->user, new BillReminder($bill, $event->field, $event->diff));
- } catch (Exception $e) {
+ } catch (\Exception $e) { // @phpstan-ignore-line
$message = $e->getMessage();
if (str_contains($message, 'Bcc')) {
- Log::warning('[Bcc] Could not send notification. Please validate your email settings, use the .env.example file as a guide.');
+ app('log')->warning('[Bcc] Could not send notification. Please validate your email settings, use the .env.example file as a guide.');
+
return;
}
if (str_contains($message, 'RFC 2822')) {
- Log::warning('[RFC] Could not send notification. Please validate your email settings, use the .env.example file as a guide.');
+ app('log')->warning('[RFC] Could not send notification. Please validate your email settings, use the .env.example file as a guide.');
+
return;
}
- Log::error($e->getMessage());
- Log::error($e->getTraceAsString());
+ app('log')->error($e->getMessage());
+ app('log')->error($e->getTraceAsString());
}
}
if (false === $preference) {
- Log::debug('User has disabled bill reminders.');
+ app('log')->debug('User has disabled bill reminders.');
}
}
}
diff --git a/app/Handlers/Events/DestroyedGroupEventHandler.php b/app/Handlers/Events/DestroyedGroupEventHandler.php
index a7948333ff..db437d989c 100644
--- a/app/Handlers/Events/DestroyedGroupEventHandler.php
+++ b/app/Handlers/Events/DestroyedGroupEventHandler.php
@@ -28,21 +28,18 @@ use FireflyIII\Events\DestroyedTransactionGroup;
use FireflyIII\Events\RequestedSendWebhookMessages;
use FireflyIII\Generator\Webhook\MessageGeneratorInterface;
use Illuminate\Support\Collection;
-use Illuminate\Support\Facades\Log;
/**
* Class DestroyedGroupEventHandler
*/
class DestroyedGroupEventHandler
{
- /**
- * @param DestroyedTransactionGroup $destroyedGroupEvent
- */
public function triggerWebhooks(DestroyedTransactionGroup $destroyedGroupEvent): void
{
- Log::debug('DestroyedTransactionGroup:triggerWebhooks');
- $group = $destroyedGroupEvent->transactionGroup;
- $user = $group->user;
+ app('log')->debug('DestroyedTransactionGroup:triggerWebhooks');
+ $group = $destroyedGroupEvent->transactionGroup;
+ $user = $group->user;
+
/** @var MessageGeneratorInterface $engine */
$engine = app(MessageGeneratorInterface::class);
$engine->setUser($user);
diff --git a/app/Handlers/Events/Model/BudgetLimitHandler.php b/app/Handlers/Events/Model/BudgetLimitHandler.php
index 8abe31998a..0211e9e78c 100644
--- a/app/Handlers/Events/Model/BudgetLimitHandler.php
+++ b/app/Handlers/Events/Model/BudgetLimitHandler.php
@@ -1,6 +1,5 @@
budgetLimit->id));
+ app('log')->debug(sprintf('BudgetLimitHandler::created(#%s)', $event->budgetLimit->id));
$this->updateAvailableBudget($event->budgetLimit);
}
- /**
- * @param BudgetLimit $budgetLimit
- *
- * @return void
- */
private function updateAvailableBudget(BudgetLimit $budgetLimit): void
{
- Log::debug(sprintf('Now in updateAvailableBudget(#%d)', $budgetLimit->id));
- $budget = Budget::find($budgetLimit->budget_id);
+ app('log')->debug(sprintf('Now in updateAvailableBudget(#%d)', $budgetLimit->id));
+ $budget = Budget::find($budgetLimit->budget_id);
if (null === $budget) {
- Log::warning('Budget is null, probably deleted, find deleted version.');
+ app('log')->warning('Budget is null, probably deleted, find deleted version.');
$budget = Budget::withTrashed()->find($budgetLimit->budget_id);
}
if (null === $budget) {
- Log::warning('Budget is still null, cannot continue, will delete budget limit.');
+ app('log')->warning('Budget is still null, cannot continue, will delete budget limit.');
$budgetLimit->forceDelete();
+
return;
}
- $user = $budget->user;
+
+ /** @var null|User $user */
+ $user = $budget->user;
// sanity check. It happens when the budget has been deleted so the original user is unknown.
if (null === $user) {
- Log::warning('User is null, cannot continue.');
+ app('log')->warning('User is null, cannot continue.');
$budgetLimit->forceDelete();
+
return;
}
@@ -87,33 +80,38 @@ class BudgetLimitHandler
// all have to be created or updated.
try {
$viewRange = app('preferences')->getForUser($user, 'viewRange', '1M')->data;
- } catch (ContainerExceptionInterface | NotFoundExceptionInterface $e) {
+ } catch (ContainerExceptionInterface|NotFoundExceptionInterface $e) {
app('log')->error($e->getMessage());
$viewRange = '1M';
}
+ // safety catch
+ if (null === $viewRange || is_array($viewRange)) {
+ $viewRange = '1M';
+ }
+ $viewRange = (string)$viewRange;
- $start = app('navigation')->startOfPeriod($budgetLimit->start_date, $viewRange);
- $end = app('navigation')->startOfPeriod($budgetLimit->end_date, $viewRange);
- $end = app('navigation')->endOfPeriod($end, $viewRange);
+ $start = app('navigation')->startOfPeriod($budgetLimit->start_date, $viewRange);
+ $end = app('navigation')->startOfPeriod($budgetLimit->end_date, $viewRange);
+ $end = app('navigation')->endOfPeriod($end, $viewRange);
// limit period in total is:
$limitPeriod = Period::make($start, $end, precision: Precision::DAY(), boundaries: Boundaries::EXCLUDE_NONE());
app('log')->debug(sprintf('Limit period is from %s to %s', $start->format('Y-m-d'), $end->format('Y-m-d')));
// from the start until the end of the budget limit, need to loop!
- $current = clone $start;
+ $current = clone $start;
while ($current <= $end) {
- $currentEnd = app('navigation')->endOfPeriod($current, $viewRange);
+ $currentEnd = app('navigation')->endOfPeriod($current, $viewRange);
// create or find AB for this particular period, and set the amount accordingly.
- /** @var AvailableBudget $availableBudget */
+ /** @var null|AvailableBudget $availableBudget */
$availableBudget = $user->availableBudgets()->where('start_date', $current->format('Y-m-d'))->where(
'end_date',
$currentEnd->format('Y-m-d')
)->where('transaction_currency_id', $budgetLimit->transaction_currency_id)->first();
if (null !== $availableBudget) {
- Log::debug('Found 1 AB, will update.');
+ app('log')->debug('Found 1 AB, will update.');
$this->calculateAmount($availableBudget);
}
if (null === $availableBudget) {
@@ -124,13 +122,13 @@ class BudgetLimitHandler
// no need to calculate if period is equal.
if ($currentPeriod->equals($limitPeriod)) {
- $amount = 0 === (int)$budgetLimit->id ? '0' : $budgetLimit->amount;
+ $amount = 0 === $budgetLimit->id ? '0' : $budgetLimit->amount;
}
if (0 === bccomp($amount, '0')) {
- Log::debug('Amount is zero, will not create AB.');
+ app('log')->debug('Amount is zero, will not create AB.');
}
if (0 !== bccomp($amount, '0')) {
- Log::debug(sprintf('Will create AB for period %s to %s', $current->format('Y-m-d'), $currentEnd->format('Y-m-d')));
+ app('log')->debug(sprintf('Will create AB for period %s to %s', $current->format('Y-m-d'), $currentEnd->format('Y-m-d')));
$availableBudget = new AvailableBudget(
[
'user_id' => $budgetLimit->budget->user->id,
@@ -142,26 +140,22 @@ class BudgetLimitHandler
]
);
$availableBudget->save();
+ app('log')->debug(sprintf('ID of new AB is #%d', $availableBudget->id));
}
}
// prep for next loop
- $current = app('navigation')->addPeriod($current, $viewRange, 0);
+ $current = app('navigation')->addPeriod($current, $viewRange, 0);
}
}
- /**
- * @param AvailableBudget $availableBudget
- *
- * @return void
- */
private function calculateAmount(AvailableBudget $availableBudget): void
{
- $repository = app(BudgetLimitRepositoryInterface::class);
+ $repository = app(BudgetLimitRepositoryInterface::class);
$repository->setUser($availableBudget->user);
- $newAmount = '0';
- $abPeriod = Period::make($availableBudget->start_date, $availableBudget->end_date, Precision::DAY());
- Log::debug(
+ $newAmount = '0';
+ $abPeriod = Period::make($availableBudget->start_date, $availableBudget->end_date, Precision::DAY());
+ app('log')->debug(
sprintf(
'Now at AB #%d, ("%s" to "%s")',
$availableBudget->id,
@@ -170,11 +164,12 @@ class BudgetLimitHandler
)
);
// have to recalculate everything just in case.
- $set = $repository->getAllBudgetLimitsByCurrency($availableBudget->transactionCurrency, $availableBudget->start_date, $availableBudget->end_date);
- Log::debug(sprintf('Found %d interesting budget limit(s).', $set->count()));
+ $set = $repository->getAllBudgetLimitsByCurrency($availableBudget->transactionCurrency, $availableBudget->start_date, $availableBudget->end_date);
+ app('log')->debug(sprintf('Found %d interesting budget limit(s).', $set->count()));
+
/** @var BudgetLimit $budgetLimit */
foreach ($set as $budgetLimit) {
- Log::debug(
+ app('log')->debug(
sprintf(
'Found interesting budget limit #%d ("%s" to "%s")',
$budgetLimit->id,
@@ -210,23 +205,19 @@ class BudgetLimitHandler
}
}
if (0 === bccomp('0', $newAmount)) {
- Log::debug('New amount is zero, deleting AB.');
+ app('log')->debug('New amount is zero, deleting AB.');
$availableBudget->delete();
+
return;
}
- Log::debug(sprintf('Concluded new amount for this AB must be %s', $newAmount));
+ app('log')->debug(sprintf('Concluded new amount for this AB must be %s', $newAmount));
$availableBudget->amount = app('steam')->bcround($newAmount, $availableBudget->transactionCurrency->decimal_places);
$availableBudget->save();
}
- /**
- * @param BudgetLimit $budgetLimit
- *
- * @return string
- */
private function getDailyAmount(BudgetLimit $budgetLimit): string
{
- if (0 === (int)$budgetLimit->id) {
+ if (0 === $budgetLimit->id) {
return '0';
}
$limitPeriod = Period::make(
@@ -236,35 +227,25 @@ class BudgetLimitHandler
boundaries: Boundaries::EXCLUDE_NONE()
);
$days = $limitPeriod->length();
- $amount = bcdiv((string)$budgetLimit->amount, (string)$days, 12);
- Log::debug(
+ $amount = bcdiv($budgetLimit->amount, (string)$days, 12);
+ app('log')->debug(
sprintf('Total amount for budget limit #%d is %s. Nr. of days is %d. Amount per day is %s', $budgetLimit->id, $budgetLimit->amount, $days, $amount)
);
+
return $amount;
}
- /**
- * @param Deleted $event
- *
- * @return void
- */
public function deleted(Deleted $event): void
{
- Log::debug(sprintf('BudgetLimitHandler::deleted(#%s)', $event->budgetLimit->id));
+ app('log')->debug(sprintf('BudgetLimitHandler::deleted(#%s)', $event->budgetLimit->id));
$budgetLimit = $event->budgetLimit;
- $budgetLimit->id = null;
+ $budgetLimit->id = 0;
$this->updateAvailableBudget($event->budgetLimit);
}
- /**
- * @param Updated $event
- *
- * @return void
- */
public function updated(Updated $event): void
{
- Log::debug(sprintf('BudgetLimitHandler::updated(#%s)', $event->budgetLimit->id));
+ app('log')->debug(sprintf('BudgetLimitHandler::updated(#%s)', $event->budgetLimit->id));
$this->updateAvailableBudget($event->budgetLimit);
}
-
}
diff --git a/app/Handlers/Events/Model/PiggyBankEventHandler.php b/app/Handlers/Events/Model/PiggyBankEventHandler.php
index 5eca00f652..f97319bac6 100644
--- a/app/Handlers/Events/Model/PiggyBankEventHandler.php
+++ b/app/Handlers/Events/Model/PiggyBankEventHandler.php
@@ -26,18 +26,12 @@ namespace FireflyIII\Handlers\Events\Model;
use FireflyIII\Events\Model\PiggyBank\ChangedAmount;
use FireflyIII\Models\PiggyBankEvent;
-use Illuminate\Support\Facades\Log;
/**
* Class PiggyBankEventHandler
*/
class PiggyBankEventHandler
{
- /**
- * @param ChangedAmount $event
- *
- * @return void
- */
public function changePiggyAmount(ChangedAmount $event): void
{
// find journal if group is present.
@@ -45,14 +39,16 @@ class PiggyBankEventHandler
if (null !== $event->transactionGroup) {
$journal = $event->transactionGroup->transactionJournals()->first();
}
- $date = $journal?->date ?? today(config('app.timezone'));
+ $date = $journal?->date ?? today(config('app.timezone'));
// sanity check: event must not already exist for this journal and piggy bank.
if (null !== $journal) {
$exists = PiggyBankEvent::where('piggy_bank_id', $event->piggyBank->id)
- ->where('transaction_journal_id', $journal->id)
- ->exists();
+ ->where('transaction_journal_id', $journal->id)
+ ->exists()
+ ;
if ($exists) {
- Log::warning('Already have event for this journal and piggy, will not create another.');
+ app('log')->warning('Already have event for this journal and piggy, will not create another.');
+
return;
}
}
diff --git a/app/Handlers/Events/Model/RuleHandler.php b/app/Handlers/Events/Model/RuleHandler.php
index 99f9aa208b..ea3bb107c8 100644
--- a/app/Handlers/Events/Model/RuleHandler.php
+++ b/app/Handlers/Events/Model/RuleHandler.php
@@ -1,6 +1,5 @@
ruleAction;
- $rule = $ruleAction->rule;
- $preference = Preferences::getForUser($rule->user, 'notification_rule_action_failures', true)->data;
+ $ruleAction = $event->ruleAction;
+ $rule = $ruleAction->rule;
+
+ /** @var bool $preference */
+ $preference = app('preferences')->getForUser($rule->user, 'notification_rule_action_failures', true)->data;
if (false === $preference) {
return;
}
app('log')->debug('Now in ruleActionFailedOnArray');
- $journal = $event->journal;
- $error = $event->error;
- $user = $ruleAction->rule->user;
+ $journal = $event->journal;
+ $error = $event->error;
+ $user = $ruleAction->rule->user;
$mainMessage = trans('rules.main_message', ['rule' => $rule->title, 'action' => $ruleAction->action_type, 'group' => $journal['transaction_group_id'], 'error' => $error]);
$groupTitle = $journal['description'] ?? '';
@@ -61,27 +58,27 @@ class RuleHandler
$ruleLink = route('rules.edit', [$rule->id]);
$params = [$mainMessage, $groupTitle, $groupLink, $ruleTitle, $ruleLink];
-
- Notification::send($user, new RuleActionFailed($params));
+ try {
+ Notification::send($user, new RuleActionFailed($params));
+ } catch (ClientException $e) {
+ Log::error(sprintf('[a] Error sending notification that the rule action failed: %s', $e->getMessage()));
+ }
}
- /**
- * @param RuleActionFailedOnObject $event
- *
- * @return void
- */
public function ruleActionFailedOnObject(RuleActionFailedOnObject $event): void
{
- $ruleAction = $event->ruleAction;
- $rule = $ruleAction->rule;
- $preference = Preferences::getForUser($rule->user, 'notification_rule_action_failures', true)->data;
+ $ruleAction = $event->ruleAction;
+ $rule = $ruleAction->rule;
+
+ /** @var bool $preference */
+ $preference = app('preferences')->getForUser($rule->user, 'notification_rule_action_failures', true)->data;
if (false === $preference) {
return;
}
app('log')->debug('Now in ruleActionFailedOnObject');
- $journal = $event->journal;
- $error = $event->error;
- $user = $ruleAction->rule->user;
+ $journal = $event->journal;
+ $error = $event->error;
+ $user = $ruleAction->rule->user;
$mainMessage = trans('rules.main_message', ['rule' => $rule->title, 'action' => $ruleAction->action_type, 'group' => $journal->transaction_group_id, 'error' => $error]);
$groupTitle = $journal->description ?? '';
@@ -90,8 +87,10 @@ class RuleHandler
$ruleLink = route('rules.edit', [$rule->id]);
$params = [$mainMessage, $groupTitle, $groupLink, $ruleTitle, $ruleLink];
-
- Notification::send($user, new RuleActionFailed($params));
+ try {
+ Notification::send($user, new RuleActionFailed($params));
+ } catch (ClientException $e) {
+ Log::error(sprintf('[b] Error sending notification that the rule action failed: %s', $e->getMessage()));
+ }
}
-
}
diff --git a/app/Handlers/Events/StoredAccountEventHandler.php b/app/Handlers/Events/StoredAccountEventHandler.php
index a4a48f4cbf..574148def2 100644
--- a/app/Handlers/Events/StoredAccountEventHandler.php
+++ b/app/Handlers/Events/StoredAccountEventHandler.php
@@ -32,14 +32,12 @@ use FireflyIII\Services\Internal\Support\CreditRecalculateService;
*/
class StoredAccountEventHandler
{
- /**
- * @param StoredAccount $event
- */
public function recalculateCredit(StoredAccount $event): void
{
$account = $event->account;
+
/** @var CreditRecalculateService $object */
- $object = app(CreditRecalculateService::class);
+ $object = app(CreditRecalculateService::class);
$object->setAccount($account);
$object->recalculate();
}
diff --git a/app/Handlers/Events/StoredGroupEventHandler.php b/app/Handlers/Events/StoredGroupEventHandler.php
index 853f299fb2..53faaffe21 100644
--- a/app/Handlers/Events/StoredGroupEventHandler.php
+++ b/app/Handlers/Events/StoredGroupEventHandler.php
@@ -32,7 +32,6 @@ use FireflyIII\Repositories\RuleGroup\RuleGroupRepositoryInterface;
use FireflyIII\Services\Internal\Support\CreditRecalculateService;
use FireflyIII\TransactionRules\Engine\RuleEngineInterface;
use Illuminate\Support\Collection;
-use Illuminate\Support\Facades\Log;
/**
* Class StoredGroupEventHandler
@@ -41,26 +40,25 @@ class StoredGroupEventHandler
{
/**
* This method grabs all the users rules and processes them.
- *
- * @param StoredTransactionGroup $storedGroupEvent
*/
public function processRules(StoredTransactionGroup $storedGroupEvent): void
{
if (false === $storedGroupEvent->applyRules) {
- Log::info(sprintf('Will not run rules on group #%d', $storedGroupEvent->transactionGroup->id));
+ app('log')->info(sprintf('Will not run rules on group #%d', $storedGroupEvent->transactionGroup->id));
return;
}
- Log::debug('Now in StoredGroupEventHandler::processRules()');
+ app('log')->debug('Now in StoredGroupEventHandler::processRules()');
+
+ $journals = $storedGroupEvent->transactionGroup->transactionJournals;
+ $array = [];
- $journals = $storedGroupEvent->transactionGroup->transactionJournals;
- $array = [];
/** @var TransactionJournal $journal */
foreach ($journals as $journal) {
$array[] = $journal->id;
}
- $journalIds = implode(',', $array);
- Log::debug(sprintf('Add local operator for journal(s): %s', $journalIds));
+ $journalIds = implode(',', $array);
+ app('log')->debug(sprintf('Add local operator for journal(s): %s', $journalIds));
// collect rules:
$ruleGroupRepository = app(RuleGroupRepositoryInterface::class);
@@ -68,22 +66,20 @@ class StoredGroupEventHandler
// add the groups to the rule engine.
// it should run the rules in the group and cancel the group if necessary.
- $groups = $ruleGroupRepository->getRuleGroupsWithRules('store-journal');
+ $groups = $ruleGroupRepository->getRuleGroupsWithRules('store-journal');
// create and fire rule engine.
- $newRuleEngine = app(RuleEngineInterface::class);
+ $newRuleEngine = app(RuleEngineInterface::class);
$newRuleEngine->setUser($storedGroupEvent->transactionGroup->user);
$newRuleEngine->addOperator(['type' => 'journal_id', 'value' => $journalIds]);
$newRuleEngine->setRuleGroups($groups);
$newRuleEngine->fire();
}
- /**
- * @param StoredTransactionGroup $event
- */
public function recalculateCredit(StoredTransactionGroup $event): void
{
- $group = $event->transactionGroup;
+ $group = $event->transactionGroup;
+
/** @var CreditRecalculateService $object */
$object = app(CreditRecalculateService::class);
$object->setGroup($group);
@@ -92,20 +88,19 @@ class StoredGroupEventHandler
/**
* This method processes all webhooks that respond to the "stored transaction group" trigger (100)
- *
- * @param StoredTransactionGroup $storedGroupEvent
*/
public function triggerWebhooks(StoredTransactionGroup $storedGroupEvent): void
{
- Log::debug(__METHOD__);
- $group = $storedGroupEvent->transactionGroup;
+ app('log')->debug(__METHOD__);
+ $group = $storedGroupEvent->transactionGroup;
if (false === $storedGroupEvent->fireWebhooks) {
- Log::info(sprintf('Will not fire webhooks for transaction group #%d', $group->id));
+ app('log')->info(sprintf('Will not fire webhooks for transaction group #%d', $group->id));
return;
}
- $user = $group->user;
+ $user = $group->user;
+
/** @var MessageGeneratorInterface $engine */
$engine = app(MessageGeneratorInterface::class);
$engine->setUser($user);
diff --git a/app/Handlers/Events/UpdatedAccountEventHandler.php b/app/Handlers/Events/UpdatedAccountEventHandler.php
index 6874fcbba4..59c137e817 100644
--- a/app/Handlers/Events/UpdatedAccountEventHandler.php
+++ b/app/Handlers/Events/UpdatedAccountEventHandler.php
@@ -32,14 +32,12 @@ use FireflyIII\Services\Internal\Support\CreditRecalculateService;
*/
class UpdatedAccountEventHandler
{
- /**
- * @param UpdatedAccount $event
- */
public function recalculateCredit(UpdatedAccount $event): void
{
$account = $event->account;
+
/** @var CreditRecalculateService $object */
- $object = app(CreditRecalculateService::class);
+ $object = app(CreditRecalculateService::class);
$object->setAccount($account);
$object->recalculate();
}
diff --git a/app/Handlers/Events/UpdatedGroupEventHandler.php b/app/Handlers/Events/UpdatedGroupEventHandler.php
index 991edabd6d..3daa2604b9 100644
--- a/app/Handlers/Events/UpdatedGroupEventHandler.php
+++ b/app/Handlers/Events/UpdatedGroupEventHandler.php
@@ -35,7 +35,6 @@ use FireflyIII\Repositories\RuleGroup\RuleGroupRepositoryInterface;
use FireflyIII\Services\Internal\Support\CreditRecalculateService;
use FireflyIII\TransactionRules\Engine\RuleEngineInterface;
use Illuminate\Support\Collection;
-use Illuminate\Support\Facades\Log;
/**
* Class UpdatedGroupEventHandler
@@ -44,65 +43,60 @@ class UpdatedGroupEventHandler
{
/**
* This method will check all the rules when a journal is updated.
- *
- * @param UpdatedTransactionGroup $updatedGroupEvent
*/
public function processRules(UpdatedTransactionGroup $updatedGroupEvent): void
{
if (false === $updatedGroupEvent->applyRules) {
- Log::info(sprintf('Will not run rules on group #%d', $updatedGroupEvent->transactionGroup->id));
+ app('log')->info(sprintf('Will not run rules on group #%d', $updatedGroupEvent->transactionGroup->id));
return;
}
- $journals = $updatedGroupEvent->transactionGroup->transactionJournals;
- $array = [];
+ $journals = $updatedGroupEvent->transactionGroup->transactionJournals;
+ $array = [];
+
/** @var TransactionJournal $journal */
foreach ($journals as $journal) {
$array[] = $journal->id;
}
- $journalIds = implode(',', $array);
- Log::debug(sprintf('Add local operator for journal(s): %s', $journalIds));
+ $journalIds = implode(',', $array);
+ app('log')->debug(sprintf('Add local operator for journal(s): %s', $journalIds));
// collect rules:
$ruleGroupRepository = app(RuleGroupRepositoryInterface::class);
$ruleGroupRepository->setUser($updatedGroupEvent->transactionGroup->user);
- $groups = $ruleGroupRepository->getRuleGroupsWithRules('update-journal');
+ $groups = $ruleGroupRepository->getRuleGroupsWithRules('update-journal');
// file rule engine.
- $newRuleEngine = app(RuleEngineInterface::class);
+ $newRuleEngine = app(RuleEngineInterface::class);
$newRuleEngine->setUser($updatedGroupEvent->transactionGroup->user);
$newRuleEngine->addOperator(['type' => 'journal_id', 'value' => $journalIds]);
$newRuleEngine->setRuleGroups($groups);
$newRuleEngine->fire();
}
- /**
- * @param UpdatedTransactionGroup $event
- */
public function recalculateCredit(UpdatedTransactionGroup $event): void
{
- $group = $event->transactionGroup;
+ $group = $event->transactionGroup;
+
/** @var CreditRecalculateService $object */
$object = app(CreditRecalculateService::class);
$object->setGroup($group);
$object->recalculate();
}
- /**
- * @param UpdatedTransactionGroup $updatedGroupEvent
- */
public function triggerWebhooks(UpdatedTransactionGroup $updatedGroupEvent): void
{
- Log::debug(__METHOD__);
- $group = $updatedGroupEvent->transactionGroup;
+ app('log')->debug(__METHOD__);
+ $group = $updatedGroupEvent->transactionGroup;
if (false === $updatedGroupEvent->fireWebhooks) {
- Log::info(sprintf('Will not fire webhooks for transaction group #%d', $group->id));
+ app('log')->info(sprintf('Will not fire webhooks for transaction group #%d', $group->id));
return;
}
- $user = $group->user;
+ $user = $group->user;
+
/** @var MessageGeneratorInterface $engine */
$engine = app(MessageGeneratorInterface::class);
$engine->setUser($user);
@@ -115,45 +109,50 @@ class UpdatedGroupEventHandler
/**
* This method will make sure all source / destination accounts are the same.
- *
- * @param UpdatedTransactionGroup $updatedGroupEvent
*/
public function unifyAccounts(UpdatedTransactionGroup $updatedGroupEvent): void
{
- $group = $updatedGroupEvent->transactionGroup;
+ $group = $updatedGroupEvent->transactionGroup;
if (1 === $group->transactionJournals->count()) {
return;
}
+
// first journal:
- /** @var TransactionJournal|null $first */
- $first = $group->transactionJournals()
- ->orderBy('transaction_journals.date', 'DESC')
- ->orderBy('transaction_journals.order', 'ASC')
- ->orderBy('transaction_journals.id', 'DESC')
- ->orderBy('transaction_journals.description', 'DESC')
- ->first();
+ /** @var null|TransactionJournal $first */
+ $first = $group->transactionJournals()
+ ->orderBy('transaction_journals.date', 'DESC')
+ ->orderBy('transaction_journals.order', 'ASC')
+ ->orderBy('transaction_journals.id', 'DESC')
+ ->orderBy('transaction_journals.description', 'DESC')
+ ->first()
+ ;
if (null === $first) {
app('log')->warning(sprintf('Group #%d has no transaction journals.', $group->id));
+
return;
}
- $all = $group->transactionJournals()->get()->pluck('id')->toArray();
+ $all = $group->transactionJournals()->get()->pluck('id')->toArray();
+
/** @var Account $sourceAccount */
$sourceAccount = $first->transactions()->where('amount', '<', '0')->first()->account;
- /** @var Account $destAccount */
- $destAccount = $first->transactions()->where('amount', '>', '0')->first()->account;
- $type = $first->transactionType->type;
+ /** @var Account $destAccount */
+ $destAccount = $first->transactions()->where('amount', '>', '0')->first()->account;
+
+ $type = $first->transactionType->type;
if (TransactionType::TRANSFER === $type || TransactionType::WITHDRAWAL === $type) {
// set all source transactions to source account:
Transaction::whereIn('transaction_journal_id', $all)
- ->where('amount', '<', 0)->update(['account_id' => $sourceAccount->id]);
+ ->where('amount', '<', 0)->update(['account_id' => $sourceAccount->id])
+ ;
}
if (TransactionType::TRANSFER === $type || TransactionType::DEPOSIT === $type) {
// set all destination transactions to destination account:
Transaction::whereIn('transaction_journal_id', $all)
- ->where('amount', '>', 0)->update(['account_id' => $destAccount->id]);
+ ->where('amount', '>', 0)->update(['account_id' => $destAccount->id])
+ ;
}
}
}
diff --git a/app/Handlers/Events/UserEventHandler.php b/app/Handlers/Events/UserEventHandler.php
index 6f534d04a1..8f414e6b97 100644
--- a/app/Handlers/Events/UserEventHandler.php
+++ b/app/Handlers/Events/UserEventHandler.php
@@ -25,7 +25,6 @@ namespace FireflyIII\Handlers\Events;
use Carbon\Carbon;
use Database\Seeders\ExchangeRateSeeder;
-use Exception;
use FireflyIII\Enums\UserRoleEnum;
use FireflyIII\Events\ActuallyLoggedIn;
use FireflyIII\Events\Admin\InvitationCreated;
@@ -45,10 +44,8 @@ use FireflyIII\Notifications\User\UserLogin;
use FireflyIII\Notifications\User\UserNewPassword;
use FireflyIII\Notifications\User\UserRegistration as UserRegistrationNotification;
use FireflyIII\Repositories\User\UserRepositoryInterface;
-use FireflyIII\Support\Facades\FireflyConfig;
use FireflyIII\User;
use Illuminate\Auth\Events\Login;
-use Illuminate\Support\Facades\Log;
use Illuminate\Support\Facades\Notification;
use Mail;
@@ -63,8 +60,6 @@ class UserEventHandler
{
/**
* This method will bestow upon a user the "owner" role if he is the first user in the system.
- *
- * @param RegisteredUser $event
*/
public function attachUserRole(RegisteredUser $event): void
{
@@ -73,15 +68,13 @@ class UserEventHandler
// first user ever?
if (1 === $repository->count()) {
- Log::debug('User count is one, attach role.');
+ app('log')->debug('User count is one, attach role.');
$repository->attachRole($event->user, 'owner');
}
}
/**
* Fires to see if a user is admin.
- *
- * @param Login $event
*/
public function checkSingleUserIsAdmin(Login $event): void
{
@@ -89,8 +82,8 @@ class UserEventHandler
$repository = app(UserRepositoryInterface::class);
/** @var User $user */
- $user = $event->user;
- $count = $repository->count();
+ $user = $event->user;
+ $count = $repository->count();
// only act when there is 1 user in the system and he has no admin rights.
if (1 === $count && !$repository->hasRole($user, 'owner')) {
@@ -99,17 +92,17 @@ class UserEventHandler
if (null === $role) {
// create role, does not exist. Very strange situation so let's raise a big fuss about it.
$role = $repository->createRole('owner', 'Site Owner', 'User runs this instance of FF3');
- Log::error('Could not find role "owner". This is weird.');
+ app('log')->error('Could not find role "owner". This is weird.');
}
- Log::info(sprintf('Gave user #%d role #%d ("%s")', $user->id, $role->id, $role->name));
+ app('log')->info(sprintf('Gave user #%d role #%d ("%s")', $user->id, $role->id, $role->name));
// give user the role
$repository->attachRole($user, 'owner');
}
}
/**
- * @param RegisteredUser $event
+ * @SuppressWarnings(PHPMD.UnusedFormalParameter)
*/
public function createExchangeRates(RegisteredUser $event): void
{
@@ -118,34 +111,35 @@ class UserEventHandler
}
/**
- * @param RegisteredUser $event
- *
* @throws FireflyException
*/
public function createGroupMembership(RegisteredUser $event): void
{
- $user = $event->user;
- $groupExists = true;
- $groupTitle = $user->email;
- $index = 1;
+ $user = $event->user;
+ $groupExists = true;
+ $groupTitle = $user->email;
+ $index = 1;
+
/** @var UserGroup $group */
- $group = null;
+ $group = null;
// create a new group.
- while (true === $groupExists) {
+ while (true === $groupExists) { // @phpstan-ignore-line
$groupExists = UserGroup::where('title', $groupTitle)->count() > 0;
if (false === $groupExists) {
$group = UserGroup::create(['title' => $groupTitle]);
+
break;
}
- $groupTitle = sprintf('%s-%d', $user->email, $index);
- $index++;
+ $groupTitle = sprintf('%s-%d', $user->email, $index);
+ ++$index;
if ($index > 99) {
throw new FireflyException('Email address can no longer be used for registrations.');
}
}
- /** @var UserRole|null $role */
- $role = UserRole::where('title', UserRoleEnum::OWNER->value)->first();
+
+ /** @var null|UserRole $role */
+ $role = UserRole::where('title', UserRoleEnum::OWNER->value)->first();
if (null === $role) {
throw new FireflyException('The user role is unexpectedly empty. Did you run all migrations?');
}
@@ -163,8 +157,6 @@ class UserEventHandler
/**
* Set the demo user back to English.
*
- * @param Login $event
- *
* @throws FireflyException
*/
public function demoUserBackToEnglish(Login $event): void
@@ -173,7 +165,7 @@ class UserEventHandler
$repository = app(UserRepositoryInterface::class);
/** @var User $user */
- $user = $event->user;
+ $user = $event->user;
if ($repository->hasRole($user, 'demo')) {
// set user back to English.
app('preferences')->setForUser($user, 'language', 'en_US');
@@ -183,39 +175,41 @@ class UserEventHandler
}
/**
- * @param DetectedNewIPAddress $event
- *
* @throws FireflyException
*/
public function notifyNewIPAddress(DetectedNewIPAddress $event): void
{
$user = $event->user;
- $email = $user->email;
$ipAddress = $event->ipAddress;
if ($user->hasRole('demo')) {
return; // do not email demo user.
}
- $list = app('preferences')->getForUser($user, 'login_ip_history', [])->data;
+ $list = app('preferences')->getForUser($user, 'login_ip_history', [])->data;
+ if (!is_array($list)) {
+ $list = [];
+ }
/** @var array $entry */
foreach ($list as $index => $entry) {
if (false === $entry['notified']) {
try {
Notification::send($user, new UserLogin($ipAddress));
- } catch (Exception $e) {
+ } catch (\Exception $e) { // @phpstan-ignore-line
$message = $e->getMessage();
if (str_contains($message, 'Bcc')) {
- Log::warning('[Bcc] Could not send notification. Please validate your email settings, use the .env.example file as a guide.');
+ app('log')->warning('[Bcc] Could not send notification. Please validate your email settings, use the .env.example file as a guide.');
+
return;
}
if (str_contains($message, 'RFC 2822')) {
- Log::warning('[RFC] Could not send notification. Please validate your email settings, use the .env.example file as a guide.');
+ app('log')->warning('[RFC] Could not send notification. Please validate your email settings, use the .env.example file as a guide.');
+
return;
}
- Log::error($e->getMessage());
- Log::error($e->getTraceAsString());
+ app('log')->error($e->getMessage());
+ app('log')->error($e->getTraceAsString());
}
}
$list[$index]['notified'] = true;
@@ -224,12 +218,9 @@ class UserEventHandler
app('preferences')->setForUser($user, 'login_ip_history', $list);
}
- /**
- * @param RegisteredUser $event
- */
public function sendAdminRegistrationNotification(RegisteredUser $event): void
{
- $sendMail = FireflyConfig::get('notification_admin_new_reg', true)->data;
+ $sendMail = (bool)app('fireflyconfig')->get('notification_admin_new_reg', true)->data;
if ($sendMail) {
/** @var UserRepositoryInterface $repository */
$repository = app(UserRepositoryInterface::class);
@@ -238,18 +229,20 @@ class UserEventHandler
if ($repository->hasRole($user, 'owner')) {
try {
Notification::send($user, new AdminRegistrationNotification($event->user));
- } catch (Exception $e) {
+ } catch (\Exception $e) { // @phpstan-ignore-line
$message = $e->getMessage();
if (str_contains($message, 'Bcc')) {
- Log::warning('[Bcc] Could not send notification. Please validate your email settings, use the .env.example file as a guide.');
+ app('log')->warning('[Bcc] Could not send notification. Please validate your email settings, use the .env.example file as a guide.');
+
return;
}
if (str_contains($message, 'RFC 2822')) {
- Log::warning('[RFC] Could not send notification. Please validate your email settings, use the .env.example file as a guide.');
+ app('log')->warning('[RFC] Could not send notification. Please validate your email settings, use the .env.example file as a guide.');
+
return;
}
- Log::error($e->getMessage());
- Log::error($e->getTraceAsString());
+ app('log')->error($e->getMessage());
+ app('log')->error($e->getTraceAsString());
}
}
}
@@ -260,8 +253,6 @@ class UserEventHandler
* Send email to confirm email change. Will not be made into a notification, because
* this requires some custom fields from the user and not just the "user" object.
*
- * @param UserChangedEmail $event
- *
* @throws FireflyException
*/
public function sendEmailChangeConfirmMail(UserChangedEmail $event): void
@@ -273,10 +264,11 @@ class UserEventHandler
$url = route('profile.confirm-email-change', [$token->data]);
try {
- Mail::to($newEmail)->send(new ConfirmEmailChangeMail($newEmail, $oldEmail, $url));
- } catch (Exception $e) { // intentional generic exception
- Log::error($e->getMessage());
- Log::error($e->getTraceAsString());
+ \Mail::to($newEmail)->send(new ConfirmEmailChangeMail($newEmail, $oldEmail, $url));
+ } catch (\Exception $e) {
+ app('log')->error($e->getMessage());
+ app('log')->error($e->getTraceAsString());
+
throw new FireflyException($e->getMessage(), 0, $e);
}
}
@@ -285,8 +277,6 @@ class UserEventHandler
* Send email to be able to undo email change. Will not be made into a notification, because
* this requires some custom fields from the user and not just the "user" object.
*
- * @param UserChangedEmail $event
- *
* @throws FireflyException
*/
public function sendEmailChangeUndoMail(UserChangedEmail $event): void
@@ -297,43 +287,42 @@ class UserEventHandler
$token = app('preferences')->getForUser($user, 'email_change_undo_token', 'invalid');
$hashed = hash('sha256', sprintf('%s%s', (string)config('app.key'), $oldEmail));
$url = route('profile.undo-email-change', [$token->data, $hashed]);
+
try {
- Mail::to($oldEmail)->send(new UndoEmailChangeMail($newEmail, $oldEmail, $url));
- } catch (Exception $e) { // intentional generic exception
- Log::error($e->getMessage());
- Log::error($e->getTraceAsString());
+ \Mail::to($oldEmail)->send(new UndoEmailChangeMail($newEmail, $oldEmail, $url));
+ } catch (\Exception $e) {
+ app('log')->error($e->getMessage());
+ app('log')->error($e->getTraceAsString());
+
throw new FireflyException($e->getMessage(), 0, $e);
}
}
/**
* Send a new password to the user.
- *
- * @param RequestedNewPassword $event
*/
public function sendNewPassword(RequestedNewPassword $event): void
{
try {
Notification::send($event->user, new UserNewPassword(route('password.reset', [$event->token])));
- } catch (Exception $e) {
+ } catch (\Exception $e) { // @phpstan-ignore-line
$message = $e->getMessage();
if (str_contains($message, 'Bcc')) {
- Log::warning('[Bcc] Could not send notification. Please validate your email settings, use the .env.example file as a guide.');
+ app('log')->warning('[Bcc] Could not send notification. Please validate your email settings, use the .env.example file as a guide.');
+
return;
}
if (str_contains($message, 'RFC 2822')) {
- Log::warning('[RFC] Could not send notification. Please validate your email settings, use the .env.example file as a guide.');
+ app('log')->warning('[RFC] Could not send notification. Please validate your email settings, use the .env.example file as a guide.');
+
return;
}
- Log::error($e->getMessage());
- Log::error($e->getTraceAsString());
+ app('log')->error($e->getMessage());
+ app('log')->error($e->getTraceAsString());
}
}
/**
- * @param InvitationCreated $event
- *
- * @return void
* @throws FireflyException
*/
public function sendRegistrationInvite(InvitationCreated $event): void
@@ -341,11 +330,13 @@ class UserEventHandler
$invitee = $event->invitee->email;
$admin = $event->invitee->user->email;
$url = route('invite', [$event->invitee->invite_code]);
+
try {
- Mail::to($invitee)->send(new InvitationMail($invitee, $admin, $url));
- } catch (Exception $e) { // intentional generic exception
- Log::error($e->getMessage());
- Log::error($e->getTraceAsString());
+ \Mail::to($invitee)->send(new InvitationMail($invitee, $admin, $url));
+ } catch (\Exception $e) {
+ app('log')->error($e->getMessage());
+ app('log')->error($e->getTraceAsString());
+
throw new FireflyException($e->getMessage(), 0, $e);
}
}
@@ -353,44 +344,42 @@ class UserEventHandler
/**
* This method will send the user a registration mail, welcoming him or her to Firefly III.
* This message is only sent when the configuration of Firefly III says so.
- *
- * @param RegisteredUser $event
- *
*/
public function sendRegistrationMail(RegisteredUser $event): void
{
- $sendMail = FireflyConfig::get('notification_user_new_reg', true)->data;
+ $sendMail = (bool)app('fireflyconfig')->get('notification_user_new_reg', true)->data;
if ($sendMail) {
try {
Notification::send($event->user, new UserRegistrationNotification());
- } catch (Exception $e) {
+ } catch (\Exception $e) { // @phpstan-ignore-line
$message = $e->getMessage();
if (str_contains($message, 'Bcc')) {
- Log::warning('[Bcc] Could not send notification. Please validate your email settings, use the .env.example file as a guide.');
+ app('log')->warning('[Bcc] Could not send notification. Please validate your email settings, use the .env.example file as a guide.');
+
return;
}
if (str_contains($message, 'RFC 2822')) {
- Log::warning('[RFC] Could not send notification. Please validate your email settings, use the .env.example file as a guide.');
+ app('log')->warning('[RFC] Could not send notification. Please validate your email settings, use the .env.example file as a guide.');
+
return;
}
- Log::error($e->getMessage());
- Log::error($e->getTraceAsString());
+ app('log')->error($e->getMessage());
+ app('log')->error($e->getTraceAsString());
}
}
}
/**
- * @param ActuallyLoggedIn $event
- *
* @throws FireflyException
*/
public function storeUserIPAddress(ActuallyLoggedIn $event): void
{
- Log::debug('Now in storeUserIPAddress');
- $user = $event->user;
+ app('log')->debug('Now in storeUserIPAddress');
+ $user = $event->user;
if ($user->hasRole('demo')) {
- Log::debug('Do not log demo user logins');
+ app('log')->debug('Do not log demo user logins');
+
return;
}
@@ -399,25 +388,25 @@ class UserEventHandler
$preference = app('preferences')->getForUser($user, 'login_ip_history', [])->data;
} catch (FireflyException $e) {
// don't care.
- Log::error($e->getMessage());
+ app('log')->error($e->getMessage());
return;
}
- $inArray = false;
- $ip = request()->ip();
- Log::debug(sprintf('User logging in from IP address %s', $ip));
+ $inArray = false;
+ $ip = request()->ip();
+ app('log')->debug(sprintf('User logging in from IP address %s', $ip));
// update array if in array
foreach ($preference as $index => $row) {
if ($row['ip'] === $ip) {
- Log::debug('Found IP in array, refresh time.');
+ app('log')->debug('Found IP in array, refresh time.');
$preference[$index]['time'] = now(config('app.timezone'))->format('Y-m-d H:i:s');
$inArray = true;
}
// clean up old entries (6 months)
$carbon = Carbon::createFromFormat('Y-m-d H:i:s', $preference[$index]['time']);
- if ($carbon->diffInMonths(today()) > 6) {
- Log::debug(sprintf('Entry for %s is very old, remove it.', $row['ip']));
+ if (false !== $carbon && $carbon->diffInMonths(today()) > 6) {
+ app('log')->debug(sprintf('Entry for %s is very old, remove it.', $row['ip']));
unset($preference[$index]);
}
}
@@ -430,8 +419,9 @@ class UserEventHandler
];
}
$preference = array_values($preference);
+
/** @var bool $send */
- $send = app('preferences')->getForUser($user, 'notification_user_login', true)->data;
+ $send = app('preferences')->getForUser($user, 'notification_user_login', true)->data;
app('preferences')->setForUser($user, 'login_ip_history', $preference);
if (false === $inArray && true === $send) {
diff --git a/app/Handlers/Events/VersionCheckEventHandler.php b/app/Handlers/Events/VersionCheckEventHandler.php
index 5b39792b23..70a104ac07 100644
--- a/app/Handlers/Events/VersionCheckEventHandler.php
+++ b/app/Handlers/Events/VersionCheckEventHandler.php
@@ -28,9 +28,6 @@ use FireflyIII\Exceptions\FireflyException;
use FireflyIII\Helpers\Update\UpdateTrait;
use FireflyIII\Models\Configuration;
use FireflyIII\Repositories\User\UserRepositoryInterface;
-use Illuminate\Support\Facades\Log;
-use Psr\Container\ContainerExceptionInterface;
-use Psr\Container\NotFoundExceptionInterface;
/**
* Class VersionCheckEventHandler
@@ -42,32 +39,29 @@ class VersionCheckEventHandler
/**
* Checks with GitHub to see if there is a new version.
*
- * @param RequestedVersionCheckStatus $event
- *
* @throws FireflyException
- * @throws ContainerExceptionInterface
- * @throws NotFoundExceptionInterface
+ *
* @deprecated ?
*/
public function checkForUpdates(RequestedVersionCheckStatus $event): void
{
- Log::debug('Now in checkForUpdates()');
+ app('log')->debug('Now in checkForUpdates()');
// should not check for updates:
- $permission = app('fireflyconfig')->get('permission_update_check', -1);
- $value = (int)$permission->data;
+ $permission = app('fireflyconfig')->get('permission_update_check', -1);
+ $value = (int)$permission->data;
if (1 !== $value) {
- Log::debug('Update check is not enabled.');
+ app('log')->debug('Update check is not enabled.');
$this->warnToCheckForUpdates($event);
return;
}
/** @var UserRepositoryInterface $repository */
- $repository = app(UserRepositoryInterface::class);
- $user = $event->user;
+ $repository = app(UserRepositoryInterface::class);
+ $user = $event->user;
if (!$repository->hasRole($user, 'owner')) {
- Log::debug('User is not admin, done.');
+ app('log')->debug('User is not admin, done.');
return;
}
@@ -76,34 +70,30 @@ class VersionCheckEventHandler
$lastCheckTime = app('fireflyconfig')->get('last_update_check', time());
$now = time();
$diff = $now - $lastCheckTime->data;
- Log::debug(sprintf('Last check time is %d, current time is %d, difference is %d', $lastCheckTime->data, $now, $diff));
+ app('log')->debug(sprintf('Last check time is %d, current time is %d, difference is %d', $lastCheckTime->data, $now, $diff));
if ($diff < 604800) {
- Log::debug(sprintf('Checked for updates less than a week ago (on %s).', date('Y-m-d H:i:s', $lastCheckTime->data)));
+ app('log')->debug(sprintf('Checked for updates less than a week ago (on %s).', date('Y-m-d H:i:s', $lastCheckTime->data)));
return;
}
// last check time was more than a week ago.
- Log::debug('Have not checked for a new version in a week!');
- $release = $this->getLatestRelease();
+ app('log')->debug('Have not checked for a new version in a week!');
+ $release = $this->getLatestRelease();
session()->flash($release['level'], $release['message']);
app('fireflyconfig')->set('last_update_check', time());
}
/**
- * @param RequestedVersionCheckStatus $event
- *
* @throws FireflyException
- * @throws ContainerExceptionInterface
- * @throws NotFoundExceptionInterface
*/
protected function warnToCheckForUpdates(RequestedVersionCheckStatus $event): void
{
/** @var UserRepositoryInterface $repository */
- $repository = app(UserRepositoryInterface::class);
- $user = $event->user;
+ $repository = app(UserRepositoryInterface::class);
+ $user = $event->user;
if (!$repository->hasRole($user, 'owner')) {
- Log::debug('User is not admin, done.');
+ app('log')->debug('User is not admin, done.');
return;
}
@@ -112,14 +102,14 @@ class VersionCheckEventHandler
$lastCheckTime = app('fireflyconfig')->get('last_update_warning', time());
$now = time();
$diff = $now - $lastCheckTime->data;
- Log::debug(sprintf('Last warning time is %d, current time is %d, difference is %d', $lastCheckTime->data, $now, $diff));
+ app('log')->debug(sprintf('Last warning time is %d, current time is %d, difference is %d', $lastCheckTime->data, $now, $diff));
if ($diff < 604800 * 4) {
- Log::debug(sprintf('Warned about updates less than four weeks ago (on %s).', date('Y-m-d H:i:s', $lastCheckTime->data)));
+ app('log')->debug(sprintf('Warned about updates less than four weeks ago (on %s).', date('Y-m-d H:i:s', $lastCheckTime->data)));
return;
}
// last check time was more than a week ago.
- Log::debug('Have warned about a new version in four weeks!');
+ app('log')->debug('Have warned about a new version in four weeks!');
session()->flash('info', (string)trans('firefly.disabled_but_check'));
app('fireflyconfig')->set('last_update_warning', time());
diff --git a/app/Handlers/Events/WebhookEventHandler.php b/app/Handlers/Events/WebhookEventHandler.php
index c678510606..863800c594 100644
--- a/app/Handlers/Events/WebhookEventHandler.php
+++ b/app/Handlers/Events/WebhookEventHandler.php
@@ -25,7 +25,6 @@ namespace FireflyIII\Handlers\Events;
use FireflyIII\Jobs\SendWebhookMessage;
use FireflyIII\Models\WebhookMessage;
-use Illuminate\Support\Facades\Log;
/**
* Class WebhookEventHandler
@@ -37,23 +36,24 @@ class WebhookEventHandler
*/
public function sendWebhookMessages(): void
{
- Log::debug(sprintf('Now in %s', __METHOD__));
+ app('log')->debug(sprintf('Now in %s', __METHOD__));
// kick off the job!
$messages = WebhookMessage::where('webhook_messages.sent', false)
- ->get(['webhook_messages.*'])
- ->filter(
- function (WebhookMessage $message) {
- return $message->webhookAttempts()->count() <= 2;
- }
- )->splice(0, 5);
- Log::debug(sprintf('Found %d webhook message(s) ready to be send.', $messages->count()));
+ ->get(['webhook_messages.*'])
+ ->filter(
+ static function (WebhookMessage $message) {
+ return $message->webhookAttempts()->count() <= 2;
+ }
+ )->splice(0, 5)
+ ;
+ app('log')->debug(sprintf('Found %d webhook message(s) ready to be send.', $messages->count()));
foreach ($messages as $message) {
if (false === $message->sent) {
- Log::debug(sprintf('Send message #%d', $message->id));
+ app('log')->debug(sprintf('Send message #%d', $message->id));
SendWebhookMessage::dispatch($message)->afterResponse();
}
if (false !== $message->sent) {
- Log::debug(sprintf('Skip message #%d', $message->id));
+ app('log')->debug(sprintf('Skip message #%d', $message->id));
}
}
}
diff --git a/app/Handlers/Observer/AccountObserver.php b/app/Handlers/Observer/AccountObserver.php
index b5ad9971a7..9d8cb9de9e 100644
--- a/app/Handlers/Observer/AccountObserver.php
+++ b/app/Handlers/Observer/AccountObserver.php
@@ -32,10 +32,6 @@ class AccountObserver
{
/**
* Also delete related objects.
- *
- * @param Account $account
- *
- * @return void
*/
public function deleting(Account $account): void
{
@@ -52,7 +48,5 @@ class AccountObserver
}
$account->notes()->delete();
$account->locations()->delete();
-
}
-
}
diff --git a/app/Handlers/Observer/BillObserver.php b/app/Handlers/Observer/BillObserver.php
index 42206dc7f0..5d93e8609f 100644
--- a/app/Handlers/Observer/BillObserver.php
+++ b/app/Handlers/Observer/BillObserver.php
@@ -30,11 +30,6 @@ use FireflyIII\Models\Bill;
*/
class BillObserver
{
- /**
- * @param Bill $bill
- *
- * @return void
- */
public function deleting(Bill $bill): void
{
app('log')->debug('Observe "deleting" of a bill.');
@@ -43,5 +38,4 @@ class BillObserver
}
$bill->notes()->delete();
}
-
}
diff --git a/app/Handlers/Observer/BudgetObserver.php b/app/Handlers/Observer/BudgetObserver.php
index 1c8dc4791e..d13abec746 100644
--- a/app/Handlers/Observer/BudgetObserver.php
+++ b/app/Handlers/Observer/BudgetObserver.php
@@ -24,28 +24,30 @@ declare(strict_types=1);
namespace FireflyIII\Handlers\Observer;
use FireflyIII\Models\Budget;
+use FireflyIII\Models\BudgetLimit;
/**
* Class BudgetObserver
*/
class BudgetObserver
{
- /**
- * @param Budget $budget
- *
- * @return void
- */
public function deleting(Budget $budget): void
{
app('log')->debug('Observe "deleting" of a budget.');
foreach ($budget->attachments()->get() as $attachment) {
$attachment->delete();
}
+ $budgetLimits = $budget->budgetlimits()->get();
- $budget->budgetlimits()->delete();
+ /** @var BudgetLimit $budgetLimit */
+ foreach ($budgetLimits as $budgetLimit) {
+ // this loop exists so several events are fired.
+ $budgetLimit->delete();
+ }
$budget->notes()->delete();
$budget->autoBudgets()->delete();
- }
+ // recalculate available budgets.
+ }
}
diff --git a/app/Handlers/Observer/CategoryObserver.php b/app/Handlers/Observer/CategoryObserver.php
index d1029ef2cf..0cc866761a 100644
--- a/app/Handlers/Observer/CategoryObserver.php
+++ b/app/Handlers/Observer/CategoryObserver.php
@@ -30,11 +30,6 @@ use FireflyIII\Models\Category;
*/
class CategoryObserver
{
- /**
- * @param Category $category
- *
- * @return void
- */
public function deleting(Category $category): void
{
app('log')->debug('Observe "deleting" of a category.');
@@ -43,5 +38,4 @@ class CategoryObserver
}
$category->notes()->delete();
}
-
}
diff --git a/app/Handlers/Observer/PiggyBankObserver.php b/app/Handlers/Observer/PiggyBankObserver.php
index e448e8378b..7e9b879892 100644
--- a/app/Handlers/Observer/PiggyBankObserver.php
+++ b/app/Handlers/Observer/PiggyBankObserver.php
@@ -31,28 +31,19 @@ use FireflyIII\Models\PiggyBankRepetition;
*/
class PiggyBankObserver
{
- /**
- * @param PiggyBank $piggyBank
- *
- * @return void
- */
public function created(PiggyBank $piggyBank): void
{
app('log')->debug('Observe "created" of a piggy bank.');
- $repetition = new PiggyBankRepetition();
+ $repetition = new PiggyBankRepetition();
$repetition->piggyBank()->associate($piggyBank);
$repetition->startdate = $piggyBank->startdate;
$repetition->targetdate = $piggyBank->targetdate;
- $repetition->currentamount = 0;
+ $repetition->currentamount = '0';
$repetition->save();
}
/**
* Also delete related objects.
- *
- * @param PiggyBank $piggyBank
- *
- * @return void
*/
public function deleting(PiggyBank $piggyBank): void
{
@@ -67,5 +58,4 @@ class PiggyBankObserver
$piggyBank->notes()->delete();
}
-
}
diff --git a/app/Handlers/Observer/RecurrenceObserver.php b/app/Handlers/Observer/RecurrenceObserver.php
index 086a79966a..c892315f60 100644
--- a/app/Handlers/Observer/RecurrenceObserver.php
+++ b/app/Handlers/Observer/RecurrenceObserver.php
@@ -30,11 +30,6 @@ use FireflyIII\Models\Recurrence;
*/
class RecurrenceObserver
{
- /**
- * @param Recurrence $recurrence
- *
- * @return void
- */
public function deleting(Recurrence $recurrence): void
{
app('log')->debug('Observe "deleting" of a recurrence.');
@@ -48,7 +43,5 @@ class RecurrenceObserver
$transaction->delete();
}
$recurrence->notes()->delete();
-
}
-
}
diff --git a/app/Handlers/Observer/RecurrenceTransactionObserver.php b/app/Handlers/Observer/RecurrenceTransactionObserver.php
index 45cb092f63..f88cb38b5d 100644
--- a/app/Handlers/Observer/RecurrenceTransactionObserver.php
+++ b/app/Handlers/Observer/RecurrenceTransactionObserver.php
@@ -30,15 +30,9 @@ use FireflyIII\Models\RecurrenceTransaction;
*/
class RecurrenceTransactionObserver
{
- /**
- * @param RecurrenceTransaction $transaction
- *
- * @return void
- */
public function deleting(RecurrenceTransaction $transaction): void
{
app('log')->debug('Observe "deleting" of a recurrence transaction.');
$transaction->recurrenceTransactionMeta()->delete();
}
-
}
diff --git a/app/Handlers/Observer/RuleGroupObserver.php b/app/Handlers/Observer/RuleGroupObserver.php
index 1b14d7276a..c7e1c223bf 100644
--- a/app/Handlers/Observer/RuleGroupObserver.php
+++ b/app/Handlers/Observer/RuleGroupObserver.php
@@ -30,18 +30,11 @@ use FireflyIII\Models\RuleGroup;
*/
class RuleGroupObserver
{
- /**
- * @param RuleGroup $ruleGroup
- *
- * @return void
- */
public function deleting(RuleGroup $ruleGroup): void
{
app('log')->debug('Observe "deleting" of a rule group.');
foreach ($ruleGroup->rules()->get() as $rule) {
$rule->delete();
}
-
}
-
}
diff --git a/app/Handlers/Observer/RuleObserver.php b/app/Handlers/Observer/RuleObserver.php
index 098b7037d1..3121a6b62e 100644
--- a/app/Handlers/Observer/RuleObserver.php
+++ b/app/Handlers/Observer/RuleObserver.php
@@ -30,16 +30,10 @@ use FireflyIII\Models\Rule;
*/
class RuleObserver
{
- /**
- * @param Rule $rule
- *
- * @return void
- */
public function deleting(Rule $rule): void
{
app('log')->debug('Observe "deleting" of a rule.');
$rule->ruleActions()->delete();
$rule->ruleTriggers()->delete();
}
-
}
diff --git a/app/Handlers/Observer/TagObserver.php b/app/Handlers/Observer/TagObserver.php
index 85c6c16c63..1994a30aa1 100644
--- a/app/Handlers/Observer/TagObserver.php
+++ b/app/Handlers/Observer/TagObserver.php
@@ -30,11 +30,6 @@ use FireflyIII\Models\Tag;
*/
class TagObserver
{
- /**
- * @param Tag $tag
- *
- * @return void
- */
public function deleting(Tag $tag): void
{
app('log')->debug('Observe "deleting" of a tag.');
@@ -44,7 +39,5 @@ class TagObserver
}
$tag->locations()->delete();
-
}
-
}
diff --git a/app/Handlers/Observer/TransactionGroupObserver.php b/app/Handlers/Observer/TransactionGroupObserver.php
index 5b351cec06..418356668c 100644
--- a/app/Handlers/Observer/TransactionGroupObserver.php
+++ b/app/Handlers/Observer/TransactionGroupObserver.php
@@ -37,5 +37,4 @@ class TransactionGroupObserver
$journal->delete();
}
}
-
}
diff --git a/app/Handlers/Observer/TransactionJournalObserver.php b/app/Handlers/Observer/TransactionJournalObserver.php
index c24f1089da..3bb106783e 100644
--- a/app/Handlers/Observer/TransactionJournalObserver.php
+++ b/app/Handlers/Observer/TransactionJournalObserver.php
@@ -30,17 +30,12 @@ use FireflyIII\Models\TransactionJournal;
*/
class TransactionJournalObserver
{
- /**
- * @param TransactionJournal $transactionJournal
- *
- * @return void
- */
public function deleting(TransactionJournal $transactionJournal): void
{
app('log')->debug('Observe "deleting" of a transaction journal.');
// to make sure the listener doesn't get back to use and loop
- TransactionJournal::withoutEvents(function () use ($transactionJournal) {
+ TransactionJournal::withoutEvents(static function () use ($transactionJournal): void {
foreach ($transactionJournal->transactions()->get() as $transaction) {
$transaction->delete();
}
@@ -53,5 +48,4 @@ class TransactionJournalObserver
$transactionJournal->destJournalLinks()->delete();
$transactionJournal->auditLogEntries()->delete();
}
-
}
diff --git a/app/Handlers/Observer/TransactionObserver.php b/app/Handlers/Observer/TransactionObserver.php
index d1d117f1a0..1c39335bc1 100644
--- a/app/Handlers/Observer/TransactionObserver.php
+++ b/app/Handlers/Observer/TransactionObserver.php
@@ -30,10 +30,9 @@ use FireflyIII\Models\Transaction;
*/
class TransactionObserver
{
- public function deleting(Transaction $transaction): void
+ public function deleting(?Transaction $transaction): void
{
app('log')->debug('Observe "deleting" of a transaction.');
$transaction?->transactionJournal?->delete();
}
-
}
diff --git a/app/Handlers/Observer/WebhookMessageObserver.php b/app/Handlers/Observer/WebhookMessageObserver.php
index 5744e3e5f8..6248dc4d3c 100644
--- a/app/Handlers/Observer/WebhookMessageObserver.php
+++ b/app/Handlers/Observer/WebhookMessageObserver.php
@@ -30,11 +30,6 @@ use FireflyIII\Models\WebhookMessage;
*/
class WebhookMessageObserver
{
- /**
- * @param WebhookMessage $webhookMessage
- *
- * @return void
- */
public function deleting(WebhookMessage $webhookMessage): void
{
app('log')->debug('Observe "deleting" of a webhook message.');
diff --git a/app/Handlers/Observer/WebhookObserver.php b/app/Handlers/Observer/WebhookObserver.php
index dd19ebacb5..6a0799db99 100644
--- a/app/Handlers/Observer/WebhookObserver.php
+++ b/app/Handlers/Observer/WebhookObserver.php
@@ -30,17 +30,11 @@ use FireflyIII\Models\Webhook;
*/
class WebhookObserver
{
- /**
- * @param Webhook $webhook
- *
- * @return void
- */
public function deleting(Webhook $webhook): void
{
app('log')->debug('Observe "deleting" of a webhook.');
- foreach ($webhook->webhookMessages() as $message) {
+ foreach ($webhook->webhookMessages()->get() as $message) {
$message->delete();
}
}
-
}
diff --git a/app/Helpers/Attachments/AttachmentHelper.php b/app/Helpers/Attachments/AttachmentHelper.php
index 8c9c038992..b3b22d058a 100644
--- a/app/Helpers/Attachments/AttachmentHelper.php
+++ b/app/Helpers/Attachments/AttachmentHelper.php
@@ -23,7 +23,6 @@ declare(strict_types=1);
namespace FireflyIII\Helpers\Attachments;
-use Crypt;
use FireflyIII\Exceptions\FireflyException;
use FireflyIII\Models\Attachment;
use FireflyIII\Models\PiggyBank;
@@ -48,13 +47,10 @@ class AttachmentHelper implements AttachmentHelperInterface
protected array $allowedMimes = [];
protected int $maxUploadSize = 0;
- /** @var Filesystem The disk where attachments are stored. */
- protected $uploadDisk;
+ protected Filesystem $uploadDisk;
/**
* AttachmentHelper constructor.
- *
-
*/
public function __construct()
{
@@ -68,17 +64,13 @@ class AttachmentHelper implements AttachmentHelperInterface
/**
* Returns the content of an attachment.
- *
- *
- * @param Attachment $attachment
- *
- * @return string
*/
public function getAttachmentContent(Attachment $attachment): string
{
$encryptedData = (string)$this->uploadDisk->get(sprintf('at-%d.data', $attachment->id));
+
try {
- $unencryptedData = Crypt::decrypt($encryptedData); // verified
+ $unencryptedData = \Crypt::decrypt($encryptedData); // verified
} catch (DecryptException $e) {
Log::error(sprintf('Could not decrypt data of attachment #%d: %s', $attachment->id, $e->getMessage()));
$unencryptedData = $encryptedData;
@@ -89,20 +81,14 @@ class AttachmentHelper implements AttachmentHelperInterface
/**
* Returns the file path relative to upload disk for an attachment,
- *
- * @param Attachment $attachment
- *
- * @return string
*/
public function getAttachmentLocation(Attachment $attachment): string
{
- return sprintf('%sat-%d.data', DIRECTORY_SEPARATOR, (int)$attachment->id);
+ return sprintf('%sat-%d.data', \DIRECTORY_SEPARATOR, $attachment->id);
}
/**
* Get all attachments.
- *
- * @return Collection
*/
public function getAttachments(): Collection
{
@@ -111,8 +97,6 @@ class AttachmentHelper implements AttachmentHelperInterface
/**
* Get all errors.
- *
- * @return MessageBag
*/
public function getErrors(): MessageBag
{
@@ -121,8 +105,6 @@ class AttachmentHelper implements AttachmentHelperInterface
/**
* Get all messages.
- *
- * @return MessageBag
*/
public function getMessages(): MessageBag
{
@@ -131,15 +113,11 @@ class AttachmentHelper implements AttachmentHelperInterface
/**
* Uploads a file as a string.
- *
- * @param Attachment $attachment
- * @param string $content
- *
- * @return bool
*/
public function saveAttachmentFromApi(Attachment $attachment, string $content): bool
{
- $resource = tmpfile();
+ Log::debug(sprintf('Now in %s', __METHOD__));
+ $resource = tmpfile();
if (false === $resource) {
Log::error('Cannot create temp-file for file upload.');
@@ -152,51 +130,65 @@ class AttachmentHelper implements AttachmentHelperInterface
return false;
}
- $path = stream_get_meta_data($resource)['uri'];
- fwrite($resource, $content);
- $finfo = finfo_open(FILEINFO_MIME_TYPE);
- $mime = finfo_file($finfo, $path);
- $allowedMime = config('firefly.allowedMimes');
+ $path = stream_get_meta_data($resource)['uri'];
+ Log::debug(sprintf('Path is %s', $path));
+ $result = fwrite($resource, $content);
+ if (false === $result) {
+ Log::error('Could not write temp file.');
+
+ return false;
+ }
+ Log::debug(sprintf('Wrote %d bytes to temp file.', $result));
+ $finfo = finfo_open(FILEINFO_MIME_TYPE);
+ if (false === $finfo) {
+ Log::error('Could not open finfo.');
+ fclose($resource);
+
+ return false;
+ }
+ $mime = (string)finfo_file($finfo, $path);
+ $allowedMime = config('firefly.allowedMimes');
if (!in_array($mime, $allowedMime, true)) {
Log::error(sprintf('Mime type %s is not allowed for API file upload.', $mime));
fclose($resource);
return false;
}
+ Log::debug(sprintf('Found mime "%s" in file "%s"', $mime, $path));
// is allowed? Save the file, without encryption.
- $parts = explode('/', $attachment->fileName());
- $file = $parts[count($parts) - 1];
+ $parts = explode('/', $attachment->fileName());
+ $file = $parts[count($parts) - 1];
+ Log::debug(sprintf('Write file to disk in file named "%s"', $file));
$this->uploadDisk->put($file, $content);
// update attachment.
- $attachment->md5 = md5_file($path);
+ $attachment->md5 = (string)md5_file($path);
$attachment->mime = $mime;
$attachment->size = strlen($content);
$attachment->uploaded = true;
$attachment->save();
+ Log::debug('Done!');
+
return true;
}
/**
* Save attachments that get uploaded with models, through the app.
*
- * @param object $model
- * @param array|null $files
- *
- * @return bool
* @throws FireflyException
*/
public function saveAttachmentsForModel(object $model, ?array $files): bool
{
- if (!($model instanceof Model)) {
+ if (!$model instanceof Model) {
return false;
}
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 */
+
+ /** @var null|UploadedFile $entry */
foreach ($files as $entry) {
if (null !== $entry) {
$this->processFile($entry, $model);
@@ -214,10 +206,6 @@ class AttachmentHelper implements AttachmentHelperInterface
/**
* Process the upload of a file.
*
- * @param UploadedFile $file
- * @param Model $model
- *
- * @return Attachment|null
* @throws FireflyException
* @throws EncryptException
*/
@@ -227,16 +215,16 @@ class AttachmentHelper implements AttachmentHelperInterface
$validation = $this->validateUpload($file, $model);
$attachment = null;
if (false !== $validation) {
- $user = $model->user; // @phpstan-ignore-line
+ $user = $model->user;
// ignore lines about polymorphic calls.
if ($model instanceof PiggyBank) {
$user = $model->account->user;
}
- $attachment = new Attachment(); // create Attachment object.
+ $attachment = new Attachment(); // create Attachment object.
$attachment->user()->associate($user);
$attachment->attachable()->associate($model);
- $attachment->md5 = md5_file($file->getRealPath());
+ $attachment->md5 = (string)md5_file($file->getRealPath());
$attachment->filename = $file->getClientOriginalName();
$attachment->mime = $file->getMimeType();
$attachment->size = $file->getSize();
@@ -244,14 +232,14 @@ class AttachmentHelper implements AttachmentHelperInterface
$attachment->save();
Log::debug('Created attachment:', $attachment->toArray());
- $fileObject = $file->openFile();
+ $fileObject = $file->openFile();
$fileObject->rewind();
if (0 === $file->getSize()) {
throw new FireflyException('Cannot upload empty or non-existent file.');
}
- $content = $fileObject->fread($file->getSize());
+ $content = (string)$fileObject->fread($file->getSize());
Log::debug(sprintf('Full file length is %d and upload size is %d.', strlen($content), $file->getSize()));
// store it without encryption.
@@ -260,8 +248,8 @@ class AttachmentHelper implements AttachmentHelperInterface
$attachment->save();
$this->attachments->push($attachment);
- $name = e($file->getClientOriginalName()); // add message:
- $msg = (string)trans('validation.file_attached', ['name' => $name]);
+ $name = e($file->getClientOriginalName()); // add message:
+ $msg = (string)trans('validation.file_attached', ['name' => $name]);
$this->messages->add('attachments', $msg);
}
@@ -270,11 +258,6 @@ class AttachmentHelper implements AttachmentHelperInterface
/**
* Verify if the file was uploaded correctly.
- *
- * @param UploadedFile $file
- * @param Model $model
- *
- * @return bool
*/
protected function validateUpload(UploadedFile $file, Model $model): bool
{
@@ -288,7 +271,6 @@ class AttachmentHelper implements AttachmentHelperInterface
$result = false;
}
-
// can't seem to reach this point.
if (true === $result && !$this->validSize($file)) {
$result = false;
@@ -303,22 +285,18 @@ class AttachmentHelper implements AttachmentHelperInterface
/**
* Verify if the mime of a file is valid.
- *
- * @param UploadedFile $file
- *
- * @return bool
*/
protected function validMime(UploadedFile $file): bool
{
Log::debug('Now in validMime()');
- $mime = e($file->getMimeType());
- $name = e($file->getClientOriginalName());
+ $mime = e($file->getMimeType());
+ $name = e($file->getClientOriginalName());
Log::debug(sprintf('Name is %s, and mime is %s', $name, $mime));
Log::debug('Valid mimes are', $this->allowedMimes);
$result = true;
if (!in_array($mime, $this->allowedMimes, true)) {
- $msg = (string)trans('validation.file_invalid_mime', ['name' => $name, 'mime' => $mime]);
+ $msg = (string)trans('validation.file_invalid_mime', ['name' => $name, 'mime' => $mime]);
$this->errors->add('attachments', $msg);
Log::error($msg);
@@ -330,11 +308,6 @@ class AttachmentHelper implements AttachmentHelperInterface
/**
* Verify if the size of a file is valid.
- *
- *
- * @param UploadedFile $file
- *
- * @return bool
*/
protected function validSize(UploadedFile $file): bool
{
@@ -342,7 +315,7 @@ class AttachmentHelper implements AttachmentHelperInterface
$name = e($file->getClientOriginalName());
$result = true;
if ($size > $this->maxUploadSize) {
- $msg = (string)trans('validation.file_too_large', ['name' => $name]);
+ $msg = (string)trans('validation.file_too_large', ['name' => $name]);
$this->errors->add('attachments', $msg);
Log::error($msg);
@@ -354,28 +327,23 @@ class AttachmentHelper implements AttachmentHelperInterface
/**
* Check if a model already has this file attached.
- *
- * @param UploadedFile $file
- * @param Model $model
- *
- * @return bool
*/
protected function hasFile(UploadedFile $file, Model $model): bool
{
- $md5 = md5_file($file->getRealPath());
- $name = $file->getClientOriginalName();
- $class = get_class($model);
- $count = 0;
+ $md5 = md5_file($file->getRealPath());
+ $name = $file->getClientOriginalName();
+ $class = get_class($model);
+ $count = 0;
// ignore lines about polymorphic calls.
if ($model instanceof PiggyBank) {
$count = $model->account->user->attachments()->where('md5', $md5)->where('attachable_id', $model->id)->where('attachable_type', $class)->count();
}
- if (!($model instanceof PiggyBank)) {
- $count = $model->user->attachments()->where('md5', $md5)->where('attachable_id', $model->id)->where('attachable_type', $class)->count(); // @phpstan-ignore-line
+ if (!$model instanceof PiggyBank) {
+ $count = $model->user->attachments()->where('md5', $md5)->where('attachable_id', $model->id)->where('attachable_type', $class)->count();
}
$result = false;
if ($count > 0) {
- $msg = (string)trans('validation.file_already_attached', ['name' => $name]);
+ $msg = (string)trans('validation.file_already_attached', ['name' => $name]);
$this->errors->add('attachments', $msg);
Log::error($msg);
$result = true;
diff --git a/app/Helpers/Attachments/AttachmentHelperInterface.php b/app/Helpers/Attachments/AttachmentHelperInterface.php
index 766193e86b..4640d5deb8 100644
--- a/app/Helpers/Attachments/AttachmentHelperInterface.php
+++ b/app/Helpers/Attachments/AttachmentHelperInterface.php
@@ -34,60 +34,36 @@ interface AttachmentHelperInterface
{
/**
* Get content of an attachment.
- *
- * @param Attachment $attachment
- *
- * @return string
*/
public function getAttachmentContent(Attachment $attachment): string;
/**
* Get the location of an attachment.
- *
- * @param Attachment $attachment
- *
- * @return string
*/
public function getAttachmentLocation(Attachment $attachment): string;
/**
* Get all attachments.
- *
- * @return Collection
*/
public function getAttachments(): Collection;
/**
* Get all errors.
- *
- * @return MessageBag
*/
public function getErrors(): MessageBag;
/**
* Get all messages/
- *
- * @return MessageBag
*/
public function getMessages(): MessageBag;
/**
* Uploads a file as a string.
- *
- * @param Attachment $attachment
- * @param string $content
- *
- * @return bool
*/
public function saveAttachmentFromApi(Attachment $attachment, string $content): bool;
/**
* Save attachments that got uploaded.
- *
- * @param object $model
- * @param null|array $files
- *
- * @return bool
*/
public function saveAttachmentsForModel(object $model, ?array $files): bool;
}
diff --git a/app/Helpers/Collector/Extensions/AccountCollection.php b/app/Helpers/Collector/Extensions/AccountCollection.php
index afb2466ea4..1de78d7f31 100644
--- a/app/Helpers/Collector/Extensions/AccountCollection.php
+++ b/app/Helpers/Collector/Extensions/AccountCollection.php
@@ -35,10 +35,6 @@ trait AccountCollection
{
/**
* These accounts must not be included.
- *
- * @param Collection $accounts
- *
- * @return GroupCollectorInterface
*/
public function excludeAccounts(Collection $accounts): GroupCollectorInterface
{
@@ -55,10 +51,6 @@ trait AccountCollection
/**
* These accounts must not be destination accounts.
- *
- * @param Collection $accounts
- *
- * @return GroupCollectorInterface
*/
public function excludeDestinationAccounts(Collection $accounts): GroupCollectorInterface
{
@@ -74,10 +66,6 @@ trait AccountCollection
/**
* These accounts must not be source accounts.
- *
- * @param Collection $accounts
- *
- * @return GroupCollectorInterface
*/
public function excludeSourceAccounts(Collection $accounts): GroupCollectorInterface
{
@@ -93,22 +81,18 @@ trait AccountCollection
/**
* Define which accounts can be part of the source and destination transactions.
- *
- * @param Collection $accounts
- *
- * @return GroupCollectorInterface
*/
public function setAccounts(Collection $accounts): GroupCollectorInterface
{
if ($accounts->count() > 0) {
$accountIds = $accounts->pluck('id')->toArray();
$this->query->where(
- static function (EloquentBuilder $query) use ($accountIds) {
+ static function (EloquentBuilder $query) use ($accountIds): void { // @phpstan-ignore-line
$query->whereIn('source.account_id', $accountIds);
$query->orWhereIn('destination.account_id', $accountIds);
}
);
- //app('log')->debug(sprintf('GroupCollector: setAccounts: %s', implode(', ', $accountIds)));
+ // app('log')->debug(sprintf('GroupCollector: setAccounts: %s', implode(', ', $accountIds)));
}
return $this;
@@ -116,17 +100,13 @@ trait AccountCollection
/**
* Both source AND destination must be in this list of accounts.
- *
- * @param Collection $accounts
- *
- * @return GroupCollectorInterface
*/
public function setBothAccounts(Collection $accounts): GroupCollectorInterface
{
if ($accounts->count() > 0) {
$accountIds = $accounts->pluck('id')->toArray();
$this->query->where(
- static function (EloquentBuilder $query) use ($accountIds) {
+ static function (EloquentBuilder $query) use ($accountIds): void { // @phpstan-ignore-line
$query->whereIn('source.account_id', $accountIds);
$query->whereIn('destination.account_id', $accountIds);
}
@@ -139,10 +119,6 @@ trait AccountCollection
/**
* Define which accounts can be part of the source and destination transactions.
- *
- * @param Collection $accounts
- *
- * @return GroupCollectorInterface
*/
public function setDestinationAccounts(Collection $accounts): GroupCollectorInterface
{
@@ -158,22 +134,18 @@ trait AccountCollection
/**
* Define which accounts can NOT be part of the source and destination transactions.
- *
- * @param Collection $accounts
- *
- * @return GroupCollectorInterface
*/
public function setNotAccounts(Collection $accounts): GroupCollectorInterface
{
if ($accounts->count() > 0) {
$accountIds = $accounts->pluck('id')->toArray();
$this->query->where(
- static function (EloquentBuilder $query) use ($accountIds) {
+ static function (EloquentBuilder $query) use ($accountIds): void { // @phpstan-ignore-line
$query->whereNotIn('source.account_id', $accountIds);
$query->whereNotIn('destination.account_id', $accountIds);
}
);
- //app('log')->debug(sprintf('GroupCollector: setAccounts: %s', implode(', ', $accountIds)));
+ // app('log')->debug(sprintf('GroupCollector: setAccounts: %s', implode(', ', $accountIds)));
}
return $this;
@@ -181,10 +153,6 @@ trait AccountCollection
/**
* Define which accounts can be part of the source and destination transactions.
- *
- * @param Collection $accounts
- *
- * @return GroupCollectorInterface
*/
public function setSourceAccounts(Collection $accounts): GroupCollectorInterface
{
@@ -200,28 +168,24 @@ trait AccountCollection
/**
* Either account can be set, but NOT both. This effectively excludes internal transfers.
- *
- * @param Collection $accounts
- *
- * @return GroupCollectorInterface
*/
public function setXorAccounts(Collection $accounts): GroupCollectorInterface
{
if ($accounts->count() > 0) {
$accountIds = $accounts->pluck('id')->toArray();
$this->query->where(
- static function (EloquentBuilder $q1) use ($accountIds) {
+ static function (EloquentBuilder $q1) use ($accountIds): void { // @phpstan-ignore-line
// sourceAccount is in the set, and destination is NOT.
$q1->where(
- static function (EloquentBuilder $q2) use ($accountIds) {
+ static function (EloquentBuilder $q2) use ($accountIds): void {
$q2->whereIn('source.account_id', $accountIds);
$q2->whereNotIn('destination.account_id', $accountIds);
}
);
// destination is in the set, and source is NOT
$q1->orWhere(
- static function (EloquentBuilder $q3) use ($accountIds) {
+ static function (EloquentBuilder $q3) use ($accountIds): void {
$q3->whereNotIn('source.account_id', $accountIds);
$q3->whereIn('destination.account_id', $accountIds);
}
@@ -237,8 +201,6 @@ trait AccountCollection
/**
* Will include the source and destination account names and types.
- *
- * @return GroupCollectorInterface
*/
public function withAccountInformation(): GroupCollectorInterface
{
@@ -249,9 +211,9 @@ trait AccountCollection
$this->query->leftJoin('account_types as source_account_type', 'source_account_type.id', '=', 'source_account.account_type_id');
// add source account fields:
- $this->fields[] = 'source_account.name as source_account_name';
- $this->fields[] = 'source_account.iban as source_account_iban';
- $this->fields[] = 'source_account_type.type as source_account_type';
+ $this->fields[] = 'source_account.name as source_account_name';
+ $this->fields[] = 'source_account.iban as source_account_iban';
+ $this->fields[] = 'source_account_type.type as source_account_type';
// same for dest
$this->query->leftJoin('accounts as dest_account', 'dest_account.id', '=', 'destination.account_id');
diff --git a/app/Helpers/Collector/Extensions/AmountCollection.php b/app/Helpers/Collector/Extensions/AmountCollection.php
index 7e71d6e422..6daf0192a7 100644
--- a/app/Helpers/Collector/Extensions/AmountCollection.php
+++ b/app/Helpers/Collector/Extensions/AmountCollection.php
@@ -34,15 +34,11 @@ trait AmountCollection
{
/**
* Get transactions with a specific amount.
- *
- * @param string $amount
- *
- * @return GroupCollectorInterface
*/
public function amountIs(string $amount): GroupCollectorInterface
{
$this->query->where(
- static function (EloquentBuilder $q) use ($amount) {
+ static function (EloquentBuilder $q) use ($amount): void { // @phpstan-ignore-line
$q->where('source.amount', app('steam')->negative($amount));
}
);
@@ -50,13 +46,10 @@ trait AmountCollection
return $this;
}
- /**
- * @inheritDoc
- */
public function amountIsNot(string $amount): GroupCollectorInterface
{
$this->query->where(
- static function (EloquentBuilder $q) use ($amount) {
+ static function (EloquentBuilder $q) use ($amount): void { // @phpstan-ignore-line
$q->where('source.amount', '!=', app('steam')->negative($amount));
}
);
@@ -66,15 +59,11 @@ trait AmountCollection
/**
* Get transactions where the amount is less than.
- *
- * @param string $amount
- *
- * @return GroupCollectorInterface
*/
public function amountLess(string $amount): GroupCollectorInterface
{
$this->query->where(
- function (EloquentBuilder $q) use ($amount) {
+ static function (EloquentBuilder $q) use ($amount): void { // @phpstan-ignore-line
$q->where('destination.amount', '<=', app('steam')->positive($amount));
}
);
@@ -84,15 +73,11 @@ trait AmountCollection
/**
* Get transactions where the amount is more than.
- *
- * @param string $amount
- *
- * @return GroupCollectorInterface
*/
public function amountMore(string $amount): GroupCollectorInterface
{
$this->query->where(
- function (EloquentBuilder $q) use ($amount) {
+ static function (EloquentBuilder $q) use ($amount): void { // @phpstan-ignore-line
$q->where('destination.amount', '>=', app('steam')->positive($amount));
}
);
@@ -102,15 +87,11 @@ trait AmountCollection
/**
* Get transactions with a specific foreign amount.
- *
- * @param string $amount
- *
- * @return GroupCollectorInterface
*/
public function foreignAmountIs(string $amount): GroupCollectorInterface
{
$this->query->where(
- static function (EloquentBuilder $q) use ($amount) {
+ static function (EloquentBuilder $q) use ($amount): void { // @phpstan-ignore-line
$q->whereNotNull('source.foreign_amount');
$q->where('source.foreign_amount', app('steam')->negative($amount));
}
@@ -121,15 +102,11 @@ trait AmountCollection
/**
* Get transactions with a specific foreign amount.
- *
- * @param string $amount
- *
- * @return GroupCollectorInterface
*/
public function foreignAmountIsNot(string $amount): GroupCollectorInterface
{
$this->query->where(
- static function (EloquentBuilder $q) use ($amount) {
+ static function (EloquentBuilder $q) use ($amount): void { // @phpstan-ignore-line
$q->whereNull('source.foreign_amount');
$q->orWhere('source.foreign_amount', '!=', app('steam')->negative($amount));
}
@@ -140,15 +117,11 @@ trait AmountCollection
/**
* Get transactions where the amount is less than.
- *
- * @param string $amount
- *
- * @return GroupCollectorInterface
*/
public function foreignAmountLess(string $amount): GroupCollectorInterface
{
$this->query->where(
- function (EloquentBuilder $q) use ($amount) {
+ static function (EloquentBuilder $q) use ($amount): void { // @phpstan-ignore-line
$q->whereNotNull('destination.foreign_amount');
$q->where('destination.foreign_amount', '<=', app('steam')->positive($amount));
}
@@ -159,15 +132,11 @@ trait AmountCollection
/**
* Get transactions where the amount is more than.
- *
- * @param string $amount
- *
- * @return GroupCollectorInterface
*/
public function foreignAmountMore(string $amount): GroupCollectorInterface
{
$this->query->where(
- function (EloquentBuilder $q) use ($amount) {
+ static function (EloquentBuilder $q) use ($amount): void { // @phpstan-ignore-line
$q->whereNotNull('destination.foreign_amount');
$q->where('destination.foreign_amount', '>=', app('steam')->positive($amount));
}
diff --git a/app/Helpers/Collector/Extensions/AttachmentCollection.php b/app/Helpers/Collector/Extensions/AttachmentCollection.php
index 161422d107..6140a20ba4 100644
--- a/app/Helpers/Collector/Extensions/AttachmentCollection.php
+++ b/app/Helpers/Collector/Extensions/AttachmentCollection.php
@@ -29,23 +29,24 @@ use FireflyIII\Models\Attachment;
use FireflyIII\Models\TransactionJournal;
use Illuminate\Database\Eloquent\Builder;
use Illuminate\Database\Eloquent\Builder as EloquentBuilder;
-use Illuminate\Support\Facades\Log;
/**
* Trait AttachmentCollection
*/
trait AttachmentCollection
{
- /**
- * @param string $name
- *
- * @return GroupCollectorInterface
- */
public function attachmentNameContains(string $name): GroupCollectorInterface
{
$this->hasAttachments();
$this->withAttachmentInformation();
- $filter = function (int $index, array $object) use ($name): bool {
+
+ /**
+ * @param int $index
+ * @param array $object
+ *
+ * @return bool
+ */
+ $filter = static function (array $object) use ($name): bool {
/** @var array $transaction */
foreach ($object['transactions'] as $transaction) {
/** @var array $attachment */
@@ -59,6 +60,7 @@ trait AttachmentCollection
}
}
}
+
return false;
};
$this->postFilters[] = $filter;
@@ -68,12 +70,10 @@ trait AttachmentCollection
/**
* Has attachments
- *
- * @return GroupCollectorInterface
*/
public function hasAttachments(): GroupCollectorInterface
{
- Log::debug('Add filter on attachment ID.');
+ app('log')->debug('Add filter on attachment ID.');
$this->joinAttachmentTables();
$this->query->whereNotNull('attachments.attachable_id');
$this->query->whereNull('attachments.deleted_at');
@@ -90,20 +90,18 @@ trait AttachmentCollection
// join some extra tables:
$this->hasJoinedAttTables = true;
$this->query->leftJoin('attachments', 'attachments.attachable_id', '=', 'transaction_journals.id')
- ->where(
- static function (EloquentBuilder $q1) {
- $q1->where('attachments.attachable_type', TransactionJournal::class);
- $q1->where('attachments.uploaded', true);
- $q1->whereNull('attachments.deleted_at');
- $q1->orWhereNull('attachments.attachable_type');
- }
- );
+ ->where(
+ static function (EloquentBuilder $q1): void { // @phpstan-ignore-line
+ $q1->where('attachments.attachable_type', TransactionJournal::class);
+ $q1->where('attachments.uploaded', true);
+ $q1->whereNull('attachments.deleted_at');
+ $q1->orWhereNull('attachments.attachable_type');
+ }
+ )
+ ;
}
}
- /**
- * @inheritDoc
- */
public function withAttachmentInformation(): GroupCollectorInterface
{
$this->fields[] = 'attachments.id as attachment_id';
@@ -115,16 +113,20 @@ trait AttachmentCollection
return $this;
}
- /**
- * @param string $name
- *
- * @return GroupCollectorInterface
- */
public function attachmentNameDoesNotContain(string $name): GroupCollectorInterface
{
$this->hasAttachments();
$this->withAttachmentInformation();
- $filter = function (int $index, array $object) use ($name): bool {
+
+ /**
+ * @param int $index
+ * @param array $object
+ *
+ * @return bool
+ *
+ * @SuppressWarnings(PHPMD.UnusedFormalParameter)
+ */
+ $filter = static function (array $object) use ($name): bool {
/** @var array $transaction */
foreach ($object['transactions'] as $transaction) {
/** @var array $attachment */
@@ -138,6 +140,7 @@ trait AttachmentCollection
}
}
}
+
return false;
};
$this->postFilters[] = $filter;
@@ -145,16 +148,20 @@ trait AttachmentCollection
return $this;
}
- /**
- * @param string $name
- *
- * @return GroupCollectorInterface
- */
public function attachmentNameDoesNotEnd(string $name): GroupCollectorInterface
{
$this->hasAttachments();
$this->withAttachmentInformation();
- $filter = function (int $index, array $object) use ($name): bool {
+
+ /**
+ * @param int $index
+ * @param array $object
+ *
+ * @return bool
+ *
+ * @SuppressWarnings(PHPMD.UnusedFormalParameter)
+ */
+ $filter = static function (array $object) use ($name): bool {
/** @var array $transaction */
foreach ($object['transactions'] as $transaction) {
/** @var array $attachment */
@@ -168,6 +175,7 @@ trait AttachmentCollection
}
}
}
+
return false;
};
$this->postFilters[] = $filter;
@@ -175,16 +183,20 @@ trait AttachmentCollection
return $this;
}
- /**
- * @param string $name
- *
- * @return GroupCollectorInterface
- */
public function attachmentNameDoesNotStart(string $name): GroupCollectorInterface
{
$this->hasAttachments();
$this->withAttachmentInformation();
- $filter = function (int $index, array $object) use ($name): bool {
+
+ /**
+ * @param int $index
+ * @param array $object
+ *
+ * @return bool
+ *
+ * @SuppressWarnings(PHPMD.UnusedFormalParameter)
+ */
+ $filter = static function (array $object) use ($name): bool {
/** @var array $transaction */
foreach ($object['transactions'] as $transaction) {
/** @var array $attachment */
@@ -198,6 +210,7 @@ trait AttachmentCollection
}
}
}
+
return false;
};
$this->postFilters[] = $filter;
@@ -205,16 +218,11 @@ trait AttachmentCollection
return $this;
}
- /**
- * @param string $name
- *
- * @return GroupCollectorInterface
- */
public function attachmentNameEnds(string $name): GroupCollectorInterface
{
$this->hasAttachments();
$this->withAttachmentInformation();
- $filter = function (int $index, array $object) use ($name): bool {
+ $filter = static function (array $object) use ($name): bool {
/** @var array $transaction */
foreach ($object['transactions'] as $transaction) {
/** @var array $attachment */
@@ -228,6 +236,7 @@ trait AttachmentCollection
}
}
}
+
return false;
};
$this->postFilters[] = $filter;
@@ -235,16 +244,11 @@ trait AttachmentCollection
return $this;
}
- /**
- * @param string $name
- *
- * @return GroupCollectorInterface
- */
public function attachmentNameIs(string $name): GroupCollectorInterface
{
$this->hasAttachments();
$this->withAttachmentInformation();
- $filter = function (int $index, array $object) use ($name): bool {
+ $filter = static function (array $object) use ($name): bool {
/** @var array $transaction */
foreach ($object['transactions'] as $transaction) {
/** @var array $attachment */
@@ -255,6 +259,7 @@ trait AttachmentCollection
}
}
}
+
return false;
};
$this->postFilters[] = $filter;
@@ -262,16 +267,11 @@ trait AttachmentCollection
return $this;
}
- /**
- * @param string $name
- *
- * @return GroupCollectorInterface
- */
public function attachmentNameIsNot(string $name): GroupCollectorInterface
{
$this->hasAttachments();
$this->withAttachmentInformation();
- $filter = function (int $index, array $object) use ($name): bool {
+ $filter = static function (array $object) use ($name): bool {
/** @var array $transaction */
foreach ($object['transactions'] as $transaction) {
/** @var array $attachment */
@@ -282,6 +282,7 @@ trait AttachmentCollection
}
}
}
+
return false;
};
$this->postFilters[] = $filter;
@@ -289,16 +290,11 @@ trait AttachmentCollection
return $this;
}
- /**
- * @param string $name
- *
- * @return GroupCollectorInterface
- */
public function attachmentNameStarts(string $name): GroupCollectorInterface
{
$this->hasAttachments();
$this->withAttachmentInformation();
- $filter = function (int $index, array $object) use ($name): bool {
+ $filter = static function (array $object) use ($name): bool {
/** @var array $transaction */
foreach ($object['transactions'] as $transaction) {
/** @var array $attachment */
@@ -312,6 +308,7 @@ trait AttachmentCollection
}
}
}
+
return false;
};
$this->postFilters[] = $filter;
@@ -319,26 +316,23 @@ trait AttachmentCollection
return $this;
}
- /**
- * @param string $value
- *
- * @return GroupCollectorInterface
- */
public function attachmentNotesAre(string $value): GroupCollectorInterface
{
$this->hasAttachments();
$this->withAttachmentInformation();
- $filter = function (int $index, array $object) use ($value): bool {
+ $filter = static function (array $object) use ($value): bool {
/** @var array $transaction */
foreach ($object['transactions'] as $transaction) {
/** @var array $attachment */
foreach ($transaction['attachments'] as $attachment) {
- /** @var Attachment|null $object */
+ /** @var null|Attachment $object */
$object = auth()->user()->attachments()->find($attachment['id']);
$notes = (string)$object?->notes()->first()?->text;
- return $notes !== '' && $notes === $value;
+
+ return '' !== $notes && $notes === $value;
}
}
+
return false;
};
$this->postFilters[] = $filter;
@@ -346,26 +340,23 @@ trait AttachmentCollection
return $this;
}
- /**
- * @param string $value
- *
- * @return GroupCollectorInterface
- */
public function attachmentNotesAreNot(string $value): GroupCollectorInterface
{
$this->hasAttachments();
$this->withAttachmentInformation();
- $filter = function (int $index, array $object) use ($value): bool {
+ $filter = static function (array $object) use ($value): bool {
/** @var array $transaction */
foreach ($object['transactions'] as $transaction) {
/** @var array $attachment */
foreach ($transaction['attachments'] as $attachment) {
- /** @var Attachment|null $object */
+ /** @var null|Attachment $object */
$object = auth()->user()->attachments()->find($attachment['id']);
$notes = (string)$object?->notes()->first()?->text;
- return $notes !== '' && $notes !== $value;
+
+ return '' !== $notes && $notes !== $value;
}
}
+
return false;
};
$this->postFilters[] = $filter;
@@ -373,26 +364,23 @@ trait AttachmentCollection
return $this;
}
- /**
- * @param string $value
- *
- * @return GroupCollectorInterface
- */
public function attachmentNotesContains(string $value): GroupCollectorInterface
{
$this->hasAttachments();
$this->withAttachmentInformation();
- $filter = function (int $index, array $object) use ($value): bool {
+ $filter = static function (array $object) use ($value): bool {
/** @var array $transaction */
foreach ($object['transactions'] as $transaction) {
/** @var array $attachment */
foreach ($transaction['attachments'] as $attachment) {
- /** @var Attachment|null $object */
+ /** @var null|Attachment $object */
$object = auth()->user()->attachments()->find($attachment['id']);
$notes = (string)$object?->notes()->first()?->text;
- return $notes !== '' && str_contains(strtolower($notes), strtolower($value));
+
+ return '' !== $notes && str_contains(strtolower($notes), strtolower($value));
}
}
+
return false;
};
$this->postFilters[] = $filter;
@@ -400,26 +388,23 @@ trait AttachmentCollection
return $this;
}
- /**
- * @param string $value
- *
- * @return GroupCollectorInterface
- */
public function attachmentNotesDoNotContain(string $value): GroupCollectorInterface
{
$this->hasAttachments();
$this->withAttachmentInformation();
- $filter = function (int $index, array $object) use ($value): bool {
+ $filter = static function (array $object) use ($value): bool {
/** @var array $transaction */
foreach ($object['transactions'] as $transaction) {
/** @var array $attachment */
foreach ($transaction['attachments'] as $attachment) {
- /** @var Attachment|null $object */
+ /** @var null|Attachment $object */
$object = auth()->user()->attachments()->find($attachment['id']);
$notes = (string)$object?->notes()->first()?->text;
- return $notes !== '' && !str_contains(strtolower($notes), strtolower($value));
+
+ return '' !== $notes && !str_contains(strtolower($notes), strtolower($value));
}
}
+
return false;
};
$this->postFilters[] = $filter;
@@ -427,26 +412,23 @@ trait AttachmentCollection
return $this;
}
- /**
- * @param string $value
- *
- * @return GroupCollectorInterface
- */
public function attachmentNotesDoNotEnd(string $value): GroupCollectorInterface
{
$this->hasAttachments();
$this->withAttachmentInformation();
- $filter = function (int $index, array $object) use ($value): bool {
+ $filter = static function (array $object) use ($value): bool {
/** @var array $transaction */
foreach ($object['transactions'] as $transaction) {
/** @var array $attachment */
foreach ($transaction['attachments'] as $attachment) {
- /** @var Attachment|null $object */
+ /** @var null|Attachment $object */
$object = auth()->user()->attachments()->find($attachment['id']);
$notes = (string)$object?->notes()->first()?->text;
- return $notes !== '' && !str_ends_with(strtolower($notes), strtolower($value));
+
+ return '' !== $notes && !str_ends_with(strtolower($notes), strtolower($value));
}
}
+
return false;
};
$this->postFilters[] = $filter;
@@ -454,26 +436,23 @@ trait AttachmentCollection
return $this;
}
- /**
- * @param string $value
- *
- * @return GroupCollectorInterface
- */
public function attachmentNotesDoNotStart(string $value): GroupCollectorInterface
{
$this->hasAttachments();
$this->withAttachmentInformation();
- $filter = function (int $index, array $object) use ($value): bool {
+ $filter = static function (array $object) use ($value): bool {
/** @var array $transaction */
foreach ($object['transactions'] as $transaction) {
/** @var array $attachment */
foreach ($transaction['attachments'] as $attachment) {
- /** @var Attachment|null $object */
+ /** @var null|Attachment $object */
$object = auth()->user()->attachments()->find($attachment['id']);
$notes = (string)$object?->notes()->first()?->text;
- return $notes !== '' && !str_starts_with(strtolower($notes), strtolower($value));
+
+ return '' !== $notes && !str_starts_with(strtolower($notes), strtolower($value));
}
}
+
return false;
};
$this->postFilters[] = $filter;
@@ -481,26 +460,23 @@ trait AttachmentCollection
return $this;
}
- /**
- * @param string $value
- *
- * @return GroupCollectorInterface
- */
public function attachmentNotesEnds(string $value): GroupCollectorInterface
{
$this->hasAttachments();
$this->withAttachmentInformation();
- $filter = function (int $index, array $object) use ($value): bool {
+ $filter = static function (array $object) use ($value): bool {
/** @var array $transaction */
foreach ($object['transactions'] as $transaction) {
/** @var array $attachment */
foreach ($transaction['attachments'] as $attachment) {
- /** @var Attachment|null $object */
+ /** @var null|Attachment $object */
$object = auth()->user()->attachments()->find($attachment['id']);
$notes = (string)$object?->notes()->first()?->text;
- return $notes !== '' && str_ends_with(strtolower($notes), strtolower($value));
+
+ return '' !== $notes && str_ends_with(strtolower($notes), strtolower($value));
}
}
+
return false;
};
$this->postFilters[] = $filter;
@@ -508,26 +484,23 @@ trait AttachmentCollection
return $this;
}
- /**
- * @param string $value
- *
- * @return GroupCollectorInterface
- */
public function attachmentNotesStarts(string $value): GroupCollectorInterface
{
$this->hasAttachments();
$this->withAttachmentInformation();
- $filter = function (int $index, array $object) use ($value): bool {
+ $filter = static function (array $object) use ($value): bool {
/** @var array $transaction */
foreach ($object['transactions'] as $transaction) {
/** @var array $attachment */
foreach ($transaction['attachments'] as $attachment) {
- /** @var Attachment|null $object */
+ /** @var null|Attachment $object */
$object = auth()->user()->attachments()->find($attachment['id']);
$notes = (string)$object?->notes()->first()?->text;
- return $notes !== '' && str_starts_with(strtolower($notes), strtolower($value));
+
+ return '' !== $notes && str_starts_with(strtolower($notes), strtolower($value));
}
}
+
return false;
};
$this->postFilters[] = $filter;
@@ -537,27 +510,26 @@ trait AttachmentCollection
/**
* Has attachments
- *
- * @return GroupCollectorInterface
*/
public function hasNoAttachments(): GroupCollectorInterface
{
- Log::debug('Add filter on no attachments.');
+ app('log')->debug('Add filter on no attachments.');
$this->joinAttachmentTables();
- $this->query->where(function (Builder $q1) {
+ $this->query->where(static function (Builder $q1): void { // @phpstan-ignore-line
$q1
->whereNull('attachments.attachable_id')
- ->orWhere(function (Builder $q2) {
+ ->orWhere(static function (Builder $q2): void {
$q2
->whereNotNull('attachments.attachable_id')
- ->whereNotNull('attachments.deleted_at');
+ ->whereNotNull('attachments.deleted_at')
+ ;
// id is not null
// deleted at is not null.
- });
+ })
+ ;
});
-
return $this;
}
}
diff --git a/app/Helpers/Collector/Extensions/CollectorProperties.php b/app/Helpers/Collector/Extensions/CollectorProperties.php
index bfdb78349b..fa6c626fbc 100644
--- a/app/Helpers/Collector/Extensions/CollectorProperties.php
+++ b/app/Helpers/Collector/Extensions/CollectorProperties.php
@@ -33,30 +33,34 @@ use Illuminate\Database\Eloquent\Relations\HasMany;
*/
trait CollectorProperties
{
- public const TEST = 'Test';
- private bool $expandGroupSearch;
- private array $fields;
- private bool $hasAccountInfo;
- private bool $hasBillInformation;
- private bool $hasBudgetInformation;
- private bool $hasCatInformation;
- private bool $hasJoinedAttTables;
- private bool $hasJoinedMetaTables;
- private bool $hasJoinedTagTables;
- private bool $hasNotesInformation;
- private array $integerFields;
- private ?int $limit;
- private ?int $page;
- private array $postFilters;
+ /** @var array */
+ public array $sorting;
+ public const string TEST = 'Test';
+ private ?int $endRow;
+ private bool $expandGroupSearch;
+ private array $fields;
+ private bool $hasAccountInfo;
+ private bool $hasBillInformation;
+ private bool $hasBudgetInformation;
+ private bool $hasCatInformation;
+ private bool $hasJoinedAttTables;
+ private bool $hasJoinedMetaTables;
+ private bool $hasJoinedTagTables;
+ private bool $hasNotesInformation;
+ private array $integerFields;
+ private ?int $limit;
+ private ?int $page;
+ private array $postFilters;
private HasMany $query;
- private array $stringFields;
+ private ?int $startRow;
+ private array $stringFields;
/*
* This array is used to collect ALL tags the user may search for (using 'setTags').
* This way the user can call 'setTags' multiple times and get a joined result.
*
*/
- private array $tags;
- private int $total;
- private ?User $user;
+ private array $tags;
+ private int $total;
+ private ?User $user;
private ?UserGroup $userGroup;
}
diff --git a/app/Helpers/Collector/Extensions/MetaCollection.php b/app/Helpers/Collector/Extensions/MetaCollection.php
index a8217a4b0a..305d2a88f4 100644
--- a/app/Helpers/Collector/Extensions/MetaCollection.php
+++ b/app/Helpers/Collector/Extensions/MetaCollection.php
@@ -33,19 +33,17 @@ use Illuminate\Database\Eloquent\Builder;
use Illuminate\Database\Eloquent\Builder as EloquentBuilder;
use Illuminate\Database\Query\JoinClause;
use Illuminate\Support\Collection;
+use Illuminate\Support\Facades\Log;
/**
* Trait MetaCollection
*/
trait MetaCollection
{
- /**
- * @inheritDoc
- */
public function excludeBills(Collection $bills): GroupCollectorInterface
{
$this->withBillInformation();
- $this->query->where(static function (EloquentBuilder $q1) use ($bills) {
+ $this->query->where(static function (EloquentBuilder $q1) use ($bills): void { // @phpstan-ignore-line
$q1->whereNotIn('transaction_journals.bill_id', $bills->pluck('id')->toArray());
$q1->orWhereNull('transaction_journals.bill_id');
});
@@ -55,8 +53,6 @@ trait MetaCollection
/**
* Will include bill name + ID, if any.
- *
- * @return GroupCollectorInterface
*/
public function withBillInformation(): GroupCollectorInterface
{
@@ -74,16 +70,12 @@ trait MetaCollection
/**
* Exclude a specific budget.
- *
- * @param Budget $budget
- *
- * @return GroupCollectorInterface
*/
public function excludeBudget(Budget $budget): GroupCollectorInterface
{
$this->withBudgetInformation();
- $this->query->where(static function (EloquentBuilder $q2) use ($budget) {
+ $this->query->where(static function (EloquentBuilder $q2) use ($budget): void { // @phpstan-ignore-line
$q2->where('budgets.id', '!=', $budget->id);
$q2->orWhereNull('budgets.id');
});
@@ -93,8 +85,6 @@ trait MetaCollection
/**
* Will include budget ID + name, if any.
- *
- * @return GroupCollectorInterface
*/
public function withBudgetInformation(): GroupCollectorInterface
{
@@ -112,14 +102,11 @@ trait MetaCollection
return $this;
}
- /**
- * @inheritDoc
- */
public function excludeBudgets(Collection $budgets): GroupCollectorInterface
{
if ($budgets->count() > 0) {
$this->withBudgetInformation();
- $this->query->where(static function (EloquentBuilder $q1) use ($budgets) {
+ $this->query->where(static function (EloquentBuilder $q1) use ($budgets): void { // @phpstan-ignore-line
$q1->whereNotIn('budgets.id', $budgets->pluck('id')->toArray());
$q1->orWhereNull('budgets.id');
});
@@ -128,14 +115,11 @@ trait MetaCollection
return $this;
}
- /**
- * @inheritDoc
- */
public function excludeCategories(Collection $categories): GroupCollectorInterface
{
if ($categories->count() > 0) {
$this->withCategoryInformation();
- $this->query->where(static function (EloquentBuilder $q1) use ($categories) {
+ $this->query->where(static function (EloquentBuilder $q1) use ($categories): void { // @phpstan-ignore-line
$q1->whereNotIn('categories.id', $categories->pluck('id')->toArray());
$q1->orWhereNull('categories.id');
});
@@ -146,8 +130,6 @@ trait MetaCollection
/**
* Will include category ID + name, if any.
- *
- * @return GroupCollectorInterface
*/
public function withCategoryInformation(): GroupCollectorInterface
{
@@ -167,16 +149,12 @@ trait MetaCollection
/**
* Exclude a specific category.
- *
- * @param Category $category
- *
- * @return GroupCollectorInterface
*/
public function excludeCategory(Category $category): GroupCollectorInterface
{
$this->withCategoryInformation();
- $this->query->where(static function (EloquentBuilder $q2) use ($category) {
+ $this->query->where(static function (EloquentBuilder $q2) use ($category): void { // @phpstan-ignore-line
$q2->where('categories.id', '!=', $category->id);
$q2->orWhereNull('categories.id');
});
@@ -184,9 +162,6 @@ trait MetaCollection
return $this;
}
- /**
- * @inheritDoc
- */
public function excludeExternalId(string $externalId): GroupCollectorInterface
{
$this->joinMetaDataTables();
@@ -204,14 +179,11 @@ trait MetaCollection
if (false === $this->hasJoinedMetaTables) {
$this->hasJoinedMetaTables = true;
$this->query->leftJoin('journal_meta', 'transaction_journals.id', '=', 'journal_meta.transaction_journal_id');
- $this->fields[] = 'journal_meta.name as meta_name';
- $this->fields[] = 'journal_meta.data as meta_data';
+ $this->fields[] = 'journal_meta.name as meta_name';
+ $this->fields[] = 'journal_meta.data as meta_data';
}
}
- /**
- * @inheritDoc
- */
public function excludeExternalUrl(string $url): GroupCollectorInterface
{
$this->joinMetaDataTables();
@@ -221,12 +193,9 @@ trait MetaCollection
return $this;
}
- /**
- * @inheritDoc
- */
public function excludeInternalReference(string $internalReference): GroupCollectorInterface
{
- $internalReference = json_encode($internalReference);
+ $internalReference = (string)json_encode($internalReference);
$internalReference = str_replace('\\', '\\\\', trim($internalReference, '"'));
$this->joinMetaDataTables();
@@ -236,9 +205,6 @@ trait MetaCollection
return $this;
}
- /**
- * @inheritDoc
- */
public function excludeRecurrenceId(string $recurringId): GroupCollectorInterface
{
$this->joinMetaDataTables();
@@ -248,12 +214,9 @@ trait MetaCollection
return $this;
}
- /**
- * @inheritDoc
- */
public function externalIdContains(string $externalId): GroupCollectorInterface
{
- $externalId = json_encode($externalId);
+ $externalId = (string)json_encode($externalId);
$externalId = str_replace('\\', '\\\\', trim($externalId, '"'));
$this->joinMetaDataTables();
@@ -263,12 +226,9 @@ trait MetaCollection
return $this;
}
- /**
- * @inheritDoc
- */
public function externalIdDoesNotContain(string $externalId): GroupCollectorInterface
{
- $externalId = json_encode($externalId);
+ $externalId = (string)json_encode($externalId);
$externalId = str_replace('\\', '\\\\', trim($externalId, '"'));
$this->joinMetaDataTables();
@@ -278,12 +238,9 @@ trait MetaCollection
return $this;
}
- /**
- * @inheritDoc
- */
public function externalIdDoesNotEnd(string $externalId): GroupCollectorInterface
{
- $externalId = json_encode($externalId);
+ $externalId = (string)json_encode($externalId);
$externalId = str_replace('\\', '\\\\', trim($externalId, '"'));
$this->joinMetaDataTables();
@@ -293,12 +250,9 @@ trait MetaCollection
return $this;
}
- /**
- * @inheritDoc
- */
public function externalIdDoesNotStart(string $externalId): GroupCollectorInterface
{
- $externalId = json_encode($externalId);
+ $externalId = (string)json_encode($externalId);
$externalId = str_replace('\\', '\\\\', trim($externalId, '"'));
$this->joinMetaDataTables();
@@ -308,12 +262,9 @@ trait MetaCollection
return $this;
}
- /**
- * @inheritDoc
- */
public function externalIdEnds(string $externalId): GroupCollectorInterface
{
- $externalId = json_encode($externalId);
+ $externalId = (string)json_encode($externalId);
$externalId = str_replace('\\', '\\\\', trim($externalId, '"'));
$this->joinMetaDataTables();
@@ -323,12 +274,9 @@ trait MetaCollection
return $this;
}
- /**
- * @inheritDoc
- */
public function externalIdStarts(string $externalId): GroupCollectorInterface
{
- $externalId = json_encode($externalId);
+ $externalId = (string)json_encode($externalId);
$externalId = str_replace('\\', '\\\\', trim($externalId, '"'));
$this->joinMetaDataTables();
@@ -338,15 +286,10 @@ trait MetaCollection
return $this;
}
- /**
- * @param string $url
- *
- * @return GroupCollectorInterface
- */
public function externalUrlContains(string $url): GroupCollectorInterface
{
$this->joinMetaDataTables();
- $url = json_encode($url);
+ $url = (string)json_encode($url);
$url = str_replace('\\', '\\\\', trim($url, '"'));
$this->query->where('journal_meta.name', '=', 'external_url');
$this->query->where('journal_meta.data', 'LIKE', sprintf('%%%s%%', $url));
@@ -354,15 +297,10 @@ trait MetaCollection
return $this;
}
- /**
- * @param string $url
- *
- * @return GroupCollectorInterface
- */
public function externalUrlDoesNotContain(string $url): GroupCollectorInterface
{
$this->joinMetaDataTables();
- $url = json_encode($url);
+ $url = (string)json_encode($url);
$url = str_replace('\\', '\\\\', trim($url, '"'));
$this->query->where('journal_meta.name', '=', 'external_url');
$this->query->where('journal_meta.data', 'NOT LIKE', sprintf('%%%s%%', $url));
@@ -370,15 +308,10 @@ trait MetaCollection
return $this;
}
- /**
- * @param string $url
- *
- * @return GroupCollectorInterface
- */
public function externalUrlDoesNotEnd(string $url): GroupCollectorInterface
{
$this->joinMetaDataTables();
- $url = json_encode($url);
+ $url = (string)json_encode($url);
$url = str_replace('\\', '\\\\', ltrim($url, '"'));
$this->query->where('journal_meta.name', '=', 'external_url');
$this->query->where('journal_meta.data', 'NOT LIKE', sprintf('%%%s', $url));
@@ -386,17 +319,12 @@ trait MetaCollection
return $this;
}
- /**
- * @param string $url
- *
- * @return GroupCollectorInterface
- */
public function externalUrlDoesNotStart(string $url): GroupCollectorInterface
{
$this->joinMetaDataTables();
- $url = json_encode($url);
+ $url = (string)json_encode($url);
$url = str_replace('\\', '\\\\', rtrim($url, '"'));
- //var_dump($url);
+ // var_dump($url);
$this->query->where('journal_meta.name', '=', 'external_url');
$this->query->where('journal_meta.data', 'NOT LIKE', sprintf('%s%%', $url));
@@ -404,15 +332,10 @@ trait MetaCollection
return $this;
}
- /**
- * @param string $url
- *
- * @return GroupCollectorInterface
- */
public function externalUrlEnds(string $url): GroupCollectorInterface
{
$this->joinMetaDataTables();
- $url = json_encode($url);
+ $url = (string)json_encode($url);
$url = str_replace('\\', '\\\\', ltrim($url, '"'));
$this->query->where('journal_meta.name', '=', 'external_url');
$this->query->where('journal_meta.data', 'LIKE', sprintf('%%%s', $url));
@@ -420,17 +343,12 @@ trait MetaCollection
return $this;
}
- /**
- * @param string $url
- *
- * @return GroupCollectorInterface
- */
public function externalUrlStarts(string $url): GroupCollectorInterface
{
$this->joinMetaDataTables();
- $url = json_encode($url);
+ $url = (string)json_encode($url);
$url = str_replace('\\', '\\\\', rtrim($url, '"'));
- //var_dump($url);
+ // var_dump($url);
$this->query->where('journal_meta.name', '=', 'external_url');
$this->query->where('journal_meta.data', 'LIKE', sprintf('%s%%', $url));
@@ -440,8 +358,6 @@ trait MetaCollection
/**
* Where has no tags.
- *
- * @return GroupCollectorInterface
*/
public function hasAnyTag(): GroupCollectorInterface
{
@@ -451,9 +367,6 @@ trait MetaCollection
return $this;
}
- /**
- * @return GroupCollectorInterface
- */
public function withTagInformation(): GroupCollectorInterface
{
$this->fields[] = 'tags.id as tag_id';
@@ -482,15 +395,12 @@ trait MetaCollection
}
}
- /**
- * @inheritDoc
- */
public function internalReferenceContains(string $internalReference): GroupCollectorInterface
{
- $internalReference = json_encode($internalReference);
+ $internalReference = (string)json_encode($internalReference);
$internalReference = str_replace('\\', '\\\\', trim($internalReference, '"'));
- //var_dump($internalReference);
- //exit;
+ // var_dump($internalReference);
+ // exit;
$this->joinMetaDataTables();
$this->query->where('journal_meta.name', '=', 'internal_reference');
@@ -499,12 +409,9 @@ trait MetaCollection
return $this;
}
- /**
- * @inheritDoc
- */
public function internalReferenceDoesNotContain(string $internalReference): GroupCollectorInterface
{
- $internalReference = json_encode($internalReference);
+ $internalReference = (string)json_encode($internalReference);
$internalReference = str_replace('\\', '\\\\', trim($internalReference, '"'));
$this->joinMetaDataTables();
@@ -514,12 +421,9 @@ trait MetaCollection
return $this;
}
- /**
- * @inheritDoc
- */
public function internalReferenceDoesNotEnd(string $internalReference): GroupCollectorInterface
{
- $internalReference = json_encode($internalReference);
+ $internalReference = (string)json_encode($internalReference);
$internalReference = str_replace('\\', '\\\\', trim($internalReference, '"'));
$this->joinMetaDataTables();
@@ -529,12 +433,9 @@ trait MetaCollection
return $this;
}
- /**
- * @inheritDoc
- */
public function internalReferenceDoesNotStart(string $internalReference): GroupCollectorInterface
{
- $internalReference = json_encode($internalReference);
+ $internalReference = (string)json_encode($internalReference);
$internalReference = str_replace('\\', '\\\\', trim($internalReference, '"'));
$this->joinMetaDataTables();
@@ -544,12 +445,9 @@ trait MetaCollection
return $this;
}
- /**
- * @inheritDoc
- */
public function internalReferenceEnds(string $internalReference): GroupCollectorInterface
{
- $internalReference = json_encode($internalReference);
+ $internalReference = (string)json_encode($internalReference);
$internalReference = str_replace('\\', '\\\\', trim($internalReference, '"'));
$this->joinMetaDataTables();
@@ -559,12 +457,9 @@ trait MetaCollection
return $this;
}
- /**
- * @inheritDoc
- */
public function internalReferenceStarts(string $internalReference): GroupCollectorInterface
{
- $internalReference = json_encode($internalReference);
+ $internalReference = (string)json_encode($internalReference);
$internalReference = str_replace('\\', '\\\\', trim($internalReference, '"'));
$this->joinMetaDataTables();
@@ -574,11 +469,6 @@ trait MetaCollection
return $this;
}
- /**
- * @param string $value
- *
- * @return GroupCollectorInterface
- */
public function notesContain(string $value): GroupCollectorInterface
{
$this->withNotes();
@@ -587,16 +477,13 @@ trait MetaCollection
return $this;
}
- /**
- * @inheritDoc
- */
public function withNotes(): GroupCollectorInterface
{
if (false === $this->hasNotesInformation) {
// join bill table
$this->query->leftJoin(
'notes',
- static function (JoinClause $join) {
+ static function (JoinClause $join): void {
$join->on('notes.noteable_id', '=', 'transaction_journals.id');
$join->where('notes.noteable_type', '=', 'FireflyIII\Models\TransactionJournal');
$join->whereNull('notes.deleted_at');
@@ -610,15 +497,10 @@ trait MetaCollection
return $this;
}
- /**
- * @param string $value
- *
- * @return GroupCollectorInterface
- */
public function notesDoNotContain(string $value): GroupCollectorInterface
{
$this->withNotes();
- $this->query->where(static function (Builder $q) use ($value) {
+ $this->query->where(static function (Builder $q) use ($value): void { // @phpstan-ignore-line
$q->whereNull('notes.text');
$q->orWhere('notes.text', 'NOT LIKE', sprintf('%%%s%%', $value));
});
@@ -626,15 +508,10 @@ trait MetaCollection
return $this;
}
- /**
- * @param string $value
- *
- * @return GroupCollectorInterface
- */
public function notesDontEndWith(string $value): GroupCollectorInterface
{
$this->withNotes();
- $this->query->where(static function (Builder $q) use ($value) {
+ $this->query->where(static function (Builder $q) use ($value): void { // @phpstan-ignore-line
$q->whereNull('notes.text');
$q->orWhere('notes.text', 'NOT LIKE', sprintf('%%%s', $value));
});
@@ -642,15 +519,10 @@ trait MetaCollection
return $this;
}
- /**
- * @param string $value
- *
- * @return GroupCollectorInterface
- */
public function notesDontStartWith(string $value): GroupCollectorInterface
{
$this->withNotes();
- $this->query->where(static function (Builder $q) use ($value) {
+ $this->query->where(static function (Builder $q) use ($value): void { // @phpstan-ignore-line
$q->whereNull('notes.text');
$q->orWhere('notes.text', 'NOT LIKE', sprintf('%s%%', $value));
});
@@ -658,11 +530,6 @@ trait MetaCollection
return $this;
}
- /**
- * @param string $value
- *
- * @return GroupCollectorInterface
- */
public function notesEndWith(string $value): GroupCollectorInterface
{
$this->withNotes();
@@ -671,11 +538,6 @@ trait MetaCollection
return $this;
}
- /**
- * @param string $value
- *
- * @return GroupCollectorInterface
- */
public function notesExactly(string $value): GroupCollectorInterface
{
$this->withNotes();
@@ -684,15 +546,10 @@ trait MetaCollection
return $this;
}
- /**
- * @param string $value
- *
- * @return GroupCollectorInterface
- */
public function notesExactlyNot(string $value): GroupCollectorInterface
{
$this->withNotes();
- $this->query->where(static function (Builder $q) use ($value) {
+ $this->query->where(static function (Builder $q) use ($value): void { // @phpstan-ignore-line
$q->whereNull('notes.text');
$q->orWhere('notes.text', '!=', sprintf('%s', $value));
});
@@ -700,11 +557,6 @@ trait MetaCollection
return $this;
}
- /**
- * @param string $value
- *
- * @return GroupCollectorInterface
- */
public function notesStartWith(string $value): GroupCollectorInterface
{
$this->withNotes();
@@ -713,12 +565,65 @@ trait MetaCollection
return $this;
}
+ /**
+ * Limit results to a SPECIFIC set of tags.
+ */
+ public function setAllTags(Collection $tags): GroupCollectorInterface
+ {
+ Log::debug(sprintf('Now in setAllTags(%d tag(s))', $tags->count()));
+ $this->withTagInformation();
+ $this->query->whereNotNull('tag_transaction_journal.tag_id');
+
+ // this method adds a "postFilter" to the collector.
+ $list = $tags->pluck('tag')->toArray();
+ $list = array_map('strtolower', $list);
+ $filter = static function (array $object) use ($list): bool|array {
+ $includedJournals = [];
+ $return = $object;
+ unset($return['transactions']);
+ $return['transactions'] = [];
+ Log::debug(sprintf('Now in setAllTags(%s) filter', implode(', ', $list)));
+ $expectedTagCount = count($list);
+ $foundTagCount = 0;
+ foreach ($object['transactions'] as $transaction) {
+ $transactionTagCount = count($transaction['tags']);
+ app('log')->debug(sprintf('Transaction #%d has %d tag(s)', $transaction['transaction_journal_id'], $transactionTagCount));
+ if ($transactionTagCount < $expectedTagCount) {
+ app('log')->debug(sprintf('Transaction has %d tag(s), we expect %d tag(s), return false.', $transactionTagCount, $expectedTagCount));
+
+ return false;
+ }
+ foreach ($transaction['tags'] as $tag) {
+ Log::debug(sprintf('"%s" versus', strtolower($tag['name'])), $list);
+ if (in_array(strtolower($tag['name']), $list, true)) {
+ app('log')->debug(sprintf('Transaction has tag "%s" so count++.', $tag['name']));
+ ++$foundTagCount;
+ $journalId = $transaction['transaction_journal_id'];
+ // #8377 prevent adding a transaction twice when multiple tag searches find this transaction
+ if (!in_array($journalId, $includedJournals, true)) {
+ $includedJournals[] = $journalId;
+ $return['transactions'][] = $transaction;
+ }
+ }
+ }
+ }
+ Log::debug(sprintf('Found %d tags, need at least %d.', $foundTagCount, $expectedTagCount));
+
+ // found at least the expected tags.
+ $result = $foundTagCount >= $expectedTagCount;
+ if (true === $result) {
+ return $return;
+ }
+
+ return false;
+ };
+ $this->postFilters[] = $filter;
+
+ return $this;
+ }
+
/**
* Limit the search to a specific bill.
- *
- * @param Bill $bill
- *
- * @return GroupCollectorInterface
*/
public function setBill(Bill $bill): GroupCollectorInterface
{
@@ -730,10 +635,6 @@ trait MetaCollection
/**
* Limit the search to a specific set of bills.
- *
- * @param Collection $bills
- *
- * @return GroupCollectorInterface
*/
public function setBills(Collection $bills): GroupCollectorInterface
{
@@ -745,10 +646,6 @@ trait MetaCollection
/**
* Limit the search to a specific budget.
- *
- * @param Budget $budget
- *
- * @return GroupCollectorInterface
*/
public function setBudget(Budget $budget): GroupCollectorInterface
{
@@ -760,10 +657,6 @@ trait MetaCollection
/**
* Limit the search to a specific set of budgets.
- *
- * @param Collection $budgets
- *
- * @return GroupCollectorInterface
*/
public function setBudgets(Collection $budgets): GroupCollectorInterface
{
@@ -777,10 +670,6 @@ trait MetaCollection
/**
* Limit the search to a specific bunch of categories.
- *
- * @param Collection $categories
- *
- * @return GroupCollectorInterface
*/
public function setCategories(Collection $categories): GroupCollectorInterface
{
@@ -794,10 +683,6 @@ trait MetaCollection
/**
* Limit the search to a specific category.
- *
- * @param Category $category
- *
- * @return GroupCollectorInterface
*/
public function setCategory(Category $category): GroupCollectorInterface
{
@@ -807,9 +692,6 @@ trait MetaCollection
return $this;
}
- /**
- * @inheritDoc
- */
public function setExternalId(string $externalId): GroupCollectorInterface
{
$this->joinMetaDataTables();
@@ -819,9 +701,6 @@ trait MetaCollection
return $this;
}
- /**
- * @inheritDoc
- */
public function setExternalUrl(string $url): GroupCollectorInterface
{
$this->joinMetaDataTables();
@@ -831,12 +710,9 @@ trait MetaCollection
return $this;
}
- /**
- * @inheritDoc
- */
public function setInternalReference(string $internalReference): GroupCollectorInterface
{
- $internalReference = json_encode($internalReference);
+ $internalReference = (string)json_encode($internalReference);
$internalReference = str_replace('\\', '\\\\', trim($internalReference, '"'));
$this->joinMetaDataTables();
@@ -846,9 +722,6 @@ trait MetaCollection
return $this;
}
- /**
- * @inheritDoc
- */
public function setRecurrenceId(string $recurringId): GroupCollectorInterface
{
$this->joinMetaDataTables();
@@ -858,9 +731,6 @@ trait MetaCollection
return $this;
}
- /**
- * @inheritDoc
- */
public function setSepaCT(string $sepaCT): GroupCollectorInterface
{
$this->joinMetaDataTables();
@@ -873,41 +743,50 @@ trait MetaCollection
/**
* Limit results to a specific tag.
- *
- * @param Tag $tag
- *
- * @return GroupCollectorInterface
*/
public function setTag(Tag $tag): GroupCollectorInterface
{
$this->withTagInformation();
- $this->query->where('tag_transaction_journal.tag_id', $tag->id);
+ $this->setTags(new Collection([$tag]));
return $this;
}
/**
- * Limit results to a specific set of tags.
- *
- * @param Collection $tags
- *
- * @return GroupCollectorInterface
+ * Limit results to any of the tags in the list.
*/
public function setTags(Collection $tags): GroupCollectorInterface
{
+ Log::debug(sprintf('Now in setTags(%d tag(s))', $tags->count()));
$this->withTagInformation();
- $this->tags = array_merge($this->tags, $tags->pluck('id')->toArray());
- $this->query->whereIn('tag_transaction_journal.tag_id', $this->tags);
+ $this->query->whereNotNull('tag_transaction_journal.tag_id');
+
+ // this method adds a "postFilter" to the collector.
+ $list = $tags->pluck('tag')->toArray();
+ $list = array_map('strtolower', $list);
+ $filter = static function (array $object) use ($list): bool {
+ Log::debug(sprintf('Now in setTags(%s) filter', implode(', ', $list)));
+ foreach ($object['transactions'] as $transaction) {
+ foreach ($transaction['tags'] as $tag) {
+ Log::debug(sprintf('"%s" versus', strtolower($tag['name'])), $list);
+ if (in_array(strtolower($tag['name']), $list, true)) {
+ app('log')->debug(sprintf('Transaction has tag "%s" so return true.', $tag['name']));
+
+ return true;
+ }
+ }
+ }
+ app('log')->debug('Transaction has no tags from the list, so return false.');
+
+ return false;
+ };
+ $this->postFilters[] = $filter;
return $this;
}
/**
* Without tags
- *
- * @param Collection $tags
- *
- * @return GroupCollectorInterface
*/
public function setWithoutSpecificTags(Collection $tags): GroupCollectorInterface
{
@@ -915,25 +794,28 @@ trait MetaCollection
// this method adds a "postFilter" to the collector.
$list = $tags->pluck('tag')->toArray();
- $filter = function (int $index, array $object) use ($list): bool {
+ $list = array_map('strtolower', $list);
+ $filter = static function (array $object) use ($list): bool {
+ Log::debug(sprintf('Now in setWithoutSpecificTags(%s) filter', implode(', ', $list)));
foreach ($object['transactions'] as $transaction) {
+ app('log')->debug(sprintf('Transaction has %d tag(s)', count($transaction['tags'])));
foreach ($transaction['tags'] as $tag) {
- if (in_array($tag['name'], $list, true)) {
+ Log::debug(sprintf('"%s" versus', strtolower($tag['name'])), $list);
+ if (in_array(strtolower($tag['name']), $list, true)) {
+ app('log')->debug(sprintf('Transaction has tag "%s", but should not have it, return false.', $tag['name']));
+
return false;
}
}
}
+
return true;
};
$this->postFilters[] = $filter;
-
return $this;
}
- /**
- * @return GroupCollectorInterface
- */
public function withAnyNotes(): GroupCollectorInterface
{
$this->withNotes();
@@ -944,8 +826,6 @@ trait MetaCollection
/**
* Limit results to transactions without a bill.
- *
- * @return GroupCollectorInterface
*/
public function withBill(): GroupCollectorInterface
{
@@ -957,8 +837,6 @@ trait MetaCollection
/**
* Limit results to a transactions without a budget..
- *
- * @return GroupCollectorInterface
*/
public function withBudget(): GroupCollectorInterface
{
@@ -970,8 +848,6 @@ trait MetaCollection
/**
* Limit results to a transactions without a category.
- *
- * @return GroupCollectorInterface
*/
public function withCategory(): GroupCollectorInterface
{
@@ -981,9 +857,6 @@ trait MetaCollection
return $this;
}
- /**
- * @inheritDoc
- */
public function withExternalId(): GroupCollectorInterface
{
$this->joinMetaDataTables();
@@ -993,9 +866,6 @@ trait MetaCollection
return $this;
}
- /**
- * @inheritDoc
- */
public function withExternalUrl(): GroupCollectorInterface
{
$this->joinMetaDataTables();
@@ -1007,8 +877,6 @@ trait MetaCollection
/**
* Limit results to a transactions without a bill.
- *
- * @return GroupCollectorInterface
*/
public function withoutBill(): GroupCollectorInterface
{
@@ -1019,8 +887,6 @@ trait MetaCollection
/**
* Limit results to a transactions without a budget..
- *
- * @return GroupCollectorInterface
*/
public function withoutBudget(): GroupCollectorInterface
{
@@ -1032,8 +898,6 @@ trait MetaCollection
/**
* Limit results to a transactions without a category.
- *
- * @return GroupCollectorInterface
*/
public function withoutCategory(): GroupCollectorInterface
{
@@ -1043,20 +907,17 @@ trait MetaCollection
return $this;
}
- /**
- * @inheritDoc
- */
public function withoutExternalId(): GroupCollectorInterface
{
$this->joinMetaDataTables();
// TODO not sure if this will work properly.
- $this->query->where(function (Builder $q1) {
- $q1->where(function (Builder $q2) {
+ $this->query->where(static function (Builder $q1): void { // @phpstan-ignore-line
+ $q1->where(static function (Builder $q2): void {
$q2->where('journal_meta.name', '=', 'external_id');
$q2->whereNull('journal_meta.data');
- })->orWhere(function (Builder $q3) {
+ })->orWhere(static function (Builder $q3): void {
$q3->where('journal_meta.name', '!=', 'external_id');
- })->orWhere(function (Builder $q4) {
+ })->orWhere(static function (Builder $q4): void {
$q4->whereNull('journal_meta.name');
});
});
@@ -1064,20 +925,17 @@ trait MetaCollection
return $this;
}
- /**
- * @inheritDoc
- */
public function withoutExternalUrl(): GroupCollectorInterface
{
$this->joinMetaDataTables();
// TODO not sure if this will work properly.
- $this->query->where(function (Builder $q1) {
- $q1->where(function (Builder $q2) {
+ $this->query->where(static function (Builder $q1): void { // @phpstan-ignore-line
+ $q1->where(static function (Builder $q2): void {
$q2->where('journal_meta.name', '=', 'external_url');
$q2->whereNull('journal_meta.data');
- })->orWhere(function (Builder $q3) {
+ })->orWhere(static function (Builder $q3): void {
$q3->where('journal_meta.name', '!=', 'external_url');
- })->orWhere(function (Builder $q4) {
+ })->orWhere(static function (Builder $q4): void {
$q4->whereNull('journal_meta.name');
});
});
@@ -1085,13 +943,10 @@ trait MetaCollection
return $this;
}
- /**
- * @return GroupCollectorInterface
- */
public function withoutNotes(): GroupCollectorInterface
{
$this->withNotes();
- $this->query->where(function (Builder $q) {
+ $this->query->where(static function (Builder $q): void { // @phpstan-ignore-line
$q->whereNull('notes.text');
$q->orWhere('notes.text', '');
});
@@ -1101,8 +956,6 @@ trait MetaCollection
/**
* Where has no tags.
- *
- * @return GroupCollectorInterface
*/
public function withoutTags(): GroupCollectorInterface
{
diff --git a/app/Helpers/Collector/Extensions/TimeCollection.php b/app/Helpers/Collector/Extensions/TimeCollection.php
index 3908686d69..c596cfdb77 100644
--- a/app/Helpers/Collector/Extensions/TimeCollection.php
+++ b/app/Helpers/Collector/Extensions/TimeCollection.php
@@ -32,68 +32,45 @@ use FireflyIII\Helpers\Collector\GroupCollectorInterface;
*/
trait TimeCollection
{
- /**
- * @param string $day
- *
- * @return GroupCollectorInterface
- */
public function dayAfter(string $day): GroupCollectorInterface
{
$this->query->whereDay('transaction_journals.date', '>=', $day);
+
return $this;
}
- /**
- * @param string $day
- *
- * @return GroupCollectorInterface
- */
public function dayBefore(string $day): GroupCollectorInterface
{
$this->query->whereDay('transaction_journals.date', '<=', $day);
+
return $this;
}
- /**
- * @param string $day
- *
- * @return GroupCollectorInterface
- */
public function dayIs(string $day): GroupCollectorInterface
{
$this->query->whereDay('transaction_journals.date', '=', $day);
+
return $this;
}
- /**
- * @param string $day
- *
- * @return GroupCollectorInterface
- */
public function dayIsNot(string $day): GroupCollectorInterface
{
$this->query->whereDay('transaction_journals.date', '!=', $day);
+
return $this;
}
- /**
- * @param Carbon $start
- * @param Carbon $end
- * @param string $field
- *
- * @return GroupCollectorInterface
- */
public function excludeMetaDateRange(Carbon $start, Carbon $end, string $field): GroupCollectorInterface
{
if ($end < $start) {
[$start, $end] = [$end, $start];
}
- $end = clone $end; // this is so weird, but it works if $end and $start secretly point to the same object.
+ $end = clone $end; // this is so weird, but it works if $end and $start secretly point to the same object.
$end->endOfDay();
$start->startOfDay();
$this->withMetaDate($field);
- $filter = function (int $index, array $object) use ($field, $start, $end): bool {
+ $filter = static function (array $object) use ($field, $start, $end): bool {
foreach ($object['transactions'] as $transaction) {
if (array_key_exists($field, $transaction) && $transaction[$field] instanceof Carbon) {
return $transaction[$field]->lt($start) || $transaction[$field]->gt($end);
@@ -107,9 +84,6 @@ trait TimeCollection
return $this;
}
- /**
- * @inheritDoc
- */
public function withMetaDate(string $field): GroupCollectorInterface
{
$this->joinMetaDataTables();
@@ -119,13 +93,6 @@ trait TimeCollection
return $this;
}
- /**
- * @param Carbon $start
- * @param Carbon $end
- * @param string $field
- *
- * @return GroupCollectorInterface
- */
public function excludeObjectRange(Carbon $start, Carbon $end, string $field): GroupCollectorInterface
{
$after = $start->format('Y-m-d 00:00:00');
@@ -137,12 +104,6 @@ trait TimeCollection
return $this;
}
- /**
- * @param Carbon $start
- * @param Carbon $end
- *
- * @return GroupCollectorInterface
- */
public function excludeRange(Carbon $start, Carbon $end): GroupCollectorInterface
{
if ($end < $start) {
@@ -157,16 +118,10 @@ trait TimeCollection
return $this;
}
- /**
- * @param string $day
- * @param string $field
- *
- * @return GroupCollectorInterface
- */
public function metaDayAfter(string $day, string $field): GroupCollectorInterface
{
$this->withMetaDate($field);
- $filter = function (int $index, array $object) use ($field, $day): bool {
+ $filter = static function (array $object) use ($field, $day): bool {
foreach ($object['transactions'] as $transaction) {
if (array_key_exists($field, $transaction) && $transaction[$field] instanceof Carbon
) {
@@ -181,16 +136,10 @@ trait TimeCollection
return $this;
}
- /**
- * @param string $day
- * @param string $field
- *
- * @return GroupCollectorInterface
- */
public function metaDayBefore(string $day, string $field): GroupCollectorInterface
{
$this->withMetaDate($field);
- $filter = function (int $index, array $object) use ($field, $day): bool {
+ $filter = static function (array $object) use ($field, $day): bool {
foreach ($object['transactions'] as $transaction) {
if (array_key_exists($field, $transaction) && $transaction[$field] instanceof Carbon
) {
@@ -205,16 +154,10 @@ trait TimeCollection
return $this;
}
- /**
- * @param string $day
- * @param string $field
- *
- * @return GroupCollectorInterface
- */
public function metaDayIs(string $day, string $field): GroupCollectorInterface
{
$this->withMetaDate($field);
- $filter = function (int $index, array $object) use ($field, $day): bool {
+ $filter = static function (array $object) use ($field, $day): bool {
foreach ($object['transactions'] as $transaction) {
if (array_key_exists($field, $transaction) && $transaction[$field] instanceof Carbon
) {
@@ -225,19 +168,14 @@ trait TimeCollection
return false;
};
$this->postFilters[] = $filter;
+
return $this;
}
- /**
- * @param string $day
- * @param string $field
- *
- * @return GroupCollectorInterface
- */
public function metaDayIsNot(string $day, string $field): GroupCollectorInterface
{
$this->withMetaDate($field);
- $filter = function (int $index, array $object) use ($field, $day): bool {
+ $filter = static function (array $object) use ($field, $day): bool {
foreach ($object['transactions'] as $transaction) {
if (array_key_exists($field, $transaction) && $transaction[$field] instanceof Carbon
) {
@@ -248,19 +186,14 @@ trait TimeCollection
return false;
};
$this->postFilters[] = $filter;
+
return $this;
}
- /**
- * @param string $month
- * @param string $field
- *
- * @return GroupCollectorInterface
- */
public function metaMonthAfter(string $month, string $field): GroupCollectorInterface
{
$this->withMetaDate($field);
- $filter = function (int $index, array $object) use ($field, $month): bool {
+ $filter = static function (array $object) use ($field, $month): bool {
foreach ($object['transactions'] as $transaction) {
if (array_key_exists($field, $transaction) && $transaction[$field] instanceof Carbon
) {
@@ -275,16 +208,10 @@ trait TimeCollection
return $this;
}
- /**
- * @param string $month
- * @param string $field
- *
- * @return GroupCollectorInterface
- */
public function metaMonthBefore(string $month, string $field): GroupCollectorInterface
{
$this->withMetaDate($field);
- $filter = function (int $index, array $object) use ($field, $month): bool {
+ $filter = static function (array $object) use ($field, $month): bool {
foreach ($object['transactions'] as $transaction) {
if (array_key_exists($field, $transaction) && $transaction[$field] instanceof Carbon
) {
@@ -299,16 +226,10 @@ trait TimeCollection
return $this;
}
- /**
- * @param string $month
- * @param string $field
- *
- * @return GroupCollectorInterface
- */
public function metaMonthIs(string $month, string $field): GroupCollectorInterface
{
$this->withMetaDate($field);
- $filter = function (int $index, array $object) use ($field, $month): bool {
+ $filter = static function (array $object) use ($field, $month): bool {
foreach ($object['transactions'] as $transaction) {
if (array_key_exists($field, $transaction) && $transaction[$field] instanceof Carbon
) {
@@ -319,19 +240,14 @@ trait TimeCollection
return false;
};
$this->postFilters[] = $filter;
+
return $this;
}
- /**
- * @param string $month
- * @param string $field
- *
- * @return GroupCollectorInterface
- */
public function metaMonthIsNot(string $month, string $field): GroupCollectorInterface
{
$this->withMetaDate($field);
- $filter = function (int $index, array $object) use ($field, $month): bool {
+ $filter = static function (array $object) use ($field, $month): bool {
foreach ($object['transactions'] as $transaction) {
if (array_key_exists($field, $transaction) && $transaction[$field] instanceof Carbon
) {
@@ -342,19 +258,14 @@ trait TimeCollection
return false;
};
$this->postFilters[] = $filter;
+
return $this;
}
- /**
- * @param string $year
- * @param string $field
- *
- * @return GroupCollectorInterface
- */
public function metaYearAfter(string $year, string $field): GroupCollectorInterface
{
$this->withMetaDate($field);
- $filter = function (int $index, array $object) use ($field, $year): bool {
+ $filter = static function (array $object) use ($field, $year): bool {
foreach ($object['transactions'] as $transaction) {
if (array_key_exists($field, $transaction) && $transaction[$field] instanceof Carbon
) {
@@ -369,16 +280,10 @@ trait TimeCollection
return $this;
}
- /**
- * @param string $year
- * @param string $field
- *
- * @return GroupCollectorInterface
- */
public function metaYearBefore(string $year, string $field): GroupCollectorInterface
{
$this->withMetaDate($field);
- $filter = function (int $index, array $object) use ($field, $year): bool {
+ $filter = static function (array $object) use ($field, $year): bool {
foreach ($object['transactions'] as $transaction) {
if (array_key_exists($field, $transaction) && $transaction[$field] instanceof Carbon
) {
@@ -393,16 +298,10 @@ trait TimeCollection
return $this;
}
- /**
- * @param string $year
- * @param string $field
- *
- * @return GroupCollectorInterface
- */
public function metaYearIs(string $year, string $field): GroupCollectorInterface
{
$this->withMetaDate($field);
- $filter = function (int $index, array $object) use ($field, $year): bool {
+ $filter = static function (array $object) use ($field, $year): bool {
foreach ($object['transactions'] as $transaction) {
if (array_key_exists($field, $transaction) && $transaction[$field] instanceof Carbon
) {
@@ -417,22 +316,17 @@ trait TimeCollection
return $this;
}
- /**
- * @param string $year
- * @param string $field
- *
- * @return GroupCollectorInterface
- */
public function metaYearIsNot(string $year, string $field): GroupCollectorInterface
{
$this->withMetaDate($field);
- $filter = function (int $index, array $object) use ($field, $year): bool {
+ $filter = static function (array $object) use ($field, $year): bool {
foreach ($object['transactions'] as $transaction) {
if (array_key_exists($field, $transaction) && $transaction[$field] instanceof Carbon
) {
return $year !== (string)$transaction[$field]->year;
}
}
+
return true;
};
$this->postFilters[] = $filter;
@@ -440,200 +334,120 @@ trait TimeCollection
return $this;
}
- /**
- * @param string $month
- *
- * @return GroupCollectorInterface
- */
public function monthAfter(string $month): GroupCollectorInterface
{
$this->query->whereMonth('transaction_journals.date', '>=', $month);
+
return $this;
}
- /**
- * @param string $month
- *
- * @return GroupCollectorInterface
- */
public function monthBefore(string $month): GroupCollectorInterface
{
$this->query->whereMonth('transaction_journals.date', '<=', $month);
+
return $this;
}
- /**
- * @param string $month
- *
- * @return GroupCollectorInterface
- */
public function monthIs(string $month): GroupCollectorInterface
{
$this->query->whereMonth('transaction_journals.date', '=', $month);
+
return $this;
}
- /**
- * @param string $month
- *
- * @return GroupCollectorInterface
- */
public function monthIsNot(string $month): GroupCollectorInterface
{
$this->query->whereMonth('transaction_journals.date', '!=', $month);
+
return $this;
}
- /**
- * @param string $day
- * @param string $field
- *
- * @return GroupCollectorInterface
- */
public function objectDayAfter(string $day, string $field): GroupCollectorInterface
{
$this->query->whereDay(sprintf('transaction_journals.%s', $field), '>=', $day);
+
return $this;
}
- /**
- * @param string $day
- * @param string $field
- *
- * @return GroupCollectorInterface
- */
public function objectDayBefore(string $day, string $field): GroupCollectorInterface
{
$this->query->whereDay(sprintf('transaction_journals.%s', $field), '<=', $day);
+
return $this;
}
- /**
- * @param string $day
- * @param string $field
- *
- * @return GroupCollectorInterface
- */
public function objectDayIs(string $day, string $field): GroupCollectorInterface
{
$this->query->whereDay(sprintf('transaction_journals.%s', $field), '=', $day);
+
return $this;
}
- /**
- * @param string $day
- * @param string $field
- *
- * @return GroupCollectorInterface
- */
public function objectDayIsNot(string $day, string $field): GroupCollectorInterface
{
$this->query->whereDay(sprintf('transaction_journals.%s', $field), '!=', $day);
+
return $this;
}
- /**
- * @param string $month
- * @param string $field
- *
- * @return GroupCollectorInterface
- */
public function objectMonthAfter(string $month, string $field): GroupCollectorInterface
{
$this->query->whereMonth(sprintf('transaction_journals.%s', $field), '>=', $month);
+
return $this;
}
- /**
- * @param string $month
- * @param string $field
- *
- * @return GroupCollectorInterface
- */
public function objectMonthBefore(string $month, string $field): GroupCollectorInterface
{
$this->query->whereMonth(sprintf('transaction_journals.%s', $field), '<=', $month);
+
return $this;
}
- /**
- * @param string $month
- * @param string $field
- *
- * @return GroupCollectorInterface
- */
public function objectMonthIs(string $month, string $field): GroupCollectorInterface
{
$this->query->whereMonth(sprintf('transaction_journals.%s', $field), '=', $month);
+
return $this;
}
- /**
- * @param string $month
- * @param string $field
- *
- * @return GroupCollectorInterface
- */
public function objectMonthIsNot(string $month, string $field): GroupCollectorInterface
{
$this->query->whereMonth(sprintf('transaction_journals.%s', $field), '!=', $month);
+
return $this;
}
- /**
- * @param string $year
- * @param string $field
- *
- * @return GroupCollectorInterface
- */
public function objectYearAfter(string $year, string $field): GroupCollectorInterface
{
$this->query->whereYear(sprintf('transaction_journals.%s', $field), '>=', $year);
+
return $this;
}
- /**
- * @param string $year
- * @param string $field
- *
- * @return GroupCollectorInterface
- */
public function objectYearBefore(string $year, string $field): GroupCollectorInterface
{
$this->query->whereYear(sprintf('transaction_journals.%s', $field), '<=', $year);
+
return $this;
}
- /**
- * @param string $year
- * @param string $field
- *
- * @return GroupCollectorInterface
- */
public function objectYearIs(string $year, string $field): GroupCollectorInterface
{
$this->query->whereYear(sprintf('transaction_journals.%s', $field), '=', $year);
+
return $this;
}
- /**
- * @param string $year
- * @param string $field
- *
- * @return GroupCollectorInterface
- */
public function objectYearIsNot(string $year, string $field): GroupCollectorInterface
{
$this->query->whereYear(sprintf('transaction_journals.%s', $field), '!=', $year);
+
return $this;
}
/**
* Collect transactions after a specific date.
- *
- * @param Carbon $date
- *
- * @return GroupCollectorInterface
*/
public function setAfter(Carbon $date): GroupCollectorInterface
{
@@ -645,14 +459,10 @@ trait TimeCollection
/**
* Collect transactions before a specific date.
- *
- * @param Carbon $date
- *
- * @return GroupCollectorInterface
*/
public function setBefore(Carbon $date): GroupCollectorInterface
{
- $beforeStr = $date->format('Y-m-d 00:00:00');
+ $beforeStr = $date->format('Y-m-d 23:59:59');
$this->query->where('transaction_journals.date', '<=', $beforeStr);
return $this;
@@ -660,10 +470,6 @@ trait TimeCollection
/**
* Collect transactions created on a specific date.
- *
- * @param Carbon $date
- *
- * @return GroupCollectorInterface
*/
public function setCreatedAt(Carbon $date): GroupCollectorInterface
{
@@ -677,10 +483,6 @@ trait TimeCollection
/**
* Set the end time of the results to return.
- *
- * @param Carbon $end
- *
- * @return GroupCollectorInterface
*/
public function setEnd(Carbon $end): GroupCollectorInterface
{
@@ -692,17 +494,11 @@ trait TimeCollection
return $this;
}
- /**
- * @param Carbon $date
- * @param string $field
- *
- * @return GroupCollectorInterface
- */
public function setMetaAfter(Carbon $date, string $field): GroupCollectorInterface
{
$this->withMetaDate($field);
$date->startOfDay();
- $filter = function (int $index, array $object) use ($field, $date): bool {
+ $filter = static function (array $object) use ($field, $date): bool {
foreach ($object['transactions'] as $transaction) {
if (array_key_exists($field, $transaction) && $transaction[$field] instanceof Carbon
) {
@@ -717,16 +513,10 @@ trait TimeCollection
return $this;
}
- /**
- * @param Carbon $date
- * @param string $field
- *
- * @return GroupCollectorInterface
- */
public function setMetaBefore(Carbon $date, string $field): GroupCollectorInterface
{
$this->withMetaDate($field);
- $filter = function (int $index, array $object) use ($field, $date): bool {
+ $filter = static function (array $object) use ($field, $date): bool {
foreach ($object['transactions'] as $transaction) {
if (array_key_exists($field, $transaction) && $transaction[$field] instanceof Carbon
) {
@@ -741,24 +531,17 @@ trait TimeCollection
return $this;
}
- /**
- * @param Carbon $start
- * @param Carbon $end
- * @param string $field
- *
- * @return GroupCollectorInterface
- */
public function setMetaDateRange(Carbon $start, Carbon $end, string $field): GroupCollectorInterface
{
if ($end < $start) {
[$start, $end] = [$end, $start];
}
- $end = clone $end; // this is so weird, but it works if $end and $start secretly point to the same object.
+ $end = clone $end; // this is so weird, but it works if $end and $start secretly point to the same object.
$end->endOfDay();
$start->startOfDay();
$this->withMetaDate($field);
- $filter = function (int $index, array $object) use ($field, $start, $end): bool {
+ $filter = static function (array $object) use ($field, $start, $end): bool {
foreach ($object['transactions'] as $transaction) {
if (array_key_exists($field, $transaction) && $transaction[$field] instanceof Carbon
) {
@@ -769,15 +552,10 @@ trait TimeCollection
return false;
};
$this->postFilters[] = $filter;
+
return $this;
}
- /**
- * @param Carbon $date
- * @param string $field
- *
- * @return GroupCollectorInterface
- */
public function setObjectAfter(Carbon $date, string $field): GroupCollectorInterface
{
$afterStr = $date->format('Y-m-d 00:00:00');
@@ -786,26 +564,14 @@ trait TimeCollection
return $this;
}
- /**
- * @param Carbon $date
- * @param string $field
- *
- * @return GroupCollectorInterface
- */
public function setObjectBefore(Carbon $date, string $field): GroupCollectorInterface
{
$afterStr = $date->format('Y-m-d 00:00:00');
$this->query->where(sprintf('transaction_journals.%s', $field), '<=', $afterStr);
+
return $this;
}
- /**
- * @param Carbon $start
- * @param Carbon $end
- * @param string $field
- *
- * @return GroupCollectorInterface
- */
public function setObjectRange(Carbon $start, Carbon $end, string $field): GroupCollectorInterface
{
$after = $start->format('Y-m-d 00:00:00');
@@ -820,11 +586,6 @@ trait TimeCollection
* Set the start and end time of the results to return.
*
* Can either or both be NULL
- *
- * @param Carbon|null $start
- * @param Carbon|null $end
- *
- * @return GroupCollectorInterface
*/
public function setRange(?Carbon $start, ?Carbon $end): GroupCollectorInterface
{
@@ -847,10 +608,6 @@ trait TimeCollection
/**
* Set the start time of the results to return.
- *
- * @param Carbon $start
- *
- * @return GroupCollectorInterface
*/
public function setStart(Carbon $start): GroupCollectorInterface
{
@@ -863,10 +620,6 @@ trait TimeCollection
/**
* Collect transactions updated on a specific date.
- *
- * @param Carbon $date
- *
- * @return GroupCollectorInterface
*/
public function setUpdatedAt(Carbon $date): GroupCollectorInterface
{
@@ -878,47 +631,31 @@ trait TimeCollection
return $this;
}
- /**
- * @param string $year
- *
- * @return GroupCollectorInterface
- */
public function yearAfter(string $year): GroupCollectorInterface
{
$this->query->whereYear('transaction_journals.date', '>=', $year);
+
return $this;
}
- /**
- * @param string $year
- *
- * @return GroupCollectorInterface
- */
public function yearBefore(string $year): GroupCollectorInterface
{
$this->query->whereYear('transaction_journals.date', '<=', $year);
+
return $this;
}
- /**
- * @param string $year
- *
- * @return GroupCollectorInterface
- */
public function yearIs(string $year): GroupCollectorInterface
{
$this->query->whereYear('transaction_journals.date', '=', $year);
+
return $this;
}
- /**
- * @param string $year
- *
- * @return GroupCollectorInterface
- */
public function yearIsNot(string $year): GroupCollectorInterface
{
$this->query->whereYear('transaction_journals.date', '!=', $year);
+
return $this;
}
}
diff --git a/app/Helpers/Collector/GroupCollector.php b/app/Helpers/Collector/GroupCollector.php
index eee489d612..0e3b1de766 100644
--- a/app/Helpers/Collector/GroupCollector.php
+++ b/app/Helpers/Collector/GroupCollector.php
@@ -25,8 +25,6 @@ namespace FireflyIII\Helpers\Collector;
use Carbon\Carbon;
use Carbon\Exceptions\InvalidFormatException;
-use Closure;
-use Exception;
use FireflyIII\Exceptions\FireflyException;
use FireflyIII\Helpers\Collector\Extensions\AccountCollection;
use FireflyIII\Helpers\Collector\Extensions\AmountCollection;
@@ -48,29 +46,30 @@ use Illuminate\Support\Facades\Log;
/**
* Class GroupCollector
- *
-
*/
class GroupCollector implements GroupCollectorInterface
{
- use CollectorProperties;
use AccountCollection;
use AmountCollection;
- use TimeCollection;
- use MetaCollection;
use AttachmentCollection;
+ use CollectorProperties;
+ use MetaCollection;
+ use TimeCollection;
/**
* Group collector constructor.
*/
public function __construct()
{
- $this->postFilters = [];
- $this->tags = [];
- $this->user = null;
- $this->userGroup = null;
- $this->limit = null;
- $this->page = null;
+ $this->sorting = [];
+ $this->postFilters = [];
+ $this->tags = [];
+ $this->user = null;
+ $this->userGroup = null;
+ $this->limit = null;
+ $this->page = null;
+ $this->startRow = null;
+ $this->endRow = null;
$this->hasAccountInfo = false;
$this->hasCatInformation = false;
@@ -102,30 +101,32 @@ class GroupCollector implements GroupCollectorInterface
$this->stringFields = ['amount', 'foreign_amount'];
$this->total = 0;
$this->fields = [
- # group
+ // group
'transaction_groups.id as transaction_group_id',
'transaction_groups.user_id as user_id',
'transaction_groups.user_group_id as user_group_id',
'transaction_groups.created_at as created_at',
'transaction_groups.updated_at as updated_at',
'transaction_groups.title as transaction_group_title',
+ 'transaction_groups.created_at as group_created_at',
+ 'transaction_groups.updated_at as group_updated_at',
- # journal
+ // journal
'transaction_journals.id as transaction_journal_id',
'transaction_journals.transaction_type_id',
'transaction_journals.description',
'transaction_journals.date',
'transaction_journals.order',
- # types
+ // types
'transaction_types.type as transaction_type_type',
- # source info (always present)
+ // source info (always present)
'source.id as source_transaction_id',
'source.account_id as source_account_id',
'source.reconciled',
- # currency info:
+ // currency info:
'source.amount as amount',
'source.transaction_currency_id as currency_id',
'currency.code as currency_code',
@@ -133,7 +134,7 @@ class GroupCollector implements GroupCollectorInterface
'currency.symbol as currency_symbol',
'currency.decimal_places as currency_decimal_places',
- # foreign currency info
+ // foreign currency info
'source.foreign_amount as foreign_amount',
'source.foreign_currency_id as foreign_currency_id',
'foreign_currency.code as foreign_currency_code',
@@ -141,20 +142,17 @@ class GroupCollector implements GroupCollectorInterface
'foreign_currency.symbol as foreign_currency_symbol',
'foreign_currency.decimal_places as foreign_currency_decimal_places',
- # destination account info (always present)
+ // destination account info (always present)
'destination.account_id as destination_account_id',
];
}
- /**
- * @inheritDoc
- */
public function descriptionDoesNotEnd(array $array): GroupCollectorInterface
{
$this->query->where(
- static function (EloquentBuilder $q) use ($array) {
+ static function (EloquentBuilder $q) use ($array): void { // @phpstan-ignore-line
$q->where(
- static function (EloquentBuilder $q1) use ($array) {
+ static function (EloquentBuilder $q1) use ($array): void {
foreach ($array as $word) {
$keyword = sprintf('%%%s', $word);
$q1->where('transaction_journals.description', 'NOT LIKE', $keyword);
@@ -162,7 +160,7 @@ class GroupCollector implements GroupCollectorInterface
}
);
$q->where(
- static function (EloquentBuilder $q2) use ($array) {
+ static function (EloquentBuilder $q2) use ($array): void {
foreach ($array as $word) {
$keyword = sprintf('%%%s', $word);
$q2->where('transaction_groups.title', 'NOT LIKE', $keyword);
@@ -176,15 +174,12 @@ class GroupCollector implements GroupCollectorInterface
return $this;
}
- /**
- * @inheritDoc
- */
public function descriptionDoesNotStart(array $array): GroupCollectorInterface
{
$this->query->where(
- static function (EloquentBuilder $q) use ($array) {
+ static function (EloquentBuilder $q) use ($array): void { // @phpstan-ignore-line
$q->where(
- static function (EloquentBuilder $q1) use ($array) {
+ static function (EloquentBuilder $q1) use ($array): void {
foreach ($array as $word) {
$keyword = sprintf('%s%%', $word);
$q1->where('transaction_journals.description', 'NOT LIKE', $keyword);
@@ -192,7 +187,7 @@ class GroupCollector implements GroupCollectorInterface
}
);
$q->where(
- static function (EloquentBuilder $q2) use ($array) {
+ static function (EloquentBuilder $q2) use ($array): void {
foreach ($array as $word) {
$keyword = sprintf('%s%%', $word);
$q2->where('transaction_groups.title', 'NOT LIKE', $keyword);
@@ -206,15 +201,12 @@ class GroupCollector implements GroupCollectorInterface
return $this;
}
- /**
- * @inheritDoc
- */
public function descriptionEnds(array $array): GroupCollectorInterface
{
$this->query->where(
- static function (EloquentBuilder $q) use ($array) {
+ static function (EloquentBuilder $q) use ($array): void { // @phpstan-ignore-line
$q->where(
- static function (EloquentBuilder $q1) use ($array) {
+ static function (EloquentBuilder $q1) use ($array): void {
foreach ($array as $word) {
$keyword = sprintf('%%%s', $word);
$q1->where('transaction_journals.description', 'LIKE', $keyword);
@@ -222,7 +214,7 @@ class GroupCollector implements GroupCollectorInterface
}
);
$q->orWhere(
- static function (EloquentBuilder $q2) use ($array) {
+ static function (EloquentBuilder $q2) use ($array): void {
foreach ($array as $word) {
$keyword = sprintf('%%%s', $word);
$q2->where('transaction_groups.title', 'LIKE', $keyword);
@@ -235,13 +227,10 @@ class GroupCollector implements GroupCollectorInterface
return $this;
}
- /**
- * @inheritDoc
- */
public function descriptionIs(string $value): GroupCollectorInterface
{
$this->query->where(
- static function (EloquentBuilder $q) use ($value) {
+ static function (EloquentBuilder $q) use ($value): void { // @phpstan-ignore-line
$q->where('transaction_journals.description', '=', $value);
$q->orWhere('transaction_groups.title', '=', $value);
}
@@ -250,16 +239,13 @@ class GroupCollector implements GroupCollectorInterface
return $this;
}
- /**
- * @inheritDoc
- */
public function descriptionIsNot(string $value): GroupCollectorInterface
{
$this->query->where(
- static function (EloquentBuilder $q) use ($value) {
+ static function (EloquentBuilder $q) use ($value): void { // @phpstan-ignore-line
$q->where('transaction_journals.description', '!=', $value);
$q->where(
- static function (EloquentBuilder $q2) use ($value) {
+ static function (EloquentBuilder $q2) use ($value): void {
$q2->where('transaction_groups.title', '!=', $value);
$q2->orWhereNull('transaction_groups.title');
}
@@ -270,15 +256,12 @@ class GroupCollector implements GroupCollectorInterface
return $this;
}
- /**
- * @inheritDoc
- */
public function descriptionStarts(array $array): GroupCollectorInterface
{
$this->query->where(
- static function (EloquentBuilder $q) use ($array) {
+ static function (EloquentBuilder $q) use ($array): void { // @phpstan-ignore-line
$q->where(
- static function (EloquentBuilder $q1) use ($array) {
+ static function (EloquentBuilder $q1) use ($array): void {
foreach ($array as $word) {
$keyword = sprintf('%s%%', $word);
$q1->where('transaction_journals.description', 'LIKE', $keyword);
@@ -286,7 +269,7 @@ class GroupCollector implements GroupCollectorInterface
}
);
$q->orWhere(
- static function (EloquentBuilder $q2) use ($array) {
+ static function (EloquentBuilder $q2) use ($array): void {
foreach ($array as $word) {
$keyword = sprintf('%s%%', $word);
$q2->where('transaction_groups.title', 'LIKE', $keyword);
@@ -299,9 +282,6 @@ class GroupCollector implements GroupCollectorInterface
return $this;
}
- /**
- *
- */
public function dumpQuery(): void
{
$query = $this->query->select($this->fields)->toSql();
@@ -311,8 +291,8 @@ class GroupCollector implements GroupCollectorInterface
if (is_int($param)) {
$replace = (string)$param;
}
- $pos = strpos($query, '?');
- if ($pos !== false) {
+ $pos = strpos($query, '?');
+ if (false !== $pos) {
$query = substr_replace($query, $replace, $pos, 1);
}
}
@@ -323,29 +303,22 @@ class GroupCollector implements GroupCollectorInterface
echo '';
}
- /**
- *
- */
public function dumpQueryInLogs(): void
{
- Log::debug($this->query->select($this->fields)->toSql());
- Log::debug('Bindings', $this->query->getBindings());
+ app('log')->debug($this->query->select($this->fields)->toSql());
+ app('log')->debug('Bindings', $this->query->getBindings());
}
/**
* Limit results to NOT a specific currency, either foreign or normal one.
- *
- * @param TransactionCurrency $currency
- *
- * @return GroupCollectorInterface
*/
public function excludeCurrency(TransactionCurrency $currency): GroupCollectorInterface
{
$this->query->where(
- static function (EloquentBuilder $q) use ($currency) {
+ static function (EloquentBuilder $q) use ($currency): void { // @phpstan-ignore-line
$q->where('source.transaction_currency_id', '!=', $currency->id);
$q->where(
- static function (EloquentBuilder $q2) use ($currency) {
+ static function (EloquentBuilder $q2) use ($currency): void {
$q2->where('source.foreign_currency_id', '!=', $currency->id);
$q2->orWhereNull('source.foreign_currency_id');
}
@@ -356,12 +329,9 @@ class GroupCollector implements GroupCollectorInterface
return $this;
}
- /**
- * @inheritDoc
- */
public function excludeForeignCurrency(TransactionCurrency $currency): GroupCollectorInterface
{
- $this->query->where(static function (EloquentBuilder $q2) use ($currency) {
+ $this->query->where(static function (EloquentBuilder $q2) use ($currency): void { // @phpstan-ignore-line
$q2->where('source.foreign_currency_id', '!=', $currency->id);
$q2->orWhereNull('source.foreign_currency_id');
});
@@ -371,10 +341,6 @@ class GroupCollector implements GroupCollectorInterface
/**
* Limit the result to NOT a set of specific transaction groups.
- *
- * @param array $groupIds
- *
- * @return GroupCollectorInterface
*/
public function excludeIds(array $groupIds): GroupCollectorInterface
{
@@ -385,10 +351,6 @@ class GroupCollector implements GroupCollectorInterface
/**
* Limit the result to NOT a set of specific journals.
- *
- * @param array $journalIds
- *
- * @return GroupCollectorInterface
*/
public function excludeJournalIds(array $journalIds): GroupCollectorInterface
{
@@ -396,7 +358,6 @@ class GroupCollector implements GroupCollectorInterface
// make all integers.
$integerIDs = array_map('intval', $journalIds);
-
$this->query->whereNotIn('transaction_journals.id', $integerIDs);
}
@@ -405,10 +366,6 @@ class GroupCollector implements GroupCollectorInterface
/**
* Search for words in descriptions.
- *
- * @param array $array
- *
- * @return GroupCollectorInterface
*/
public function excludeSearchWords(array $array): GroupCollectorInterface
{
@@ -416,9 +373,9 @@ class GroupCollector implements GroupCollectorInterface
return $this;
}
$this->query->where(
- static function (EloquentBuilder $q) use ($array) {
+ static function (EloquentBuilder $q) use ($array): void { // @phpstan-ignore-line
$q->where(
- static function (EloquentBuilder $q1) use ($array) {
+ static function (EloquentBuilder $q1) use ($array): void {
foreach ($array as $word) {
$keyword = sprintf('%%%s%%', $word);
$q1->where('transaction_journals.description', 'NOT LIKE', $keyword);
@@ -426,7 +383,7 @@ class GroupCollector implements GroupCollectorInterface
}
);
$q->where(
- static function (EloquentBuilder $q2) use ($array) {
+ static function (EloquentBuilder $q2) use ($array): void {
foreach ($array as $word) {
$keyword = sprintf('%%%s%%', $word);
$q2->where('transaction_groups.title', 'NOT LIKE', $keyword);
@@ -440,9 +397,6 @@ class GroupCollector implements GroupCollectorInterface
return $this;
}
- /**
- * @inheritDoc
- */
public function excludeTypes(array $types): GroupCollectorInterface
{
$this->query->whereNotIn('transaction_types.type', $types);
@@ -450,9 +404,6 @@ class GroupCollector implements GroupCollectorInterface
return $this;
}
- /**
- * @inheritDoc
- */
public function exists(): GroupCollectorInterface
{
$this->query->whereNull('transaction_groups.deleted_at');
@@ -460,12 +411,10 @@ class GroupCollector implements GroupCollectorInterface
'transaction_types.type',
[TransactionType::LIABILITY_CREDIT, TransactionType::OPENING_BALANCE, TransactionType::RECONCILIATION]
);
+
return $this;
}
- /**
- * @inheritDoc
- */
public function findNothing(): GroupCollectorInterface
{
$this->query->where('transaction_groups.id', -1);
@@ -473,9 +422,6 @@ class GroupCollector implements GroupCollectorInterface
return $this;
}
- /**
- * @return bool
- */
public function getExpandGroupSearch(): bool
{
return $this->expandGroupSearch;
@@ -483,13 +429,12 @@ class GroupCollector implements GroupCollectorInterface
/**
* Return the transaction journals without group information. Is useful in some instances.
- *
- * @return array
*/
public function getExtractedJournals(): array
{
$selection = $this->getGroups();
$return = [];
+
/** @var array $group */
foreach ($selection as $group) {
$count = count($group['transactions']);
@@ -505,8 +450,6 @@ class GroupCollector implements GroupCollectorInterface
/**
* Return the groups.
- *
- * @return Collection
*/
public function getGroups(): Collection
{
@@ -516,14 +459,16 @@ class GroupCollector implements GroupCollectorInterface
// add to query:
$this->query->orWhereIn('transaction_journals.transaction_group_id', $groupIds);
}
-
- $result = $this->query->get($this->fields);
+ $result = $this->query->get($this->fields);
// now to parse this into an array.
- $collection = $this->parseArray($result);
+ $collection = $this->parseArray($result);
// filter the array using all available post filters:
- $collection = $this->postFilterCollection($collection);
+ $collection = $this->postFilterCollection($collection);
+
+ // sort the collection, if sort instructions are present.
+ $collection = $this->sortCollection($collection);
// count it and continue:
$this->total = $collection->count();
@@ -534,40 +479,41 @@ class GroupCollector implements GroupCollectorInterface
return $collection->slice($offset, $this->limit);
}
+ // OR filter the array according to the start and end row variable
+ if (null !== $this->startRow && null !== $this->endRow) {
+ return $collection->slice($this->startRow, $this->endRow);
+ }
return $collection;
}
- /**
- * @return array
- */
private function getCollectedGroupIds(): array
{
return $this->query->get(['transaction_journals.transaction_group_id'])->pluck('transaction_group_id')->toArray();
}
/**
- * @param Collection $collection
- *
- * @return Collection
* @throws FireflyException
*/
private function parseArray(Collection $collection): Collection
{
$groups = [];
+
/** @var TransactionJournal $augumentedJournal */
foreach ($collection as $augumentedJournal) {
- $groupId = (int)$augumentedJournal->transaction_group_id;
+ $groupId = (int)$augumentedJournal->transaction_group_id;
if (!array_key_exists($groupId, $groups)) {
// make new array
- $parsedGroup = $this->parseAugmentedJournal($augumentedJournal);
- $groupArray = [
+ $parsedGroup = $this->parseAugmentedJournal($augumentedJournal);
+ $groupArray = [
'id' => (int)$augumentedJournal->transaction_group_id,
- 'user_id' => (int)$augumentedJournal->user_id,
- 'user_group_id' => (int)$augumentedJournal->user_group_id,
+ 'user_id' => $augumentedJournal->user_id,
+ 'user_group_id' => $augumentedJournal->user_group_id,
// Field transaction_group_title was added by the query.
'title' => $augumentedJournal->transaction_group_title, // @phpstan-ignore-line
+ 'created_at' => new Carbon($augumentedJournal->group_created_at, config('app.timezone')),
+ 'updated_at' => new Carbon($augumentedJournal->group_updated_at, config('app.timezone')),
'transaction_type' => $parsedGroup['transaction_type_type'],
'count' => 1,
'sums' => [],
@@ -577,6 +523,7 @@ class GroupCollector implements GroupCollectorInterface
$journalId = (int)$augumentedJournal->transaction_journal_id; // @phpstan-ignore-line
$groupArray['transactions'][$journalId] = $parsedGroup;
$groups[$groupId] = $groupArray;
+
continue;
}
// or parse the rest.
@@ -590,7 +537,7 @@ class GroupCollector implements GroupCollectorInterface
if (!array_key_exists($journalId, $groups[$groupId]['transactions'])) {
// create second, third, fourth split:
- $groups[$groupId]['count']++;
+ ++$groups[$groupId]['count'];
$groups[$groupId]['transactions'][$journalId] = $this->parseAugmentedJournal($augumentedJournal);
}
}
@@ -601,9 +548,6 @@ class GroupCollector implements GroupCollectorInterface
}
/**
- * @param TransactionJournal $augumentedJournal
- *
- * @return array
* @throws FireflyException
*/
private function parseAugmentedJournal(TransactionJournal $augumentedJournal): array
@@ -617,6 +561,7 @@ class GroupCollector implements GroupCollectorInterface
$result['book_date'] = null;
$result['due_date'] = null;
$result['process_date'] = null;
+
try {
$result['date'] = new Carbon($result['date'], 'UTC');
$result['created_at'] = new Carbon($result['created_at'], 'UTC');
@@ -626,13 +571,14 @@ class GroupCollector implements GroupCollectorInterface
$result['date']->setTimezone(config('app.timezone'));
$result['created_at']->setTimezone(config('app.timezone'));
$result['updated_at']->setTimezone(config('app.timezone'));
- } catch (Exception $e) { // intentional generic exception
- Log::error($e->getMessage());
+ } catch (\Exception $e) { // intentional generic exception
+ app('log')->error($e->getMessage());
+
throw new FireflyException($e->getMessage(), 0, $e);
}
// try to process meta date value (if present)
- $dates = ['interest_date', 'payment_date', 'invoice_date', 'book_date', 'due_date', 'process_date'];
+ $dates = ['interest_date', 'payment_date', 'invoice_date', 'book_date', 'due_date', 'process_date'];
if (array_key_exists('meta_name', $result) && in_array($result['meta_name'], $dates, true)) {
$name = $result['meta_name'];
if (array_key_exists('meta_data', $result) && '' !== (string)$result['meta_data']) {
@@ -641,19 +587,20 @@ class GroupCollector implements GroupCollectorInterface
}
// convert values to integers:
- $result = $this->convertToInteger($result);
+ $result = $this->convertToInteger($result);
// convert back to strings because SQLite is dumb like that.
- $result = $this->convertToStrings($result);
+ $result = $this->convertToStrings($result);
- $result['reconciled'] = 1 === (int)$result['reconciled'];
+ $result['reconciled'] = 1 === (int)$result['reconciled'];
if (array_key_exists('tag_id', $result) && null !== $result['tag_id']) { // assume the other fields are present as well.
- $tagId = (int)$augumentedJournal['tag_id'];
- $tagDate = null;
+ $tagId = (int)$augumentedJournal['tag_id'];
+ $tagDate = null;
+
try {
$tagDate = Carbon::parse($augumentedJournal['tag_date']);
} catch (InvalidFormatException $e) {
- Log::debug(sprintf('Could not parse date: %s', $e->getMessage()));
+ app('log')->debug(sprintf('Could not parse date: %s', $e->getMessage()));
}
$result['tags'][$tagId] = [
@@ -682,7 +629,6 @@ class GroupCollector implements GroupCollectorInterface
$result['tag_name'], $result['tag_date'], $result['tag_description'],
$result['tag_latitude'], $result['tag_longitude'], $result['tag_zoom_level'],
$result['attachment_filename'], $result['attachment_id']
-
);
return $result;
@@ -690,10 +636,6 @@ class GroupCollector implements GroupCollectorInterface
/**
* Convert a selected set of fields to arrays.
- *
- * @param array $array
- *
- * @return array
*/
private function convertToInteger(array $array): array
{
@@ -704,11 +646,6 @@ class GroupCollector implements GroupCollectorInterface
return $array;
}
- /**
- * @param array $array
- *
- * @return array
- */
private function convertToStrings(array $array): array
{
foreach ($this->stringFields as $field) {
@@ -718,23 +655,18 @@ class GroupCollector implements GroupCollectorInterface
return $array;
}
- /**
- * @param array $existingJournal
- * @param TransactionJournal $newJournal
- *
- * @return array
- */
private function mergeTags(array $existingJournal, TransactionJournal $newJournal): array
{
$newArray = $newJournal->toArray();
if (array_key_exists('tag_id', $newArray)) { // assume the other fields are present as well.
- $tagId = (int)$newJournal['tag_id'];
+ $tagId = (int)$newJournal['tag_id'];
+
+ $tagDate = null;
- $tagDate = null;
try {
$tagDate = Carbon::parse($newArray['tag_date']);
} catch (InvalidFormatException $e) {
- Log::debug(sprintf('Could not parse date: %s', $e->getMessage()));
+ app('log')->debug(sprintf('Could not parse date: %s', $e->getMessage()));
}
$existingJournal['tags'][$tagId] = [
@@ -748,17 +680,11 @@ class GroupCollector implements GroupCollectorInterface
return $existingJournal;
}
- /**
- * @param array $existingJournal
- * @param TransactionJournal $newJournal
- *
- * @return array
- */
private function mergeAttachments(array $existingJournal, TransactionJournal $newJournal): array
{
$newArray = $newJournal->toArray();
if (array_key_exists('attachment_id', $newArray)) {
- $attachmentId = (int)$newJournal['attachment_id'];
+ $attachmentId = (int)$newJournal['attachment_id'];
$existingJournal['attachments'][$attachmentId] = [
'id' => $attachmentId,
@@ -768,11 +694,6 @@ class GroupCollector implements GroupCollectorInterface
return $existingJournal;
}
- /**
- * @param array $groups
- *
- * @return array
- */
private function parseSums(array $groups): array
{
/**
@@ -782,7 +703,10 @@ class GroupCollector implements GroupCollectorInterface
foreach ($groups as $groudId => $group) {
/** @var array $transaction */
foreach ($group['transactions'] as $transaction) {
- $currencyId = (int)$transaction['currency_id'];
+ $currencyId = (int)$transaction['currency_id'];
+ if (null === $transaction['amount']) {
+ throw new FireflyException(sprintf('Amount is NULL for a transaction in group #%d, please investigate.', $groudId));
+ }
// set default:
if (!array_key_exists($currencyId, $groups[$groudId]['sums'])) {
@@ -795,7 +719,7 @@ class GroupCollector implements GroupCollectorInterface
$groups[$groudId]['sums'][$currencyId]['amount'] = bcadd($groups[$groudId]['sums'][$currencyId]['amount'], $transaction['amount']);
if (null !== $transaction['foreign_amount'] && null !== $transaction['foreign_currency_id']) {
- $currencyId = (int)$transaction['foreign_currency_id'];
+ $currencyId = (int)$transaction['foreign_currency_id'];
// set default:
if (!array_key_exists($currencyId, $groups[$groudId]['sums'])) {
@@ -813,43 +737,53 @@ class GroupCollector implements GroupCollectorInterface
return $groups;
}
- /**
- * @param Collection $collection
- *
- * @return Collection
- */
private function postFilterCollection(Collection $collection): Collection
{
$currentCollection = $collection;
+ $countFilters = count($this->postFilters);
+ $countCollection = count($currentCollection);
+ if (0 === $countFilters && 0 === $countCollection) {
+ return $currentCollection;
+ }
+ app('log')->debug(sprintf('GroupCollector: postFilterCollection has %d filter(s) and %d transaction(s).', count($this->postFilters), count($currentCollection)));
+
/**
- * @var Closure $function
+ * @var \Closure $function
*/
foreach ($this->postFilters as $function) {
- $nextCollection = new Collection();
+ app('log')->debug('Applying filter...');
+ $nextCollection = new Collection();
+
// loop everything in the current collection
// and save it (or not) in the new collection.
// that new collection is the next current collection
/**
- * @var int $ii
* @var array $item
*/
- foreach ($currentCollection as $ii => $item) {
- $result = $function($ii, $item);
+ foreach ($currentCollection as $item) {
+ $result = $function($item);
if (false === $result) {
// skip other filters, continue to next item.
continue;
}
- $nextCollection->push($item);
+ // if the result is a bool, use the unedited results.
+ if (true === $result) {
+ $nextCollection->push($item);
+ }
+ // if the result is an array, the filter has changed what's being returned.
+ if (is_array($result)) {
+ $nextCollection->push($result);
+ }
}
$currentCollection = $nextCollection;
+ app('log')->debug(sprintf('GroupCollector: postFilterCollection has %d transaction(s) left.', count($currentCollection)));
}
+
return $currentCollection;
}
/**
* Same as getGroups but everything is in a paginator.
- *
- * @return LengthAwarePaginator
*/
public function getPaginatedGroups(): LengthAwarePaginator
{
@@ -857,54 +791,47 @@ class GroupCollector implements GroupCollectorInterface
if (0 === $this->limit) {
$this->setLimit(50);
}
+ if (null !== $this->startRow && null !== $this->endRow) {
+ $total = $this->endRow - $this->startRow;
+
+ return new LengthAwarePaginator($set, $this->total, $total, 1);
+ }
return new LengthAwarePaginator($set, $this->total, $this->limit, $this->page);
}
/**
* Limit the number of returned entries.
- *
- * @param int $limit
- *
- * @return GroupCollectorInterface
*/
public function setLimit(int $limit): GroupCollectorInterface
{
$this->limit = $limit;
- //app('log')->debug(sprintf('GroupCollector: The limit is now %d', $limit));
+ // app('log')->debug(sprintf('GroupCollector: The limit is now %d', $limit));
return $this;
}
- /**
- * @inheritDoc
- */
public function isNotReconciled(): GroupCollectorInterface
{
$this->query->where('source.reconciled', 0)->where('destination.reconciled', 0);
+
return $this;
}
- /**
- * @inheritDoc
- */
public function isReconciled(): GroupCollectorInterface
{
$this->query->where('source.reconciled', 1)->where('destination.reconciled', 1);
+
return $this;
}
/**
* Limit results to a specific currency, either foreign or normal one.
- *
- * @param TransactionCurrency $currency
- *
- * @return GroupCollectorInterface
*/
public function setCurrency(TransactionCurrency $currency): GroupCollectorInterface
{
$this->query->where(
- static function (EloquentBuilder $q) use ($currency) {
+ static function (EloquentBuilder $q) use ($currency): void { // @phpstan-ignore-line
$q->where('source.transaction_currency_id', $currency->id);
$q->orWhere('source.foreign_currency_id', $currency->id);
}
@@ -913,17 +840,20 @@ class GroupCollector implements GroupCollectorInterface
return $this;
}
- /**
- * @param bool $expandGroupSearch
- */
- public function setExpandGroupSearch(bool $expandGroupSearch): void
+ public function setEndRow(int $endRow): self
{
- $this->expandGroupSearch = $expandGroupSearch;
+ $this->endRow = $endRow;
+
+ return $this;
+ }
+
+ public function setExpandGroupSearch(bool $expandGroupSearch): GroupCollectorInterface
+ {
+ $this->expandGroupSearch = $expandGroupSearch;
+
+ return $this;
}
- /**
- * @inheritDoc
- */
public function setForeignCurrency(TransactionCurrency $currency): GroupCollectorInterface
{
$this->query->where('source.foreign_currency_id', $currency->id);
@@ -933,10 +863,6 @@ class GroupCollector implements GroupCollectorInterface
/**
* Limit the result to a set of specific transaction groups.
- *
- * @param array $groupIds
- *
- * @return GroupCollectorInterface
*/
public function setIds(array $groupIds): GroupCollectorInterface
{
@@ -947,17 +873,13 @@ class GroupCollector implements GroupCollectorInterface
/**
* Limit the result to a set of specific journals.
- *
- * @param array $journalIds
- *
- * @return GroupCollectorInterface
*/
public function setJournalIds(array $journalIds): GroupCollectorInterface
{
if (0 !== count($journalIds)) {
// make all integers.
$integerIDs = array_map('intval', $journalIds);
-
+ Log::debug(sprintf('GroupCollector: setJournalIds: %s', implode(', ', $integerIDs)));
$this->query->whereIn('transaction_journals.id', $integerIDs);
}
@@ -967,26 +889,18 @@ class GroupCollector implements GroupCollectorInterface
/**
* Set the page to get.
- *
- * @param int $page
- *
- * @return GroupCollectorInterface
*/
public function setPage(int $page): GroupCollectorInterface
{
$page = 0 === $page ? 1 : $page;
$this->page = $page;
- //app('log')->debug(sprintf('GroupCollector: page is now %d', $page));
+ // app('log')->debug(sprintf('GroupCollector: page is now %d', $page));
return $this;
}
/**
* Search for words in descriptions.
- *
- * @param array $array
- *
- * @return GroupCollectorInterface
*/
public function setSearchWords(array $array): GroupCollectorInterface
{
@@ -994,9 +908,9 @@ class GroupCollector implements GroupCollectorInterface
return $this;
}
$this->query->where(
- static function (EloquentBuilder $q) use ($array) {
+ static function (EloquentBuilder $q) use ($array): void { // @phpstan-ignore-line
$q->where(
- static function (EloquentBuilder $q1) use ($array) {
+ static function (EloquentBuilder $q1) use ($array): void {
foreach ($array as $word) {
$keyword = sprintf('%%%s%%', $word);
$q1->where('transaction_journals.description', 'LIKE', $keyword);
@@ -1004,7 +918,7 @@ class GroupCollector implements GroupCollectorInterface
}
);
$q->orWhere(
- static function (EloquentBuilder $q2) use ($array) {
+ static function (EloquentBuilder $q2) use ($array): void {
foreach ($array as $word) {
$keyword = sprintf('%%%s%%', $word);
$q2->where('transaction_groups.title', 'LIKE', $keyword);
@@ -1017,12 +931,15 @@ class GroupCollector implements GroupCollectorInterface
return $this;
}
+ public function setStartRow(int $startRow): self
+ {
+ $this->startRow = $startRow;
+
+ return $this;
+ }
+
/**
* Limit the search to one specific transaction group.
- *
- * @param TransactionGroup $transactionGroup
- *
- * @return GroupCollectorInterface
*/
public function setTransactionGroup(TransactionGroup $transactionGroup): GroupCollectorInterface
{
@@ -1033,10 +950,6 @@ class GroupCollector implements GroupCollectorInterface
/**
* Limit the included transaction types.
- *
- * @param array $types
- *
- * @return GroupCollectorInterface
*/
public function setTypes(array $types): GroupCollectorInterface
{
@@ -1047,10 +960,6 @@ class GroupCollector implements GroupCollectorInterface
/**
* Set the user object and start the query.
- *
- * @param User $user
- *
- * @return GroupCollectorInterface
*/
public function setUser(User $user): GroupCollectorInterface
{
@@ -1067,27 +976,29 @@ class GroupCollector implements GroupCollectorInterface
*/
private function startQuery(): void
{
- //app('log')->debug('GroupCollector::startQuery');
+ // app('log')->debug('GroupCollector::startQuery');
$this->query = $this->user
- //->transactionGroups()
- //->leftJoin('transaction_journals', 'transaction_journals.transaction_group_id', 'transaction_groups.id')
+ // ->transactionGroups()
+ // ->leftJoin('transaction_journals', 'transaction_journals.transaction_group_id', 'transaction_groups.id')
->transactionJournals()
->leftJoin('transaction_groups', 'transaction_journals.transaction_group_id', 'transaction_groups.id')
// join source transaction.
->leftJoin(
'transactions as source',
- function (JoinClause $join) {
+ static function (JoinClause $join): void {
$join->on('source.transaction_journal_id', '=', 'transaction_journals.id')
- ->where('source.amount', '<', 0);
+ ->where('source.amount', '<', 0)
+ ;
}
)
// join destination transaction
->leftJoin(
'transactions as destination',
- function (JoinClause $join) {
+ static function (JoinClause $join): void {
$join->on('destination.transaction_journal_id', '=', 'transaction_journals.id')
- ->where('destination.amount', '>', 0);
+ ->where('destination.amount', '>', 0)
+ ;
}
)
// left join transaction type.
@@ -1102,15 +1013,12 @@ class GroupCollector implements GroupCollectorInterface
->orderBy('transaction_journals.order', 'ASC')
->orderBy('transaction_journals.id', 'DESC')
->orderBy('transaction_journals.description', 'DESC')
- ->orderBy('source.amount', 'DESC');
+ ->orderBy('source.amount', 'DESC')
+ ;
}
/**
* Set the user object and start the query.
- *
- * @param User $user
- *
- * @return GroupCollectorInterface
*/
public function setUserGroup(UserGroup $userGroup): GroupCollectorInterface
{
@@ -1127,7 +1035,7 @@ class GroupCollector implements GroupCollectorInterface
*/
private function startQueryForGroup(): void
{
- //app('log')->debug('GroupCollector::startQuery');
+ // app('log')->debug('GroupCollector::startQuery');
$this->query = $this->userGroup
->transactionJournals()
->leftJoin('transaction_groups', 'transaction_journals.transaction_group_id', 'transaction_groups.id')
@@ -1135,17 +1043,19 @@ class GroupCollector implements GroupCollectorInterface
// join source transaction.
->leftJoin(
'transactions as source',
- function (JoinClause $join) {
+ static function (JoinClause $join): void {
$join->on('source.transaction_journal_id', '=', 'transaction_journals.id')
- ->where('source.amount', '<', 0);
+ ->where('source.amount', '<', 0)
+ ;
}
)
// join destination transaction
->leftJoin(
'transactions as destination',
- function (JoinClause $join) {
+ static function (JoinClause $join): void {
$join->on('destination.transaction_journal_id', '=', 'transaction_journals.id')
- ->where('destination.amount', '>', 0);
+ ->where('destination.amount', '>', 0)
+ ;
}
)
// left join transaction type.
@@ -1160,24 +1070,61 @@ class GroupCollector implements GroupCollectorInterface
->orderBy('transaction_journals.order', 'ASC')
->orderBy('transaction_journals.id', 'DESC')
->orderBy('transaction_journals.description', 'DESC')
- ->orderBy('source.amount', 'DESC');
+ ->orderBy('source.amount', 'DESC')
+ ;
}
/**
* Automatically include all stuff required to make API calls work.
- *
- * @return GroupCollectorInterface
*/
public function withAPIInformation(): GroupCollectorInterface
{
// include source + destination account name and type.
$this->withAccountInformation()
// include category ID + name (if any)
- ->withCategoryInformation()
+ ->withCategoryInformation()
// include budget ID + name (if any)
- ->withBudgetInformation()
+ ->withBudgetInformation()
// include bill ID + name (if any)
- ->withBillInformation();
+ ->withBillInformation()
+ ;
+
+ return $this;
+ }
+
+ #[\Override]
+ public function sortCollection(Collection $collection): Collection
+ {
+ /**
+ * @var string $field
+ * @var string $direction
+ */
+ foreach ($this->sorting as $field => $direction) {
+ $func = 'ASC' === $direction ? 'sortBy' : 'sortByDesc';
+ $collection = $collection->{$func}(function (array $product, int $key) use ($field) { // @phpstan-ignore-line
+ // depends on $field:
+ if ('description' === $field) {
+ if (1 === count($product['transactions'])) {
+ return array_values($product['transactions'])[0][$field];
+ }
+ if (count($product['transactions']) > 1) {
+ return $product['title'];
+ }
+
+ return 'zzz';
+ }
+
+ exit('here we are');
+ });
+ }
+
+ return $collection;
+ }
+
+ #[\Override]
+ public function setSorting(array $instructions): GroupCollectorInterface
+ {
+ $this->sorting = $instructions;
return $this;
}
diff --git a/app/Helpers/Collector/GroupCollectorInterface.php b/app/Helpers/Collector/GroupCollectorInterface.php
index 49880b7cf2..a77fb36adb 100644
--- a/app/Helpers/Collector/GroupCollectorInterface.php
+++ b/app/Helpers/Collector/GroupCollectorInterface.php
@@ -42,1504 +42,693 @@ interface GroupCollectorInterface
{
/**
* Get transactions with a specific amount.
- *
- * @param string $amount
- *
- * @return GroupCollectorInterface
*/
- public function amountIs(string $amount): GroupCollectorInterface;
+ public function amountIs(string $amount): self;
- /**
- * @param string $amount
- *
- * @return GroupCollectorInterface
- */
- public function amountIsNot(string $amount): GroupCollectorInterface;
+ public function amountIsNot(string $amount): self;
/**
* Get transactions where the amount is less than.
- *
- * @param string $amount
- *
- * @return GroupCollectorInterface
*/
- public function amountLess(string $amount): GroupCollectorInterface;
+ public function amountLess(string $amount): self;
/**
* Get transactions where the foreign amount is more than.
- *
- * @param string $amount
- *
- * @return GroupCollectorInterface
*/
- public function amountMore(string $amount): GroupCollectorInterface;
+ public function amountMore(string $amount): self;
- /**
- * @param string $name
- *
- * @return GroupCollectorInterface
- */
- public function attachmentNameContains(string $name): GroupCollectorInterface;
+ public function attachmentNameContains(string $name): self;
- /**
- * @param string $name
- *
- * @return GroupCollectorInterface
- */
- public function attachmentNameDoesNotContain(string $name): GroupCollectorInterface;
+ public function attachmentNameDoesNotContain(string $name): self;
- /**
- * @param string $name
- *
- * @return GroupCollectorInterface
- */
- public function attachmentNameDoesNotEnd(string $name): GroupCollectorInterface;
+ public function attachmentNameDoesNotEnd(string $name): self;
- /**
- * @param string $name
- *
- * @return GroupCollectorInterface
- */
- public function attachmentNameDoesNotStart(string $name): GroupCollectorInterface;
+ public function attachmentNameDoesNotStart(string $name): self;
- /**
- * @param string $name
- *
- * @return GroupCollectorInterface
- */
- public function attachmentNameEnds(string $name): GroupCollectorInterface;
+ public function attachmentNameEnds(string $name): self;
- /**
- * @param string $name
- *
- * @return GroupCollectorInterface
- */
- public function attachmentNameIs(string $name): GroupCollectorInterface;
+ public function attachmentNameIs(string $name): self;
- /**
- * @param string $name
- *
- * @return GroupCollectorInterface
- */
- public function attachmentNameIsNot(string $name): GroupCollectorInterface;
+ public function attachmentNameIsNot(string $name): self;
- /**
- * @param string $name
- *
- * @return GroupCollectorInterface
- */
- public function attachmentNameStarts(string $name): GroupCollectorInterface;
+ public function attachmentNameStarts(string $name): self;
- /**
- * @param string $value
- *
- * @return GroupCollectorInterface
- */
- public function attachmentNotesAre(string $value): GroupCollectorInterface;
+ public function attachmentNotesAre(string $value): self;
- /**
- * @param string $value
- *
- * @return GroupCollectorInterface
- */
- public function attachmentNotesAreNot(string $value): GroupCollectorInterface;
+ public function attachmentNotesAreNot(string $value): self;
- /**
- * @param string $value
- *
- * @return GroupCollectorInterface
- */
- public function attachmentNotesContains(string $value): GroupCollectorInterface;
+ public function attachmentNotesContains(string $value): self;
- /**
- * @param string $value
- *
- * @return GroupCollectorInterface
- */
- public function attachmentNotesDoNotContain(string $value): GroupCollectorInterface;
+ public function attachmentNotesDoNotContain(string $value): self;
- /**
- * @param string $value
- *
- * @return GroupCollectorInterface
- */
- public function attachmentNotesDoNotEnd(string $value): GroupCollectorInterface;
+ public function attachmentNotesDoNotEnd(string $value): self;
- /**
- * @param string $value
- *
- * @return GroupCollectorInterface
- */
- public function attachmentNotesDoNotStart(string $value): GroupCollectorInterface;
+ public function attachmentNotesDoNotStart(string $value): self;
- /**
- * @param string $value
- *
- * @return GroupCollectorInterface
- */
- public function attachmentNotesEnds(string $value): GroupCollectorInterface;
+ public function attachmentNotesEnds(string $value): self;
- /**
- * @param string $value
- *
- * @return GroupCollectorInterface
- */
- public function attachmentNotesStarts(string $value): GroupCollectorInterface;
+ public function attachmentNotesStarts(string $value): self;
- /**
- * @param string $day
- *
- * @return GroupCollectorInterface
- */
- public function dayAfter(string $day): GroupCollectorInterface;
+ public function dayAfter(string $day): self;
- /**
- * @param string $day
- *
- * @return GroupCollectorInterface
- */
- public function dayBefore(string $day): GroupCollectorInterface;
+ public function dayBefore(string $day): self;
- /**
- * @param string $day
- *
- * @return GroupCollectorInterface
- */
- public function dayIs(string $day): GroupCollectorInterface;
+ public function dayIs(string $day): self;
- /**
- * @param string $day
- *
- * @return GroupCollectorInterface
- */
- public function dayIsNot(string $day): GroupCollectorInterface;
+ public function dayIsNot(string $day): self;
/**
* End of the description must not match:
- *
- * @param array $array
- *
- * @return GroupCollectorInterface
*/
- public function descriptionDoesNotEnd(array $array): GroupCollectorInterface;
+ public function descriptionDoesNotEnd(array $array): self;
/**
* Beginning of the description must not start with:
- *
- * @param array $array
- *
- * @return GroupCollectorInterface
*/
- public function descriptionDoesNotStart(array $array): GroupCollectorInterface;
+ public function descriptionDoesNotStart(array $array): self;
/**
* End of the description must match:
- *
- * @param array $array
- *
- * @return GroupCollectorInterface
*/
- public function descriptionEnds(array $array): GroupCollectorInterface;
+ public function descriptionEnds(array $array): self;
/**
* Description must be:
- *
- * @param string $value
- *
- * @return GroupCollectorInterface
*/
- public function descriptionIs(string $value): GroupCollectorInterface;
+ public function descriptionIs(string $value): self;
/**
* Description must not be:
- *
- * @param string $value
- *
- * @return GroupCollectorInterface
*/
- public function descriptionIsNot(string $value): GroupCollectorInterface;
+ public function descriptionIsNot(string $value): self;
/**
* Beginning of the description must match:
- *
- * @param array $array
- *
- * @return GroupCollectorInterface
*/
- public function descriptionStarts(array $array): GroupCollectorInterface;
+ public function descriptionStarts(array $array): self;
/**
* These accounts must not be accounts.
- *
- * @param Collection $accounts
- *
- * @return GroupCollectorInterface
*/
- public function excludeAccounts(Collection $accounts): GroupCollectorInterface;
+ public function excludeAccounts(Collection $accounts): self;
/**
* Exclude a specific set of bills
- *
- * @param Collection $bills
- *
- * @return GroupCollectorInterface
*/
- public function excludeBills(Collection $bills): GroupCollectorInterface;
+ public function excludeBills(Collection $bills): self;
/**
* Exclude a budget
- *
- * @param Budget $budget
- *
- * @return GroupCollectorInterface
*/
- public function excludeBudget(Budget $budget): GroupCollectorInterface;
+ public function excludeBudget(Budget $budget): self;
/**
* Exclude a budget.
- *
- * @param Collection $budgets
- *
- * @return GroupCollectorInterface
*/
- public function excludeBudgets(Collection $budgets): GroupCollectorInterface;
+ public function excludeBudgets(Collection $budgets): self;
/**
* Exclude a set of categories.
- *
- * @param Collection $categories
- *
- * @return GroupCollectorInterface
*/
- public function excludeCategories(Collection $categories): GroupCollectorInterface;
+ public function excludeCategories(Collection $categories): self;
/**
* Exclude a specific category
- *
- * @param Category $category
- *
- * @return GroupCollectorInterface
*/
- public function excludeCategory(Category $category): GroupCollectorInterface;
+ public function excludeCategory(Category $category): self;
/**
* Limit results to NOT a specific currency, either foreign or normal one.
- *
- * @param TransactionCurrency $currency
- *
- * @return GroupCollectorInterface
*/
- public function excludeCurrency(TransactionCurrency $currency): GroupCollectorInterface;
+ public function excludeCurrency(TransactionCurrency $currency): self;
/**
* Exclude destination accounts.
- *
- * @param Collection $accounts
- *
- * @return GroupCollectorInterface
*/
- public function excludeDestinationAccounts(Collection $accounts): GroupCollectorInterface;
+ public function excludeDestinationAccounts(Collection $accounts): self;
/**
* Look for specific external ID's.
- *
- * @param string $externalId
- *
- * @return GroupCollectorInterface
*/
- public function excludeExternalId(string $externalId): GroupCollectorInterface;
+ public function excludeExternalId(string $externalId): self;
- /**
- * @param string $url
- *
- * @return GroupCollectorInterface
- */
- public function excludeExternalUrl(string $url): GroupCollectorInterface;
+ public function excludeExternalUrl(string $url): self;
/**
* Limit results to exclude a specific foreign currency.
- *
- * @param TransactionCurrency $currency
- *
- * @return GroupCollectorInterface
*/
- public function excludeForeignCurrency(TransactionCurrency $currency): GroupCollectorInterface;
+ public function excludeForeignCurrency(TransactionCurrency $currency): self;
/**
* Limit the result to NOT a set of specific transaction groups.
- *
- * @param array $groupIds
- *
- * @return GroupCollectorInterface
*/
- public function excludeIds(array $groupIds): GroupCollectorInterface;
+ public function excludeIds(array $groupIds): self;
/**
* Look for specific external ID's.
- *
- * @param string $internalReference
- *
- * @return GroupCollectorInterface
*/
- public function excludeInternalReference(string $internalReference): GroupCollectorInterface;
+ public function excludeInternalReference(string $internalReference): self;
/**
* Limit the result to NOT a set of specific transaction journals.
- *
- * @param array $journalIds
- *
- * @return GroupCollectorInterface
*/
- public function excludeJournalIds(array $journalIds): GroupCollectorInterface;
+ public function excludeJournalIds(array $journalIds): self;
- /**
- * @param Carbon $start
- * @param Carbon $end
- * @param string $field
- *
- * @return GroupCollectorInterface
- */
- public function excludeMetaDateRange(Carbon $start, Carbon $end, string $field): GroupCollectorInterface;
+ public function excludeMetaDateRange(Carbon $start, Carbon $end, string $field): self;
- /**
- * @param Carbon $start
- * @param Carbon $end
- * @param string $field
- *
- * @return GroupCollectorInterface
- */
- public function excludeObjectRange(Carbon $start, Carbon $end, string $field): GroupCollectorInterface;
+ public function excludeObjectRange(Carbon $start, Carbon $end, string $field): self;
- /**
- * @param Carbon $start
- * @param Carbon $end
- *
- * @return GroupCollectorInterface
- */
- public function excludeRange(Carbon $start, Carbon $end): GroupCollectorInterface;
+ public function excludeRange(Carbon $start, Carbon $end): self;
- /**
- * @param string $recurringId
- *
- * @return GroupCollectorInterface
- */
- public function excludeRecurrenceId(string $recurringId): GroupCollectorInterface;
+ public function excludeRecurrenceId(string $recurringId): self;
/**
* Exclude words in descriptions.
- *
- * @param array $array
- *
- * @return GroupCollectorInterface
*/
- public function excludeSearchWords(array $array): GroupCollectorInterface;
+ public function excludeSearchWords(array $array): self;
/**
* These accounts must not be source accounts.
- *
- * @param Collection $accounts
- *
- * @return GroupCollectorInterface
*/
- public function excludeSourceAccounts(Collection $accounts): GroupCollectorInterface;
+ public function excludeSourceAccounts(Collection $accounts): self;
/**
* Limit the included transaction types.
- *
- * @param array $types
- *
- * @return GroupCollectorInterface
*/
- public function excludeTypes(array $types): GroupCollectorInterface;
+ public function excludeTypes(array $types): self;
- /**
- * @return GroupCollectorInterface
- */
- public function exists(): GroupCollectorInterface;
+ public function exists(): self;
- /**
- * @param string $externalId
- *
- * @return GroupCollectorInterface
- */
- public function externalIdContains(string $externalId): GroupCollectorInterface;
+ public function externalIdContains(string $externalId): self;
- /**
- * @param string $externalId
- *
- * @return GroupCollectorInterface
- */
- public function externalIdDoesNotContain(string $externalId): GroupCollectorInterface;
+ public function externalIdDoesNotContain(string $externalId): self;
- /**
- * @param string $externalId
- *
- * @return GroupCollectorInterface
- */
- public function externalIdDoesNotEnd(string $externalId): GroupCollectorInterface;
+ public function externalIdDoesNotEnd(string $externalId): self;
- /**
- * @param string $externalId
- *
- * @return GroupCollectorInterface
- */
- public function externalIdDoesNotStart(string $externalId): GroupCollectorInterface;
+ public function externalIdDoesNotStart(string $externalId): self;
- /**
- * @param string $externalId
- *
- * @return GroupCollectorInterface
- */
- public function externalIdEnds(string $externalId): GroupCollectorInterface;
+ public function externalIdEnds(string $externalId): self;
- /**
- * @param string $externalId
- *
- * @return GroupCollectorInterface
- */
- public function externalIdStarts(string $externalId): GroupCollectorInterface;
+ public function externalIdStarts(string $externalId): self;
- /**
- * @param string $url
- *
- * @return GroupCollectorInterface
- */
- public function externalUrlContains(string $url): GroupCollectorInterface;
+ public function externalUrlContains(string $url): self;
- /**
- * @param string $url
- *
- * @return GroupCollectorInterface
- */
- public function externalUrlDoesNotContain(string $url): GroupCollectorInterface;
+ public function externalUrlDoesNotContain(string $url): self;
- /**
- * @param string $url
- *
- * @return GroupCollectorInterface
- */
- public function externalUrlDoesNotEnd(string $url): GroupCollectorInterface;
+ public function externalUrlDoesNotEnd(string $url): self;
- /**
- * @param string $url
- *
- * @return GroupCollectorInterface
- */
- public function externalUrlDoesNotStart(string $url): GroupCollectorInterface;
+ public function externalUrlDoesNotStart(string $url): self;
- /**
- * @param string $url
- *
- * @return GroupCollectorInterface
- */
- public function externalUrlEnds(string $url): GroupCollectorInterface;
+ public function externalUrlEnds(string $url): self;
- /**
- * @param string $url
- *
- * @return GroupCollectorInterface
- */
- public function externalUrlStarts(string $url): GroupCollectorInterface;
+ public function externalUrlStarts(string $url): self;
/**
* Ensure the search will find nothing at all, zero results.
- *
- * @return GroupCollectorInterface
*/
- public function findNothing(): GroupCollectorInterface;
+ public function findNothing(): self;
/**
* Get transactions with a specific foreign amount.
- *
- * @param string $amount
- *
- * @return GroupCollectorInterface
*/
- public function foreignAmountIs(string $amount): GroupCollectorInterface;
+ public function foreignAmountIs(string $amount): self;
/**
* Get transactions with a specific foreign amount.
- *
- * @param string $amount
- *
- * @return GroupCollectorInterface
*/
- public function foreignAmountIsNot(string $amount): GroupCollectorInterface;
+ public function foreignAmountIsNot(string $amount): self;
/**
* Get transactions where the amount is less than.
- *
- * @param string $amount
- *
- * @return GroupCollectorInterface
*/
- public function foreignAmountLess(string $amount): GroupCollectorInterface;
+ public function foreignAmountLess(string $amount): self;
/**
* Get transactions where the foreign amount is more than.
- *
- * @param string $amount
- *
- * @return GroupCollectorInterface
*/
- public function foreignAmountMore(string $amount): GroupCollectorInterface;
+ public function foreignAmountMore(string $amount): self;
- /**
- * @return bool
- */
public function getExpandGroupSearch(): bool;
/**
* Return the transaction journals without group information. Is useful in some instances.
- *
- * @return array
*/
public function getExtractedJournals(): array;
/**
* Return the groups.
- *
- * @return Collection
*/
public function getGroups(): Collection;
/**
* Same as getGroups but everything is in a paginator.
- *
- * @return LengthAwarePaginator
*/
public function getPaginatedGroups(): LengthAwarePaginator;
+ public function setSorting(array $instructions): self;
+
/**
- * @return GroupCollectorInterface
+ * Sort the collection on a column.
*/
- public function hasAnyTag(): GroupCollectorInterface;
+ public function sortCollection(Collection $collection): Collection;
+
+ public function hasAnyTag(): self;
/**
* Has attachments
- *
- * @return GroupCollectorInterface
*/
- public function hasAttachments(): GroupCollectorInterface;
+ public function hasAttachments(): self;
/**
* Has no attachments
- *
- * @return GroupCollectorInterface
*/
- public function hasNoAttachments(): GroupCollectorInterface;
+ public function hasNoAttachments(): self;
- /**
- * @param string $internalReference
- *
- * @return GroupCollectorInterface
- */
- public function internalReferenceContains(string $internalReference): GroupCollectorInterface;
+ public function internalReferenceContains(string $internalReference): self;
- /**
- * @param string $internalReference
- *
- * @return GroupCollectorInterface
- */
- public function internalReferenceDoesNotContain(string $internalReference): GroupCollectorInterface;
+ public function internalReferenceDoesNotContain(string $internalReference): self;
- /**
- * @param string $internalReference
- *
- * @return GroupCollectorInterface
- */
- public function internalReferenceDoesNotEnd(string $internalReference): GroupCollectorInterface;
+ public function internalReferenceDoesNotEnd(string $internalReference): self;
- /**
- * @param string $internalReference
- *
- * @return GroupCollectorInterface
- */
- public function internalReferenceDoesNotStart(string $internalReference): GroupCollectorInterface;
+ public function internalReferenceDoesNotStart(string $internalReference): self;
- /**
- * @param string $internalReference
- *
- * @return GroupCollectorInterface
- */
- public function internalReferenceEnds(string $internalReference): GroupCollectorInterface;
+ public function internalReferenceEnds(string $internalReference): self;
- /**
- * @param string $internalReference
- *
- * @return GroupCollectorInterface
- */
- public function internalReferenceStarts(string $internalReference): GroupCollectorInterface;
+ public function internalReferenceStarts(string $internalReference): self;
/**
* Only journals that are reconciled.
- *
- * @return GroupCollectorInterface
*/
- public function isNotReconciled(): GroupCollectorInterface;
+ public function isNotReconciled(): self;
/**
* Only journals that are reconciled.
- *
- * @return GroupCollectorInterface
*/
- public function isReconciled(): GroupCollectorInterface;
+ public function isReconciled(): self;
- /**
- * @param string $day
- * @param string $field
- *
- * @return GroupCollectorInterface
- */
- public function metaDayAfter(string $day, string $field): GroupCollectorInterface;
+ public function metaDayAfter(string $day, string $field): self;
- /**
- * @param string $day
- * @param string $field
- *
- * @return GroupCollectorInterface
- */
- public function metaDayBefore(string $day, string $field): GroupCollectorInterface;
+ public function metaDayBefore(string $day, string $field): self;
- /**
- * @param string $day
- * @param string $field
- *
- * @return GroupCollectorInterface
- */
- public function metaDayIs(string $day, string $field): GroupCollectorInterface;
+ public function metaDayIs(string $day, string $field): self;
- /**
- * @param string $day
- * @param string $field
- *
- * @return GroupCollectorInterface
- */
- public function metaDayIsNot(string $day, string $field): GroupCollectorInterface;
+ public function metaDayIsNot(string $day, string $field): self;
- /**
- * @param string $month
- * @param string $field
- *
- * @return GroupCollectorInterface
- */
- public function metaMonthAfter(string $month, string $field): GroupCollectorInterface;
+ public function metaMonthAfter(string $month, string $field): self;
- /**
- * @param string $month
- * @param string $field
- *
- * @return GroupCollectorInterface
- */
- public function metaMonthBefore(string $month, string $field): GroupCollectorInterface;
+ public function metaMonthBefore(string $month, string $field): self;
- /**
- * @param string $month
- * @param string $field
- *
- * @return GroupCollectorInterface
- */
- public function metaMonthIs(string $month, string $field): GroupCollectorInterface;
+ public function metaMonthIs(string $month, string $field): self;
- /**
- * @param string $month
- * @param string $field
- *
- * @return GroupCollectorInterface
- */
- public function metaMonthIsNot(string $month, string $field): GroupCollectorInterface;
+ public function metaMonthIsNot(string $month, string $field): self;
- /**
- * @param string $year
- * @param string $field
- *
- * @return GroupCollectorInterface
- */
- public function metaYearAfter(string $year, string $field): GroupCollectorInterface;
+ public function metaYearAfter(string $year, string $field): self;
- /**
- * @param string $year
- * @param string $field
- *
- * @return GroupCollectorInterface
- */
- public function metaYearBefore(string $year, string $field): GroupCollectorInterface;
+ public function metaYearBefore(string $year, string $field): self;
- /**
- * @param string $year
- * @param string $field
- *
- * @return GroupCollectorInterface
- */
- public function metaYearIs(string $year, string $field): GroupCollectorInterface;
+ public function metaYearIs(string $year, string $field): self;
- /**
- * @param string $year
- * @param string $field
- *
- * @return GroupCollectorInterface
- */
- public function metaYearIsNot(string $year, string $field): GroupCollectorInterface;
+ public function metaYearIsNot(string $year, string $field): self;
- /**
- * @param string $month
- *
- * @return GroupCollectorInterface
- */
- public function monthAfter(string $month): GroupCollectorInterface;
+ public function monthAfter(string $month): self;
- /**
- * @param string $month
- *
- * @return GroupCollectorInterface
- */
- public function monthBefore(string $month): GroupCollectorInterface;
+ public function monthBefore(string $month): self;
- /**
- * @param string $month
- *
- * @return GroupCollectorInterface
- */
- public function monthIs(string $month): GroupCollectorInterface;
+ public function monthIs(string $month): self;
- /**
- * @param string $month
- *
- * @return GroupCollectorInterface
- */
- public function monthIsNot(string $month): GroupCollectorInterface;
+ public function monthIsNot(string $month): self;
- /**
- * @param string $value
- *
- * @return GroupCollectorInterface
- */
- public function notesContain(string $value): GroupCollectorInterface;
+ public function notesContain(string $value): self;
- /**
- * @param string $value
- *
- * @return GroupCollectorInterface
- */
- public function notesDoNotContain(string $value): GroupCollectorInterface;
+ public function notesDoNotContain(string $value): self;
- /**
- * @param string $value
- *
- * @return GroupCollectorInterface
- */
- public function notesDontEndWith(string $value): GroupCollectorInterface;
+ public function notesDontEndWith(string $value): self;
- /**
- * @param string $value
- *
- * @return GroupCollectorInterface
- */
- public function notesDontStartWith(string $value): GroupCollectorInterface;
+ public function notesDontStartWith(string $value): self;
- /**
- * @param string $value
- *
- * @return GroupCollectorInterface
- */
- public function notesEndWith(string $value): GroupCollectorInterface;
+ public function notesEndWith(string $value): self;
- /**
- * @param string $value
- *
- * @return GroupCollectorInterface
- */
- public function notesExactly(string $value): GroupCollectorInterface;
+ public function notesExactly(string $value): self;
- /**
- * @param string $value
- *
- * @return GroupCollectorInterface
- */
- public function notesExactlyNot(string $value): GroupCollectorInterface;
+ public function notesExactlyNot(string $value): self;
- /**
- * @param string $value
- *
- * @return GroupCollectorInterface
- */
- public function notesStartWith(string $value): GroupCollectorInterface;
+ public function notesStartWith(string $value): self;
- /**
- * @param string $day
- * @param string $field
- *
- * @return GroupCollectorInterface
- */
- public function objectDayAfter(string $day, string $field): GroupCollectorInterface;
+ public function objectDayAfter(string $day, string $field): self;
- /**
- * @param string $day
- * @param string $field
- *
- * @return GroupCollectorInterface
- */
- public function objectDayBefore(string $day, string $field): GroupCollectorInterface;
+ public function objectDayBefore(string $day, string $field): self;
- /**
- * @param string $day
- * @param string $field
- *
- * @return GroupCollectorInterface
- */
- public function objectDayIs(string $day, string $field): GroupCollectorInterface;
+ public function objectDayIs(string $day, string $field): self;
- /**
- * @param string $day
- * @param string $field
- *
- * @return GroupCollectorInterface
- */
- public function objectDayIsNot(string $day, string $field): GroupCollectorInterface;
+ public function objectDayIsNot(string $day, string $field): self;
- /**
- * @param string $month
- * @param string $field
- *
- * @return GroupCollectorInterface
- */
- public function objectMonthAfter(string $month, string $field): GroupCollectorInterface;
+ public function objectMonthAfter(string $month, string $field): self;
- /**
- * @param string $month
- * @param string $field
- *
- * @return GroupCollectorInterface
- */
- public function objectMonthBefore(string $month, string $field): GroupCollectorInterface;
+ public function objectMonthBefore(string $month, string $field): self;
- /**
- * @param string $month
- * @param string $field
- *
- * @return GroupCollectorInterface
- */
- public function objectMonthIs(string $month, string $field): GroupCollectorInterface;
+ public function objectMonthIs(string $month, string $field): self;
- /**
- * @param string $month
- * @param string $field
- *
- * @return GroupCollectorInterface
- */
- public function objectMonthIsNot(string $month, string $field): GroupCollectorInterface;
+ public function objectMonthIsNot(string $month, string $field): self;
- /**
- * @param string $year
- * @param string $field
- *
- * @return GroupCollectorInterface
- */
- public function objectYearAfter(string $year, string $field): GroupCollectorInterface;
+ public function objectYearAfter(string $year, string $field): self;
- /**
- * @param string $year
- * @param string $field
- *
- * @return GroupCollectorInterface
- */
- public function objectYearBefore(string $year, string $field): GroupCollectorInterface;
+ public function objectYearBefore(string $year, string $field): self;
- /**
- * @param string $year
- * @param string $field
- *
- * @return GroupCollectorInterface
- */
- public function objectYearIs(string $year, string $field): GroupCollectorInterface;
+ public function objectYearIs(string $year, string $field): self;
- /**
- * @param string $year
- * @param string $field
- *
- * @return GroupCollectorInterface
- */
- public function objectYearIsNot(string $year, string $field): GroupCollectorInterface;
+ public function objectYearIsNot(string $year, string $field): self;
/**
* Define which accounts can be part of the source and destination transactions.
- *
- * @param Collection $accounts
- *
- * @return GroupCollectorInterface
*/
- public function setAccounts(Collection $accounts): GroupCollectorInterface;
+ public function setAccounts(Collection $accounts): self;
/**
* Collect transactions after a specific date.
- *
- * @param Carbon $date
- *
- * @return GroupCollectorInterface
*/
- public function setAfter(Carbon $date): GroupCollectorInterface;
+ public function setAfter(Carbon $date): self;
+
+ /**
+ * Limit results to a SPECIFIC set of tags.
+ */
+ public function setAllTags(Collection $tags): self;
/**
* Collect transactions before a specific date.
- *
- * @param Carbon $date
- *
- * @return GroupCollectorInterface
*/
- public function setBefore(Carbon $date): GroupCollectorInterface;
+ public function setBefore(Carbon $date): self;
/**
* Limit the search to a specific bill.
- *
- * @param Bill $bill
- *
- * @return GroupCollectorInterface
*/
- public function setBill(Bill $bill): GroupCollectorInterface;
+ public function setBill(Bill $bill): self;
/**
* Limit the search to a specific set of bills.
- *
- * @param Collection $bills
- *
- * @return GroupCollectorInterface
*/
- public function setBills(Collection $bills): GroupCollectorInterface;
+ public function setBills(Collection $bills): self;
/**
* Both source AND destination must be in this list of accounts.
- *
- * @param Collection $accounts
- *
- * @return GroupCollectorInterface
*/
- public function setBothAccounts(Collection $accounts): GroupCollectorInterface;
+ public function setBothAccounts(Collection $accounts): self;
/**
* Limit the search to a specific budget.
- *
- * @param Budget $budget
- *
- * @return GroupCollectorInterface
*/
- public function setBudget(Budget $budget): GroupCollectorInterface;
+ public function setBudget(Budget $budget): self;
/**
* Limit the search to a specific set of budgets.
- *
- * @param Collection $budgets
- *
- * @return GroupCollectorInterface
*/
- public function setBudgets(Collection $budgets): GroupCollectorInterface;
+ public function setBudgets(Collection $budgets): self;
/**
* Limit the search to a specific bunch of categories.
- *
- * @param Collection $categories
- *
- * @return GroupCollectorInterface
*/
- public function setCategories(Collection $categories): GroupCollectorInterface;
+ public function setCategories(Collection $categories): self;
/**
* Limit the search to a specific category.
- *
- * @param Category $category
- *
- * @return GroupCollectorInterface
*/
- public function setCategory(Category $category): GroupCollectorInterface;
+ public function setCategory(Category $category): self;
/**
* Collect transactions created on a specific date.
- *
- * @param Carbon $date
- *
- * @return GroupCollectorInterface
*/
- public function setCreatedAt(Carbon $date): GroupCollectorInterface;
+ public function setCreatedAt(Carbon $date): self;
/**
* Limit results to a specific currency, either foreign or normal one.
- *
- * @param TransactionCurrency $currency
- *
- * @return GroupCollectorInterface
*/
- public function setCurrency(TransactionCurrency $currency): GroupCollectorInterface;
+ public function setCurrency(TransactionCurrency $currency): self;
/**
* Set destination accounts.
- *
- * @param Collection $accounts
- *
- * @return GroupCollectorInterface
*/
- public function setDestinationAccounts(Collection $accounts): GroupCollectorInterface;
+ public function setDestinationAccounts(Collection $accounts): self;
/**
* Set the end time of the results to return.
- *
- * @param Carbon $end
- *
- * @return GroupCollectorInterface
*/
- public function setEnd(Carbon $end): GroupCollectorInterface;
-
- /**
- * @param bool $expandGroupSearch
- */
- public function setExpandGroupSearch(bool $expandGroupSearch);
-
- /**
- * Look for specific external ID's.
- *
- * @param string $externalId
- *
- * @return GroupCollectorInterface
- */
- public function setExternalId(string $externalId): GroupCollectorInterface;
-
- /**
- * @param string $url
- *
- * @return GroupCollectorInterface
- */
- public function setExternalUrl(string $url): GroupCollectorInterface;
-
- /**
- * Limit results to a specific foreign currency.
- *
- * @param TransactionCurrency $currency
- *
- * @return GroupCollectorInterface
- */
- public function setForeignCurrency(TransactionCurrency $currency): GroupCollectorInterface;
-
- /**
- * Limit the result to a set of specific transaction groups.
- *
- * @param array $groupIds
- *
- * @return GroupCollectorInterface
- */
- public function setIds(array $groupIds): GroupCollectorInterface;
-
- /**
- * Look for specific external ID's.
- *
- * @param string $internalReference
- *
- * @return GroupCollectorInterface
- */
- public function setInternalReference(string $internalReference): GroupCollectorInterface;
-
- /**
- * Limit the result to a set of specific transaction journals.
- *
- * @param array $journalIds
- *
- * @return GroupCollectorInterface
- */
- public function setJournalIds(array $journalIds): GroupCollectorInterface;
-
- /**
- * Limit the number of returned entries.
- *
- * @param int $limit
- *
- * @return GroupCollectorInterface
- */
- public function setLimit(int $limit): GroupCollectorInterface;
-
- /**
- * Collect transactions after a specific date.
- *
- * @param Carbon $date
- * @param string $field
- *
- * @return GroupCollectorInterface
- */
- public function setMetaAfter(Carbon $date, string $field): GroupCollectorInterface;
-
- /**
- * Collect transactions before a specific date.
- *
- * @param Carbon $date
- * @param string $field
- *
- * @return GroupCollectorInterface
- */
- public function setMetaBefore(Carbon $date, string $field): GroupCollectorInterface;
-
- /**
- * Set the start and end time of the results to return, based on meta data.
- *
- * @param Carbon $start
- * @param Carbon $end
- * @param string $field
- *
- * @return GroupCollectorInterface
- */
- public function setMetaDateRange(Carbon $start, Carbon $end, string $field): GroupCollectorInterface;
-
- /**
- * Define which accounts can NOT be part of the source and destination transactions.
- *
- * @param Collection $accounts
- *
- * @return GroupCollectorInterface
- */
- public function setNotAccounts(Collection $accounts): GroupCollectorInterface;
-
- /**
- * @param Carbon $date
- * @param string $field
- *
- * @return GroupCollectorInterface
- */
- public function setObjectAfter(Carbon $date, string $field): GroupCollectorInterface;
-
- /**
- * @param Carbon $date
- * @param string $field
- *
- * @return GroupCollectorInterface
- */
- public function setObjectBefore(Carbon $date, string $field): GroupCollectorInterface;
-
- /**
- * @param Carbon $start
- * @param Carbon $end
- * @param string $field
- *
- * @return GroupCollectorInterface
- */
- public function setObjectRange(Carbon $start, Carbon $end, string $field): GroupCollectorInterface;
+ public function setEnd(Carbon $end): self;
/**
* Set the page to get.
- *
- * @param int $page
- *
- * @return GroupCollectorInterface
*/
- public function setPage(int $page): GroupCollectorInterface;
+ public function setEndRow(int $endRow): self;
+
+ public function setExpandGroupSearch(bool $expandGroupSearch): self;
+
+ /**
+ * Look for specific external ID's.
+ */
+ public function setExternalId(string $externalId): self;
+
+ public function setExternalUrl(string $url): self;
+
+ /**
+ * Limit results to a specific foreign currency.
+ */
+ public function setForeignCurrency(TransactionCurrency $currency): self;
+
+ /**
+ * Limit the result to a set of specific transaction groups.
+ */
+ public function setIds(array $groupIds): self;
+
+ /**
+ * Look for specific external ID's.
+ */
+ public function setInternalReference(string $internalReference): self;
+
+ /**
+ * Limit the result to a set of specific transaction journals.
+ */
+ public function setJournalIds(array $journalIds): self;
+
+ /**
+ * Limit the number of returned entries.
+ */
+ public function setLimit(int $limit): self;
+
+ /**
+ * Collect transactions after a specific date.
+ */
+ public function setMetaAfter(Carbon $date, string $field): self;
+
+ /**
+ * Collect transactions before a specific date.
+ */
+ public function setMetaBefore(Carbon $date, string $field): self;
+
+ /**
+ * Set the start and end time of the results to return, based on meta data.
+ */
+ public function setMetaDateRange(Carbon $start, Carbon $end, string $field): self;
+
+ /**
+ * Define which accounts can NOT be part of the source and destination transactions.
+ */
+ public function setNotAccounts(Collection $accounts): self;
+
+ public function setObjectAfter(Carbon $date, string $field): self;
+
+ public function setObjectBefore(Carbon $date, string $field): self;
+
+ public function setObjectRange(Carbon $start, Carbon $end, string $field): self;
+
+ /**
+ * Set the page to get.
+ */
+ public function setPage(int $page): self;
/**
* Set the start and end time of the results to return.
- *
- * @param Carbon $start
- * @param Carbon $end
- *
- * @return GroupCollectorInterface
*/
- public function setRange(Carbon $start, Carbon $end): GroupCollectorInterface;
+ public function setRange(Carbon $start, Carbon $end): self;
/**
* Look for specific recurring ID's.
- *
- * @param string $recurringId
- *
- * @return GroupCollectorInterface
*/
- public function setRecurrenceId(string $recurringId): GroupCollectorInterface;
+ public function setRecurrenceId(string $recurringId): self;
/**
* Search for words in descriptions.
- *
- * @param array $array
- *
- * @return GroupCollectorInterface
*/
- public function setSearchWords(array $array): GroupCollectorInterface;
+ public function setSearchWords(array $array): self;
- /**
- * @param string $sepaCT
- *
- * @return GroupCollectorInterface
- */
- public function setSepaCT(string $sepaCT): GroupCollectorInterface;
+ public function setSepaCT(string $sepaCT): self;
/**
* Set source accounts.
- *
- * @param Collection $accounts
- *
- * @return GroupCollectorInterface
*/
- public function setSourceAccounts(Collection $accounts): GroupCollectorInterface;
+ public function setSourceAccounts(Collection $accounts): self;
/**
* Set the start time of the results to return.
- *
- * @param Carbon $start
- *
- * @return GroupCollectorInterface
*/
- public function setStart(Carbon $start): GroupCollectorInterface;
+ public function setStart(Carbon $start): self;
+
+ /**
+ * Set the page to get.
+ */
+ public function setStartRow(int $startRow): self;
/**
* Limit results to a specific tag.
- *
- * @param Tag $tag
- *
- * @return GroupCollectorInterface
*/
- public function setTag(Tag $tag): GroupCollectorInterface;
+ public function setTag(Tag $tag): self;
/**
- * Limit results to a specific set of tags.
- *
- * @param Collection $tags
- *
- * @return GroupCollectorInterface
+ * Limit results to any of the specified tags.
*/
- public function setTags(Collection $tags): GroupCollectorInterface;
+ public function setTags(Collection $tags): self;
/**
* Limit the search to one specific transaction group.
- *
- * @param TransactionGroup $transactionGroup
- *
- * @return GroupCollectorInterface
*/
- public function setTransactionGroup(TransactionGroup $transactionGroup): GroupCollectorInterface;
+ public function setTransactionGroup(TransactionGroup $transactionGroup): self;
/**
* Limit the included transaction types.
- *
- * @param array $types
- *
- * @return GroupCollectorInterface
*/
- public function setTypes(array $types): GroupCollectorInterface;
+ public function setTypes(array $types): self;
/**
* Collect transactions updated on a specific date.
- *
- * @param Carbon $date
- *
- * @return GroupCollectorInterface
*/
- public function setUpdatedAt(Carbon $date): GroupCollectorInterface;
+ public function setUpdatedAt(Carbon $date): self;
/**
* Set the user object and start the query.
- *
- * @param User $user
- *
- * @return GroupCollectorInterface
*/
- public function setUser(User $user): GroupCollectorInterface;
+ public function setUser(User $user): self;
/**
* Set the user group object and start the query.
- *
- * @param UserGroup $userGroup
- *
- * @return GroupCollectorInterface
*/
- public function setUserGroup(UserGroup $userGroup): GroupCollectorInterface;
+ public function setUserGroup(UserGroup $userGroup): self;
/**
* Only when does not have these tags
- *
- * @param Collection $tags
- *
- * @return GroupCollectorInterface
*/
- public function setWithoutSpecificTags(Collection $tags): GroupCollectorInterface;
+ public function setWithoutSpecificTags(Collection $tags): self;
/**
* Either account can be set, but NOT both. This effectively excludes internal transfers.
- *
- * @param Collection $accounts
- *
- * @return GroupCollectorInterface
*/
- public function setXorAccounts(Collection $accounts): GroupCollectorInterface;
+ public function setXorAccounts(Collection $accounts): self;
/**
* Automatically include all stuff required to make API calls work.
- *
- * @return GroupCollectorInterface
*/
- public function withAPIInformation(): GroupCollectorInterface;
+ public function withAPIInformation(): self;
/**
* Will include the source and destination account names and types.
- *
- * @return GroupCollectorInterface
*/
- public function withAccountInformation(): GroupCollectorInterface;
+ public function withAccountInformation(): self;
/**
* Any notes, no matter what.
- *
- * @return GroupCollectorInterface
*/
- public function withAnyNotes(): GroupCollectorInterface;
+ public function withAnyNotes(): self;
/**
* Add basic info on attachments of transactions.
- *
- * @return GroupCollectorInterface
*/
- public function withAttachmentInformation(): GroupCollectorInterface;
+ public function withAttachmentInformation(): self;
/**
* Limit results to transactions without a bill..
- *
- * @return GroupCollectorInterface
*/
- public function withBill(): GroupCollectorInterface;
+ public function withBill(): self;
/**
* Include bill name + ID.
- *
- * @return GroupCollectorInterface
*/
- public function withBillInformation(): GroupCollectorInterface;
+ public function withBillInformation(): self;
/**
* Limit results to a transactions with a budget.
- *
- * @return GroupCollectorInterface
*/
- public function withBudget(): GroupCollectorInterface;
+ public function withBudget(): self;
/**
* Will include budget ID + name, if any.
- *
- * @return GroupCollectorInterface
*/
- public function withBudgetInformation(): GroupCollectorInterface;
+ public function withBudgetInformation(): self;
/**
* Limit results to a transactions with a category.
- *
- * @return GroupCollectorInterface
*/
- public function withCategory(): GroupCollectorInterface;
+ public function withCategory(): self;
/**
* Will include category ID + name, if any.
- *
- * @return GroupCollectorInterface
*/
- public function withCategoryInformation(): GroupCollectorInterface;
+ public function withCategoryInformation(): self;
/**
* Transactions with any external ID
- *
- * @return GroupCollectorInterface
*/
- public function withExternalId(): GroupCollectorInterface;
+ public function withExternalId(): self;
/**
* Transactions with any external URL
- *
- * @return GroupCollectorInterface
*/
- public function withExternalUrl(): GroupCollectorInterface;
+ public function withExternalUrl(): self;
/**
* Transaction must have meta date field X.
- *
- * @param string $field
- *
- * @return GroupCollectorInterface
*/
- public function withMetaDate(string $field): GroupCollectorInterface;
+ public function withMetaDate(string $field): self;
/**
* Will include notes.
- *
- * @return GroupCollectorInterface
*/
- public function withNotes(): GroupCollectorInterface;
+ public function withNotes(): self;
/**
* Add tag info.
- *
- * @return GroupCollectorInterface
*/
- public function withTagInformation(): GroupCollectorInterface;
+ public function withTagInformation(): self;
/**
* Limit results to a transactions without a bill.
- *
- * @return GroupCollectorInterface
*/
- public function withoutBill(): GroupCollectorInterface;
+ public function withoutBill(): self;
/**
* Limit results to a transactions without a budget.
- *
- * @return GroupCollectorInterface
*/
- public function withoutBudget(): GroupCollectorInterface;
+ public function withoutBudget(): self;
/**
* Limit results to a transactions without a category.
- *
- * @return GroupCollectorInterface
*/
- public function withoutCategory(): GroupCollectorInterface;
+ public function withoutCategory(): self;
/**
* Transactions without an external ID
- *
- * @return GroupCollectorInterface
*/
- public function withoutExternalId(): GroupCollectorInterface;
+ public function withoutExternalId(): self;
/**
* Transactions without an external URL
- *
- * @return GroupCollectorInterface
*/
- public function withoutExternalUrl(): GroupCollectorInterface;
+ public function withoutExternalUrl(): self;
- /**
- * @return GroupCollectorInterface
- */
- public function withoutNotes(): GroupCollectorInterface;
+ public function withoutNotes(): self;
- /**
- * @return GroupCollectorInterface
- */
- public function withoutTags(): GroupCollectorInterface;
+ public function withoutTags(): self;
- /**
- * @param string $year
- *
- * @return GroupCollectorInterface
- */
- public function yearAfter(string $year): GroupCollectorInterface;
+ public function yearAfter(string $year): self;
- /**
- * @param string $year
- *
- * @return GroupCollectorInterface
- */
- public function yearBefore(string $year): GroupCollectorInterface;
-
- /**
- * @param string $year
- *
- * @return GroupCollectorInterface
- */
- public function yearIs(string $year): GroupCollectorInterface;
-
- /**
- * @param string $year
- *
- * @return GroupCollectorInterface
- */
- public function yearIsNot(string $year): GroupCollectorInterface;
+ public function yearBefore(string $year): self;
+ public function yearIs(string $year): self;
+ public function yearIsNot(string $year): self;
}
diff --git a/app/Helpers/Fiscal/FiscalHelper.php b/app/Helpers/Fiscal/FiscalHelper.php
index a1c86ce9eb..c977bc773b 100644
--- a/app/Helpers/Fiscal/FiscalHelper.php
+++ b/app/Helpers/Fiscal/FiscalHelper.php
@@ -24,8 +24,6 @@ declare(strict_types=1);
namespace FireflyIII\Helpers\Fiscal;
use Carbon\Carbon;
-use Psr\Container\ContainerExceptionInterface;
-use Psr\Container\NotFoundExceptionInterface;
/**
* Class FiscalHelper.
@@ -44,15 +42,11 @@ class FiscalHelper implements FiscalHelperInterface
}
/**
- * @param Carbon $date
- *
* @return Carbon date object
- * @throws ContainerExceptionInterface
- * @throws NotFoundExceptionInterface
*/
public function endOfFiscalYear(Carbon $date): Carbon
{
- // Log::debug(sprintf('Now in endOfFiscalYear(%s).', $date->format('Y-m-d')));
+ // app('log')->debug(sprintf('Now in endOfFiscalYear(%s).', $date->format('Y-m-d')));
$endDate = $this->startOfFiscalYear($date);
if (true === $this->useCustomFiscalYear) {
// add 1 year and sub 1 day
@@ -62,17 +56,13 @@ class FiscalHelper implements FiscalHelperInterface
if (false === $this->useCustomFiscalYear) {
$endDate->endOfYear();
}
- // Log::debug(sprintf('Result of endOfFiscalYear(%s) = %s', $date->format('Y-m-d'), $endDate->format('Y-m-d')));
+ // app('log')->debug(sprintf('Result of endOfFiscalYear(%s) = %s', $date->format('Y-m-d'), $endDate->format('Y-m-d')));
return $endDate;
}
/**
- * @param Carbon $date
- *
* @return Carbon date object
- * @throws ContainerExceptionInterface
- * @throws NotFoundExceptionInterface
*/
public function startOfFiscalYear(Carbon $date): Carbon
{
@@ -80,7 +70,11 @@ class FiscalHelper implements FiscalHelperInterface
$startDate = clone $date;
if (true === $this->useCustomFiscalYear) {
$prefStartStr = app('preferences')->get('fiscalYearStart', '01-01')->data;
- [$mth, $day] = explode('-', $prefStartStr);
+ if (is_array($prefStartStr)) {
+ $prefStartStr = '01-01';
+ }
+ $prefStartStr = (string)$prefStartStr;
+ [$mth, $day] = explode('-', $prefStartStr);
$startDate->day((int)$day)->month((int)$mth);
// if start date is after passed date, sub 1 year.
@@ -92,7 +86,7 @@ class FiscalHelper implements FiscalHelperInterface
$startDate->startOfYear();
}
- // Log::debug(sprintf('Result of startOfFiscalYear(%s) = %s', $date->format('Y-m-d'), $startDate->format('Y-m-d')));
+ // app('log')->debug(sprintf('Result of startOfFiscalYear(%s) = %s', $date->format('Y-m-d'), $startDate->format('Y-m-d')));
return $startDate;
}
diff --git a/app/Helpers/Fiscal/FiscalHelperInterface.php b/app/Helpers/Fiscal/FiscalHelperInterface.php
index 957c6c36dd..5285048623 100644
--- a/app/Helpers/Fiscal/FiscalHelperInterface.php
+++ b/app/Helpers/Fiscal/FiscalHelperInterface.php
@@ -34,8 +34,6 @@ interface FiscalHelperInterface
* This method produces a clone of the Carbon date object passed, checks preferences
* and calculates the last day of the fiscal year.
*
- * @param Carbon $date
- *
* @return Carbon date object
*/
public function endOfFiscalYear(Carbon $date): Carbon;
@@ -44,8 +42,6 @@ interface FiscalHelperInterface
* This method produces a clone of the Carbon date object passed, checks preferences
* and calculates the first day of the fiscal year.
*
- * @param Carbon $date
- *
* @return Carbon date object
*/
public function startOfFiscalYear(Carbon $date): Carbon;
diff --git a/app/Helpers/Report/NetWorth.php b/app/Helpers/Report/NetWorth.php
index f8505c7321..1e39f98e65 100644
--- a/app/Helpers/Report/NetWorth.php
+++ b/app/Helpers/Report/NetWorth.php
@@ -29,14 +29,14 @@ use FireflyIII\Models\Account;
use FireflyIII\Models\AccountType;
use FireflyIII\Models\UserGroup;
use FireflyIII\Repositories\Account\AccountRepositoryInterface;
-use FireflyIII\Repositories\Currency\CurrencyRepositoryInterface;
use FireflyIII\Repositories\UserGroups\Account\AccountRepositoryInterface as AdminAccountRepositoryInterface;
+use FireflyIII\Repositories\UserGroups\Currency\CurrencyRepositoryInterface;
use FireflyIII\Support\CacheProperties;
use FireflyIII\Support\Http\Api\ExchangeRateConverter;
use FireflyIII\User;
use Illuminate\Contracts\Auth\Authenticatable;
use Illuminate\Support\Collection;
-use JsonException;
+use Illuminate\Support\Facades\Log;
/**
* This class can handle both request with and without a user group and will return the appropriate repository when
@@ -51,20 +51,21 @@ class NetWorth implements NetWorthInterface
private CurrencyRepositoryInterface $currencyRepos;
private User $user;
- private null | UserGroup $userGroup;
+ private ?UserGroup $userGroup;
/**
- * @param Collection $accounts
- * @param Carbon $date
+ * This method collects the user's net worth in ALL the user's currencies
+ * (1, 4 and 8) and also in the 'native' currency for ease of use.
+ *
+ * The set of accounts has to be fed to it.
*
- * @return array
* @throws FireflyException
*/
public function byAccounts(Collection $accounts, Carbon $date): array
{
// start in the past, end in the future? use $date
- $ids = implode(',', $accounts->pluck('id')->toArray());
- $cache = new CacheProperties();
+ $ids = implode(',', $accounts->pluck('id')->toArray());
+ $cache = new CacheProperties();
$cache->addProperty($date);
$cache->addProperty('net-worth-by-accounts');
$cache->addProperty($ids);
@@ -72,188 +73,102 @@ class NetWorth implements NetWorthInterface
return $cache->get();
}
app('log')->debug(sprintf('Now in byAccounts("%s", "%s")', $ids, $date->format('Y-m-d')));
-
+ Log::debug(sprintf('Created new ExchangeRateConverter in %s', __METHOD__));
$default = app('amount')->getDefaultCurrency();
$converter = new ExchangeRateConverter();
// default "native" currency has everything twice, for consistency.
- $netWorth = [
+ $netWorth = [
'native' => [
- 'balance' => '0',
- 'native_balance' => '0',
- 'currency_id' => (int)$default->id,
- 'currency_code' => $default->code,
- 'currency_name' => $default->name,
- 'currency_symbol' => $default->symbol,
- 'currency_decimal_places' => (int)$default->decimal_places,
- 'native_id' => (int)$default->id,
- 'native_code' => $default->code,
- 'native_name' => $default->name,
- 'native_symbol' => $default->symbol,
- 'native_decimal_places' => (int)$default->decimal_places,
+ 'balance' => '0',
+ 'native_balance' => '0',
+ 'currency_id' => $default->id,
+ 'currency_code' => $default->code,
+ 'currency_name' => $default->name,
+ 'currency_symbol' => $default->symbol,
+ 'currency_decimal_places' => $default->decimal_places,
+ 'native_currency_id' => $default->id,
+ 'native_currency_code' => $default->code,
+ 'native_currency_name' => $default->name,
+ 'native_currency_symbol' => $default->symbol,
+ 'native_currency_decimal_places' => $default->decimal_places,
],
];
- $balances = app('steam')->balancesByAccountsConverted($accounts, $date);
+ $balances = app('steam')->balancesByAccountsConverted($accounts, $date);
/** @var Account $account */
foreach ($accounts as $account) {
app('log')->debug(sprintf('Now at account #%d ("%s")', $account->id, $account->name));
- $currency = $this->getRepository()->getAccountCurrency($account);
- $currencyId = (int)$currency->id;
- $balance = '0';
- $nativeBalance = '0';
- if (array_key_exists((int)$account->id, $balances)) {
- $balance = $balances[(int)$account->id]['balance'] ?? '0';
- $nativeBalance = $balances[(int)$account->id]['native_balance'] ?? '0';
+ $currency = $this->getRepository()->getAccountCurrency($account);
+ if (null === $currency) {
+ $currency = app('amount')->getDefaultCurrency();
+ }
+ $currencyCode = $currency->code;
+ $balance = '0';
+ $nativeBalance = '0';
+ if (array_key_exists($account->id, $balances)) {
+ $balance = $balances[$account->id]['balance'] ?? '0';
+ $nativeBalance = $balances[$account->id]['native_balance'] ?? '0';
}
app('log')->debug(sprintf('Balance is %s, native balance is %s', $balance, $nativeBalance));
// always subtract virtual balance
- $virtualBalance = (string)$account->virtual_balance;
+ $virtualBalance = $account->virtual_balance;
if ('' !== $virtualBalance) {
$balance = bcsub($balance, $virtualBalance);
$nativeVirtualBalance = $converter->convert($default, $currency, $account->created_at, $virtualBalance);
$nativeBalance = bcsub($nativeBalance, $nativeVirtualBalance);
}
- $netWorth[$currencyId] = $netWorth[$currencyId] ?? [
- 'balance' => '0',
- 'native_balance' => '0',
- 'currency_id' => $currencyId,
- 'currency_code' => $currency->code,
- 'currency_name' => $currency->name,
- 'currency_symbol' => $currency->symbol,
- 'currency_decimal_places' => (int)$currency->decimal_places,
- 'native_id' => (int)$default->id,
- 'native_code' => $default->code,
- 'native_name' => $default->name,
- 'native_symbol' => $default->symbol,
- 'native_decimal_places' => (int)$default->decimal_places,
+ $netWorth[$currencyCode] ??= [
+ 'balance' => '0',
+ 'native_balance' => '0',
+ 'currency_id' => (string)$currency->id,
+ 'currency_code' => $currency->code,
+ 'currency_name' => $currency->name,
+ 'currency_symbol' => $currency->symbol,
+ 'currency_decimal_places' => $currency->decimal_places,
+ 'native_currency_id' => (string)$default->id,
+ 'native_currency_code' => $default->code,
+ 'native_currency_name' => $default->name,
+ 'native_currency_symbol' => $default->symbol,
+ 'native_currency_decimal_places' => $default->decimal_places,
];
- $netWorth[$currencyId]['balance'] = bcadd($balance, $netWorth[$currencyId]['balance']);
- $netWorth[$currencyId]['native_balance'] = bcadd($nativeBalance, $netWorth[$currencyId]['native_balance']);
- $netWorth['native']['balance'] = bcadd($nativeBalance, $netWorth['native']['balance']);
- $netWorth['native']['native_balance'] = bcadd($nativeBalance, $netWorth['native']['native_balance']);
+ $netWorth[$currencyCode]['balance'] = bcadd($balance, $netWorth[$currencyCode]['balance']);
+ $netWorth[$currencyCode]['native_balance'] = bcadd($nativeBalance, $netWorth[$currencyCode]['native_balance']);
+ $netWorth['native']['balance'] = bcadd($nativeBalance, $netWorth['native']['balance']);
+ $netWorth['native']['native_balance'] = bcadd($nativeBalance, $netWorth['native']['native_balance']);
}
$cache->store($netWorth);
+ $converter->summarize();
return $netWorth;
}
- /**
- * @return AdminAccountRepositoryInterface|AccountRepositoryInterface
- */
- private function getRepository(): AdminAccountRepositoryInterface | AccountRepositoryInterface
+ private function getRepository(): AccountRepositoryInterface|AdminAccountRepositoryInterface
{
if (null === $this->userGroup) {
return $this->accountRepository;
}
+
return $this->adminAccountRepository;
}
- /**
- * Returns the user's net worth in an array with the following layout:
- *
- * -
- * - currency: TransactionCurrency object
- * - date: the current date
- * - amount: the user's net worth in that currency.
- *
- * This repeats for each currency the user has transactions in.
- * Result of this method is cached.
- *
- * @param Collection $accounts
- * @param Carbon $date
- *
- * @return array
- * @throws JsonException
- * @throws FireflyException
- * @deprecated
- */
- public function getNetWorthByCurrency(Collection $accounts, Carbon $date): array
+ public function setUser(null|Authenticatable|User $user): void
{
- // start in the past, end in the future? use $date
- $cache = new CacheProperties();
- $cache->addProperty($date);
- $cache->addProperty('net-worth-by-currency');
- $cache->addProperty(implode(',', $accounts->pluck('id')->toArray()));
- if ($cache->has()) {
- return $cache->get();
- }
-
- $netWorth = [];
- $result = [];
- // Log::debug(sprintf('Now in getNetWorthByCurrency(%s)', $date->format('Y-m-d')));
-
- // get default currency
- $default = app('amount')->getDefaultCurrencyByUser($this->user);
-
- // get all balances:
- $balances = app('steam')->balancesByAccounts($accounts, $date);
-
- // get the preferred currency for this account
- /** @var Account $account */
- foreach ($accounts as $account) {
- // Log::debug(sprintf('Now at account #%d: "%s"', $account->id, $account->name));
- $currencyId = (int)$this->getRepository()->getMetaValue($account, 'currency_id');
- $currencyId = 0 === $currencyId ? $default->id : $currencyId;
-
- // Log::debug(sprintf('Currency ID is #%d', $currencyId));
-
- // balance in array:
- $balance = $balances[$account->id] ?? '0';
-
- //Log::debug(sprintf('Balance for %s is %s', $date->format('Y-m-d'), $balance));
-
- // always subtract virtual balance.
- $virtualBalance = (string)$account->virtual_balance;
- if ('' !== $virtualBalance) {
- $balance = bcsub($balance, $virtualBalance);
- }
-
- // Log::debug(sprintf('Balance corrected to %s because of virtual balance (%s)', $balance, $virtualBalance));
-
- if (!array_key_exists($currencyId, $netWorth)) {
- $netWorth[$currencyId] = '0';
- }
- $netWorth[$currencyId] = bcadd($balance, $netWorth[$currencyId]);
- // Log::debug(sprintf('Total net worth for currency #%d is %s', $currencyId, $netWorth[$currencyId]));
- }
- ksort($netWorth);
-
- // loop results and add currency information:
- foreach ($netWorth as $currencyId => $balance) {
- $result[] = [
- 'currency' => $this->currencyRepos->find($currencyId),
- 'balance' => $balance,
- ];
- }
- $cache->store($result);
-
- return $result;
- }
-
- /**
- * @param User|Authenticatable|null $user
- */
- public function setUser(User | Authenticatable | null $user): void
- {
- if (null === $user) {
+ if (!$user instanceof User) {
return;
}
- $this->user = $user;
- $this->userGroup = null;
+ $this->user = $user;
+ $this->userGroup = null;
// make repository:
$this->accountRepository = app(AccountRepositoryInterface::class);
$this->accountRepository->setUser($this->user);
- $this->currencyRepos = app(CurrencyRepositoryInterface::class);
+ $this->currencyRepos = app(CurrencyRepositoryInterface::class);
$this->currencyRepos->setUser($this->user);
}
- /**
- * @inheritDoc
- */
public function setUserGroup(UserGroup $userGroup): void
{
$this->userGroup = $userGroup;
@@ -262,7 +177,7 @@ class NetWorth implements NetWorthInterface
}
/**
- * @inheritDoc
+ * @deprecated
*/
public function sumNetWorthByCurrency(Carbon $date): array
{
@@ -273,16 +188,16 @@ class NetWorth implements NetWorthInterface
$return = [];
$balances = app('steam')->balancesByAccounts($accounts, $date);
foreach ($accounts as $account) {
- $currency = $this->getRepository()->getAccountCurrency($account);
- $balance = $balances[$account->id] ?? '0';
+ $currency = $this->getRepository()->getAccountCurrency($account);
+ $balance = $balances[$account->id] ?? '0';
// always subtract virtual balance.
- $virtualBalance = (string)$account->virtual_balance;
+ $virtualBalance = $account->virtual_balance;
if ('' !== $virtualBalance) {
$balance = bcsub($balance, $virtualBalance);
}
- $return[$currency->id] = $return[$currency->id] ?? [
+ $return[$currency->id] ??= [
'id' => (string)$currency->id,
'name' => $currency->name,
'symbol' => $currency->symbol,
@@ -296,21 +211,20 @@ class NetWorth implements NetWorthInterface
return $return;
}
- /**
- * @return Collection
- */
private function getAccounts(): Collection
{
$accounts = $this->getRepository()->getAccountsByType(
[AccountType::ASSET, AccountType::DEFAULT, AccountType::LOAN, AccountType::DEBT, AccountType::MORTGAGE]
);
$filtered = new Collection();
+
/** @var Account $account */
foreach ($accounts as $account) {
if (1 === (int)$this->getRepository()->getMetaValue($account, 'include_net_worth')) {
$filtered->push($account);
}
}
+
return $filtered;
}
}
diff --git a/app/Helpers/Report/NetWorthInterface.php b/app/Helpers/Report/NetWorthInterface.php
index 61f4c9455c..0713f52c6a 100644
--- a/app/Helpers/Report/NetWorthInterface.php
+++ b/app/Helpers/Report/NetWorthInterface.php
@@ -31,7 +31,6 @@ use Illuminate\Support\Collection;
/**
* Interface NetWorthInterface
- *
*/
interface NetWorthInterface
{
@@ -42,43 +41,11 @@ interface NetWorthInterface
* of that amount in the native currency.
*
* Includes extra array with the total(!) net worth in the native currency.
- *
- * @param Collection $accounts
- * @param Carbon $date
- *
- * @return array
*/
public function byAccounts(Collection $accounts, Carbon $date): array;
- /**
- * TODO unsure why this is deprecated.
- *
- * Returns the user's net worth in an array with the following layout:
- *
- * -
- * - currency: TransactionCurrency object
- * - date: the current date
- * - amount: the user's net worth in that currency.
- *
- * This repeats for each currency the user has transactions in.
- * Result of this method is cached.
- *
- * @param Collection $accounts
- * @param Carbon $date
- *
- * @return array
- * @deprecated
- */
- public function getNetWorthByCurrency(Collection $accounts, Carbon $date): array;
+ public function setUser(null|Authenticatable|User $user): void;
- /**
- * @param User|Authenticatable|null $user
- */
- public function setUser(User | Authenticatable | null $user): void;
-
- /**
- * @param UserGroup $userGroup
- */
public function setUserGroup(UserGroup $userGroup): void;
/**
@@ -86,9 +53,7 @@ interface NetWorthInterface
*
* Same as above but cleaner function with less dependencies.
*
- * @param Carbon $date
- *
- * @return array
+ * @deprecated
*/
public function sumNetWorthByCurrency(Carbon $date): array;
}
diff --git a/app/Helpers/Report/PopupReport.php b/app/Helpers/Report/PopupReport.php
index 94b56ac7fd..e5276d6161 100644
--- a/app/Helpers/Report/PopupReport.php
+++ b/app/Helpers/Report/PopupReport.php
@@ -29,46 +29,34 @@ use FireflyIII\Models\Budget;
use FireflyIII\Models\Category;
use FireflyIII\Models\TransactionType;
use FireflyIII\Repositories\Account\AccountRepositoryInterface;
-use FireflyIII\Repositories\Currency\CurrencyRepositoryInterface;
use FireflyIII\Repositories\Journal\JournalRepositoryInterface;
+use FireflyIII\Repositories\UserGroups\Currency\CurrencyRepositoryInterface;
use Illuminate\Support\Collection;
/**
* Class PopupReport.
- *
-
*/
class PopupReport implements PopupReportInterface
{
/**
* Collect the transactions for one account and one budget.
- *
- * @param Budget $budget
- * @param Account $account
- * @param array $attributes
- *
- * @return array
*/
public function balanceForBudget(Budget $budget, Account $account, array $attributes): array
{
/** @var GroupCollectorInterface $collector */
$collector = app(GroupCollectorInterface::class);
$collector->setAccounts(new Collection([$account]))
- ->withAccountInformation()
- ->withBudgetInformation()
- ->withCategoryInformation()
- ->setRange($attributes['startDate'], $attributes['endDate'])->setBudget($budget);
+ ->withAccountInformation()
+ ->withBudgetInformation()
+ ->withCategoryInformation()
+ ->setRange($attributes['startDate'], $attributes['endDate'])->setBudget($budget)
+ ;
return $collector->getExtractedJournals();
}
/**
* Collect the transactions for one account and no budget.
- *
- * @param Account $account
- * @param array $attributes
- *
- * @return array
*/
public function balanceForNoBudget(Account $account, array $attributes): array
{
@@ -80,15 +68,17 @@ class PopupReport implements PopupReportInterface
$repos = app(CurrencyRepositoryInterface::class);
$currency = $repos->find((int)$currencyId);
}
+
/** @var GroupCollectorInterface $collector */
- $collector = app(GroupCollectorInterface::class);
+ $collector = app(GroupCollectorInterface::class);
$collector
->setAccounts(new Collection([$account]))
->setTypes([TransactionType::WITHDRAWAL])
->withAccountInformation()
->withCategoryInformation()
->setRange($attributes['startDate'], $attributes['endDate'])
- ->withoutBudget();
+ ->withoutBudget()
+ ;
if (null !== $currency) {
$collector->setCurrency($currency);
@@ -99,11 +89,6 @@ class PopupReport implements PopupReportInterface
/**
* Collect the transactions for a budget.
- *
- * @param Budget $budget
- * @param array $attributes
- *
- * @return array
*/
public function byBudget(Budget $budget, array $attributes): array
{
@@ -115,13 +100,15 @@ class PopupReport implements PopupReportInterface
$repos = app(CurrencyRepositoryInterface::class);
$currency = $repos->find((int)$currencyId);
}
+
/** @var GroupCollectorInterface $collector */
- $collector = app(GroupCollectorInterface::class);
+ $collector = app(GroupCollectorInterface::class);
$collector->setAccounts($attributes['accounts'])
- ->withAccountInformation()
- ->withBudgetInformation()
- ->withCategoryInformation()
- ->setRange($attributes['startDate'], $attributes['endDate']);
+ ->withAccountInformation()
+ ->withBudgetInformation()
+ ->withCategoryInformation()
+ ->setRange($attributes['startDate'], $attributes['endDate'])
+ ;
if (null !== $currency) {
$collector->setCurrency($currency);
@@ -139,11 +126,6 @@ class PopupReport implements PopupReportInterface
/**
* Collect journals by a category.
- *
- * @param Category|null $category
- * @param array $attributes
- *
- * @return array
*/
public function byCategory(?Category $category, array $attributes): array
{
@@ -157,14 +139,15 @@ class PopupReport implements PopupReportInterface
}
/** @var GroupCollectorInterface $collector */
- $collector = app(GroupCollectorInterface::class);
+ $collector = app(GroupCollectorInterface::class);
$collector->setAccounts($attributes['accounts'])
- ->setTypes([TransactionType::WITHDRAWAL, TransactionType::TRANSFER, TransactionType::DEPOSIT])
- ->withAccountInformation()
- ->withBudgetInformation()
- ->withCategoryInformation()
- ->setRange($attributes['startDate'], $attributes['endDate'])->withAccountInformation();
+ ->setTypes([TransactionType::WITHDRAWAL, TransactionType::TRANSFER, TransactionType::DEPOSIT])
+ ->withAccountInformation()
+ ->withBudgetInformation()
+ ->withCategoryInformation()
+ ->setRange($attributes['startDate'], $attributes['endDate'])->withAccountInformation()
+ ;
if (null !== $category) {
$collector->setCategory($category);
@@ -182,17 +165,12 @@ class PopupReport implements PopupReportInterface
/**
* Group transactions by expense.
- *
- * @param Account $account
- * @param array $attributes
- *
- * @return array
*/
public function byExpenses(Account $account, array $attributes): array
{
// filter by currency, if set.
- $currencyId = $attributes['currencyId'] ?? null;
- $currency = null;
+ $currencyId = $attributes['currencyId'] ?? null;
+ $currency = null;
if (null !== $currencyId) {
/** @var CurrencyRepositoryInterface $repos */
$repos = app(CurrencyRepositoryInterface::class);
@@ -200,47 +178,45 @@ class PopupReport implements PopupReportInterface
}
/** @var JournalRepositoryInterface $repository */
- $repository = app(JournalRepositoryInterface::class);
+ $repository = app(JournalRepositoryInterface::class);
$repository->setUser($account->user);
$accountRepository = app(AccountRepositoryInterface::class);
$accountRepository->setUser($account->user);
/** @var GroupCollectorInterface $collector */
- $collector = app(GroupCollectorInterface::class);
+ $collector = app(GroupCollectorInterface::class);
// set report accounts + the request accounts:
- //$set = $attributes['accounts'] ?? new Collection;
- //$set->push($account);
+ // $set = $attributes['accounts'] ?? new Collection;
+ // $set->push($account);
$collector->setDestinationAccounts(new Collection([$account]))
- ->setRange($attributes['startDate'], $attributes['endDate'])
- ->withAccountInformation()
- ->withBudgetInformation()
- ->withCategoryInformation()
- ->setTypes([TransactionType::WITHDRAWAL, TransactionType::TRANSFER]);
+ ->setRange($attributes['startDate'], $attributes['endDate'])
+ ->withAccountInformation()
+ ->withBudgetInformation()
+ ->withCategoryInformation()
+ ->setTypes([TransactionType::WITHDRAWAL, TransactionType::TRANSFER])
+ ;
if (null !== $currency) {
$collector->setCurrency($currency);
}
+
return $collector->getExtractedJournals();
}
/**
* Collect transactions by income.
- *
- * @param Account $account
- * @param array $attributes
- *
- * @return array
*/
public function byIncome(Account $account, array $attributes): array
{
/** @var JournalRepositoryInterface $repository */
$repository = app(JournalRepositoryInterface::class);
$repository->setUser($account->user);
+
/** @var GroupCollectorInterface $collector */
- $collector = app(GroupCollectorInterface::class);
+ $collector = app(GroupCollectorInterface::class);
$collector
->setSourceAccounts(new Collection([$account]))
->setDestinationAccounts($attributes['accounts'])
@@ -249,7 +225,8 @@ class PopupReport implements PopupReportInterface
->withAccountInformation()
->withBudgetInformation()
->withCategoryInformation()
- ->withAccountInformation();
+ ->withAccountInformation()
+ ;
return $collector->getExtractedJournals();
}
diff --git a/app/Helpers/Report/PopupReportInterface.php b/app/Helpers/Report/PopupReportInterface.php
index 311dfa8501..3a03cdb049 100644
--- a/app/Helpers/Report/PopupReportInterface.php
+++ b/app/Helpers/Report/PopupReportInterface.php
@@ -34,62 +34,31 @@ interface PopupReportInterface
{
/**
* Get balances for budget.
- *
- * @param Budget $budget
- * @param Account $account
- * @param array $attributes
- *
- * @return array
*/
public function balanceForBudget(Budget $budget, Account $account, array $attributes): array;
/**
* Get balances for transactions without a budget.
- *
- * @param Account $account
- * @param array $attributes
- *
- * @return array
*/
public function balanceForNoBudget(Account $account, array $attributes): array;
/**
* Group by budget.
- *
- * @param Budget $budget
- * @param array $attributes
- *
- * @return array
*/
public function byBudget(Budget $budget, array $attributes): array;
/**
* Group by category.
- *
- * @param Category|null $category
- * @param array $attributes
- *
- * @return array
*/
public function byCategory(?Category $category, array $attributes): array;
/**
* Do something with expense. Sorry, I am not very inspirational here.
- *
- * @param Account $account
- * @param array $attributes
- *
- * @return array
*/
public function byExpenses(Account $account, array $attributes): array;
/**
* Do something with income. Sorry, I am not very inspirational here.
- *
- * @param Account $account
- * @param array $attributes
- *
- * @return array
*/
public function byIncome(Account $account, array $attributes): array;
}
diff --git a/app/Helpers/Report/ReportHelper.php b/app/Helpers/Report/ReportHelper.php
index 92a9841d74..9582c7287d 100644
--- a/app/Helpers/Report/ReportHelper.php
+++ b/app/Helpers/Report/ReportHelper.php
@@ -33,8 +33,6 @@ use Illuminate\Support\Collection;
/**
* Class ReportHelper.
- *
-
*/
class ReportHelper implements ReportHelperInterface
{
@@ -43,8 +41,6 @@ class ReportHelper implements ReportHelperInterface
/**
* ReportHelper constructor.
- *
- * @param BudgetRepositoryInterface $budgetRepository
*/
public function __construct(BudgetRepositoryInterface $budgetRepository)
{
@@ -56,12 +52,6 @@ class ReportHelper implements ReportHelperInterface
* the users bills and their payments.
*
* Excludes bills which have not had a payment on the mentioned accounts.
- *
- * @param Carbon $start
- * @param Carbon $end
- * @param Collection $accounts
- *
- * @return array
*/
public function getBillReport(Collection $accounts, Carbon $start, Carbon $end): array
{
@@ -74,10 +64,10 @@ class ReportHelper implements ReportHelperInterface
/** @var Bill $bill */
foreach ($bills as $bill) {
- $expectedDates = $repository->getPayDatesInRange($bill, $start, $end);
- $billId = $bill->id;
- $currency = $bill->transactionCurrency;
- $current = [
+ $expectedDates = $repository->getPayDatesInRange($bill, $start, $end);
+ $billId = $bill->id;
+ $currency = $bill->transactionCurrency;
+ $current = [
'id' => $bill->id,
'name' => $bill->name,
'active' => $bill->active,
@@ -94,11 +84,11 @@ class ReportHelper implements ReportHelperInterface
/** @var Carbon $expectedStart */
foreach ($expectedDates as $expectedStart) {
- $expectedEnd = app('navigation')->endOfX($expectedStart, $bill->repeat_freq, null);
+ $expectedEnd = app('navigation')->endOfX($expectedStart, $bill->repeat_freq, null);
// is paid in this period maybe?
/** @var GroupCollectorInterface $collector */
- $collector = app(GroupCollectorInterface::class);
+ $collector = app(GroupCollectorInterface::class);
$collector->setAccounts($accounts)->setRange($expectedStart, $expectedEnd)->setBill($bill);
$current['paid_moments'][] = $collector->getExtractedJournals();
}
@@ -112,10 +102,6 @@ class ReportHelper implements ReportHelperInterface
/**
* Generate a list of months for the report.
- *
- * @param Carbon $date
- *
- * @return array
*/
public function listOfMonths(Carbon $date): array
{
@@ -123,12 +109,12 @@ class ReportHelper implements ReportHelperInterface
$fiscalHelper = app(FiscalHelperInterface::class);
$start = clone $date;
$start->startOfMonth();
- $end = today(config('app.timezone'));
+ $end = today(config('app.timezone'));
$end->endOfMonth();
- $months = [];
+ $months = [];
while ($start <= $end) {
- $year = $fiscalHelper->endOfFiscalYear($start)->year; // current year
+ $year = $fiscalHelper->endOfFiscalYear($start)->year; // current year
if (!array_key_exists($year, $months)) {
$months[$year] = [
'fiscal_start' => $fiscalHelper->startOfFiscalYear($start)->format('Y-m-d'),
@@ -139,7 +125,7 @@ class ReportHelper implements ReportHelperInterface
];
}
- $currentEnd = clone $start;
+ $currentEnd = clone $start;
$currentEnd->endOfMonth();
$months[$year]['months'][] = [
'formatted' => $start->isoFormat((string)trans('config.month_js')),
@@ -149,7 +135,7 @@ class ReportHelper implements ReportHelperInterface
'year' => $year,
];
- $start = clone $currentEnd; // to make the hop to the next month properly
+ $start = clone $currentEnd; // to make the hop to the next month properly
$start->addDay();
}
diff --git a/app/Helpers/Report/ReportHelperInterface.php b/app/Helpers/Report/ReportHelperInterface.php
index 6dfceaac77..1320127896 100644
--- a/app/Helpers/Report/ReportHelperInterface.php
+++ b/app/Helpers/Report/ReportHelperInterface.php
@@ -36,21 +36,11 @@ interface ReportHelperInterface
* the users bills and their payments.
*
* Excludes bills which have not had a payment on the mentioned accounts.
- *
- * @param Carbon $start
- * @param Carbon $end
- * @param Collection $accounts
- *
- * @return array
*/
public function getBillReport(Collection $accounts, Carbon $start, Carbon $end): array;
/**
* Generate a list of months.
- *
- * @param Carbon $date
- *
- * @return array
*/
public function listOfMonths(Carbon $date): array;
}
diff --git a/app/Helpers/Update/UpdateTrait.php b/app/Helpers/Update/UpdateTrait.php
index b5443da8de..acdc836917 100644
--- a/app/Helpers/Update/UpdateTrait.php
+++ b/app/Helpers/Update/UpdateTrait.php
@@ -24,13 +24,9 @@ declare(strict_types=1);
namespace FireflyIII\Helpers\Update;
use FireflyIII\Services\FireflyIIIOrg\Update\UpdateRequestInterface;
-use Illuminate\Support\Facades\Log;
-use Psr\Container\ContainerExceptionInterface;
-use Psr\Container\NotFoundExceptionInterface;
/**
* Trait UpdateTrait
- *
*/
trait UpdateTrait
{
@@ -38,18 +34,15 @@ trait UpdateTrait
* Returns an array with info on the next release, if any.
* 'message' => 'A new version is available.
* 'level' => 'info' / 'success' / 'error'
- *
- * @return array
- * @throws ContainerExceptionInterface
- * @throws NotFoundExceptionInterface
*/
public function getLatestRelease(): array
{
- Log::debug('Now in getLatestRelease()');
+ app('log')->debug('Now in getLatestRelease()');
+
/** @var UpdateRequestInterface $checker */
$checker = app(UpdateRequestInterface::class);
$channelConfig = app('fireflyconfig')->get('update_channel', 'stable');
- $channel = $channelConfig ? $channelConfig->data : 'stable';
+ $channel = (string)$channelConfig->data;
return $checker->getUpdateInformation($channel);
}
diff --git a/app/Helpers/Webhook/Sha3SignatureGenerator.php b/app/Helpers/Webhook/Sha3SignatureGenerator.php
index c51edf0a4f..dfa342af70 100644
--- a/app/Helpers/Webhook/Sha3SignatureGenerator.php
+++ b/app/Helpers/Webhook/Sha3SignatureGenerator.php
@@ -25,8 +25,6 @@ namespace FireflyIII\Helpers\Webhook;
use FireflyIII\Exceptions\FireflyException;
use FireflyIII\Models\WebhookMessage;
-use Illuminate\Support\Facades\Log;
-use JsonException;
/**
* Class Sha3SignatureGenerator
@@ -36,7 +34,6 @@ class Sha3SignatureGenerator implements SignatureGeneratorInterface
private int $version = 1;
/**
- * @inheritDoc
* @throws FireflyException
*/
public function generate(WebhookMessage $message): string
@@ -45,15 +42,16 @@ class Sha3SignatureGenerator implements SignatureGeneratorInterface
if (null === $message->webhook) {
throw new FireflyException('Part of a deleted webhook.');
}
-
+ $json = '';
try {
$json = json_encode($message->message, JSON_THROW_ON_ERROR);
- } catch (JsonException $e) {
- Log::error('Could not generate hash.');
- Log::error(sprintf('JSON value: %s', $json));
- Log::error($e->getMessage());
- Log::error($e->getTraceAsString());
+ } catch (\JsonException $e) {
+ app('log')->error('Could not generate hash.');
+ app('log')->error(sprintf('JSON value: %s', $json));
+ app('log')->error($e->getMessage());
+ app('log')->error($e->getTraceAsString());
+
throw new FireflyException('Could not generate JSON for SHA3 hash.', 0, $e);
}
@@ -74,9 +72,6 @@ class Sha3SignatureGenerator implements SignatureGeneratorInterface
return sprintf('t=%s,v%d=%s', $timestamp, $this->getVersion(), $signature);
}
- /**
- * @inheritDoc
- */
public function getVersion(): int
{
return $this->version;
diff --git a/app/Helpers/Webhook/SignatureGeneratorInterface.php b/app/Helpers/Webhook/SignatureGeneratorInterface.php
index ebbc8a5278..f3f46b2ad7 100644
--- a/app/Helpers/Webhook/SignatureGeneratorInterface.php
+++ b/app/Helpers/Webhook/SignatureGeneratorInterface.php
@@ -30,17 +30,10 @@ use FireflyIII\Models\WebhookMessage;
*/
interface SignatureGeneratorInterface
{
- /**
- * @param WebhookMessage $message
- *
- * @return string
- */
public function generate(WebhookMessage $message): string;
/**
* Return the version of this signature generator.
- *
- * @return int
*/
public function getVersion(): int;
}
diff --git a/app/Http/Controllers/Account/CreateController.php b/app/Http/Controllers/Account/CreateController.php
index ff88e40f5b..82e8b110e4 100644
--- a/app/Http/Controllers/Account/CreateController.php
+++ b/app/Http/Controllers/Account/CreateController.php
@@ -36,11 +36,8 @@ use Illuminate\Http\Request;
use Illuminate\Routing\Redirector;
use Illuminate\Support\Facades\Log;
use Illuminate\View\View;
-use Psr\Container\ContainerExceptionInterface;
-use Psr\Container\NotFoundExceptionInterface;
/**
- *
* Class CreateController
*/
class CreateController extends Controller
@@ -52,8 +49,6 @@ class CreateController extends Controller
/**
* CreateController constructor.
- *
-
*/
public function __construct()
{
@@ -76,9 +71,6 @@ class CreateController extends Controller
/**
* Create a new account.
*
- * @param Request $request
- * @param string $objectType
- *
* @return Factory|View
*/
public function create(Request $request, string $objectType)
@@ -103,7 +95,7 @@ class CreateController extends Controller
];
// interest calculation periods:
- $interestPeriods = [
+ $interestPeriods = [
'daily' => (string)trans('firefly.interest_calc_daily'),
'monthly' => (string)trans('firefly.interest_calc_monthly'),
'yearly' => (string)trans('firefly.interest_calc_yearly'),
@@ -117,6 +109,11 @@ class CreateController extends Controller
'include_net_worth' => $hasOldInput ? (bool)$request->old('include_net_worth') : true,
]
);
+ // issue #8321
+ $showNetWorth = true;
+ if ('liabilities' !== $objectType && 'asset' !== $objectType) {
+ $showNetWorth = false;
+ }
// put previous url in session if not redirect from store (not "create another").
if (true !== session('accounts.create.fromStore')) {
@@ -127,24 +124,21 @@ class CreateController extends Controller
return view(
'accounts.create',
- compact('subTitleIcon', 'liabilityDirections', 'locations', 'objectType', 'interestPeriods', 'subTitle', 'roles', 'liabilityTypes')
+ compact('subTitleIcon', 'liabilityDirections', 'showNetWorth', 'locations', 'objectType', 'interestPeriods', 'subTitle', 'roles', 'liabilityTypes')
);
}
/**
* Store the new account.
*
- * @param AccountFormRequest $request
+ * @return Redirector|RedirectResponse
*
- * @return RedirectResponse|Redirector
* @throws FireflyException
- * @throws ContainerExceptionInterface
- * @throws NotFoundExceptionInterface
*/
public function store(AccountFormRequest $request)
{
- $data = $request->getAccountData();
- $account = $this->repository->store($data);
+ $data = $request->getAccountData();
+ $account = $this->repository->store($data);
$request->session()->flash('success', (string)trans('firefly.stored_new_account', ['name' => $account->name]));
app('preferences')->mark();
@@ -152,18 +146,22 @@ class CreateController extends Controller
// update preferences if necessary:
$frontPage = app('preferences')->get('frontPageAccounts', [])->data;
+ if (!is_array($frontPage)) {
+ $frontPage = [];
+ }
if (AccountType::ASSET === $account->accountType->type) {
$frontPage[] = $account->id;
app('preferences')->set('frontPageAccounts', $frontPage);
}
// store attachment(s):
- /** @var array $files */
- $files = $request->hasFile('attachments') ? $request->file('attachments') : null;
+ /** @var null|array $files */
+ $files = $request->hasFile('attachments') ? $request->file('attachments') : null;
if (null !== $files && !auth()->user()->hasRole('demo')) {
$this->attachments->saveAttachmentsForModel($account, $files);
}
if (null !== $files && auth()->user()->hasRole('demo')) {
+ Log::channel('audit')->warning(sprintf('The demo user is trying to upload attachments in %s.', __METHOD__));
session()->flash('info', (string)trans('firefly.no_att_demo_user'));
}
@@ -172,7 +170,7 @@ class CreateController extends Controller
}
// redirect to previous URL.
- $redirect = redirect($this->getPreviousUrl('accounts.create.url'));
+ $redirect = redirect($this->getPreviousUrl('accounts.create.url'));
if (1 === (int)$request->get('create_another')) {
// set value so create routine will not overwrite URL:
$request->session()->put('accounts.create.fromStore', true);
diff --git a/app/Http/Controllers/Account/DeleteController.php b/app/Http/Controllers/Account/DeleteController.php
index a830ec9eb5..c9b9dae224 100644
--- a/app/Http/Controllers/Account/DeleteController.php
+++ b/app/Http/Controllers/Account/DeleteController.php
@@ -42,8 +42,6 @@ class DeleteController extends Controller
/**
* DeleteController constructor.
- *
-
*/
public function __construct()
{
@@ -65,9 +63,7 @@ class DeleteController extends Controller
/**
* Delete account screen.
*
- * @param Account $account
- *
- * @return Factory|RedirectResponse|Redirector|View
+ * @return Factory|Redirector|RedirectResponse|View
*/
public function delete(Account $account)
{
@@ -90,10 +86,7 @@ class DeleteController extends Controller
/**
* Delete the account.
*
- * @param Request $request
- * @param Account $account
- *
- * @return RedirectResponse|Redirector
+ * @return Redirector|RedirectResponse
*/
public function destroy(Request $request, Account $account)
{
diff --git a/app/Http/Controllers/Account/EditController.php b/app/Http/Controllers/Account/EditController.php
index 292c00ec8c..81549f45e1 100644
--- a/app/Http/Controllers/Account/EditController.php
+++ b/app/Http/Controllers/Account/EditController.php
@@ -33,10 +33,10 @@ use Illuminate\Contracts\View\Factory;
use Illuminate\Http\RedirectResponse;
use Illuminate\Http\Request;
use Illuminate\Routing\Redirector;
+use Illuminate\Support\Facades\Log;
use Illuminate\View\View;
/**
- *
* Class EditController
*/
class EditController extends Controller
@@ -68,13 +68,11 @@ class EditController extends Controller
}
/**
- * Edit account overview.
+ * Edit account overview. It's complex, but it just has a lot of if/then/else.
*
- * @param Request $request
- * @param Account $account
- * @param AccountRepositoryInterface $repository
+ * @SuppressWarnings(PHPMD.NPathComplexity)
*
- * @return Factory|RedirectResponse|Redirector|View
+ * @return Factory|Redirector|RedirectResponse|View
*/
public function edit(Request $request, Account $account, AccountRepositoryInterface $repository)
{
@@ -82,32 +80,32 @@ class EditController extends Controller
return $this->redirectAccountToAccount($account);
}
- $objectType = config('firefly.shortNamesByFullName')[$account->accountType->type];
- $subTitle = (string)trans(sprintf('firefly.edit_%s_account', $objectType), ['name' => $account->name]);
- $subTitleIcon = config(sprintf('firefly.subIconsByIdentifier.%s', $objectType));
- $roles = $this->getRoles();
- $liabilityTypes = $this->getLiabilityTypes();
- $location = $repository->getLocation($account);
- $latitude = $location ? $location->latitude : config('firefly.default_location.latitude');
- $longitude = $location ? $location->longitude : config('firefly.default_location.longitude');
- $zoomLevel = $location ? $location->zoom_level : config('firefly.default_location.zoom_level');
- $hasLocation = null !== $location;
- $locations = [
+ $objectType = config('firefly.shortNamesByFullName')[$account->accountType->type];
+ $subTitle = (string)trans(sprintf('firefly.edit_%s_account', $objectType), ['name' => $account->name]);
+ $subTitleIcon = config(sprintf('firefly.subIconsByIdentifier.%s', $objectType));
+ $roles = $this->getRoles();
+ $liabilityTypes = $this->getLiabilityTypes();
+ $location = $repository->getLocation($account);
+ $latitude = null !== $location ? $location->latitude : config('firefly.default_location.latitude');
+ $longitude = null !== $location ? $location->longitude : config('firefly.default_location.longitude');
+ $zoomLevel = null !== $location ? $location->zoom_level : config('firefly.default_location.zoom_level');
+ $hasLocation = null !== $location;
+ $locations = [
'location' => [
- 'latitude' => old('location_latitude') ?? $latitude,
- 'longitude' => old('location_longitude') ?? $longitude,
- 'zoom_level' => old('location_zoom_level') ?? $zoomLevel,
+ 'latitude' => null !== old('location_latitude') ? old('location_latitude') : $latitude,
+ 'longitude' => null !== old('location_longitude') ? old('location_longitude') : $longitude,
+ 'zoom_level' => null !== old('location_zoom_level') ? old('location_zoom_level') : $zoomLevel,
'has_location' => $hasLocation || 'true' === old('location_has_location'),
],
];
- $liabilityDirections = [
+ $liabilityDirections = [
'debit' => trans('firefly.liability_direction_debit'),
'credit' => trans('firefly.liability_direction_credit'),
];
// interest calculation periods:
- $interestPeriods = [
+ $interestPeriods = [
'daily' => (string)trans('firefly.interest_calc_daily'),
'monthly' => (string)trans('firefly.interest_calc_monthly'),
'yearly' => (string)trans('firefly.interest_calc_yearly'),
@@ -123,17 +121,23 @@ class EditController extends Controller
if ('0' === $openingBalanceAmount) {
$openingBalanceAmount = '';
}
- $openingBalanceDate = $repository->getOpeningBalanceDate($account);
- $currency = $this->repository->getAccountCurrency($account) ?? app('amount')->getDefaultCurrency();
+ $openingBalanceDate = $repository->getOpeningBalanceDate($account);
+ $currency = $this->repository->getAccountCurrency($account) ?? app('amount')->getDefaultCurrency();
// include this account in net-worth charts?
- $includeNetWorth = $repository->getMetaValue($account, 'include_net_worth');
- $includeNetWorth = null === $includeNetWorth ? true : '1' === $includeNetWorth;
+ $includeNetWorth = $repository->getMetaValue($account, 'include_net_worth');
+ $includeNetWorth = null === $includeNetWorth ? true : '1' === $includeNetWorth;
+
+ // issue #8321
+ $showNetWorth = true;
+ if ('liabilities' !== $objectType && 'asset' !== $objectType) {
+ $showNetWorth = false;
+ }
// code to handle active-checkboxes
- $hasOldInput = null !== $request->old('_token');
- $virtualBalance = null === $account->virtual_balance ? '0' : $account->virtual_balance;
- $preFilled = [
+ $hasOldInput = null !== $request->old('_token');
+ $virtualBalance = null === $account->virtual_balance ? '0' : $account->virtual_balance;
+ $preFilled = [
'account_number' => $repository->getMetaValue($account, 'account_number'),
'account_role' => $repository->getMetaValue($account, 'account_role'),
'cc_type' => $repository->getMetaValue($account, 'cc_type'),
@@ -157,31 +161,13 @@ class EditController extends Controller
$request->session()->flash('preFilled', $preFilled);
- return view(
- 'accounts.edit',
- compact(
- 'account',
- 'currency',
- 'subTitle',
- 'subTitleIcon',
- 'locations',
- 'liabilityDirections',
- 'objectType',
- 'roles',
- 'preFilled',
- 'liabilityTypes',
- 'interestPeriods'
- )
- );
+ return view('accounts.edit', compact('account', 'currency', 'showNetWorth', 'subTitle', 'subTitleIcon', 'locations', 'liabilityDirections', 'objectType', 'roles', 'preFilled', 'liabilityTypes', 'interestPeriods'));
}
/**
* Update the account.
*
- * @param AccountFormRequest $request
- * @param Account $account
- *
- * @return $this|RedirectResponse|Redirector
+ * @return $this|Redirector|RedirectResponse
*/
public function update(AccountFormRequest $request, Account $account)
{
@@ -189,18 +175,19 @@ class EditController extends Controller
return $this->redirectAccountToAccount($account);
}
- $data = $request->getAccountData();
+ $data = $request->getAccountData();
$this->repository->update($account, $data);
-
+ Log::channel('audit')->info(sprintf('Updated account #%d.', $account->id), $data);
$request->session()->flash('success', (string)trans('firefly.updated_account', ['name' => $account->name]));
// store new attachment(s):
-
- $files = $request->hasFile('attachments') ? $request->file('attachments') : null;
+ /** @var null|array $files */
+ $files = $request->hasFile('attachments') ? $request->file('attachments') : null;
if (null !== $files && !auth()->user()->hasRole('demo')) {
$this->attachments->saveAttachmentsForModel($account, $files);
}
if (null !== $files && auth()->user()->hasRole('demo')) {
+ Log::channel('audit')->warning(sprintf('The demo user is trying to upload attachments in %s.', __METHOD__));
session()->flash('info', (string)trans('firefly.no_att_demo_user'));
}
diff --git a/app/Http/Controllers/Account/IndexController.php b/app/Http/Controllers/Account/IndexController.php
index 3a6915cb8a..870999de13 100644
--- a/app/Http/Controllers/Account/IndexController.php
+++ b/app/Http/Controllers/Account/IndexController.php
@@ -32,14 +32,9 @@ use FireflyIII\Support\Http\Controllers\BasicDataSupport;
use Illuminate\Contracts\View\Factory;
use Illuminate\Http\Request;
use Illuminate\Pagination\LengthAwarePaginator;
-use Illuminate\Support\Facades\Log;
use Illuminate\View\View;
-use JsonException;
-use Psr\Container\ContainerExceptionInterface;
-use Psr\Container\NotFoundExceptionInterface;
/**
- *
* Class IndexController
*/
class IndexController extends Controller
@@ -50,8 +45,6 @@ class IndexController extends Controller
/**
* IndexController constructor.
- *
-
*/
public function __construct()
{
@@ -71,31 +64,28 @@ class IndexController extends Controller
}
/**
- * @param Request $request
- * @param string $objectType
- *
* @return Factory|View
+ *
* @throws FireflyException
- * @throws JsonException
- * @throws ContainerExceptionInterface
- * @throws NotFoundExceptionInterface
- */
+ * */
public function inactive(Request $request, string $objectType)
{
- $inactivePage = true;
- $subTitle = (string)trans(sprintf('firefly.%s_accounts_inactive', $objectType));
- $subTitleIcon = config(sprintf('firefly.subIconsByIdentifier.%s', $objectType));
- $types = config(sprintf('firefly.accountTypesByIdentifier.%s', $objectType));
- $collection = $this->repository->getInactiveAccountsByType($types);
- $total = $collection->count();
- $page = 0 === (int)$request->get('page') ? 1 : (int)$request->get('page');
- $pageSize = (int)app('preferences')->get('listPageSize', 50)->data;
- $accounts = $collection->slice(($page - 1) * $pageSize, $pageSize);
+ $inactivePage = true;
+ $subTitle = (string)trans(sprintf('firefly.%s_accounts_inactive', $objectType));
+ $subTitleIcon = config(sprintf('firefly.subIconsByIdentifier.%s', $objectType));
+ $types = config(sprintf('firefly.accountTypesByIdentifier.%s', $objectType));
+ $collection = $this->repository->getInactiveAccountsByType($types);
+ $total = $collection->count();
+ $page = 0 === (int)$request->get('page') ? 1 : (int)$request->get('page');
+ $pageSize = (int)app('preferences')->get('listPageSize', 50)->data;
+ $accounts = $collection->slice(($page - 1) * $pageSize, $pageSize);
unset($collection);
+
/** @var Carbon $start */
- $start = clone session('start', today(config('app.timezone'))->startOfMonth());
+ $start = clone session('start', today(config('app.timezone'))->startOfMonth());
+
/** @var Carbon $end */
- $end = clone session('end', today(config('app.timezone'))->endOfMonth());
+ $end = clone session('end', today(config('app.timezone'))->endOfMonth());
$start->subDay();
$ids = $accounts->pluck('id')->toArray();
@@ -104,7 +94,7 @@ class IndexController extends Controller
$activities = app('steam')->getLastActivities($ids);
$accounts->each(
- function (Account $account) use ($activities, $startBalances, $endBalances) {
+ function (Account $account) use ($activities, $startBalances, $endBalances): void {
$account->lastActivityDate = $this->isInArrayDate($activities, $account->id);
$account->startBalance = $this->isInArray($startBalances, $account->id);
$account->endBalance = $this->isInArray($endBalances, $account->id);
@@ -118,7 +108,7 @@ class IndexController extends Controller
);
// make paginator:
- $accounts = new LengthAwarePaginator($accounts, $total, $pageSize, $page);
+ $accounts = new LengthAwarePaginator($accounts, $total, $pageSize, $page);
$accounts->setPath(route('accounts.inactive.index', [$objectType]));
return view('accounts.index', compact('objectType', 'inactivePage', 'subTitleIcon', 'subTitle', 'page', 'accounts'));
@@ -127,21 +117,16 @@ class IndexController extends Controller
/**
* Show list of accounts.
*
- * @param Request $request
- * @param string $objectType
- *
* @return Factory|View
+ *
* @throws FireflyException
- * @throws JsonException
- * @throws ContainerExceptionInterface
- * @throws NotFoundExceptionInterface
- */
+ * */
public function index(Request $request, string $objectType)
{
- Log::debug(sprintf('Now at %s', __METHOD__));
- $subTitle = (string)trans(sprintf('firefly.%s_accounts', $objectType));
- $subTitleIcon = config(sprintf('firefly.subIconsByIdentifier.%s', $objectType));
- $types = config(sprintf('firefly.accountTypesByIdentifier.%s', $objectType));
+ app('log')->debug(sprintf('Now at %s', __METHOD__));
+ $subTitle = (string)trans(sprintf('firefly.%s_accounts', $objectType));
+ $subTitleIcon = config(sprintf('firefly.subIconsByIdentifier.%s', $objectType));
+ $types = config(sprintf('firefly.accountTypesByIdentifier.%s', $objectType));
$this->repository->resetAccountOrder();
@@ -152,13 +137,15 @@ class IndexController extends Controller
$accounts = $collection->slice(($page - 1) * $pageSize, $pageSize);
$inactiveCount = $this->repository->getInactiveAccountsByType($types)->count();
- Log::debug(sprintf('Count of collection: %d, count of accounts: %d', $total, $accounts->count()));
+ app('log')->debug(sprintf('Count of collection: %d, count of accounts: %d', $total, $accounts->count()));
unset($collection);
+
/** @var Carbon $start */
- $start = clone session('start', today(config('app.timezone'))->startOfMonth());
+ $start = clone session('start', today(config('app.timezone'))->startOfMonth());
+
/** @var Carbon $end */
- $end = clone session('end', today(config('app.timezone'))->endOfMonth());
+ $end = clone session('end', today(config('app.timezone'))->endOfMonth());
$start->subDay();
$ids = $accounts->pluck('id')->toArray();
@@ -166,11 +153,10 @@ class IndexController extends Controller
$endBalances = app('steam')->balancesByAccounts($accounts, $end);
$activities = app('steam')->getLastActivities($ids);
-
$accounts->each(
- function (Account $account) use ($activities, $startBalances, $endBalances) {
- $interest = (string)$this->repository->getMetaValue($account, 'interest');
- $interest = '' === $interest ? '0' : $interest;
+ function (Account $account) use ($activities, $startBalances, $endBalances): void {
+ $interest = (string)$this->repository->getMetaValue($account, 'interest');
+ $interest = '' === $interest ? '0' : $interest;
// See reference nr. 68
$account->lastActivityDate = $this->isInArrayDate($activities, $account->id);
@@ -189,13 +175,14 @@ class IndexController extends Controller
}
);
// make paginator:
- Log::debug(sprintf('Count of accounts before LAP: %d', $accounts->count()));
+ app('log')->debug(sprintf('Count of accounts before LAP: %d', $accounts->count()));
+
/** @var LengthAwarePaginator $accounts */
- $accounts = new LengthAwarePaginator($accounts, $total, $pageSize, $page);
+ $accounts = new LengthAwarePaginator($accounts, $total, $pageSize, $page);
$accounts->setPath(route('accounts.index', [$objectType]));
- Log::debug(sprintf('Count of accounts after LAP (1): %d', $accounts->count()));
- Log::debug(sprintf('Count of accounts after LAP (2): %d', $accounts->getCollection()->count()));
+ app('log')->debug(sprintf('Count of accounts after LAP (1): %d', $accounts->count()));
+ app('log')->debug(sprintf('Count of accounts after LAP (2): %d', $accounts->getCollection()->count()));
return view('accounts.index', compact('objectType', 'inactiveCount', 'subTitleIcon', 'subTitle', 'page', 'accounts'));
}
diff --git a/app/Http/Controllers/Account/ReconcileController.php b/app/Http/Controllers/Account/ReconcileController.php
index 414a14b7e7..59ffa098c2 100644
--- a/app/Http/Controllers/Account/ReconcileController.php
+++ b/app/Http/Controllers/Account/ReconcileController.php
@@ -38,11 +38,7 @@ use FireflyIII\User;
use Illuminate\Contracts\View\Factory;
use Illuminate\Http\RedirectResponse;
use Illuminate\Routing\Redirector;
-use Illuminate\Support\Facades\Log;
use Illuminate\View\View;
-use JsonException;
-use Psr\Container\ContainerExceptionInterface;
-use Psr\Container\NotFoundExceptionInterface;
/**
* Class ReconcileController.
@@ -54,8 +50,6 @@ class ReconcileController extends Controller
/**
* ReconcileController constructor.
- *
-
*/
public function __construct()
{
@@ -77,16 +71,10 @@ class ReconcileController extends Controller
/**
* Reconciliation overview.
*
- * @param Account $account
- * @param Carbon|null $start
- * @param Carbon|null $end
+ * @return Factory|Redirector|RedirectResponse|View
*
- * @return Factory|RedirectResponse|Redirector|View
* @throws FireflyException
- * @throws JsonException
- * @throws ContainerExceptionInterface
- * @throws NotFoundExceptionInterface
- */
+ * */
public function reconcile(Account $account, Carbon $start = null, Carbon $end = null)
{
if (!$this->isEditableAccount($account)) {
@@ -97,18 +85,19 @@ class ReconcileController extends Controller
return redirect(route('accounts.index', [config(sprintf('firefly.shortNamesByFullName.%s', $account->accountType->type))]));
}
- $currency = $this->accountRepos->getAccountCurrency($account) ?? app('amount')->getDefaultCurrency();
+ $currency = $this->accountRepos->getAccountCurrency($account) ?? app('amount')->getDefaultCurrency();
// no start or end:
- $range = app('navigation')->getViewRange(false);
+ $range = app('navigation')->getViewRange(false);
// get start and end
if (null === $start && null === $end) {
/** @var Carbon $start */
$start = clone session('start', app('navigation')->startOfPeriod(new Carbon(), $range));
+
/** @var Carbon $end */
- $end = clone session('end', app('navigation')->endOfPeriod(new Carbon(), $range));
+ $end = clone session('end', app('navigation')->endOfPeriod(new Carbon(), $range));
}
if (null === $end) {
/** @var Carbon $end */
@@ -119,12 +108,12 @@ class ReconcileController extends Controller
[$start, $end] = [$end, $start];
}
- $startDate = clone $start;
+ $startDate = clone $start;
$startDate->subDay();
- $startBalance = app('steam')->bcround(app('steam')->balance($account, $startDate), $currency->decimal_places);
- $endBalance = app('steam')->bcround(app('steam')->balance($account, $end), $currency->decimal_places);
- $subTitleIcon = config(sprintf('firefly.subIconsByIdentifier.%s', $account->accountType->type));
- $subTitle = (string)trans('firefly.reconcile_account', ['account' => $account->name]);
+ $startBalance = app('steam')->bcround(app('steam')->balance($account, $startDate), $currency->decimal_places);
+ $endBalance = app('steam')->bcround(app('steam')->balance($account, $end), $currency->decimal_places);
+ $subTitleIcon = config(sprintf('firefly.subIconsByIdentifier.%s', $account->accountType->type));
+ $subTitle = (string)trans('firefly.reconcile_account', ['account' => $account->name]);
// various links
$transactionsUrl = route('accounts.reconcile.transactions', [$account->id, '%start%', '%end%']);
@@ -154,14 +143,9 @@ class ReconcileController extends Controller
/**
* Submit a new reconciliation.
*
- * @param ReconciliationStoreRequest $request
- * @param Account $account
- * @param Carbon $start
- * @param Carbon $end
+ * @return Redirector|RedirectResponse
*
- * @return RedirectResponse|Redirector
* @throws DuplicateTransactionException
- * @throws JsonException
*/
public function submit(ReconciliationStoreRequest $request, Account $account, Carbon $start, Carbon $end)
{
@@ -169,14 +153,14 @@ class ReconcileController extends Controller
return $this->redirectAccountToAccount($account);
}
- Log::debug('In ReconcileController::submit()');
- $data = $request->getAll();
+ app('log')->debug('In ReconcileController::submit()');
+ $data = $request->getAll();
/** @var string $journalId */
foreach ($data['journals'] as $journalId) {
$this->repository->reconcileById((int)$journalId);
}
- Log::debug('Reconciled all transactions.');
+ app('log')->debug('Reconciled all transactions.');
// switch dates if necessary
if ($end->lt($start)) {
@@ -188,7 +172,7 @@ class ReconcileController extends Controller
if ('create' === $data['reconcile']) {
$result = $this->createReconciliation($account, $start, $end, $data['difference']);
}
- Log::debug('End of routine.');
+ app('log')->debug('End of routine.');
app('preferences')->mark();
if ('' === $result) {
session()->flash('success', (string)trans('firefly.reconciliation_stored'));
@@ -203,19 +187,12 @@ class ReconcileController extends Controller
/**
* Creates a reconciliation group.
*
- * @param Account $account
- * @param Carbon $start
- * @param Carbon $end
- * @param string $difference
- *
- * @return RedirectResponse|Redirector|string
* @throws DuplicateTransactionException
- * @throws JsonException
*/
- private function createReconciliation(Account $account, Carbon $start, Carbon $end, string $difference)
+ private function createReconciliation(Account $account, Carbon $start, Carbon $end, string $difference): string
{
if (!$this->isEditableAccount($account)) {
- return $this->redirectAccountToAccount($account);
+ return 'not-editable';
}
$reconciliation = $this->accountRepos->getReconciliation($account);
@@ -232,14 +209,14 @@ class ReconcileController extends Controller
}
// title:
- $description = trans(
+ $description = trans(
'firefly.reconciliation_transaction_title',
[
'from' => $start->isoFormat($this->monthAndDayFormat),
'to' => $end->isoFormat($this->monthAndDayFormat),
]
);
- $submission = [
+ $submission = [
'user' => auth()->user()->id,
'group_title' => null,
'transactions' => [
@@ -259,11 +236,14 @@ class ReconcileController extends Controller
],
],
];
+
/** @var TransactionGroupFactory $factory */
- $factory = app(TransactionGroupFactory::class);
+ $factory = app(TransactionGroupFactory::class);
+
/** @var User $user */
- $user = auth()->user();
+ $user = auth()->user();
$factory->setUser($user);
+
try {
$factory->create($submission);
} catch (FireflyException $e) {
diff --git a/app/Http/Controllers/Account/ShowController.php b/app/Http/Controllers/Account/ShowController.php
index 7144330d3a..5d5a11085e 100644
--- a/app/Http/Controllers/Account/ShowController.php
+++ b/app/Http/Controllers/Account/ShowController.php
@@ -36,13 +36,9 @@ use Illuminate\Http\Request;
use Illuminate\Routing\Redirector;
use Illuminate\Support\Collection;
use Illuminate\View\View;
-use JsonException;
-use Psr\Container\ContainerExceptionInterface;
-use Psr\Container\NotFoundExceptionInterface;
/**
* Class ShowController
- *
*/
class ShowController extends Controller
{
@@ -52,8 +48,6 @@ class ShowController extends Controller
/**
* ShowController constructor.
- *
-
*/
public function __construct()
{
@@ -77,29 +71,22 @@ class ShowController extends Controller
/**
* Show an account.
*
- * @param Request $request
- * @param Account $account
- * @param Carbon|null $start
- * @param Carbon|null $end
+ * @return Factory|Redirector|RedirectResponse|View
*
- * @return RedirectResponse|Redirector|Factory|View
* @throws FireflyException
- * @throws JsonException
- * @throws ContainerExceptionInterface
- * @throws NotFoundExceptionInterface
- */
+ * */
public function show(Request $request, Account $account, Carbon $start = null, Carbon $end = null)
{
- $objectType = config(sprintf('firefly.shortNamesByFullName.%s', $account->accountType->type));
+ $objectType = config(sprintf('firefly.shortNamesByFullName.%s', $account->accountType->type));
if (!$this->isEditableAccount($account)) {
return $this->redirectAccountToAccount($account);
}
- /** @var Carbon $start */
- $start = $start ?? session('start');
- /** @var Carbon $end */
- $end = $end ?? session('end');
+ // @var Carbon $start
+ $start ??= session('start');
+ // @var Carbon $end
+ $end ??= session('end');
if ($end < $start) {
[$start, $end] = [$end, $start];
@@ -123,25 +110,24 @@ class ShowController extends Controller
$subTitle = (string)trans('firefly.all_journals_for_account', ['name' => $account->name]);
}
-
/** @var GroupCollectorInterface $collector */
- $collector = app(GroupCollectorInterface::class);
+ $collector = app(GroupCollectorInterface::class);
$collector
->setAccounts(new Collection([$account]))
->setLimit($pageSize)
->setPage($page)->withAccountInformation()->withCategoryInformation()
- ->setRange($start, $end);
+ ->setRange($start, $end)
+ ;
// this search will not include transaction groups where this asset account (or liability)
// is just part of ONE of the journals. To force this:
$collector->setExpandGroupSearch(true);
-
- $groups = $collector->getPaginatedGroups();
+ $groups = $collector->getPaginatedGroups();
$groups->setPath(route('accounts.show', [$account->id, $start->format('Y-m-d'), $end->format('Y-m-d')]));
- $showAll = false;
- $balance = app('steam')->balance($account, $end);
+ $showAll = false;
+ $balance = app('steam')->balance($account, $end);
return view(
'accounts.show',
@@ -168,15 +154,10 @@ class ShowController extends Controller
/**
* Show an account.
*
- * @param Request $request
- * @param Account $account
+ * @return Factory|Redirector|RedirectResponse|View
*
- * @return RedirectResponse|Redirector|Factory|View
* @throws FireflyException
- * @throws JsonException
- * @throws ContainerExceptionInterface
- * @throws NotFoundExceptionInterface
- */
+ * */
public function showAll(Request $request, Account $account)
{
if (!$this->isEditableAccount($account)) {
@@ -189,25 +170,26 @@ class ShowController extends Controller
$end = today(config('app.timezone'));
$today = today(config('app.timezone'));
$start = $this->repository->oldestJournalDate($account) ?? today(config('app.timezone'))->startOfMonth();
- $subTitleIcon = config('firefly.subIconsByIdentifier.' . $account->accountType->type);
+ $subTitleIcon = config('firefly.subIconsByIdentifier.'.$account->accountType->type);
$page = (int)$request->get('page');
$pageSize = (int)app('preferences')->get('listPageSize', 50)->data;
$currency = $this->repository->getAccountCurrency($account) ?? app('amount')->getDefaultCurrency();
$subTitle = (string)trans('firefly.all_journals_for_account', ['name' => $account->name]);
$periods = new Collection();
+
/** @var GroupCollectorInterface $collector */
- $collector = app(GroupCollectorInterface::class);
+ $collector = app(GroupCollectorInterface::class);
$collector->setAccounts(new Collection([$account]))->setLimit($pageSize)->setPage($page)->withAccountInformation()->withCategoryInformation();
// this search will not include transaction groups where this asset account (or liability)
// is just part of ONE of the journals. To force this:
$collector->setExpandGroupSearch(true);
- $groups = $collector->getPaginatedGroups();
+ $groups = $collector->getPaginatedGroups();
$groups->setPath(route('accounts.show.all', [$account->id]));
- $chartUrl = route('chart.account.period', [$account->id, $start->format('Y-m-d'), $end->format('Y-m-d')]);
- $showAll = true;
- $balance = app('steam')->balance($account, $end);
+ $chartUrl = route('chart.account.period', [$account->id, $start->format('Y-m-d'), $end->format('Y-m-d')]);
+ $showAll = true;
+ $balance = app('steam')->balance($account, $end);
return view(
'accounts.show',
diff --git a/app/Http/Controllers/Admin/ConfigurationController.php b/app/Http/Controllers/Admin/ConfigurationController.php
index 24b1bd3f47..25e810aeab 100644
--- a/app/Http/Controllers/Admin/ConfigurationController.php
+++ b/app/Http/Controllers/Admin/ConfigurationController.php
@@ -30,8 +30,6 @@ use Illuminate\Contracts\View\Factory;
use Illuminate\Http\RedirectResponse;
use Illuminate\Support\Facades\Log;
use Illuminate\View\View;
-use Psr\Container\ContainerExceptionInterface;
-use Psr\Container\NotFoundExceptionInterface;
/**
* Class ConfigurationController.
@@ -40,8 +38,6 @@ class ConfigurationController extends Controller
{
/**
* ConfigurationController constructor.
- *
-
*/
public function __construct()
{
@@ -62,13 +58,11 @@ class ConfigurationController extends Controller
* Show configuration index.
*
* @return Factory|View
- * @throws ContainerExceptionInterface
- * @throws NotFoundExceptionInterface
*/
public function index()
{
- $subTitle = (string)trans('firefly.instance_configuration');
- $subTitleIcon = 'fa-wrench';
+ $subTitle = (string)trans('firefly.instance_configuration');
+ $subTitleIcon = 'fa-wrench';
Log::channel('audit')->info('User visits admin config index.');
@@ -86,10 +80,6 @@ class ConfigurationController extends Controller
/**
* Store new configuration values.
- *
- * @param ConfigurationRequest $request
- *
- * @return RedirectResponse
*/
public function postIndex(ConfigurationRequest $request): RedirectResponse
{
diff --git a/app/Http/Controllers/Admin/HomeController.php b/app/Http/Controllers/Admin/HomeController.php
index 38c5799cc6..a641b2f4a5 100644
--- a/app/Http/Controllers/Admin/HomeController.php
+++ b/app/Http/Controllers/Admin/HomeController.php
@@ -26,7 +26,6 @@ namespace FireflyIII\Http\Controllers\Admin;
use FireflyIII\Events\AdminRequestedTestMessage;
use FireflyIII\Http\Controllers\Controller;
use FireflyIII\Http\Middleware\IsDemoUser;
-use FireflyIII\Support\Facades\FireflyConfig;
use FireflyIII\Support\Notifications\UrlValidator;
use FireflyIII\User;
use Illuminate\Contracts\View\Factory;
@@ -35,8 +34,6 @@ use Illuminate\Http\Request;
use Illuminate\Routing\Redirector;
use Illuminate\Support\Facades\Log;
use Illuminate\View\View;
-use Psr\Container\ContainerExceptionInterface;
-use Psr\Container\NotFoundExceptionInterface;
/**
* Class HomeController.
@@ -45,8 +42,6 @@ class HomeController extends Controller
{
/**
* ConfigurationController constructor.
- *
-
*/
public function __construct()
{
@@ -58,8 +53,6 @@ class HomeController extends Controller
* Index of the admin.
*
* @return Factory|View
- * @throws ContainerExceptionInterface
- * @throws NotFoundExceptionInterface
*/
public function index()
{
@@ -75,18 +68,13 @@ class HomeController extends Controller
// admin notification settings:
$notifications = [];
foreach (config('firefly.admin_notifications') as $item) {
- $notifications[$item] = FireflyConfig::get(sprintf('notification_%s', $item), true)->data;
+ $notifications[$item] = app('fireflyconfig')->get(sprintf('notification_%s', $item), true)->data;
}
- $slackUrl = FireflyConfig::get('slack_webhook_url', '')->data;
+ $slackUrl = app('fireflyconfig')->get('slack_webhook_url', '')->data;
return view('admin.index', compact('title', 'mainTitleIcon', 'email', 'notifications', 'slackUrl'));
}
- /**
- * @param Request $request
- *
- * @return RedirectResponse
- */
public function notifications(Request $request): RedirectResponse
{
foreach (config('firefly.admin_notifications') as $item) {
@@ -94,33 +82,33 @@ class HomeController extends Controller
if ($request->has(sprintf('notification_%s', $item))) {
$value = true;
}
- FireflyConfig::set(sprintf('notification_%s', $item), $value);
+ app('fireflyconfig')->set(sprintf('notification_%s', $item), $value);
}
$url = (string)$request->get('slackUrl');
if ('' === $url) {
- FireflyConfig::delete('slack_webhook_url');
+ app('fireflyconfig')->delete('slack_webhook_url');
}
if (UrlValidator::isValidWebhookURL($url)) {
- FireflyConfig::set('slack_webhook_url', $url);
+ app('fireflyconfig')->set('slack_webhook_url', $url);
}
session()->flash('success', (string)trans('firefly.notification_settings_saved'));
+
return redirect(route('admin.index'));
}
/**
* Send a test message to the admin.
*
- * @param Request $request
- *
- * @return RedirectResponse|Redirector
+ * @return Redirector|RedirectResponse
*/
- public function testMessage(Request $request)
+ public function testMessage()
{
Log::channel('audit')->info('User sends test message.');
+
/** @var User $user */
$user = auth()->user();
- Log::debug('Now in testMessage() controller.');
+ app('log')->debug('Now in testMessage() controller.');
event(new AdminRequestedTestMessage($user));
session()->flash('info', (string)trans('firefly.send_test_triggered'));
diff --git a/app/Http/Controllers/Admin/LinkController.php b/app/Http/Controllers/Admin/LinkController.php
index 38b60a53d8..a2ccd109d8 100644
--- a/app/Http/Controllers/Admin/LinkController.php
+++ b/app/Http/Controllers/Admin/LinkController.php
@@ -44,8 +44,6 @@ class LinkController extends Controller
/**
* LinkController constructor.
- *
-
*/
public function __construct()
{
@@ -86,10 +84,7 @@ class LinkController extends Controller
/**
* Delete a link form.
*
- * @param Request $request
- * @param LinkType $linkType
- *
- * @return Factory|RedirectResponse|Redirector|View
+ * @return Factory|Redirector|RedirectResponse|View
*/
public function delete(Request $request, LinkType $linkType)
{
@@ -122,10 +117,7 @@ class LinkController extends Controller
/**
* Actually destroy the link.
*
- * @param Request $request
- * @param LinkType $linkType
- *
- * @return RedirectResponse|Redirector
+ * @return Redirector|RedirectResponse
*/
public function destroy(Request $request, LinkType $linkType)
{
@@ -143,10 +135,7 @@ class LinkController extends Controller
/**
* Edit a link form.
*
- * @param Request $request
- * @param LinkType $linkType
- *
- * @return Factory|RedirectResponse|Redirector|View
+ * @return Factory|Redirector|RedirectResponse|View
*/
public function edit(Request $request, LinkType $linkType)
{
@@ -182,7 +171,7 @@ class LinkController extends Controller
Log::channel('audit')->info('User on index of link types in admin.');
$linkTypes->each(
- function (LinkType $linkType) {
+ function (LinkType $linkType): void {
$linkType->journalCount = $this->repository->countJournals($linkType);
}
);
@@ -193,8 +182,6 @@ class LinkController extends Controller
/**
* Show a single link.
*
- * @param LinkType $linkType
- *
* @return Factory|View
*/
public function show(LinkType $linkType)
@@ -211,9 +198,7 @@ class LinkController extends Controller
/**
* Store the new link.
*
- * @param LinkTypeFormRequest $request
- *
- * @return $this|RedirectResponse|Redirector
+ * @return $this|Redirector|RedirectResponse
*/
public function store(LinkTypeFormRequest $request)
{
@@ -242,10 +227,7 @@ class LinkController extends Controller
/**
* Update an existing link.
*
- * @param LinkTypeFormRequest $request
- * @param LinkType $linkType
- *
- * @return $this|RedirectResponse|Redirector
+ * @return $this|Redirector|RedirectResponse
*/
public function update(LinkTypeFormRequest $request, LinkType $linkType)
{
@@ -255,7 +237,7 @@ class LinkController extends Controller
return redirect(route('admin.links.index'));
}
- $data = [
+ $data = [
'name' => $request->convertString('name'),
'inward' => $request->convertString('inward'),
'outward' => $request->convertString('outward'),
diff --git a/app/Http/Controllers/Admin/UpdateController.php b/app/Http/Controllers/Admin/UpdateController.php
index 6222135aad..b335ed9d07 100644
--- a/app/Http/Controllers/Admin/UpdateController.php
+++ b/app/Http/Controllers/Admin/UpdateController.php
@@ -31,8 +31,6 @@ use Illuminate\Http\RedirectResponse;
use Illuminate\Http\Request;
use Illuminate\Routing\Redirector;
use Illuminate\View\View;
-use Psr\Container\ContainerExceptionInterface;
-use Psr\Container\NotFoundExceptionInterface;
/**
* Class HomeController.
@@ -62,8 +60,6 @@ class UpdateController extends Controller
* Show page with update options.
*
* @return Factory|View
- * @throws ContainerExceptionInterface
- * @throws NotFoundExceptionInterface
*/
public function index()
{
@@ -79,7 +75,7 @@ class UpdateController extends Controller
1 => (string)trans('firefly.updates_enable_check'),
];
- $channelOptions = [
+ $channelOptions = [
'stable' => (string)trans('firefly.update_channel_stable'),
'beta' => (string)trans('firefly.update_channel_beta'),
'alpha' => (string)trans('firefly.update_channel_alpha'),
@@ -91,9 +87,7 @@ class UpdateController extends Controller
/**
* Post new settings.
*
- * @param Request $request
- *
- * @return RedirectResponse|Redirector
+ * @return Redirector|RedirectResponse
*/
public function post(Request $request)
{
diff --git a/app/Http/Controllers/Admin/UserController.php b/app/Http/Controllers/Admin/UserController.php
index 12808973f3..6c060b3bb5 100644
--- a/app/Http/Controllers/Admin/UserController.php
+++ b/app/Http/Controllers/Admin/UserController.php
@@ -36,10 +36,7 @@ use Illuminate\Contracts\View\Factory;
use Illuminate\Http\JsonResponse;
use Illuminate\Http\RedirectResponse;
use Illuminate\Routing\Redirector;
-use Illuminate\Support\Facades\Log;
use Illuminate\View\View;
-use Psr\Container\ContainerExceptionInterface;
-use Psr\Container\NotFoundExceptionInterface;
/**
* Class UserController.
@@ -70,9 +67,7 @@ class UserController extends Controller
}
/**
- * @param User $user
- *
- * @return Application|Factory|RedirectResponse|Redirector|View
+ * @return Application|Factory|Redirector|RedirectResponse|View
*/
public function delete(User $user)
{
@@ -87,31 +82,26 @@ class UserController extends Controller
return view('admin.users.delete', compact('user', 'subTitle'));
}
- /**
- * @param InvitedUser $invitedUser
- *
- * @return JsonResponse
- */
public function deleteInvite(InvitedUser $invitedUser): JsonResponse
{
- Log::debug('Will now delete invitation');
+ app('log')->debug('Will now delete invitation');
if ($invitedUser->redeemed) {
- Log::debug('Is already redeemed.');
+ app('log')->debug('Is already redeemed.');
session()->flash('error', trans('firefly.invite_is_already_redeemed', ['address' => $invitedUser->email]));
+
return response()->json(['success' => false]);
}
- Log::debug('Delete!');
+ app('log')->debug('Delete!');
session()->flash('success', trans('firefly.invite_is_deleted', ['address' => $invitedUser->email]));
$this->repository->deleteInvite($invitedUser);
+
return response()->json(['success' => true]);
}
/**
* Destroy a user.
*
- * @param User $user
- *
- * @return RedirectResponse|Redirector
+ * @return Redirector|RedirectResponse
*/
public function destroy(User $user)
{
@@ -129,8 +119,6 @@ class UserController extends Controller
/**
* Edit user form.
*
- * @param User $user
- *
* @return Factory|View
*/
public function edit(User $user)
@@ -145,11 +133,11 @@ class UserController extends Controller
}
session()->forget('users.edit.fromUpdate');
- $subTitle = (string)trans('firefly.edit_user', ['email' => $user->email]);
- $subTitleIcon = 'fa-user-o';
- $currentUser = auth()->user();
- $isAdmin = $this->repository->hasRole($user, 'owner');
- $codes = [
+ $subTitle = (string)trans('firefly.edit_user', ['email' => $user->email]);
+ $subTitleIcon = 'fa-user-o';
+ $currentUser = auth()->user();
+ $isAdmin = $this->repository->hasRole($user, 'owner');
+ $codes = [
'' => (string)trans('firefly.no_block_code'),
'bounced' => (string)trans('firefly.block_code_bounced'),
'expired' => (string)trans('firefly.block_code_expired'),
@@ -163,26 +151,24 @@ class UserController extends Controller
* Show index of user manager.
*
* @return Factory|View
- * @throws ContainerExceptionInterface
- * @throws NotFoundExceptionInterface
*/
public function index()
{
$subTitle = (string)trans('firefly.user_administration');
$subTitleIcon = 'fa-users';
$users = $this->repository->all();
- $singleUserMode = app('fireflyconfig')->get('single_user_mode', config('firefly.configuration.single_user_mode'))->data;
+ $singleUserMode = (bool)app('fireflyconfig')->get('single_user_mode', config('firefly.configuration.single_user_mode'))->data;
$allowInvites = false;
if (!$this->externalIdentity && $singleUserMode) {
// also registration enabled.
$allowInvites = true;
}
- $invitedUsers = $this->repository->getInvitedUsers();
+ $invitedUsers = $this->repository->getInvitedUsers();
// add meta stuff.
$users->each(
- function (User $user) {
+ function (User $user): void {
$user->isAdmin = $this->repository->hasRole($user, 'owner');
$user->has2FA = null !== $user->mfa_secret;
}
@@ -191,11 +177,6 @@ class UserController extends Controller
return view('admin.users.index', compact('subTitle', 'subTitleIcon', 'users', 'allowInvites', 'invitedUsers'));
}
- /**
- * @param InviteUserFormRequest $request
- *
- * @return RedirectResponse
- */
public function invite(InviteUserFormRequest $request): RedirectResponse
{
$address = (string)$request->get('invited_user');
@@ -211,8 +192,6 @@ class UserController extends Controller
/**
* Show single user.
*
- * @param User $user
- *
* @return Factory|View
*/
public function show(User $user)
@@ -239,17 +218,14 @@ class UserController extends Controller
/**
* Update single user.
*
- * @param UserFormRequest $request
- * @param User $user
- *
- * @return $this|RedirectResponse|Redirector
+ * @return $this|Redirector|RedirectResponse
*/
public function update(UserFormRequest $request, User $user)
{
- Log::debug('Actually here');
- $data = $request->getUserData();
+ app('log')->debug('Actually here');
+ $data = $request->getUserData();
- //var_dump($data);
+ // var_dump($data);
// update password
if (array_key_exists('password', $data) && '' !== $data['password']) {
diff --git a/app/Http/Controllers/AttachmentController.php b/app/Http/Controllers/AttachmentController.php
index 6f45458f30..2ae7fa576a 100644
--- a/app/Http/Controllers/AttachmentController.php
+++ b/app/Http/Controllers/AttachmentController.php
@@ -37,17 +37,13 @@ use Illuminate\View\View;
/**
* Class AttachmentController.
- *
*/
class AttachmentController extends Controller
{
- /** @var AttachmentRepositoryInterface Attachment repository */
- private $repository;
+ private AttachmentRepositoryInterface $repository;
/**
* AttachmentController constructor.
- *
-
*/
public function __construct()
{
@@ -68,8 +64,6 @@ class AttachmentController extends Controller
/**
* Form to delete an attachment.
*
- * @param Attachment $attachment
- *
* @return Factory|View
*/
public function delete(Attachment $attachment)
@@ -85,10 +79,7 @@ class AttachmentController extends Controller
/**
* Destroy attachment.
*
- * @param Request $request
- * @param Attachment $attachment
- *
- * @return RedirectResponse|Redirector
+ * @return Redirector|RedirectResponse
*/
public function destroy(Request $request, Attachment $attachment)
{
@@ -105,8 +96,6 @@ class AttachmentController extends Controller
/**
* Download attachment to PC.
*
- * @param Attachment $attachment
- *
* @return LaravelResponse
*
* @throws FireflyException
@@ -114,33 +103,32 @@ class AttachmentController extends Controller
public function download(Attachment $attachment)
{
if ($this->repository->exists($attachment)) {
- $content = $this->repository->getContent($attachment);
- $quoted = sprintf('"%s"', addcslashes(basename($attachment->filename), '"\\'));
+ $content = $this->repository->getContent($attachment);
+ $quoted = sprintf('"%s"', addcslashes(basename($attachment->filename), '"\\'));
/** @var LaravelResponse $response */
$response = response($content);
$response
->header('Content-Description', 'File Transfer')
->header('Content-Type', 'application/octet-stream')
- ->header('Content-Disposition', 'attachment; filename=' . $quoted)
+ ->header('Content-Disposition', 'attachment; filename='.$quoted)
->header('Content-Transfer-Encoding', 'binary')
->header('Connection', 'Keep-Alive')
->header('Expires', '0')
->header('Cache-Control', 'must-revalidate, post-check=0, pre-check=0')
->header('Pragma', 'public')
- ->header('Content-Length', strlen($content));
+ ->header('Content-Length', (string)strlen($content))
+ ;
return $response;
}
+
throw new FireflyException('Could not find the indicated attachment. The file is no longer there.');
}
/**
* Edit an attachment.
*
- * @param Request $request
- * @param Attachment $attachment
- *
* @return Factory|View
*/
public function edit(Request $request, Attachment $attachment)
@@ -153,7 +141,7 @@ class AttachmentController extends Controller
$this->rememberPreviousUrl('attachments.edit.url');
}
$request->session()->forget('attachments.edit.fromUpdate');
- $preFilled = [
+ $preFilled = [
'notes' => $this->repository->getNoteText($attachment),
];
$request->session()->flash('preFilled', $preFilled);
@@ -182,15 +170,10 @@ class AttachmentController extends Controller
/**
* Update attachment.
- *
- * @param AttachmentFormRequest $request
- * @param Attachment $attachment
- *
- * @return RedirectResponse
*/
public function update(AttachmentFormRequest $request, Attachment $attachment): RedirectResponse
{
- $data = $request->getAttachmentData();
+ $data = $request->getAttachmentData();
$this->repository->update($attachment, $data);
$request->session()->flash('success', (string)trans('firefly.attachment_updated', ['name' => $attachment->filename]));
@@ -210,20 +193,16 @@ class AttachmentController extends Controller
/**
* View attachment in browser.
*
- * @param Request $request
- * @param Attachment $attachment
- *
- * @return LaravelResponse
* @throws FireflyException
* @throws BindingResolutionException
*/
- public function view(Request $request, Attachment $attachment): LaravelResponse
+ public function view(Attachment $attachment): LaravelResponse
{
if ($this->repository->exists($attachment)) {
$content = $this->repository->getContent($attachment);
// prevent XSS by adding a new secure header.
- $csp = [
+ $csp = [
"default-src 'none'",
"object-src 'none'",
"script-src 'none'",
@@ -241,10 +220,11 @@ class AttachmentController extends Controller
[
'Content-Security-Policy' => implode('; ', $csp),
'Content-Type' => $attachment->mime,
- 'Content-Disposition' => 'inline; filename="' . $attachment->filename . '"',
+ 'Content-Disposition' => 'inline; filename="'.$attachment->filename.'"',
]
);
}
+
throw new FireflyException('Could not find the indicated attachment. The file is no longer there.');
}
}
diff --git a/app/Http/Controllers/Auth/ForgotPasswordController.php b/app/Http/Controllers/Auth/ForgotPasswordController.php
index 2dd3028ef2..41d7fa95b4 100644
--- a/app/Http/Controllers/Auth/ForgotPasswordController.php
+++ b/app/Http/Controllers/Auth/ForgotPasswordController.php
@@ -31,15 +31,10 @@ use Illuminate\Contracts\View\Factory;
use Illuminate\Foundation\Auth\SendsPasswordResetEmails;
use Illuminate\Http\RedirectResponse;
use Illuminate\Http\Request;
-use Illuminate\Support\Facades\Log;
use Illuminate\View\View;
-use Psr\Container\ContainerExceptionInterface;
-use Psr\Container\NotFoundExceptionInterface;
/**
* Class ForgotPasswordController
- *
-
*/
class ForgotPasswordController extends Controller
{
@@ -61,27 +56,26 @@ class ForgotPasswordController extends Controller
/**
* Send a reset link to the given user.
*
- * @param Request $request
- * @param UserRepositoryInterface $repository
- *
* @return Factory|RedirectResponse|View
*/
public function sendResetLinkEmail(Request $request, UserRepositoryInterface $repository)
{
- Log::info('Start of sendResetLinkEmail()');
+ app('log')->info('Start of sendResetLinkEmail()');
if ('web' !== config('firefly.authentication_guard')) {
$message = sprintf('Cannot reset password when authenticating over "%s".', config('firefly.authentication_guard'));
- Log::error($message);
+ app('log')->error($message);
return view('error', compact('message'));
}
+ // validate host header.
+ $this->validateHost();
$this->validateEmail($request);
// verify if the user is not a demo user. If so, we give him back an error.
- /** @var User $user */
- $user = User::where('email', $request->get('email'))->first();
+ /** @var null|User $user */
+ $user = User::where('email', $request->get('email'))->first();
if (null !== $user && $repository->hasRole($user, 'demo')) {
return back()->withErrors(['email' => (string)trans('firefly.cannot_reset_demo_user')]);
@@ -90,9 +84,9 @@ class ForgotPasswordController extends Controller
// We will send the password reset link to this user. Once we have attempted
// to send the link, we will examine the response then see the message we
// need to show to the user. Finally, we'll send out a proper response.
- $result = $this->broker()->sendResetLink($request->only('email'));
+ $result = $this->broker()->sendResetLink($request->only('email'));
if ('passwords.throttled' === $result) {
- Log::error(sprintf('Cowardly refuse to send a password reset message to user #%d because the reset button has been throttled.', $user->id));
+ app('log')->error(sprintf('Cowardly refuse to send a password reset message to user #%d because the reset button has been throttled.', $user->id));
}
// always send the same response to the user:
@@ -101,14 +95,27 @@ class ForgotPasswordController extends Controller
return back()->with('status', trans($response));
}
+ /**
+ * @throws FireflyException
+ */
+ private function validateHost(): void
+ {
+ $configuredHost = parse_url((string)config('app.url'), PHP_URL_HOST);
+ if (false === $configuredHost || null === $configuredHost) {
+ throw new FireflyException('Please set a valid and correct Firefly III URL in the APP_URL environment variable.');
+ }
+ $host = request()->host();
+ if ($configuredHost !== $host) {
+ throw new FireflyException('The Host-header does not match the host in the APP_URL environment variable. Please make sure these match. See also: https://bit.ly/FF3-host-header');
+ }
+ }
+
/**
* Show form for email recovery.
*
- *
* @return Factory|View
+ *
* @throws FireflyException
- * @throws ContainerExceptionInterface
- * @throws NotFoundExceptionInterface
*/
public function showLinkRequestForm()
{
diff --git a/app/Http/Controllers/Auth/LoginController.php b/app/Http/Controllers/Auth/LoginController.php
index 7a1892799d..137428953c 100644
--- a/app/Http/Controllers/Auth/LoginController.php
+++ b/app/Http/Controllers/Auth/LoginController.php
@@ -24,7 +24,6 @@ declare(strict_types=1);
namespace FireflyIII\Http\Controllers\Auth;
use Cookie;
-use DB;
use FireflyIII\Events\ActuallyLoggedIn;
use FireflyIII\Exceptions\FireflyException;
use FireflyIII\Http\Controllers\Controller;
@@ -34,14 +33,13 @@ use Illuminate\Contracts\View\Factory;
use Illuminate\Contracts\View\View;
use Illuminate\Foundation\Auth\AuthenticatesUsers;
use Illuminate\Foundation\Auth\ThrottlesLogins;
+use Illuminate\Http\JsonResponse;
use Illuminate\Http\RedirectResponse;
use Illuminate\Http\Request;
use Illuminate\Http\Response;
use Illuminate\Routing\Redirector;
use Illuminate\Support\Facades\Log;
use Illuminate\Validation\ValidationException;
-use Psr\Container\ContainerExceptionInterface;
-use Psr\Container\NotFoundExceptionInterface;
/**
* Class LoginController
@@ -49,8 +47,6 @@ use Psr\Container\NotFoundExceptionInterface;
* This controller handles authenticating users for the application and
* redirecting them to your home screen. The controller uses a trait
* to conveniently provide its functionality to your applications.
- *
-
*/
class LoginController extends Controller
{
@@ -59,8 +55,6 @@ class LoginController extends Controller
/**
* Where to redirect users after login.
- *
- * @var string
*/
protected string $redirectTo = RouteServiceProvider::HOME;
@@ -68,8 +62,6 @@ class LoginController extends Controller
/**
* Create a new controller instance.
- *
- * @return void
*/
public function __construct()
{
@@ -81,32 +73,31 @@ class LoginController extends Controller
/**
* Handle a login request to the application.
*
- *
* @throws ValidationException
*/
- public function login(Request $request)
+ public function login(Request $request): JsonResponse|RedirectResponse
{
Log::channel('audit')->info(sprintf('User is trying to login using "%s"', $request->get($this->username())));
- Log::info('User is trying to login.');
+ app('log')->debug('User is trying to login.');
$this->validateLogin($request);
- Log::debug('Login data is present.');
+ app('log')->debug('Login data is present.');
- /** Copied directly from AuthenticatesUsers, but with logging added: */
+ // Copied directly from AuthenticatesUsers, but with logging added:
// If the class is using the ThrottlesLogins trait, we can automatically throttle
// the login attempts for this application. We'll key this by the username and
// the IP address of the client making these requests into this application.
- if (method_exists($this, 'hasTooManyLoginAttempts') && $this->hasTooManyLoginAttempts($request)) {
- Log::channel('audit')->info(sprintf('Login for user "%s" was locked out.', $request->get($this->username())));
- Log::error(sprintf('Login for user "%s" was locked out.', $request->get($this->username())));
+ if ($this->hasTooManyLoginAttempts($request)) {
+ Log::channel('audit')->warning(sprintf('Login for user "%s" was locked out.', $request->get($this->username())));
+ app('log')->error(sprintf('Login for user "%s" was locked out.', $request->get($this->username())));
$this->fireLockoutEvent($request);
$this->sendLockoutResponse($request);
}
- /** Copied directly from AuthenticatesUsers, but with logging added: */
+ // Copied directly from AuthenticatesUsers, but with logging added:
if ($this->attemptLogin($request)) {
Log::channel('audit')->info(sprintf('User "%s" has been logged in.', $request->get($this->username())));
- Log::debug(sprintf('Redirect after login is %s.', $this->redirectPath()));
+ app('log')->debug(sprintf('Redirect after login is %s.', $this->redirectPath()));
// if you just logged in, it can't be that you have a valid 2FA cookie.
@@ -118,14 +109,17 @@ class LoginController extends Controller
}
app('log')->warning('Login attempt failed.');
- /** Copied directly from AuthenticatesUsers, but with logging added: */
+ // Copied directly from AuthenticatesUsers, but with logging added:
// If the login attempt was unsuccessful we will increment the number of attempts
// to login and redirect the user back to the login form. Of course, when this
// user surpasses their maximum number of attempts they will get locked out.
$this->incrementLoginAttempts($request);
- Log::channel('audit')->info(sprintf('Login failed. Attempt for user "%s" failed.', $request->get($this->username())));
+ Log::channel('audit')->warning(sprintf('Login failed. Attempt for user "%s" failed.', $request->get($this->username())));
$this->sendFailedLoginResponse($request);
+
+ // @noinspection PhpUnreachableStatementInspection
+ return response()->json([]);
}
/**
@@ -141,13 +135,11 @@ class LoginController extends Controller
/**
* Get the failed login response instance.
*
- * @param Request $request
- *
- * @return void
+ * @SuppressWarnings(PHPMD.UnusedFormalParameter)
*
* @throws ValidationException
*/
- protected function sendFailedLoginResponse(Request $request)
+ protected function sendFailedLoginResponse(Request $request): void
{
$exception = ValidationException::withMessages(
[
@@ -162,14 +154,12 @@ class LoginController extends Controller
/**
* Log the user out of the application.
*
- * @param Request $request
- *
- * @return RedirectResponse|Redirector|Response
+ * @return Redirector|RedirectResponse|Response
*/
public function logout(Request $request)
{
- $authGuard = config('firefly.authentication_guard');
- $logoutUrl = config('firefly.custom_logout_url');
+ $authGuard = config('firefly.authentication_guard');
+ $logoutUrl = config('firefly.custom_logout_url');
if ('remote_user_guard' === $authGuard && '' !== $logoutUrl) {
return redirect($logoutUrl);
}
@@ -179,7 +169,7 @@ class LoginController extends Controller
// also logout current 2FA tokens.
$cookieName = config('google2fa.cookie_name', 'google2fa_token');
- Cookie::forget($cookieName);
+ \Cookie::forget($cookieName);
$this->guard()->logout();
@@ -187,9 +177,7 @@ class LoginController extends Controller
$request->session()->regenerateToken();
- if ($response = $this->loggedOut($request)) {
- return $response;
- }
+ $this->loggedOut($request);
return $request->wantsJson()
? new Response('', 204)
@@ -199,20 +187,17 @@ class LoginController extends Controller
/**
* Show the application's login form.
*
- * @param Request $request
+ * @return Application|Factory|Redirector|RedirectResponse|View
*
- * @return Factory|Application|View|Redirector|RedirectResponse
* @throws FireflyException
- * @throws ContainerExceptionInterface
- * @throws NotFoundExceptionInterface
*/
public function showLoginForm(Request $request)
{
Log::channel('audit')->info('Show login form (1.1).');
- $count = DB::table('users')->count();
- $guard = config('auth.defaults.guard');
- $title = (string)trans('firefly.login_page_title');
+ $count = \DB::table('users')->count();
+ $guard = config('auth.defaults.guard');
+ $title = (string)trans('firefly.login_page_title');
if (0 === $count && 'web' === $guard) {
return redirect(route('register'));
@@ -232,15 +217,15 @@ class LoginController extends Controller
$allowReset = false;
}
- $email = $request->old('email');
- $remember = $request->old('remember');
+ $email = $request->old('email');
+ $remember = $request->old('remember');
- $storeInCookie = config('google2fa.store_in_cookie', false);
+ $storeInCookie = config('google2fa.store_in_cookie', false);
if (false !== $storeInCookie) {
$cookieName = config('google2fa.cookie_name', 'google2fa_token');
request()->cookies->set($cookieName, 'invalid');
}
- $usernameField = $this->username();
+ $usernameField = $this->username();
return view('auth.login', compact('allowRegistration', 'email', 'remember', 'allowReset', 'title', 'usernameField'));
}
diff --git a/app/Http/Controllers/Auth/RegisterController.php b/app/Http/Controllers/Auth/RegisterController.php
index 331ecc66bc..b84453522f 100644
--- a/app/Http/Controllers/Auth/RegisterController.php
+++ b/app/Http/Controllers/Auth/RegisterController.php
@@ -35,7 +35,6 @@ use Illuminate\Foundation\Auth\RegistersUsers;
use Illuminate\Http\RedirectResponse;
use Illuminate\Http\Request;
use Illuminate\Routing\Redirector;
-use Illuminate\Support\Facades\Log;
use Illuminate\Validation\ValidationException;
use Illuminate\View\View;
use Psr\Container\ContainerExceptionInterface;
@@ -47,13 +46,11 @@ use Psr\Container\NotFoundExceptionInterface;
* This controller handles the registration of new users as well as their
* validation and creation. By default this controller uses a trait to
* provide this functionality without requiring any additional code.
- *
-
*/
class RegisterController extends Controller
{
- use RegistersUsers;
use CreateStuff;
+ use RegistersUsers;
/**
* Where to redirect users after registration.
@@ -78,9 +75,8 @@ class RegisterController extends Controller
/**
* Handle a registration request for the application.
*
- * @param Request $request
- *
* @return Application|Redirector|RedirectResponse
+ *
* @throws FireflyException
* @throws ValidationException
*/
@@ -95,10 +91,9 @@ class RegisterController extends Controller
throw new FireflyException('Registration is currently not available :(');
}
-
$this->validator($request->all())->validate();
- $user = $this->createUser($request->all());
- Log::info(sprintf('Registered new user %s', $user->email));
+ $user = $this->createUser($request->all());
+ app('log')->info(sprintf('Registered new user %s', $user->email));
event(new RegisteredUser($user));
$this->guard()->login($user);
@@ -115,37 +110,36 @@ class RegisterController extends Controller
}
/**
- * @return bool
* @throws FireflyException
*/
protected function allowedToRegister(): bool
{
// is allowed to register?
$allowRegistration = true;
+
try {
$singleUserMode = app('fireflyconfig')->get('single_user_mode', config('firefly.configuration.single_user_mode'))->data;
- } catch (ContainerExceptionInterface | NotFoundExceptionInterface $e) {
+ } catch (ContainerExceptionInterface|NotFoundExceptionInterface $e) {
$singleUserMode = true;
}
- $userCount = User::count();
- $guard = config('auth.defaults.guard');
+ $userCount = User::count();
+ $guard = config('auth.defaults.guard');
if (true === $singleUserMode && $userCount > 0 && 'web' === $guard) {
$allowRegistration = false;
}
if ('web' !== $guard) {
$allowRegistration = false;
}
+
return $allowRegistration;
}
/**
* Show the application registration form if the invitation code is valid.
*
- *
* @return Factory|View
- * @throws ContainerExceptionInterface
+ *
* @throws FireflyException
- * @throws NotFoundExceptionInterface
*/
public function showInviteForm(Request $request, string $code)
{
@@ -167,7 +161,7 @@ class RegisterController extends Controller
return view('error', compact('message'));
}
- $email = $request->old('email');
+ $email = $request->old('email');
return view('auth.register', compact('isDemoSite', 'email', 'pageTitle', 'inviteCode'));
}
@@ -175,12 +169,9 @@ class RegisterController extends Controller
/**
* Show the application registration form.
*
- * @param Request $request
- *
* @return Factory|View
- * @throws ContainerExceptionInterface
+ *
* @throws FireflyException
- * @throws NotFoundExceptionInterface
*/
public function showRegistrationForm(Request $request)
{
@@ -194,7 +185,7 @@ class RegisterController extends Controller
return view('error', compact('message'));
}
- $email = $request->old('email');
+ $email = $request->old('email');
return view('auth.register', compact('isDemoSite', 'email', 'pageTitle'));
}
diff --git a/app/Http/Controllers/Auth/ResetPasswordController.php b/app/Http/Controllers/Auth/ResetPasswordController.php
index 5d477d1f7e..09982b2063 100644
--- a/app/Http/Controllers/Auth/ResetPasswordController.php
+++ b/app/Http/Controllers/Auth/ResetPasswordController.php
@@ -34,8 +34,6 @@ use Illuminate\Http\Request;
use Illuminate\Support\Facades\Password;
use Illuminate\Validation\ValidationException;
use Illuminate\View\View;
-use Psr\Container\ContainerExceptionInterface;
-use Psr\Container\NotFoundExceptionInterface;
/**
* Class ResetPasswordController
@@ -43,8 +41,6 @@ use Psr\Container\NotFoundExceptionInterface;
* This controller is responsible for handling password reset requests
* and uses a simple trait to include this behavior. You're free to
* explore this trait and override any methods you wish to tweak.
- *
-
*/
class ResetPasswordController extends Controller
{
@@ -73,11 +69,9 @@ class ResetPasswordController extends Controller
/**
* Reset the given user's password.
*
- * @param Request $request
- *
* @return Factory|JsonResponse|RedirectResponse|View
- * @throws ValidationException
*
+ * @throws ValidationException
*/
public function reset(Request $request)
{
@@ -86,7 +80,8 @@ class ResetPasswordController extends Controller
return view('error', compact('message'));
}
- $rules = [
+
+ $rules = [
'token' => 'required',
'email' => 'required|email',
'password' => 'required|confirmed|min:16|secure_password',
@@ -96,10 +91,10 @@ class ResetPasswordController extends Controller
// Here we will attempt to reset the user's password. If it is successful we
// will update the password on an actual user model and persist it to the
- // database. Otherwise we will parse the error and return the response.
+ // database. Otherwise, we will parse the error and return the response.
$response = $this->broker()->reset(
$this->credentials($request),
- function ($user, $password) {
+ function ($user, $password): void {
$this->resetPassword($user, $password);
}
);
@@ -107,7 +102,7 @@ class ResetPasswordController extends Controller
// If the password was successfully reset, we will redirect the user back to
// the application's home authenticated view. If there is an error we can
// redirect them back to where they came from with their error message.
- return $response === Password::PASSWORD_RESET
+ return Password::PASSWORD_RESET === $response
? $this->sendResetResponse($request, $response)
: $this->sendResetFailedResponse($request, $response);
}
@@ -117,13 +112,11 @@ class ResetPasswordController extends Controller
*
* If no token is present, display the link request form.
*
- * @param Request $request
- * @param null $token
+ * @param null $token
*
* @return Factory|View
+ *
* @throws FireflyException
- * @throws ContainerExceptionInterface
- * @throws NotFoundExceptionInterface
*/
public function showResetForm(Request $request, $token = null)
{
diff --git a/app/Http/Controllers/Auth/TwoFactorController.php b/app/Http/Controllers/Auth/TwoFactorController.php
index 7bd4eabc5b..7ea8448a18 100644
--- a/app/Http/Controllers/Auth/TwoFactorController.php
+++ b/app/Http/Controllers/Auth/TwoFactorController.php
@@ -31,7 +31,6 @@ use Illuminate\Http\RedirectResponse;
use Illuminate\Http\Request;
use Illuminate\Routing\Redirector;
use PragmaRX\Google2FALaravel\Support\Authenticator;
-use Preferences;
/**
* Class TwoFactorController.
@@ -54,15 +53,13 @@ class TwoFactorController extends Controller
}
/**
- * @param Request $request
- *
- * @return RedirectResponse|Redirector
+ * @return Redirector|RedirectResponse
*/
public function submitMFA(Request $request)
{
/** @var array $mfaHistory */
- $mfaHistory = Preferences::get('mfa_history', [])->data;
- $mfaCode = (string)$request->get('one_time_password');
+ $mfaHistory = app('preferences')->get('mfa_history', [])->data;
+ $mfaCode = (string)$request->get('one_time_password');
// is in history? then refuse to use it.
if ($this->inMFAHistory($mfaCode, $mfaHistory)) {
@@ -101,11 +98,6 @@ class TwoFactorController extends Controller
/**
* Each MFA history has a timestamp and a code, saving the MFA entries for 5 minutes. So if the
* submitted MFA code has been submitted in the last 5 minutes, it won't work despite being valid.
- *
- * @param string $mfaCode
- * @param array $mfaHistory
- *
- * @return bool
*/
private function inMFAHistory(string $mfaCode, array $mfaHistory): bool
{
@@ -127,7 +119,7 @@ class TwoFactorController extends Controller
private function filterMFAHistory(): void
{
/** @var array $mfaHistory */
- $mfaHistory = Preferences::get('mfa_history', [])->data;
+ $mfaHistory = app('preferences')->get('mfa_history', [])->data;
$newHistory = [];
$now = time();
foreach ($mfaHistory as $entry) {
@@ -140,36 +132,32 @@ class TwoFactorController extends Controller
];
}
}
- Preferences::set('mfa_history', $newHistory);
+ app('preferences')->set('mfa_history', $newHistory);
}
- /**
- * @param string $mfaCode
- */
private function addToMFAHistory(string $mfaCode): void
{
/** @var array $mfaHistory */
- $mfaHistory = Preferences::get('mfa_history', [])->data;
+ $mfaHistory = app('preferences')->get('mfa_history', [])->data;
$entry = [
'time' => time(),
'code' => $mfaCode,
];
$mfaHistory[] = $entry;
- Preferences::set('mfa_history', $mfaHistory);
+ app('preferences')->set('mfa_history', $mfaHistory);
$this->filterMFAHistory();
}
/**
* Checks if code is in users backup codes.
- *
- * @param string $mfaCode
- *
- * @return bool
*/
private function isBackupCode(string $mfaCode): bool
{
- $list = Preferences::get('mfa_recovery', [])->data;
+ $list = app('preferences')->get('mfa_recovery', [])->data;
+ if (!is_array($list)) {
+ $list = [];
+ }
if (in_array($mfaCode, $list, true)) {
return true;
}
@@ -179,13 +167,14 @@ class TwoFactorController extends Controller
/**
* Remove the used code from the list of backup codes.
- *
- * @param string $mfaCode
*/
private function removeFromBackupCodes(string $mfaCode): void
{
- $list = Preferences::get('mfa_recovery', [])->data;
+ $list = app('preferences')->get('mfa_recovery', [])->data;
+ if (!is_array($list)) {
+ $list = [];
+ }
$newList = array_values(array_diff($list, [$mfaCode]));
- Preferences::set('mfa_recovery', $newList);
+ app('preferences')->set('mfa_recovery', $newList);
}
}
diff --git a/app/Http/Controllers/Bill/CreateController.php b/app/Http/Controllers/Bill/CreateController.php
index 8dfdde0f48..f55075856d 100644
--- a/app/Http/Controllers/Bill/CreateController.php
+++ b/app/Http/Controllers/Bill/CreateController.php
@@ -45,8 +45,6 @@ class CreateController extends Controller
/**
* BillController constructor.
- *
-
*/
public function __construct()
{
@@ -67,17 +65,16 @@ class CreateController extends Controller
/**
* Create a new bill.
*
- * @param Request $request
- *
* @return Factory|View
*/
public function create(Request $request)
{
- $periods = [];
+ $periods = [];
+
/** @var array $billPeriods */
- $billPeriods = config('firefly.bill_periods');
+ $billPeriods = config('firefly.bill_periods');
foreach ($billPeriods as $current) {
- $periods[$current] = (string)trans('firefly.repeat_freq_' . $current);
+ $periods[$current] = (string)trans('firefly.repeat_freq_'.$current);
}
$subTitle = (string)trans('firefly.create_new_bill');
$defaultCurrency = app('amount')->getDefaultCurrency();
@@ -93,34 +90,33 @@ class CreateController extends Controller
/**
* Store a new bill.
- *
- * @param BillStoreRequest $request
- *
- * @return RedirectResponse
- *
*/
public function store(BillStoreRequest $request): RedirectResponse
{
- $billData = $request->getBillData();
+ $billData = $request->getBillData();
$billData['active'] = true;
+
try {
$bill = $this->repository->store($billData);
} catch (FireflyException $e) {
- Log::error($e->getMessage());
+ app('log')->error($e->getMessage());
$request->session()->flash('error', (string)trans('firefly.bill_store_error'));
return redirect(route('bills.create'))->withInput();
}
+
+ Log::channel('audit')->info('Stored new bill.', $billData);
$request->session()->flash('success', (string)trans('firefly.stored_new_bill', ['name' => $bill->name]));
app('preferences')->mark();
- /** @var array $files */
- $files = $request->hasFile('attachments') ? $request->file('attachments') : null;
+ /** @var null|array $files */
+ $files = $request->hasFile('attachments') ? $request->file('attachments') : null;
if (null !== $files && !auth()->user()->hasRole('demo')) {
$this->attachments->saveAttachmentsForModel($bill, $files);
}
if (null !== $files && auth()->user()->hasRole('demo')) {
+ Log::channel('audit')->warning(sprintf('The demo user is trying to upload attachments in %s.', __METHOD__));
session()->flash('info', (string)trans('firefly.no_att_demo_user'));
}
diff --git a/app/Http/Controllers/Bill/DeleteController.php b/app/Http/Controllers/Bill/DeleteController.php
index 3499e40176..c69aa3d22f 100644
--- a/app/Http/Controllers/Bill/DeleteController.php
+++ b/app/Http/Controllers/Bill/DeleteController.php
@@ -42,8 +42,6 @@ class DeleteController extends Controller
/**
* BillController constructor.
- *
-
*/
public function __construct()
{
@@ -65,8 +63,6 @@ class DeleteController extends Controller
/**
* Delete a bill.
*
- * @param Bill $bill
- *
* @return Factory|View
*/
public function delete(Bill $bill)
@@ -81,10 +77,7 @@ class DeleteController extends Controller
/**
* Destroy a bill.
*
- * @param Request $request
- * @param Bill $bill
- *
- * @return RedirectResponse|Redirector
+ * @return Redirector|RedirectResponse
*/
public function destroy(Request $request, Bill $bill)
{
diff --git a/app/Http/Controllers/Bill/EditController.php b/app/Http/Controllers/Bill/EditController.php
index f3f9e935cb..73909da27d 100644
--- a/app/Http/Controllers/Bill/EditController.php
+++ b/app/Http/Controllers/Bill/EditController.php
@@ -33,6 +33,7 @@ use Illuminate\Contracts\View\Factory;
use Illuminate\Contracts\View\View;
use Illuminate\Http\RedirectResponse;
use Illuminate\Http\Request;
+use Illuminate\Support\Facades\Log;
/**
* Class EditController
@@ -44,8 +45,6 @@ class EditController extends Controller
/**
* BillController constructor.
- *
-
*/
public function __construct()
{
@@ -66,22 +65,20 @@ class EditController extends Controller
/**
* Edit a bill.
*
- * @param Request $request
- * @param Bill $bill
- *
* @return Factory|View
*/
public function edit(Request $request, Bill $bill)
{
- $periods = [];
+ $periods = [];
+
/** @var array $billPeriods */
- $billPeriods = config('firefly.bill_periods');
+ $billPeriods = config('firefly.bill_periods');
foreach ($billPeriods as $current) {
- $periods[$current] = (string)trans('firefly.' . $current);
+ $periods[$current] = (string)trans('firefly.'.$current);
}
- $subTitle = (string)trans('firefly.edit_bill', ['name' => $bill->name]);
+ $subTitle = (string)trans('firefly.edit_bill', ['name' => $bill->name]);
// put previous url in session if not redirect from store (not "return_to_edit").
if (true !== session('bills.edit.fromUpdate')) {
@@ -95,15 +92,15 @@ class EditController extends Controller
$defaultCurrency = app('amount')->getDefaultCurrency();
// code to handle active-checkboxes
- $hasOldInput = null !== $request->old('_token');
+ $hasOldInput = null !== $request->old('_token');
- $preFilled = [
+ $preFilled = [
'bill_end_date' => $bill->end_date,
'extension_date' => $bill->extension_date,
'notes' => $this->repository->getNoteText($bill),
'transaction_currency_id' => $bill->transaction_currency_id,
'active' => $hasOldInput ? (bool)$request->old('active') : $bill->active,
- 'object_group' => $bill->objectGroups->first() ? $bill->objectGroups->first()->title : '',
+ 'object_group' => null !== $bill->objectGroups->first() ? $bill->objectGroups->first()->title : '',
];
$request->session()->flash('preFilled', $preFilled);
@@ -114,26 +111,24 @@ class EditController extends Controller
/**
* Update a bill.
- *
- * @param BillUpdateRequest $request
- * @param Bill $bill
- *
- * @return RedirectResponse
*/
public function update(BillUpdateRequest $request, Bill $bill): RedirectResponse
{
$billData = $request->getBillData();
$bill = $this->repository->update($bill, $billData);
+ Log::channel('audit')->info(sprintf('Updated bill #%d.', $bill->id), $billData);
+
$request->session()->flash('success', (string)trans('firefly.updated_bill', ['name' => $bill->name]));
app('preferences')->mark();
- /** @var array $files */
- $files = $request->hasFile('attachments') ? $request->file('attachments') : null;
+ /** @var null|array $files */
+ $files = $request->hasFile('attachments') ? $request->file('attachments') : null;
if (null !== $files && !auth()->user()->hasRole('demo')) {
$this->attachments->saveAttachmentsForModel($bill, $files);
}
if (null !== $files && auth()->user()->hasRole('demo')) {
+ Log::channel('audit')->warning(sprintf('The demo user is trying to upload attachments in %s.', __METHOD__));
session()->flash('info', (string)trans('firefly.no_att_demo_user'));
}
diff --git a/app/Http/Controllers/Bill/IndexController.php b/app/Http/Controllers/Bill/IndexController.php
index 9c82002fc0..b78df5289c 100644
--- a/app/Http/Controllers/Bill/IndexController.php
+++ b/app/Http/Controllers/Bill/IndexController.php
@@ -30,11 +30,11 @@ use FireflyIII\Models\Bill;
use FireflyIII\Repositories\Bill\BillRepositoryInterface;
use FireflyIII\Repositories\ObjectGroup\OrganisesObjectGroups;
use FireflyIII\Transformers\BillTransformer;
+use Illuminate\Contracts\View\Factory;
+use Illuminate\Contracts\View\View;
+use Illuminate\Foundation\Application;
use Illuminate\Http\JsonResponse;
use Illuminate\Http\Request;
-use Illuminate\Support\Facades\Log;
-use Psr\Container\ContainerExceptionInterface;
-use Psr\Container\NotFoundExceptionInterface;
use Symfony\Component\HttpFoundation\ParameterBag;
/**
@@ -48,8 +48,6 @@ class IndexController extends Controller
/**
* BillController constructor.
- *
-
*/
public function __construct()
{
@@ -69,45 +67,46 @@ class IndexController extends Controller
/**
* Show all bills.
*/
- public function index()
+ public function index(): Application|Factory|\Illuminate\Contracts\Foundation\Application|View
{
$this->cleanupObjectGroups();
$this->repository->correctOrder();
- $start = session('start');
- $end = session('end');
- $collection = $this->repository->getBills();
- $total = $collection->count();
+ $start = session('start');
+ $end = session('end');
+ $collection = $this->repository->getBills();
+ $total = $collection->count();
$defaultCurrency = app('amount')->getDefaultCurrency();
$parameters = new ParameterBag();
// sub one day from temp start so the last paid date is one day before it should be.
- $tempStart = clone $start;
+ $tempStart = clone $start;
// 2023-06-23 do not sub one day from temp start, fix is in BillTransformer::payDates instead
- //$tempStart->subDay();
+ // $tempStart->subDay();
$parameters->set('start', $tempStart);
$parameters->set('end', $end);
/** @var BillTransformer $transformer */
- $transformer = app(BillTransformer::class);
+ $transformer = app(BillTransformer::class);
$transformer->setParameters($parameters);
// loop all bills, convert to array and add rules and stuff.
- $rules = $this->repository->getRulesForBills($collection);
+ $rules = $this->repository->getRulesForBills($collection);
// make bill groups:
- $bills = [
+ $bills = [
0 => [ // the index is the order, not the ID.
- 'object_group_id' => 0,
- 'object_group_title' => (string)trans('firefly.default_group_title_name'),
- 'bills' => [],
+ 'object_group_id' => 0,
+ 'object_group_title' => (string)trans('firefly.default_group_title_name'),
+ 'bills' => [],
],
];
+
/** @var Bill $bill */
foreach ($collection as $bill) {
- $array = $transformer->transform($bill);
- $groupOrder = (int)$array['object_group_order'];
+ $array = $transformer->transform($bill);
+ $groupOrder = (int)$array['object_group_order'];
// make group array if necessary:
- $bills[$groupOrder] = $bills[$groupOrder] ?? [
+ $bills[$groupOrder] ??= [
'object_group_id' => $array['object_group_id'],
'object_group_title' => $array['object_group_title'],
'bills' => [],
@@ -128,20 +127,15 @@ class IndexController extends Controller
ksort($bills);
// summarise per currency / per group.
- $sums = $this->getSums($bills);
- $totals = $this->getTotals($sums);
- $today = now()->startOfDay();
+ $sums = $this->getSums($bills);
+ $totals = $this->getTotals($sums);
+ $today = now()->startOfDay();
return view('bills.index', compact('bills', 'sums', 'total', 'totals', 'today'));
}
/**
- * @param array $bills
- *
- * @return array
* @throws FireflyException
- * @throws ContainerExceptionInterface
- * @throws NotFoundExceptionInterface
*/
private function getSums(array $bills): array
{
@@ -156,8 +150,8 @@ class IndexController extends Controller
continue;
}
- $currencyId = $bill['currency_id'];
- $sums[$groupOrder][$currencyId] = $sums[$groupOrder][$currencyId] ?? [
+ $currencyId = $bill['currency_id'];
+ $sums[$groupOrder][$currencyId] ??= [
'currency_id' => $currencyId,
'currency_code' => $bill['currency_code'],
'currency_name' => $bill['currency_name'],
@@ -167,8 +161,9 @@ class IndexController extends Controller
'period' => $range,
'per_period' => '0',
];
+
// only fill in avg when bill is active.
- if (count($bill['pay_dates']) > 0) {
+ if (null !== $bill['next_expected_match']) {
$avg = bcdiv(bcadd((string)$bill['amount_min'], (string)$bill['amount_max']), '2');
$avg = bcmul($avg, (string)count($bill['pay_dates']));
$sums[$groupOrder][$currencyId]['avg'] = bcadd($sums[$groupOrder][$currencyId]['avg'], $avg);
@@ -177,21 +172,16 @@ class IndexController extends Controller
$sums[$groupOrder][$currencyId]['per_period'] = bcadd($sums[$groupOrder][$currencyId]['per_period'], $this->amountPerPeriod($bill, $range));
}
}
+
return $sums;
}
- /**
- * @param array $bill
- * @param string $range
- *
- * @return string
- */
private function amountPerPeriod(array $bill, string $range): string
{
- $avg = bcdiv(bcadd((string)$bill['amount_min'], (string)$bill['amount_max']), '2');
+ $avg = bcdiv(bcadd((string)$bill['amount_min'], (string)$bill['amount_max']), '2');
- Log::debug(sprintf('Amount per period for bill #%d "%s"', $bill['id'], $bill['name']));
- Log::debug(sprintf('Average is %s', $avg));
+ app('log')->debug(sprintf('Amount per period for bill #%d "%s"', $bill['id'], $bill['name']));
+ app('log')->debug(sprintf('Average is %s', $avg));
// calculate amount per year:
$multiplies = [
'yearly' => '1',
@@ -202,10 +192,10 @@ class IndexController extends Controller
'daily' => '365.24',
];
$yearAmount = bcmul($avg, bcdiv($multiplies[$bill['repeat_freq']], (string)($bill['skip'] + 1)));
- Log::debug(sprintf('Amount per year is %s (%s * %s / %s)', $yearAmount, $avg, $multiplies[$bill['repeat_freq']], (string)($bill['skip'] + 1)));
+ app('log')->debug(sprintf('Amount per year is %s (%s * %s / %s)', $yearAmount, $avg, $multiplies[$bill['repeat_freq']], (string)($bill['skip'] + 1)));
// per period:
- $division = [
+ $division = [
'1Y' => '1',
'6M' => '2',
'3M' => '4',
@@ -220,24 +210,20 @@ class IndexController extends Controller
'last90' => '4',
'last365' => '1',
];
- $perPeriod = bcdiv($yearAmount, $division[$range]);
+ $perPeriod = bcdiv($yearAmount, $division[$range]);
- Log::debug(sprintf('Amount per %s is %s (%s / %s)', $range, $perPeriod, $yearAmount, $division[$range]));
+ app('log')->debug(sprintf('Amount per %s is %s (%s / %s)', $range, $perPeriod, $yearAmount, $division[$range]));
return $perPeriod;
}
- /**
- * @param array $sums
- *
- * @return array
- */
private function getTotals(array $sums): array
{
$totals = [];
if (count($sums) < 2) {
return [];
}
+
/**
* @var array $array
*/
@@ -247,7 +233,7 @@ class IndexController extends Controller
* @var array $entry
*/
foreach ($array as $currencyId => $entry) {
- $totals[$currencyId] = $totals[$currencyId] ?? [
+ $totals[$currencyId] ??= [
'currency_id' => $currencyId,
'currency_code' => $entry['currency_code'],
'currency_name' => $entry['currency_name'],
@@ -267,11 +253,6 @@ class IndexController extends Controller
/**
* Set the order of a bill.
- *
- * @param Request $request
- * @param Bill $bill
- *
- * @return JsonResponse
*/
public function setOrder(Request $request, Bill $bill): JsonResponse
{
diff --git a/app/Http/Controllers/Bill/ShowController.php b/app/Http/Controllers/Bill/ShowController.php
index 327c84c5f9..b0764bcd83 100644
--- a/app/Http/Controllers/Bill/ShowController.php
+++ b/app/Http/Controllers/Bill/ShowController.php
@@ -41,8 +41,6 @@ use Illuminate\View\View;
use League\Fractal\Manager;
use League\Fractal\Resource\Item;
use League\Fractal\Serializer\DataArraySerializer;
-use Psr\Container\ContainerExceptionInterface;
-use Psr\Container\NotFoundExceptionInterface;
use Symfony\Component\HttpFoundation\ParameterBag;
/**
@@ -54,8 +52,6 @@ class ShowController extends Controller
/**
* BillController constructor.
- *
-
*/
public function __construct()
{
@@ -77,24 +73,17 @@ class ShowController extends Controller
/**
* Rescan bills for transactions.
*
- * @param Request $request
- * @param Bill $bill
- *
- * @return RedirectResponse|Redirector
+ * @return Redirector|RedirectResponse
*/
public function rescan(Request $request, Bill $bill)
{
- $total = 0;
+ $total = 0;
if (false === $bill->active) {
$request->session()->flash('warning', (string)trans('firefly.cannot_scan_inactive_bill'));
return redirect(route('bills.show', [$bill->id]));
}
- $set = new Collection();
- if (true === $bill->active) {
- $set = $this->repository->getRulesForBill($bill);
- $total = 0;
- }
+ $set = $this->repository->getRulesForBill($bill);
if (0 === $set->count()) {
$request->session()->flash('error', (string)trans('firefly.no_rules_for_bill'));
@@ -112,7 +101,7 @@ class ShowController extends Controller
// file the rule(s)
$ruleEngine->fire();
- $request->session()->flash('success', (string)trans_choice('firefly.rescanned_bill', $total));
+ $request->session()->flash('success', trans_choice('firefly.rescanned_bill', $total));
app('preferences')->mark();
return redirect(route('bills.show', [$bill->id]));
@@ -121,56 +110,56 @@ class ShowController extends Controller
/**
* Show a bill.
*
- * @param Request $request
- * @param Bill $bill
- *
* @return Factory|View
- * @throws ContainerExceptionInterface
- * @throws NotFoundExceptionInterface
*/
public function show(Request $request, Bill $bill)
{
// add info about rules:
- $rules = $this->repository->getRulesForBill($bill);
- $subTitle = $bill->name;
+ $rules = $this->repository->getRulesForBill($bill);
+ $subTitle = $bill->name;
+
/** @var Carbon $start */
- $start = session('start');
+ $start = session('start');
+
/** @var Carbon $end */
- $end = session('end');
- $year = $start->year;
- $page = (int)$request->get('page');
- $pageSize = (int)app('preferences')->get('listPageSize', 50)->data;
- $yearAverage = $this->repository->getYearAverage($bill, $start);
- $overallAverage = $this->repository->getOverallAverage($bill);
- $manager = new Manager();
+ $end = session('end');
+ $year = $start->year;
+ $page = (int)$request->get('page');
+ $pageSize = (int)app('preferences')->get('listPageSize', 50)->data;
+ $yearAverage = $this->repository->getYearAverage($bill, $start);
+ $overallAverage = $this->repository->getOverallAverage($bill);
+ $manager = new Manager();
$manager->setSerializer(new DataArraySerializer());
$manager->parseIncludes(['attachments', 'notes']);
+ // add another period to end, could fix 8163
+ $range = app('navigation')->getViewRange(true);
+ $end = app('navigation')->addPeriod($end, $range);
+
// Make a resource out of the data and
- $parameters = new ParameterBag();
+ $parameters = new ParameterBag();
$parameters->set('start', $start);
$parameters->set('end', $end);
/** @var BillTransformer $transformer */
- $transformer = app(BillTransformer::class);
+ $transformer = app(BillTransformer::class);
$transformer->setParameters($parameters);
$resource = new Item($bill, $transformer, 'bill');
$object = $manager->createData($resource)->toArray();
$object['data']['currency'] = $bill->transactionCurrency;
-
/** @var GroupCollectorInterface $collector */
- $collector = app(GroupCollectorInterface::class);
+ $collector = app(GroupCollectorInterface::class);
$collector->setBill($bill)->setLimit($pageSize)->setPage($page)->withBudgetInformation()
- ->withCategoryInformation()->withAccountInformation();
- $groups = $collector->getPaginatedGroups();
+ ->withCategoryInformation()->withAccountInformation()
+ ;
+ $groups = $collector->getPaginatedGroups();
$groups->setPath(route('bills.show', [$bill->id]));
// transform any attachments as well.
- $collection = $this->repository->getAttachments($bill);
- $attachments = new Collection();
-
+ $collection = $this->repository->getAttachments($bill);
+ $attachments = new Collection();
if ($collection->count() > 0) {
/** @var AttachmentTransformer $transformer */
@@ -182,7 +171,6 @@ class ShowController extends Controller
);
}
-
return view('bills.show', compact('attachments', 'groups', 'rules', 'yearAverage', 'overallAverage', 'year', 'object', 'bill', 'subTitle'));
}
}
diff --git a/app/Http/Controllers/Budget/BudgetLimitController.php b/app/Http/Controllers/Budget/BudgetLimitController.php
index ee6c02d6b2..a293e25fae 100644
--- a/app/Http/Controllers/Budget/BudgetLimitController.php
+++ b/app/Http/Controllers/Budget/BudgetLimitController.php
@@ -32,7 +32,7 @@ use FireflyIII\Models\TransactionCurrency;
use FireflyIII\Repositories\Budget\BudgetLimitRepositoryInterface;
use FireflyIII\Repositories\Budget\BudgetRepositoryInterface;
use FireflyIII\Repositories\Budget\OperationsRepositoryInterface;
-use FireflyIII\Repositories\Currency\CurrencyRepositoryInterface;
+use FireflyIII\Repositories\UserGroups\Currency\CurrencyRepositoryInterface;
use FireflyIII\Support\Http\Controllers\DateCalculation;
use Illuminate\Contracts\View\Factory;
use Illuminate\Http\JsonResponse;
@@ -40,11 +40,9 @@ use Illuminate\Http\RedirectResponse;
use Illuminate\Http\Request;
use Illuminate\Routing\Redirector;
use Illuminate\Support\Collection;
-use Illuminate\Support\Facades\Log;
use Illuminate\View\View;
/**
- *
* Class BudgetLimitController
*/
class BudgetLimitController extends Controller
@@ -77,10 +75,6 @@ class BudgetLimitController extends Controller
}
/**
- * @param Budget $budget
- * @param Carbon $start
- * @param Carbon $end
- *
* @return Factory|View
*/
public function create(Budget $budget, Carbon $start, Carbon $end)
@@ -89,7 +83,7 @@ class BudgetLimitController extends Controller
$budgetLimits = $this->blRepository->getBudgetLimits($budget, $start, $end);
// remove already budgeted currencies with the same date range
- $currencies = $collection->filter(
+ $currencies = $collection->filter(
static function (TransactionCurrency $currency) use ($budgetLimits, $start, $end) {
/** @var BudgetLimit $limit */
foreach ($budgetLimits as $limit) {
@@ -107,12 +101,9 @@ class BudgetLimitController extends Controller
}
/**
- * @param Request $request
- * @param BudgetLimit $budgetLimit
- *
- * @return RedirectResponse|Redirector
+ * @return Redirector|RedirectResponse
*/
- public function delete(Request $request, BudgetLimit $budgetLimit)
+ public function delete(BudgetLimit $budgetLimit)
{
$this->blRepository->destroyBudgetLimit($budgetLimit);
session()->flash('success', trans('firefly.deleted_bl'));
@@ -123,23 +114,25 @@ class BudgetLimitController extends Controller
/**
* TODO why redirect AND json response?
*
- * @param Request $request
- *
- * @return RedirectResponse|JsonResponse
* @throws FireflyException
*/
- public function store(Request $request): RedirectResponse | JsonResponse
+ public function store(Request $request): JsonResponse|RedirectResponse
{
- Log::debug('Going to store new budget-limit.', $request->all());
+ app('log')->debug('Going to store new budget-limit.', $request->all());
// first search for existing one and update it if necessary.
$currency = $this->currencyRepos->find((int)$request->get('transaction_currency_id'));
$budget = $this->repository->find((int)$request->get('budget_id'));
if (null === $currency || null === $budget) {
throw new FireflyException('No valid currency or budget.');
}
- $start = Carbon::createFromFormat('Y-m-d', $request->get('start'));
- $end = Carbon::createFromFormat('Y-m-d', $request->get('end'));
- $amount = (string)$request->get('amount');
+ $start = Carbon::createFromFormat('Y-m-d', $request->get('start'));
+ $end = Carbon::createFromFormat('Y-m-d', $request->get('end'));
+
+ if (false === $start || false === $end) {
+ return response()->json([]);
+ }
+
+ $amount = (string)$request->get('amount');
$start->startOfDay();
$end->startOfDay();
@@ -147,15 +140,16 @@ class BudgetLimitController extends Controller
return response()->json([]);
}
- Log::debug(sprintf('Start: %s, end: %s', $start->format('Y-m-d'), $end->format('Y-m-d')));
+ app('log')->debug(sprintf('Start: %s, end: %s', $start->format('Y-m-d'), $end->format('Y-m-d')));
- $limit = $this->blRepository->find($budget, $currency, $start, $end);
+ $limit = $this->blRepository->find($budget, $currency, $start, $end);
// sanity check on amount:
if (0 === bccomp($amount, '0')) {
if (null !== $limit) {
$this->blRepository->destroyBudgetLimit($limit);
}
+
// return empty=ish array:
return response()->json([]);
}
@@ -183,15 +177,15 @@ class BudgetLimitController extends Controller
}
if ($request->expectsJson()) {
- $array = $limit->toArray();
+ $array = $limit->toArray();
// add some extra metadata:
- $spentArr = $this->opsRepository->sumExpenses($limit->start_date, $limit->end_date, null, new Collection([$budget]), $currency);
- $array['spent'] = $spentArr[$currency->id]['sum'] ?? '0';
- $array['left_formatted'] = app('amount')->formatAnything($limit->transactionCurrency, bcadd($array['spent'], $array['amount']));
- $array['amount_formatted'] = app('amount')->formatAnything($limit->transactionCurrency, $limit['amount']);
- $array['days_left'] = (string)$this->activeDaysLeft($start, $end);
+ $spentArr = $this->opsRepository->sumExpenses($limit->start_date, $limit->end_date, null, new Collection([$budget]), $currency);
+ $array['spent'] = $spentArr[$currency->id]['sum'] ?? '0';
+ $array['left_formatted'] = app('amount')->formatAnything($limit->transactionCurrency, bcadd($array['spent'], $array['amount']));
+ $array['amount_formatted'] = app('amount')->formatAnything($limit->transactionCurrency, $limit['amount']);
+ $array['days_left'] = (string)$this->activeDaysLeft($start, $end);
// left per day:
- $array['left_per_day'] = bcdiv(bcadd($array['spent'], $array['amount']), $array['days_left']);
+ $array['left_per_day'] = bcdiv(bcadd($array['spent'], $array['amount']), $array['days_left']);
// left per day formatted.
$array['left_per_day_formatted'] = app('amount')->formatAnything($limit->transactionCurrency, $array['left_per_day']);
@@ -202,56 +196,51 @@ class BudgetLimitController extends Controller
return redirect(route('budgets.index'));
}
- /**
- * @param Request $request
- * @param BudgetLimit $budgetLimit
- *
- * @return JsonResponse
- */
public function update(Request $request, BudgetLimit $budgetLimit): JsonResponse
{
- $amount = (string)$request->get('amount');
+ $amount = (string)$request->get('amount');
if ('' === $amount) {
$amount = '0';
}
-
+ if ((int)$amount > 268435456) { // 268 million, intentional integer
+ $amount = '268435456';
+ }
// sanity check on amount:
if (0 === bccomp($amount, '0')) {
$budgetId = $budgetLimit->budget_id;
$currency = $budgetLimit->transactionCurrency;
$this->blRepository->destroyBudgetLimit($budgetLimit);
- $array = [
+ $array = [
'budget_id' => $budgetId,
'left_formatted' => app('amount')->formatAnything($currency, '0'),
'left_per_day_formatted' => app('amount')->formatAnything($currency, '0'),
'transaction_currency_id' => $currency->id,
];
+
return response()->json($array);
}
- if ((int)$amount > 268435456) { // 268 million, intentional integer
- $amount = '268435456';
- }
+
if (-1 === bccomp($amount, '0')) {
$amount = bcmul($amount, '-1');
}
- $limit = $this->blRepository->update($budgetLimit, ['amount' => $amount]);
+ $limit = $this->blRepository->update($budgetLimit, ['amount' => $amount]);
app('preferences')->mark();
- $array = $limit->toArray();
+ $array = $limit->toArray();
- $spentArr = $this->opsRepository->sumExpenses(
+ $spentArr = $this->opsRepository->sumExpenses(
$limit->start_date,
$limit->end_date,
null,
new Collection([$budgetLimit->budget]),
$budgetLimit->transactionCurrency
);
- $array['spent'] = $spentArr[$budgetLimit->transactionCurrency->id]['sum'] ?? '0';
- $array['left_formatted'] = app('amount')->formatAnything($limit->transactionCurrency, bcadd($array['spent'], $array['amount']));
- $array['amount_formatted'] = app('amount')->formatAnything($limit->transactionCurrency, $limit['amount']);
- $array['days_left'] = (string)$this->activeDaysLeft($limit->start_date, $limit->end_date);
+ $array['spent'] = $spentArr[$budgetLimit->transactionCurrency->id]['sum'] ?? '0';
+ $array['left_formatted'] = app('amount')->formatAnything($limit->transactionCurrency, bcadd($array['spent'], $array['amount']));
+ $array['amount_formatted'] = app('amount')->formatAnything($limit->transactionCurrency, $limit['amount']);
+ $array['days_left'] = (string)$this->activeDaysLeft($limit->start_date, $limit->end_date);
// left per day:
- $array['left_per_day'] = bcdiv(bcadd($array['spent'], $array['amount']), $array['days_left']);
+ $array['left_per_day'] = bcdiv(bcadd($array['spent'], $array['amount']), $array['days_left']);
// left per day formatted.
$array['amount'] = app('steam')->bcround($limit['amount'], $limit->transactionCurrency->decimal_places);
diff --git a/app/Http/Controllers/Budget/CreateController.php b/app/Http/Controllers/Budget/CreateController.php
index da18c84c23..135305d1bf 100644
--- a/app/Http/Controllers/Budget/CreateController.php
+++ b/app/Http/Controllers/Budget/CreateController.php
@@ -32,6 +32,7 @@ use FireflyIII\Repositories\Budget\BudgetRepositoryInterface;
use Illuminate\Contracts\View\Factory;
use Illuminate\Http\RedirectResponse;
use Illuminate\Http\Request;
+use Illuminate\Support\Facades\Log;
use Illuminate\View\View;
/**
@@ -44,8 +45,6 @@ class CreateController extends Controller
/**
* CreateController constructor.
- *
-
*/
public function __construct()
{
@@ -65,13 +64,11 @@ class CreateController extends Controller
/**
* Form to create a budget.
*
- * @param Request $request
- *
* @return Factory|View
*/
public function create(Request $request)
{
- $hasOldInput = null !== $request->old('_token');
+ $hasOldInput = null !== $request->old('_token');
// auto budget types
$autoBudgetTypes = [
@@ -90,7 +87,7 @@ class CreateController extends Controller
];
$currency = app('amount')->getDefaultCurrency();
- $preFilled = [
+ $preFilled = [
'auto_budget_period' => $hasOldInput ? (bool)$request->old('auto_budget_period') : 'monthly',
'auto_budget_currency_id' => $hasOldInput ? (int)$request->old('auto_budget_currency_id') : $currency->id,
];
@@ -102,7 +99,7 @@ class CreateController extends Controller
$this->rememberPreviousUrl('budgets.create.url');
}
$request->session()->forget('budgets.create.fromStore');
- $subTitle = (string)trans('firefly.create_new_budget');
+ $subTitle = (string)trans('firefly.create_new_budget');
return view('budgets.create', compact('subTitle', 'autoBudgetTypes', 'autoBudgetPeriods'));
}
@@ -110,26 +107,27 @@ class CreateController extends Controller
/**
* Stores a budget.
*
- * @param BudgetFormStoreRequest $request
- *
- * @return RedirectResponse
* @throws FireflyException
*/
public function store(BudgetFormStoreRequest $request): RedirectResponse
{
- $data = $request->getBudgetData();
+ $data = $request->getBudgetData();
- $budget = $this->repository->store($data);
+ $budget = $this->repository->store($data);
$this->repository->cleanupBudgets();
$request->session()->flash('success', (string)trans('firefly.stored_new_budget', ['name' => $budget->name]));
app('preferences')->mark();
+ Log::channel('audit')->info('Stored new budget.', $data);
+
// store attachment(s):
- $files = $request->hasFile('attachments') ? $request->file('attachments') : null;
+ /** @var null|array $files */
+ $files = $request->hasFile('attachments') ? $request->file('attachments') : null;
if (null !== $files && !auth()->user()->hasRole('demo')) {
$this->attachments->saveAttachmentsForModel($budget, $files);
}
if (null !== $files && auth()->user()->hasRole('demo')) {
+ Log::channel('audit')->warning(sprintf('The demo user is trying to upload attachments in %s.', __METHOD__));
session()->flash('info', (string)trans('firefly.no_att_demo_user'));
}
diff --git a/app/Http/Controllers/Budget/DeleteController.php b/app/Http/Controllers/Budget/DeleteController.php
index bb8158395c..a817d0f74a 100644
--- a/app/Http/Controllers/Budget/DeleteController.php
+++ b/app/Http/Controllers/Budget/DeleteController.php
@@ -33,7 +33,6 @@ use Illuminate\Routing\Redirector;
use Illuminate\View\View;
/**
- *
* Class DeleteController
*/
class DeleteController extends Controller
@@ -43,8 +42,6 @@ class DeleteController extends Controller
/**
* DeleteController constructor.
- *
-
*/
public function __construct()
{
@@ -64,8 +61,6 @@ class DeleteController extends Controller
/**
* Deletes a budget.
*
- * @param Budget $budget
- *
* @return Factory|View
*/
public function delete(Budget $budget)
@@ -81,10 +76,7 @@ class DeleteController extends Controller
/**
* Destroys a budget.
*
- * @param Request $request
- * @param Budget $budget
- *
- * @return RedirectResponse|Redirector
+ * @return Redirector|RedirectResponse
*/
public function destroy(Request $request, Budget $budget)
{
diff --git a/app/Http/Controllers/Budget/EditController.php b/app/Http/Controllers/Budget/EditController.php
index 76a2bedbcd..39d9e18120 100644
--- a/app/Http/Controllers/Budget/EditController.php
+++ b/app/Http/Controllers/Budget/EditController.php
@@ -32,10 +32,10 @@ use FireflyIII\Repositories\Budget\BudgetRepositoryInterface;
use Illuminate\Contracts\View\Factory;
use Illuminate\Http\RedirectResponse;
use Illuminate\Http\Request;
+use Illuminate\Support\Facades\Log;
use Illuminate\View\View;
/**
- *
* Class EditController
*/
class EditController extends Controller
@@ -45,8 +45,6 @@ class EditController extends Controller
/**
* EditController constructor.
- *
-
*/
public function __construct()
{
@@ -67,15 +65,12 @@ class EditController extends Controller
/**
* Budget edit form.
*
- * @param Request $request
- * @param Budget $budget
- *
* @return Factory|View
*/
public function edit(Request $request, Budget $budget)
{
- $subTitle = (string)trans('firefly.edit_budget', ['name' => $budget->name]);
- $autoBudget = $this->repository->getAutoBudget($budget);
+ $subTitle = (string)trans('firefly.edit_budget', ['name' => $budget->name]);
+ $autoBudget = $this->repository->getAutoBudget($budget);
// auto budget types
$autoBudgetTypes = [
@@ -94,14 +89,18 @@ class EditController extends Controller
];
// code to handle active-checkboxes
- $hasOldInput = null !== $request->old('_token');
- $currency = app('amount')->getDefaultCurrency();
- $preFilled = [
+ $hasOldInput = null !== $request->old('_token');
+ $currency = app('amount')->getDefaultCurrency();
+ $preFilled = [
'active' => $hasOldInput ? (bool)$request->old('active') : $budget->active,
'auto_budget_currency_id' => $hasOldInput ? (int)$request->old('auto_budget_currency_id') : $currency->id,
];
- if ($autoBudget) {
+ if (null !== $autoBudget) {
$amount = $hasOldInput ? $request->old('auto_budget_amount') : $autoBudget->amount;
+ if (is_array($amount)) {
+ $amount = '0';
+ }
+ $amount = (string)$amount;
$preFilled['auto_budget_amount'] = app('steam')->bcround($amount, $autoBudget->transactionCurrency->decimal_places);
}
@@ -117,29 +116,28 @@ class EditController extends Controller
/**
* Budget update routine.
- *
- * @param BudgetFormUpdateRequest $request
- * @param Budget $budget
- *
- * @return RedirectResponse
*/
public function update(BudgetFormUpdateRequest $request, Budget $budget): RedirectResponse
{
- $data = $request->getBudgetData();
+ $data = $request->getBudgetData();
$this->repository->update($budget, $data);
$request->session()->flash('success', (string)trans('firefly.updated_budget', ['name' => $budget->name]));
$this->repository->cleanupBudgets();
app('preferences')->mark();
+ Log::channel('audit')->info(sprintf('Updated budget #%d.', $budget->id), $data);
+
$redirect = redirect($this->getPreviousUrl('budgets.edit.url'));
// store new attachment(s):
- $files = $request->hasFile('attachments') ? $request->file('attachments') : null;
+ /** @var null|array $files */
+ $files = $request->hasFile('attachments') ? $request->file('attachments') : null;
if (null !== $files && !auth()->user()->hasRole('demo')) {
$this->attachments->saveAttachmentsForModel($budget, $files);
}
if (null !== $files && auth()->user()->hasRole('demo')) {
+ Log::channel('audit')->warning(sprintf('The demo user is trying to upload attachments in %s.', __METHOD__));
session()->flash('info', (string)trans('firefly.no_att_demo_user'));
}
diff --git a/app/Http/Controllers/Budget/IndexController.php b/app/Http/Controllers/Budget/IndexController.php
index 550e1348a2..787cd0c2c2 100644
--- a/app/Http/Controllers/Budget/IndexController.php
+++ b/app/Http/Controllers/Budget/IndexController.php
@@ -34,20 +34,15 @@ use FireflyIII\Repositories\Budget\AvailableBudgetRepositoryInterface;
use FireflyIII\Repositories\Budget\BudgetLimitRepositoryInterface;
use FireflyIII\Repositories\Budget\BudgetRepositoryInterface;
use FireflyIII\Repositories\Budget\OperationsRepositoryInterface;
-use FireflyIII\Repositories\Currency\CurrencyRepositoryInterface;
+use FireflyIII\Repositories\UserGroups\Currency\CurrencyRepositoryInterface;
use FireflyIII\Support\Http\Controllers\DateCalculation;
use Illuminate\Contracts\View\Factory;
use Illuminate\Http\JsonResponse;
use Illuminate\Http\Request;
use Illuminate\Support\Collection;
-use Illuminate\Support\Facades\Log;
use Illuminate\View\View;
-use JsonException;
-use Psr\Container\ContainerExceptionInterface;
-use Psr\Container\NotFoundExceptionInterface;
/**
- *
* Class IndexController
*/
class IndexController extends Controller
@@ -62,8 +57,6 @@ class IndexController extends Controller
/**
* IndexController constructor.
- *
-
*/
public function __construct()
{
@@ -88,57 +81,48 @@ class IndexController extends Controller
/**
* Show all budgets.
*
- * @param Request $request
- *
- * @param Carbon|null $start
- * @param Carbon|null $end
- *
* @return Factory|View
+ *
* @throws FireflyException
- * @throws JsonException
- * @throws ContainerExceptionInterface
- * @throws NotFoundExceptionInterface
- */
- public function index(Request $request, Carbon $start = null, Carbon $end = null)
+ * */
+ public function index(Carbon $start = null, Carbon $end = null)
{
$this->abRepository->cleanup();
- Log::debug(sprintf('Start of IndexController::index("%s", "%s")', $start?->format('Y-m-d'), $end?->format('Y-m-d')));
+ app('log')->debug(sprintf('Start of IndexController::index("%s", "%s")', $start?->format('Y-m-d'), $end?->format('Y-m-d')));
// collect some basic vars:
- $range = app('navigation')->getViewRange(true);
- $isCustomRange = session('is_custom_range', false);
+ $range = app('navigation')->getViewRange(true);
+ $isCustomRange = session('is_custom_range', false);
if (false === $isCustomRange) {
- $start = $start ?? session('start', today(config('app.timezone'))->startOfMonth());
- $end = $end ?? app('navigation')->endOfPeriod($start, $range);
+ $start ??= session('start', today(config('app.timezone'))->startOfMonth());
+ $end ??= app('navigation')->endOfPeriod($start, $range);
}
// overrule start and end if necessary:
if (true === $isCustomRange) {
- $start = $start ?? session('start', today(config('app.timezone'))->startOfMonth());
- $end = $end ?? session('end', today(config('app.timezone'))->endOfMonth());
+ $start ??= session('start', today(config('app.timezone'))->startOfMonth());
+ $end ??= session('end', today(config('app.timezone'))->endOfMonth());
}
-
- $defaultCurrency = app('amount')->getDefaultCurrency();
- $currencies = $this->currencyRepository->get();
- $budgeted = '0';
- $spent = '0';
+ $defaultCurrency = app('amount')->getDefaultCurrency();
+ $currencies = $this->currencyRepository->get();
+ $budgeted = '0';
+ $spent = '0';
// new period stuff:
- $periodTitle = app('navigation')->periodShow($start, $range);
- $prevLoop = $this->getPreviousPeriods($start, $range);
- $nextLoop = $this->getNextPeriods($start, $range);
+ $periodTitle = app('navigation')->periodShow($start, $range);
+ $prevLoop = $this->getPreviousPeriods($start, $range);
+ $nextLoop = $this->getNextPeriods($start, $range);
// get all available budgets:
$availableBudgets = $this->getAllAvailableBudgets($start, $end);
-
// get all active budgets:
- $budgets = $this->getAllBudgets($start, $end, $currencies, $defaultCurrency);
- $sums = $this->getSums($budgets);
+ $budgets = $this->getAllBudgets($start, $end, $currencies, $defaultCurrency);
+ $sums = $this->getSums($budgets);
// get budgeted for default currency:
if (0 === count($availableBudgets)) {
- $budgeted = $this->blRepository->budgeted($start, $end, $defaultCurrency, );
+ $budgeted = $this->blRepository->budgeted($start, $end, $defaultCurrency);
$spentArr = $this->opsRepository->sumExpenses($start, $end, null, null, $defaultCurrency);
$spent = $spentArr[$defaultCurrency->id]['sum'] ?? '0';
unset($spentArr);
@@ -149,7 +133,7 @@ class IndexController extends Controller
$activeDaysLeft = $this->activeDaysLeft($start, $end); // see method description.
// get all inactive budgets, and simply list them:
- $inactive = $this->repository->getInactiveBudgets();
+ $inactive = $this->repository->getInactiveBudgets();
return view(
'budgets.index',
@@ -174,17 +158,12 @@ class IndexController extends Controller
);
}
- /**
- * @param Carbon $start
- * @param Carbon $end
- *
- * @return array
- */
private function getAllAvailableBudgets(Carbon $start, Carbon $end): array
{
// get all available budgets.
$ab = $this->abRepository->get($start, $end);
$availableBudgets = [];
+
// for each, complement with spent amount:
/** @var AvailableBudget $entry */
foreach ($ab as $entry) {
@@ -193,38 +172,30 @@ class IndexController extends Controller
$array['end_date'] = $entry->end_date;
// spent in period:
- $spentArr = $this->opsRepository->sumExpenses($entry->start_date, $entry->end_date, null, null, $entry->transactionCurrency);
- $array['spent'] = $spentArr[$entry->transaction_currency_id]['sum'] ?? '0';
+ $spentArr = $this->opsRepository->sumExpenses($entry->start_date, $entry->end_date, null, null, $entry->transactionCurrency);
+ $array['spent'] = $spentArr[$entry->transaction_currency_id]['sum'] ?? '0';
// budgeted in period:
- $budgeted = $this->blRepository->budgeted($entry->start_date, $entry->end_date, $entry->transactionCurrency, );
- $array['budgeted'] = $budgeted;
- $availableBudgets[] = $array;
+ $budgeted = $this->blRepository->budgeted($entry->start_date, $entry->end_date, $entry->transactionCurrency);
+ $array['budgeted'] = $budgeted;
+ $availableBudgets[] = $array;
unset($spentArr);
}
return $availableBudgets;
}
- /**
- * @param Carbon $start
- * @param Carbon $end
- * @param Collection $currencies
- * @param TransactionCurrency $defaultCurrency
- *
- * @return array
- */
private function getAllBudgets(Carbon $start, Carbon $end, Collection $currencies, TransactionCurrency $defaultCurrency): array
{
// get all budgets, and paginate them into $budgets.
$collection = $this->repository->getActiveBudgets();
$budgets = [];
- Log::debug(sprintf('7) Start is "%s", end is "%s"', $start->format('Y-m-d H:i:s'), $end->format('Y-m-d H:i:s')));
+ app('log')->debug(sprintf('7) Start is "%s", end is "%s"', $start->format('Y-m-d H:i:s'), $end->format('Y-m-d H:i:s')));
// complement budget with budget limits in range, and expenses in currency X in range.
/** @var Budget $current */
foreach ($collection as $current) {
- Log::debug(sprintf('Working on budget #%d ("%s")', $current->id, $current->name));
+ app('log')->debug(sprintf('Working on budget #%d ("%s")', $current->id, $current->name));
$array = $current->toArray();
$array['spent'] = [];
$array['spent_total'] = [];
@@ -232,9 +203,10 @@ class IndexController extends Controller
$array['attachments'] = $this->repository->getAttachments($current);
$array['auto_budget'] = $this->repository->getAutoBudget($current);
$budgetLimits = $this->blRepository->getBudgetLimits($current, $start, $end);
+
/** @var BudgetLimit $limit */
foreach ($budgetLimits as $limit) {
- Log::debug(sprintf('Working on budget limit #%d', $limit->id));
+ app('log')->debug(sprintf('Working on budget limit #%d', $limit->id));
$currency = $limit->transactionCurrency ?? $defaultCurrency;
$amount = app('steam')->bcround($limit->amount, $currency->decimal_places);
$array['budgeted'][] = [
@@ -248,7 +220,7 @@ class IndexController extends Controller
'currency_name' => $currency->name,
'currency_decimal_places' => $currency->decimal_places,
];
- Log::debug(sprintf('The amount budgeted for budget limit #%d is %s %s', $limit->id, $currency->code, $amount));
+ app('log')->debug(sprintf('The amount budgeted for budget limit #%d is %s %s', $limit->id, $currency->code, $amount));
}
/** @var TransactionCurrency $currency */
@@ -261,17 +233,12 @@ class IndexController extends Controller
$array['spent'][$currency->id]['currency_decimal_places'] = $currency->decimal_places;
}
}
- $budgets[] = $array;
+ $budgets[] = $array;
}
return $budgets;
}
- /**
- * @param array $budgets
- *
- * @return array
- */
private function getSums(array $budgets): array
{
$sums = [
@@ -286,13 +253,12 @@ class IndexController extends Controller
foreach ($budget['spent'] as $spent) {
$currencyId = $spent['currency_id'];
$sums['spent'][$currencyId]
- = $sums['spent'][$currencyId]
- ?? [
- 'amount' => '0',
- 'currency_id' => $spent['currency_id'],
- 'currency_symbol' => $spent['currency_symbol'],
- 'currency_decimal_places' => $spent['currency_decimal_places'],
- ];
+ ??= [
+ 'amount' => '0',
+ 'currency_id' => $spent['currency_id'],
+ 'currency_symbol' => $spent['currency_symbol'],
+ 'currency_decimal_places' => $spent['currency_decimal_places'],
+ ];
$sums['spent'][$currencyId]['amount'] = bcadd($sums['spent'][$currencyId]['amount'], $spent['spent']);
}
@@ -300,31 +266,30 @@ class IndexController extends Controller
foreach ($budget['budgeted'] as $budgeted) {
$currencyId = $budgeted['currency_id'];
$sums['budgeted'][$currencyId]
- = $sums['budgeted'][$currencyId]
- ?? [
- 'amount' => '0',
- 'currency_id' => $budgeted['currency_id'],
- 'currency_symbol' => $budgeted['currency_symbol'],
- 'currency_decimal_places' => $budgeted['currency_decimal_places'],
- ];
+ ??= [
+ 'amount' => '0',
+ 'currency_id' => $budgeted['currency_id'],
+ 'currency_symbol' => $budgeted['currency_symbol'],
+ 'currency_decimal_places' => $budgeted['currency_decimal_places'],
+ ];
$sums['budgeted'][$currencyId]['amount'] = bcadd($sums['budgeted'][$currencyId]['amount'], $budgeted['amount']);
// also calculate how much left from budgeted:
- $sums['left'][$currencyId] = $sums['left'][$currencyId]
- ?? [
- 'amount' => '0',
- 'currency_id' => $budgeted['currency_id'],
- 'currency_symbol' => $budgeted['currency_symbol'],
- 'currency_decimal_places' => $budgeted['currency_decimal_places'],
- ];
+ $sums['left'][$currencyId]
+ ??= [
+ 'amount' => '0',
+ 'currency_id' => $budgeted['currency_id'],
+ 'currency_symbol' => $budgeted['currency_symbol'],
+ 'currency_decimal_places' => $budgeted['currency_decimal_places'],
+ ];
}
}
+
// final calculation for 'left':
/**
- * @var int $currencyId
- * @var array $info
+ * @var int $currencyId
*/
- foreach ($sums['budgeted'] as $currencyId => $info) {
+ foreach (array_keys($sums['budgeted']) as $currencyId) {
$spent = $sums['spent'][$currencyId]['amount'] ?? '0';
$budgeted = $sums['budgeted'][$currencyId]['amount'] ?? '0';
$sums['left'][$currencyId]['amount'] = bcadd($spent, $budgeted);
@@ -333,12 +298,6 @@ class IndexController extends Controller
return $sums;
}
- /**
- * @param Request $request
- * @param BudgetRepositoryInterface $repository
- *
- * @return JsonResponse
- */
public function reorder(Request $request, BudgetRepositoryInterface $repository): JsonResponse
{
$this->abRepository->cleanup();
@@ -348,7 +307,7 @@ class IndexController extends Controller
$budgetId = (int)$budgetId;
$budget = $repository->find($budgetId);
if (null !== $budget) {
- Log::debug(sprintf('Set budget #%d ("%s") to position %d', $budget->id, $budget->name, $index + 1));
+ app('log')->debug(sprintf('Set budget #%d ("%s") to position %d', $budget->id, $budget->name, $index + 1));
$repository->setBudgetOrder($budget, $index + 1);
}
}
diff --git a/app/Http/Controllers/Budget/ShowController.php b/app/Http/Controllers/Budget/ShowController.php
index c07af019e7..7ad24fbe5a 100644
--- a/app/Http/Controllers/Budget/ShowController.php
+++ b/app/Http/Controllers/Budget/ShowController.php
@@ -37,25 +37,20 @@ use FireflyIII\Support\Http\Controllers\PeriodOverview;
use Illuminate\Contracts\View\Factory;
use Illuminate\Http\Request;
use Illuminate\View\View;
-use Psr\Container\ContainerExceptionInterface;
-use Psr\Container\NotFoundExceptionInterface;
/**
- *
* Class ShowController
*/
class ShowController extends Controller
{
- use PeriodOverview;
use AugumentData;
+ use PeriodOverview;
protected JournalRepositoryInterface $journalRepos;
private BudgetRepositoryInterface $repository;
/**
* ShowController constructor.
- *
-
*/
public function __construct()
{
@@ -76,22 +71,17 @@ class ShowController extends Controller
/**
* Show transactions without a budget.
*
- * @param Request $request
- * @param Carbon|null $start
- * @param Carbon|null $end
- *
* @return Factory|View
+ *
* @throws FireflyException
- * @throws ContainerExceptionInterface
- * @throws NotFoundExceptionInterface
*/
public function noBudget(Request $request, Carbon $start = null, Carbon $end = null)
{
- /** @var Carbon $start */
- $start = $start ?? session('start');
- /** @var Carbon $end */
- $end = $end ?? session('end');
- $subTitle = trans(
+ // @var Carbon $start
+ $start ??= session('start');
+ // @var Carbon $end
+ $end ??= session('end');
+ $subTitle = trans(
'firefly.without_budget_between',
['start' => $start->isoFormat($this->monthAndDayFormat), 'end' => $end->isoFormat($this->monthAndDayFormat)]
);
@@ -106,8 +96,9 @@ class ShowController extends Controller
/** @var GroupCollectorInterface $collector */
$collector = app(GroupCollectorInterface::class);
$collector->setRange($start, $end)->setTypes([TransactionType::WITHDRAWAL])->setLimit($pageSize)->setPage($page)
- ->withoutBudget()->withAccountInformation()->withCategoryInformation();
- $groups = $collector->getPaginatedGroups();
+ ->withoutBudget()->withAccountInformation()->withCategoryInformation()
+ ;
+ $groups = $collector->getPaginatedGroups();
$groups->setPath(route('budgets.no-budget'));
return view('budgets.no-budget', compact('groups', 'subTitle', 'periods', 'start', 'end'));
@@ -116,26 +107,23 @@ class ShowController extends Controller
/**
* Shows ALL transactions without a budget.
*
- * @param Request $request
- *
* @return Factory|View
- * @throws ContainerExceptionInterface
- * @throws NotFoundExceptionInterface
*/
public function noBudgetAll(Request $request)
{
- $subTitle = (string)trans('firefly.all_journals_without_budget');
- $first = $this->journalRepos->firstNull();
- $start = null === $first ? new Carbon() : $first->date;
- $end = today(config('app.timezone'));
- $page = (int)$request->get('page');
- $pageSize = (int)app('preferences')->get('listPageSize', 50)->data;
+ $subTitle = (string)trans('firefly.all_journals_without_budget');
+ $first = $this->journalRepos->firstNull();
+ $start = null === $first ? new Carbon() : $first->date;
+ $end = today(config('app.timezone'));
+ $page = (int)$request->get('page');
+ $pageSize = (int)app('preferences')->get('listPageSize', 50)->data;
/** @var GroupCollectorInterface $collector */
$collector = app(GroupCollectorInterface::class);
$collector->setRange($start, $end)->setTypes([TransactionType::WITHDRAWAL])->setLimit($pageSize)->setPage($page)
- ->withoutBudget()->withAccountInformation()->withCategoryInformation();
- $groups = $collector->getPaginatedGroups();
+ ->withoutBudget()->withAccountInformation()->withCategoryInformation()
+ ;
+ $groups = $collector->getPaginatedGroups();
$groups->setPath(route('budgets.no-budget-all'));
return view('budgets.no-budget', compact('groups', 'subTitle', 'start', 'end'));
@@ -144,12 +132,7 @@ class ShowController extends Controller
/**
* Show a single budget.
*
- * @param Request $request
- * @param Budget $budget
- *
* @return Factory|View
- * @throws ContainerExceptionInterface
- * @throws NotFoundExceptionInterface
*/
public function show(Request $request, Budget $budget)
{
@@ -164,14 +147,15 @@ class ShowController extends Controller
// collector:
/** @var GroupCollectorInterface $collector */
- $collector = app(GroupCollectorInterface::class);
+ $collector = app(GroupCollectorInterface::class);
$collector->setRange($allStart, $allEnd)->setBudget($budget)
- ->withAccountInformation()
- ->setLimit($pageSize)->setPage($page)->withBudgetInformation()->withCategoryInformation();
- $groups = $collector->getPaginatedGroups();
+ ->withAccountInformation()
+ ->setLimit($pageSize)->setPage($page)->withBudgetInformation()->withCategoryInformation()
+ ;
+ $groups = $collector->getPaginatedGroups();
$groups->setPath(route('budgets.show', [$budget->id]));
- $subTitle = (string)trans('firefly.all_journals_for_budget', ['name' => $budget->name]);
+ $subTitle = (string)trans('firefly.all_journals_for_budget', ['name' => $budget->name]);
return view('budgets.show', compact('limits', 'attachments', 'budget', 'repetition', 'groups', 'subTitle'));
}
@@ -179,14 +163,9 @@ class ShowController extends Controller
/**
* Show a single budget by a budget limit.
*
- * @param Request $request
- * @param Budget $budget
- * @param BudgetLimit $budgetLimit
- *
* @return Factory|View
+ *
* @throws FireflyException
- * @throws ContainerExceptionInterface
- * @throws NotFoundExceptionInterface
*/
public function showByBudgetLimit(Request $request, Budget $budget, BudgetLimit $budgetLimit)
{
@@ -194,9 +173,9 @@ class ShowController extends Controller
throw new FireflyException('This budget limit is not part of this budget.');
}
- $page = (int)$request->get('page');
- $pageSize = (int)app('preferences')->get('listPageSize', 50)->data;
- $subTitle = trans(
+ $page = (int)$request->get('page');
+ $pageSize = (int)app('preferences')->get('listPageSize', 50)->data;
+ $subTitle = trans(
'firefly.budget_in_period',
[
'name' => $budget->name,
@@ -208,12 +187,14 @@ class ShowController extends Controller
// collector:
/** @var GroupCollectorInterface $collector */
- $collector = app(GroupCollectorInterface::class);
+ $collector = app(GroupCollectorInterface::class);
$collector->setRange($budgetLimit->start_date, $budgetLimit->end_date)->withAccountInformation()
- ->setBudget($budget)->setLimit($pageSize)->setPage($page)->withBudgetInformation()->withCategoryInformation();
- $groups = $collector->getPaginatedGroups();
+ ->setBudget($budget)->setLimit($pageSize)->setPage($page)->withBudgetInformation()->withCategoryInformation()
+ ;
+ $groups = $collector->getPaginatedGroups();
$groups->setPath(route('budgets.show.limit', [$budget->id, $budgetLimit->id]));
+
/** @var Carbon $start */
$start = session('first', today(config('app.timezone'))->startOfYear());
$end = today(config('app.timezone'));
diff --git a/app/Http/Controllers/Category/CreateController.php b/app/Http/Controllers/Category/CreateController.php
index 77e2b7ea83..95ef28ab02 100644
--- a/app/Http/Controllers/Category/CreateController.php
+++ b/app/Http/Controllers/Category/CreateController.php
@@ -32,6 +32,7 @@ use Illuminate\Contracts\View\Factory;
use Illuminate\Http\RedirectResponse;
use Illuminate\Http\Request;
use Illuminate\Routing\Redirector;
+use Illuminate\Support\Facades\Log;
use Illuminate\View\View;
/**
@@ -44,8 +45,6 @@ class CreateController extends Controller
/**
* CategoryController constructor.
- *
-
*/
public function __construct()
{
@@ -66,8 +65,6 @@ class CreateController extends Controller
/**
* Create category.
*
- * @param Request $request
- *
* @return Factory|View
*/
public function create(Request $request)
@@ -84,9 +81,8 @@ class CreateController extends Controller
/**
* Store new category.
*
- * @param CategoryFormRequest $request
+ * @return $this|Redirector|RedirectResponse
*
- * @return $this|RedirectResponse|Redirector
* @throws FireflyException
*/
public function store(CategoryFormRequest $request)
@@ -98,11 +94,13 @@ class CreateController extends Controller
app('preferences')->mark();
// store attachment(s):
- $files = $request->hasFile('attachments') ? $request->file('attachments') : null;
+ /** @var null|array $files */
+ $files = $request->hasFile('attachments') ? $request->file('attachments') : null;
if (null !== $files && !auth()->user()->hasRole('demo')) {
$this->attachments->saveAttachmentsForModel($category, $files);
}
if (null !== $files && auth()->user()->hasRole('demo')) {
+ Log::channel('audit')->warning(sprintf('The demo user is trying to upload attachments in %s.', __METHOD__));
session()->flash('info', (string)trans('firefly.no_att_demo_user'));
}
diff --git a/app/Http/Controllers/Category/DeleteController.php b/app/Http/Controllers/Category/DeleteController.php
index 78b87dc95e..0c2db15c03 100644
--- a/app/Http/Controllers/Category/DeleteController.php
+++ b/app/Http/Controllers/Category/DeleteController.php
@@ -42,8 +42,6 @@ class DeleteController extends Controller
/**
* CategoryController constructor.
- *
-
*/
public function __construct()
{
@@ -63,8 +61,6 @@ class DeleteController extends Controller
/**
* Delete a category.
*
- * @param Category $category
- *
* @return Factory|View
*/
public function delete(Category $category)
@@ -80,10 +76,7 @@ class DeleteController extends Controller
/**
* Destroy a category.
*
- * @param Request $request
- * @param Category $category
- *
- * @return RedirectResponse|Redirector
+ * @return Redirector|RedirectResponse
*/
public function destroy(Request $request, Category $category)
{
diff --git a/app/Http/Controllers/Category/EditController.php b/app/Http/Controllers/Category/EditController.php
index ba3c591c9d..734d93ddfb 100644
--- a/app/Http/Controllers/Category/EditController.php
+++ b/app/Http/Controllers/Category/EditController.php
@@ -32,6 +32,7 @@ use Illuminate\Contracts\View\Factory;
use Illuminate\Http\RedirectResponse;
use Illuminate\Http\Request;
use Illuminate\Routing\Redirector;
+use Illuminate\Support\Facades\Log;
use Illuminate\View\View;
/**
@@ -44,8 +45,6 @@ class EditController extends Controller
/**
* CategoryController constructor.
- *
-
*/
public function __construct()
{
@@ -66,14 +65,11 @@ class EditController extends Controller
/**
* Edit a category.
*
- * @param Request $request
- * @param Category $category
- *
* @return Factory|View
*/
public function edit(Request $request, Category $category)
{
- $subTitle = (string)trans('firefly.edit_category', ['name' => $category->name]);
+ $subTitle = (string)trans('firefly.edit_category', ['name' => $category->name]);
// put previous url in session if not redirect from store (not "return_to_edit").
if (true !== session('categories.edit.fromUpdate')) {
@@ -91,25 +87,24 @@ class EditController extends Controller
/**
* Update category.
*
- * @param CategoryFormRequest $request
- * @param Category $category
- *
- * @return RedirectResponse|Redirector
+ * @return Redirector|RedirectResponse
*/
public function update(CategoryFormRequest $request, Category $category)
{
- $data = $request->getCategoryData();
+ $data = $request->getCategoryData();
$this->repository->update($category, $data);
$request->session()->flash('success', (string)trans('firefly.updated_category', ['name' => $category->name]));
app('preferences')->mark();
// store new attachment(s):
- $files = $request->hasFile('attachments') ? $request->file('attachments') : null;
+ /** @var null|array $files */
+ $files = $request->hasFile('attachments') ? $request->file('attachments') : null;
if (null !== $files && !auth()->user()->hasRole('demo')) {
$this->attachments->saveAttachmentsForModel($category, $files);
}
if (null !== $files && auth()->user()->hasRole('demo')) {
+ Log::channel('audit')->warning(sprintf('The demo user is trying to upload attachments in %s.', __METHOD__));
session()->flash('info', (string)trans('firefly.no_att_demo_user'));
}
diff --git a/app/Http/Controllers/Category/IndexController.php b/app/Http/Controllers/Category/IndexController.php
index 5dc6e902ac..e6b7f8c1f1 100644
--- a/app/Http/Controllers/Category/IndexController.php
+++ b/app/Http/Controllers/Category/IndexController.php
@@ -31,8 +31,6 @@ use Illuminate\Http\Request;
use Illuminate\Pagination\LengthAwarePaginator;
use Illuminate\Support\Collection;
use Illuminate\View\View;
-use Psr\Container\ContainerExceptionInterface;
-use Psr\Container\NotFoundExceptionInterface;
/**
* Class IndexController
@@ -44,8 +42,6 @@ class IndexController extends Controller
/**
* CategoryController constructor.
- *
-
*/
public function __construct()
{
@@ -65,11 +61,7 @@ class IndexController extends Controller
/**
* Show all categories.
*
- * @param Request $request
- *
* @return Factory|View
- * @throws ContainerExceptionInterface
- * @throws NotFoundExceptionInterface
*/
public function index(Request $request)
{
@@ -80,7 +72,7 @@ class IndexController extends Controller
$collection = $collection->slice(($page - 1) * $pageSize, $pageSize);
$collection->each(
- function (Category $category) {
+ function (Category $category): void {
$category->lastActivity = $this->repository->lastUseDate($category, new Collection());
}
);
diff --git a/app/Http/Controllers/Category/NoCategoryController.php b/app/Http/Controllers/Category/NoCategoryController.php
index 3b8d7bb4b3..212c955442 100644
--- a/app/Http/Controllers/Category/NoCategoryController.php
+++ b/app/Http/Controllers/Category/NoCategoryController.php
@@ -33,13 +33,9 @@ use FireflyIII\Support\Http\Controllers\PeriodOverview;
use Illuminate\Contracts\View\Factory;
use Illuminate\Http\Request;
use Illuminate\Support\Collection;
-use Illuminate\Support\Facades\Log;
use Illuminate\View\View;
-use Psr\Container\ContainerExceptionInterface;
-use Psr\Container\NotFoundExceptionInterface;
/**
- *
* Class NoCategoryController
*/
class NoCategoryController extends Controller
@@ -50,8 +46,6 @@ class NoCategoryController extends Controller
/**
* CategoryController constructor.
- *
-
*/
public function __construct()
{
@@ -72,40 +66,36 @@ class NoCategoryController extends Controller
/**
* Show transactions without a category.
*
- * @param Request $request
- * @param Carbon|null $start
- * @param Carbon|null $end
- *
* @return Factory|View
+ *
* @throws FireflyException
- * @throws ContainerExceptionInterface
- * @throws NotFoundExceptionInterface
*/
public function show(Request $request, Carbon $start = null, Carbon $end = null)
{
- Log::debug('Start of noCategory()');
- /** @var Carbon $start */
- $start = $start ?? session('start');
- /** @var Carbon $end */
- $end = $end ?? session('end');
- $page = (int)$request->get('page');
- $pageSize = (int)app('preferences')->get('listPageSize', 50)->data;
- $subTitle = trans(
+ app('log')->debug('Start of noCategory()');
+ // @var Carbon $start
+ $start ??= session('start');
+ // @var Carbon $end
+ $end ??= session('end');
+ $page = (int)$request->get('page');
+ $pageSize = (int)app('preferences')->get('listPageSize', 50)->data;
+ $subTitle = trans(
'firefly.without_category_between',
['start' => $start->isoFormat($this->monthAndDayFormat), 'end' => $end->isoFormat($this->monthAndDayFormat)]
);
- $periods = $this->getNoCategoryPeriodOverview($start);
+ $periods = $this->getNoCategoryPeriodOverview($start);
- Log::debug(sprintf('Start for noCategory() is %s', $start->format('Y-m-d')));
- Log::debug(sprintf('End for noCategory() is %s', $end->format('Y-m-d')));
+ app('log')->debug(sprintf('Start for noCategory() is %s', $start->format('Y-m-d')));
+ app('log')->debug(sprintf('End for noCategory() is %s', $end->format('Y-m-d')));
/** @var GroupCollectorInterface $collector */
$collector = app(GroupCollectorInterface::class);
$collector->setRange($start, $end)
- ->setLimit($pageSize)->setPage($page)->withoutCategory()
- ->withAccountInformation()->withBudgetInformation()
- ->setTypes([TransactionType::WITHDRAWAL, TransactionType::DEPOSIT, TransactionType::TRANSFER]);
- $groups = $collector->getPaginatedGroups();
+ ->setLimit($pageSize)->setPage($page)->withoutCategory()
+ ->withAccountInformation()->withBudgetInformation()
+ ->setTypes([TransactionType::WITHDRAWAL, TransactionType::DEPOSIT, TransactionType::TRANSFER])
+ ;
+ $groups = $collector->getPaginatedGroups();
$groups->setPath(route('categories.no-category', [$start->format('Y-m-d'), $end->format('Y-m-d')]));
return view('categories.no-category', compact('groups', 'subTitle', 'periods', 'start', 'end'));
@@ -114,34 +104,31 @@ class NoCategoryController extends Controller
/**
* Show all transactions without a category.
*
- * @param Request $request
- *
* @return Factory|View
- * @throws ContainerExceptionInterface
- * @throws NotFoundExceptionInterface
*/
public function showAll(Request $request)
{
// default values:
- $start = null;
- $end = null;
- $periods = new Collection();
- $page = (int)$request->get('page');
- $pageSize = (int)app('preferences')->get('listPageSize', 50)->data;
- Log::debug('Start of noCategory()');
- $subTitle = (string)trans('firefly.all_journals_without_category');
- $first = $this->journalRepos->firstNull();
- $start = null === $first ? new Carbon() : $first->date;
- $end = today(config('app.timezone'));
- Log::debug(sprintf('Start for noCategory() is %s', $start->format('Y-m-d')));
- Log::debug(sprintf('End for noCategory() is %s', $end->format('Y-m-d')));
+ $start = null;
+ $end = null;
+ $periods = new Collection();
+ $page = (int)$request->get('page');
+ $pageSize = (int)app('preferences')->get('listPageSize', 50)->data;
+ app('log')->debug('Start of noCategory()');
+ $subTitle = (string)trans('firefly.all_journals_without_category');
+ $first = $this->journalRepos->firstNull();
+ $start = null === $first ? new Carbon() : $first->date;
+ $end = today(config('app.timezone'));
+ app('log')->debug(sprintf('Start for noCategory() is %s', $start->format('Y-m-d')));
+ app('log')->debug(sprintf('End for noCategory() is %s', $end->format('Y-m-d')));
/** @var GroupCollectorInterface $collector */
$collector = app(GroupCollectorInterface::class);
$collector->setRange($start, $end)->setLimit($pageSize)->setPage($page)->withoutCategory()
- ->withAccountInformation()->withBudgetInformation()
- ->setTypes([TransactionType::WITHDRAWAL, TransactionType::DEPOSIT, TransactionType::TRANSFER]);
- $groups = $collector->getPaginatedGroups();
+ ->withAccountInformation()->withBudgetInformation()
+ ->setTypes([TransactionType::WITHDRAWAL, TransactionType::DEPOSIT, TransactionType::TRANSFER])
+ ;
+ $groups = $collector->getPaginatedGroups();
$groups->setPath(route('categories.no-category.all'));
return view('categories.no-category', compact('groups', 'subTitle', 'periods', 'start', 'end'));
diff --git a/app/Http/Controllers/Category/ShowController.php b/app/Http/Controllers/Category/ShowController.php
index e534a4d984..bc51b4c0a1 100644
--- a/app/Http/Controllers/Category/ShowController.php
+++ b/app/Http/Controllers/Category/ShowController.php
@@ -34,13 +34,9 @@ use Illuminate\Contracts\View\Factory;
use Illuminate\Http\Request;
use Illuminate\Support\Collection;
use Illuminate\View\View;
-use Psr\Container\ContainerExceptionInterface;
-use Psr\Container\NotFoundExceptionInterface;
/**
- *
* Class ShowController
- *
*/
class ShowController extends Controller
{
@@ -51,8 +47,6 @@ class ShowController extends Controller
/**
* CategoryController constructor.
- *
-
*/
public function __construct()
{
@@ -73,22 +67,16 @@ class ShowController extends Controller
/**
* Show a single category.
*
- * @param Request $request
- * @param Category $category
- * @param Carbon|null $start
- * @param Carbon|null $end
- *
* @return Factory|View
+ *
* @throws FireflyException
- * @throws ContainerExceptionInterface
- * @throws NotFoundExceptionInterface
*/
public function show(Request $request, Category $category, Carbon $start = null, Carbon $end = null)
{
- /** @var Carbon $start */
- $start = $start ?? session('start', today(config('app.timezone'))->startOfMonth());
- /** @var Carbon $end */
- $end = $end ?? session('end', today(config('app.timezone'))->endOfMonth());
+ // @var Carbon $start
+ $start ??= session('start', today(config('app.timezone'))->startOfMonth());
+ // @var Carbon $end
+ $end ??= session('end', today(config('app.timezone'))->endOfMonth());
$subTitleIcon = 'fa-bookmark';
$page = (int)$request->get('page');
$attachments = $this->repository->getAttachments($category);
@@ -106,12 +94,13 @@ class ShowController extends Controller
);
/** @var GroupCollectorInterface $collector */
- $collector = app(GroupCollectorInterface::class);
+ $collector = app(GroupCollectorInterface::class);
$collector->setRange($start, $end)->setLimit($pageSize)->setPage($page)
- ->withAccountInformation()
- ->setCategory($category)->withBudgetInformation()->withCategoryInformation();
+ ->withAccountInformation()
+ ->setCategory($category)->withBudgetInformation()->withCategoryInformation()
+ ;
- $groups = $collector->getPaginatedGroups();
+ $groups = $collector->getPaginatedGroups();
$groups->setPath($path);
return view('categories.show', compact('category', 'attachments', 'groups', 'periods', 'subTitle', 'subTitleIcon', 'start', 'end'));
@@ -120,12 +109,7 @@ class ShowController extends Controller
/**
* Show all transactions within a category.
*
- * @param Request $request
- * @param Category $category
- *
* @return Factory|View
- * @throws ContainerExceptionInterface
- * @throws NotFoundExceptionInterface
*/
public function showAll(Request $request, Category $category)
{
@@ -137,21 +121,23 @@ class ShowController extends Controller
$end = null;
$periods = new Collection();
- $subTitle = (string)trans('firefly.all_journals_for_category', ['name' => $category->name]);
- $first = $this->repository->firstUseDate($category);
+ $subTitle = (string)trans('firefly.all_journals_for_category', ['name' => $category->name]);
+ $first = $this->repository->firstUseDate($category);
+
/** @var Carbon $start */
- $start = $first ?? today(config('app.timezone'));
- $end = today(config('app.timezone'));
- $path = route('categories.show.all', [$category->id]);
- $attachments = $this->repository->getAttachments($category);
+ $start = $first ?? today(config('app.timezone'));
+ $end = today(config('app.timezone'));
+ $path = route('categories.show.all', [$category->id]);
+ $attachments = $this->repository->getAttachments($category);
/** @var GroupCollectorInterface $collector */
- $collector = app(GroupCollectorInterface::class);
+ $collector = app(GroupCollectorInterface::class);
$collector->setRange($start, $end)->setLimit($pageSize)->setPage($page)
- ->withAccountInformation()
- ->setCategory($category)->withBudgetInformation()->withCategoryInformation();
+ ->withAccountInformation()
+ ->setCategory($category)->withBudgetInformation()->withCategoryInformation()
+ ;
- $groups = $collector->getPaginatedGroups();
+ $groups = $collector->getPaginatedGroups();
$groups->setPath($path);
return view('categories.show', compact('category', 'attachments', 'groups', 'periods', 'subTitle', 'subTitleIcon', 'start', 'end'));
diff --git a/app/Http/Controllers/Chart/AccountController.php b/app/Http/Controllers/Chart/AccountController.php
index 00c6a5c661..3482d02195 100644
--- a/app/Http/Controllers/Chart/AccountController.php
+++ b/app/Http/Controllers/Chart/AccountController.php
@@ -33,27 +33,22 @@ use FireflyIII\Models\AccountType;
use FireflyIII\Models\TransactionCurrency;
use FireflyIII\Models\TransactionType;
use FireflyIII\Repositories\Account\AccountRepositoryInterface;
-use FireflyIII\Repositories\Currency\CurrencyRepositoryInterface;
+use FireflyIII\Repositories\UserGroups\Currency\CurrencyRepositoryInterface;
use FireflyIII\Support\CacheProperties;
use FireflyIII\Support\Http\Controllers\AugumentData;
use FireflyIII\Support\Http\Controllers\ChartGeneration;
use FireflyIII\Support\Http\Controllers\DateCalculation;
use Illuminate\Http\JsonResponse;
use Illuminate\Support\Collection;
-use Illuminate\Support\Facades\Log;
-use JsonException;
-use Psr\Container\ContainerExceptionInterface;
-use Psr\Container\NotFoundExceptionInterface;
/**
* Class AccountController.
- *
*/
class AccountController extends Controller
{
- use DateCalculation;
use AugumentData;
use ChartGeneration;
+ use DateCalculation;
protected GeneratorInterface $generator;
private AccountRepositoryInterface $accountRepository;
@@ -61,8 +56,6 @@ class AccountController extends Controller
/**
* AccountController constructor.
- *
-
*/
public function __construct()
{
@@ -83,17 +76,15 @@ class AccountController extends Controller
* Shows the balances for all the user's expense accounts (on the front page).
*
* This chart is (multi) currency aware.
- *
- * @return JsonResponse
- * @throws JsonException
*/
public function expenseAccounts(): JsonResponse
{
/** @var Carbon $start */
- $start = clone session('start', today(config('app.timezone'))->startOfMonth());
+ $start = clone session('start', today(config('app.timezone'))->startOfMonth());
+
/** @var Carbon $end */
- $end = clone session('end', today(config('app.timezone'))->endOfMonth());
- $cache = new CacheProperties();
+ $end = clone session('end', today(config('app.timezone'))->endOfMonth());
+ $cache = new CacheProperties();
$cache->addProperty($start);
$cache->addProperty($end);
$cache->addProperty('chart.account.expense-accounts');
@@ -103,13 +94,13 @@ class AccountController extends Controller
$start->subDay();
// prep some vars:
- $currencies = [];
- $chartData = [];
- $tempData = [];
+ $currencies = [];
+ $chartData = [];
+ $tempData = [];
// grab all accounts and names
- $accounts = $this->accountRepository->getAccountsByType([AccountType::EXPENSE]);
- $accountNames = $this->extractNames($accounts);
+ $accounts = $this->accountRepository->getAccountsByType([AccountType::EXPENSE]);
+ $accountNames = $this->extractNames($accounts);
// grab all balances
$startBalances = app('steam')->balancesPerCurrencyByAccounts($accounts, $start);
@@ -120,13 +111,13 @@ class AccountController extends Controller
$accountId = (int)$accountId;
// loop each expense entry (each entry can be a different currency).
foreach ($expenses as $currencyId => $endAmount) {
- $currencyId = (int)$currencyId;
+ $currencyId = (int)$currencyId;
// see if there is an accompanying start amount.
// grab the difference and find the currency.
- $startAmount = (string)($startBalances[$accountId][$currencyId] ?? '0');
- $diff = bcsub((string)$endAmount, $startAmount);
- $currencies[$currencyId] = $currencies[$currencyId] ?? $this->currencyRepository->find($currencyId);
+ $startAmount = (string)($startBalances[$accountId][$currencyId] ?? '0');
+ $diff = bcsub((string)$endAmount, $startAmount);
+ $currencies[$currencyId] ??= $this->currencyRepository->find($currencyId);
if (0 !== bccomp($diff, '0')) {
// store the values in a temporary array.
$tempData[] = [
@@ -140,7 +131,7 @@ class AccountController extends Controller
}
// sort temp array by amount.
- $amounts = array_column($tempData, 'diff_float');
+ $amounts = array_column($tempData, 'diff_float');
array_multisort($amounts, SORT_DESC, $tempData);
// loop all found currencies and build the data array for the chart.
@@ -151,12 +142,12 @@ class AccountController extends Controller
foreach ($currencies as $currencyId => $currency) {
$dataSet
= [
- 'label' => (string)trans('firefly.spent'),
- 'type' => 'bar',
- 'currency_symbol' => $currency->symbol,
- 'currency_code' => $currency->code,
- 'entries' => $this->expandNames($tempData),
- ];
+ 'label' => (string)trans('firefly.spent'),
+ 'type' => 'bar',
+ 'currency_symbol' => $currency->symbol,
+ 'currency_code' => $currency->code,
+ 'entries' => $this->expandNames($tempData),
+ ];
$chartData[$currencyId] = $dataSet;
}
@@ -167,7 +158,7 @@ class AccountController extends Controller
$chartData[$currencyId]['entries'][$name] = $entry['difference'];
}
- $data = $this->generator->multiSet($chartData);
+ $data = $this->generator->multiSet($chartData);
$cache->store($data);
return response()->json($data);
@@ -175,11 +166,6 @@ class AccountController extends Controller
/**
* Expenses per budget for all time, as shown on account overview.
- *
- * @param AccountRepositoryInterface $repository
- * @param Account $account
- *
- * @return JsonResponse
*/
public function expenseBudgetAll(AccountRepositoryInterface $repository, Account $account): JsonResponse
{
@@ -191,16 +177,10 @@ class AccountController extends Controller
/**
* Expenses per budget, as shown on account overview.
- *
- * @param Account $account
- * @param Carbon $start
- * @param Carbon $end
- *
- * @return JsonResponse
*/
public function expenseBudget(Account $account, Carbon $start, Carbon $end): JsonResponse
{
- $cache = new CacheProperties();
+ $cache = new CacheProperties();
$cache->addProperty($account->id);
$cache->addProperty($start);
$cache->addProperty($end);
@@ -208,6 +188,7 @@ class AccountController extends Controller
if ($cache->has()) {
return response()->json($cache->get());
}
+
/** @var GroupCollectorInterface $collector */
$collector = app(GroupCollectorInterface::class);
$collector->setAccounts(new Collection([$account]))->setRange($start, $end)->withBudgetInformation()->setTypes([TransactionType::WITHDRAWAL]);
@@ -215,11 +196,12 @@ class AccountController extends Controller
$chartData = [];
$result = [];
$budgetIds = [];
+
/** @var array $journal */
foreach ($journals as $journal) {
- $budgetId = (int)$journal['budget_id'];
- $key = sprintf('%d-%d', $budgetId, $journal['currency_id']);
- $budgetIds[] = $budgetId;
+ $budgetId = (int)$journal['budget_id'];
+ $key = sprintf('%d-%d', $budgetId, $journal['currency_id']);
+ $budgetIds[] = $budgetId;
if (!array_key_exists($key, $result)) {
$result[$key] = [
'total' => '0',
@@ -232,7 +214,7 @@ class AccountController extends Controller
$result[$key]['total'] = bcadd($journal['amount'], $result[$key]['total']);
}
- $names = $this->getBudgetNames($budgetIds);
+ $names = $this->getBudgetNames($budgetIds);
foreach ($result as $row) {
$budgetId = $row['budget_id'];
@@ -241,7 +223,7 @@ class AccountController extends Controller
$chartData[$label] = ['amount' => $row['total'], 'currency_symbol' => $row['currency_symbol'], 'currency_code' => $row['currency_code']];
}
- $data = $this->generator->multiCurrencyPieChart($chartData);
+ $data = $this->generator->multiCurrencyPieChart($chartData);
$cache->store($data);
return response()->json($data);
@@ -249,11 +231,6 @@ class AccountController extends Controller
/**
* Expenses grouped by category for account.
- *
- * @param AccountRepositoryInterface $repository
- * @param Account $account
- *
- * @return JsonResponse
*/
public function expenseCategoryAll(AccountRepositoryInterface $repository, Account $account): JsonResponse
{
@@ -265,16 +242,10 @@ class AccountController extends Controller
/**
* Expenses per category for one single account.
- *
- * @param Account $account
- * @param Carbon $start
- * @param Carbon $end
- *
- * @return JsonResponse
*/
public function expenseCategory(Account $account, Carbon $start, Carbon $end): JsonResponse
{
- $cache = new CacheProperties();
+ $cache = new CacheProperties();
$cache->addProperty($account->id);
$cache->addProperty($start);
$cache->addProperty($end);
@@ -292,7 +263,7 @@ class AccountController extends Controller
/** @var array $journal */
foreach ($journals as $journal) {
- $key = sprintf('%d-%d', $journal['category_id'], $journal['currency_id']);
+ $key = sprintf('%d-%d', $journal['category_id'], $journal['currency_id']);
if (!array_key_exists($key, $result)) {
$result[$key] = [
'total' => '0',
@@ -304,7 +275,7 @@ class AccountController extends Controller
}
$result[$key]['total'] = bcadd($journal['amount'], $result[$key]['total']);
}
- $names = $this->getCategoryNames(array_keys($result));
+ $names = $this->getCategoryNames(array_keys($result));
foreach ($result as $row) {
$categoryId = $row['category_id'];
@@ -313,7 +284,7 @@ class AccountController extends Controller
$chartData[$label] = ['amount' => $row['total'], 'currency_symbol' => $row['currency_symbol'], 'currency_code' => $row['currency_code']];
}
- $data = $this->generator->multiCurrencyPieChart($chartData);
+ $data = $this->generator->multiCurrencyPieChart($chartData);
$cache->store($data);
return response()->json($data);
@@ -322,38 +293,28 @@ class AccountController extends Controller
/**
* Shows the balances for all the user's frontpage accounts.
*
- * @param AccountRepositoryInterface $repository
- *
- * @return JsonResponse
* @throws FireflyException
- * @throws JsonException
- * @throws ContainerExceptionInterface
- * @throws NotFoundExceptionInterface
- */
+ * */
public function frontpage(AccountRepositoryInterface $repository): JsonResponse
{
- $start = clone session('start', today(config('app.timezone'))->startOfMonth());
- $end = clone session('end', today(config('app.timezone'))->endOfMonth());
- $defaultSet = $repository->getAccountsByType([AccountType::DEFAULT, AccountType::ASSET])->pluck('id')->toArray();
- Log::debug('Default set is ', $defaultSet);
- $frontPage = app('preferences')->get('frontPageAccounts', $defaultSet);
- Log::debug('Frontpage preference set is ', $frontPage->data);
- if (0 === count($frontPage->data)) {
+ $start = clone session('start', today(config('app.timezone'))->startOfMonth());
+ $end = clone session('end', today(config('app.timezone'))->endOfMonth());
+ $defaultSet = $repository->getAccountsByType([AccountType::DEFAULT, AccountType::ASSET])->pluck('id')->toArray();
+ app('log')->debug('Default set is ', $defaultSet);
+ $frontPage = app('preferences')->get('frontPageAccounts', $defaultSet);
+ $frontPageArray = !is_array($frontPage->data) ? [] : $frontPage->data;
+ app('log')->debug('Frontpage preference set is ', $frontPageArray);
+ if (0 === count($frontPageArray)) {
app('preferences')->set('frontPageAccounts', $defaultSet);
- Log::debug('frontpage set is empty!');
+ app('log')->debug('frontpage set is empty!');
}
- $accounts = $repository->getAccountsById($frontPage->data);
+ $accounts = $repository->getAccountsById($frontPageArray);
return response()->json($this->accountBalanceChart($accounts, $start, $end));
}
/**
* Shows the income grouped by category for an account, in all time.
- *
- * @param AccountRepositoryInterface $repository
- * @param Account $account
- *
- * @return JsonResponse
*/
public function incomeCategoryAll(AccountRepositoryInterface $repository, Account $account): JsonResponse
{
@@ -365,16 +326,10 @@ class AccountController extends Controller
/**
* Shows all income per account for each category.
- *
- * @param Account $account
- * @param Carbon $start
- * @param Carbon $end
- *
- * @return JsonResponse
*/
public function incomeCategory(Account $account, Carbon $start, Carbon $end): JsonResponse
{
- $cache = new CacheProperties();
+ $cache = new CacheProperties();
$cache->addProperty($account->id);
$cache->addProperty($start);
$cache->addProperty($end);
@@ -391,9 +346,10 @@ class AccountController extends Controller
$journals = $collector->getExtractedJournals();
$result = [];
$chartData = [];
+
/** @var array $journal */
foreach ($journals as $journal) {
- $key = sprintf('%d-%d', $journal['category_id'], $journal['currency_id']);
+ $key = sprintf('%d-%d', $journal['category_id'], $journal['currency_id']);
if (!array_key_exists($key, $result)) {
$result[$key] = [
'total' => '0',
@@ -406,14 +362,14 @@ class AccountController extends Controller
$result[$key]['total'] = bcadd($journal['amount'], $result[$key]['total']);
}
- $names = $this->getCategoryNames(array_keys($result));
+ $names = $this->getCategoryNames(array_keys($result));
foreach ($result as $row) {
$categoryId = $row['category_id'];
$name = $names[$categoryId] ?? '(unknown)';
$label = (string)trans('firefly.name_in_currency', ['name' => $name, 'currency' => $row['currency_name']]);
$chartData[$label] = ['amount' => $row['total'], 'currency_symbol' => $row['currency_symbol'], 'currency_code' => $row['currency_code']];
}
- $data = $this->generator->multiCurrencyPieChart($chartData);
+ $data = $this->generator->multiCurrencyPieChart($chartData);
$cache->store($data);
return response()->json($data);
@@ -422,19 +378,12 @@ class AccountController extends Controller
/**
* Shows overview of account during a single period.
*
- * @param Account $account
- * @param Carbon $start
- *
- * @param Carbon $end
- *
- * @return JsonResponse
* @throws FireflyException
- * @throws JsonException
*/
public function period(Account $account, Carbon $start, Carbon $end): JsonResponse
{
- $chartData = [];
- $cache = new CacheProperties();
+ $chartData = [];
+ $cache = new CacheProperties();
$cache->addProperty('chart.account.period');
$cache->addProperty($start);
$cache->addProperty($end);
@@ -454,40 +403,33 @@ class AccountController extends Controller
$chartData[] = $this->periodByCurrency($start, $end, $account, $currency);
}
- $data = $this->generator->multiSet($chartData);
+ $data = $this->generator->multiSet($chartData);
$cache->store($data);
return response()->json($data);
}
/**
- * @param Carbon $start
- * @param Carbon $end
- * @param Account $account
- * @param TransactionCurrency $currency
- *
- * @return array
* @throws FireflyException
- * @throws JsonException
*/
private function periodByCurrency(Carbon $start, Carbon $end, Account $account, TransactionCurrency $currency): array
{
app('log')->debug(sprintf('Now in periodByCurrency("%s", "%s", %s, "%s")', $start->format('Y-m-d'), $end->format('Y-m-d'), $account->id, $currency->code));
- $locale = app('steam')->getLocale();
- $step = $this->calculateStep($start, $end);
- $result = [
+ $locale = app('steam')->getLocale();
+ $step = $this->calculateStep($start, $end);
+ $result = [
'label' => sprintf('%s (%s)', $account->name, $currency->symbol),
'currency_symbol' => $currency->symbol,
'currency_code' => $currency->code,
];
- $entries = [];
- $current = clone $start;
+ $entries = [];
+ $current = clone $start;
app('log')->debug(sprintf('Step is %s', $step));
// fix for issue https://github.com/firefly-iii/firefly-iii/issues/8041
// have to make sure this chart is always based on the balance at the END of the period.
// This period depends on the size of the chart
- $current = app('navigation')->endOfX($current, $step, null);
+ $current = app('navigation')->endOfX($current, $step, null);
app('log')->debug(sprintf('$current date is %s', $current->format('Y-m-d')));
if ('1D' === $step) {
// per day the entire period, balance for every day.
@@ -511,7 +453,7 @@ class AccountController extends Controller
$entries[$label] = $balance;
$current = app('navigation')->addPeriod($current, $step, 0);
// here too, to fix #8041, the data is corrected to the end of the period.
- $current = app('navigation')->endOfX($current, $step, null);
+ $current = app('navigation')->endOfX($current, $step, null);
}
}
$result['entries'] = $entries;
@@ -524,14 +466,7 @@ class AccountController extends Controller
*
* TODO this chart is not multi currency aware.
*
- * @param Collection $accounts
- *
- * @param Carbon $start
- * @param Carbon $end
- *
- * @return JsonResponse
* @throws FireflyException
- * @throws JsonException
*/
public function report(Collection $accounts, Carbon $start, Carbon $end): JsonResponse
{
@@ -542,17 +477,15 @@ class AccountController extends Controller
* Shows the balances for all the user's revenue accounts.
*
* This chart is multi-currency aware.
- *
- * @return JsonResponse
- * @throws JsonException
*/
public function revenueAccounts(): JsonResponse
{
/** @var Carbon $start */
- $start = clone session('start', today(config('app.timezone'))->startOfMonth());
+ $start = clone session('start', today(config('app.timezone'))->startOfMonth());
+
/** @var Carbon $end */
- $end = clone session('end', today(config('app.timezone'))->endOfMonth());
- $cache = new CacheProperties();
+ $end = clone session('end', today(config('app.timezone'))->endOfMonth());
+ $cache = new CacheProperties();
$cache->addProperty($start);
$cache->addProperty($end);
$cache->addProperty('chart.account.revenue-accounts');
@@ -562,13 +495,13 @@ class AccountController extends Controller
$start->subDay();
// prep some vars:
- $currencies = [];
- $chartData = [];
- $tempData = [];
+ $currencies = [];
+ $chartData = [];
+ $tempData = [];
// grab all accounts and names
- $accounts = $this->accountRepository->getAccountsByType([AccountType::REVENUE]);
- $accountNames = $this->extractNames($accounts);
+ $accounts = $this->accountRepository->getAccountsByType([AccountType::REVENUE]);
+ $accountNames = $this->extractNames($accounts);
// grab all balances
$startBalances = app('steam')->balancesPerCurrencyByAccounts($accounts, $start);
@@ -579,13 +512,13 @@ class AccountController extends Controller
$accountId = (int)$accountId;
// loop each expense entry (each entry can be a different currency).
foreach ($expenses as $currencyId => $endAmount) {
- $currencyId = (int)$currencyId;
+ $currencyId = (int)$currencyId;
// see if there is an accompanying start amount.
// grab the difference and find the currency.
- $startAmount = (string)($startBalances[$accountId][$currencyId] ?? '0');
- $diff = bcsub((string)$endAmount, $startAmount);
- $currencies[$currencyId] = $currencies[$currencyId] ?? $this->currencyRepository->find($currencyId);
+ $startAmount = (string)($startBalances[$accountId][$currencyId] ?? '0');
+ $diff = bcsub((string)$endAmount, $startAmount);
+ $currencies[$currencyId] ??= $this->currencyRepository->find($currencyId);
if (0 !== bccomp($diff, '0')) {
// store the values in a temporary array.
$tempData[] = [
@@ -599,7 +532,7 @@ class AccountController extends Controller
}
// sort temp array by amount.
- $amounts = array_column($tempData, 'diff_float');
+ $amounts = array_column($tempData, 'diff_float');
array_multisort($amounts, SORT_ASC, $tempData);
// loop all found currencies and build the data array for the chart.
@@ -610,12 +543,12 @@ class AccountController extends Controller
foreach ($currencies as $currencyId => $currency) {
$dataSet
= [
- 'label' => (string)trans('firefly.earned'),
- 'type' => 'bar',
- 'currency_symbol' => $currency->symbol,
- 'currency_code' => $currency->code,
- 'entries' => $this->expandNames($tempData),
- ];
+ 'label' => (string)trans('firefly.earned'),
+ 'type' => 'bar',
+ 'currency_symbol' => $currency->symbol,
+ 'currency_code' => $currency->code,
+ 'entries' => $this->expandNames($tempData),
+ ];
$chartData[$currencyId] = $dataSet;
}
@@ -626,7 +559,7 @@ class AccountController extends Controller
$chartData[$currencyId]['entries'][$name] = bcmul($entry['difference'], '-1');
}
- $data = $this->generator->multiSet($chartData);
+ $data = $this->generator->multiSet($chartData);
$cache->store($data);
return response()->json($data);
diff --git a/app/Http/Controllers/Chart/BillController.php b/app/Http/Controllers/Chart/BillController.php
index 6397554f0d..3e8c23c996 100644
--- a/app/Http/Controllers/Chart/BillController.php
+++ b/app/Http/Controllers/Chart/BillController.php
@@ -41,8 +41,6 @@ class BillController extends Controller
/**
* BillController constructor.
- *
-
*/
public function __construct()
{
@@ -52,16 +50,12 @@ class BillController extends Controller
/**
* Shows all bills and whether or not they've been paid this month (pie chart).
- *
- * @param BillRepositoryInterface $repository
- *
- * @return JsonResponse
*/
public function frontpage(BillRepositoryInterface $repository): JsonResponse
{
- $start = session('start', today(config('app.timezone'))->startOfMonth());
- $end = session('end', today(config('app.timezone'))->endOfMonth());
- $cache = new CacheProperties();
+ $start = session('start', today(config('app.timezone'))->startOfMonth());
+ $end = session('end', today(config('app.timezone'))->endOfMonth());
+ $cache = new CacheProperties();
$cache->addProperty($start);
$cache->addProperty($end);
$cache->addProperty('chart.bill.frontpage');
@@ -85,6 +79,7 @@ class BillController extends Controller
'currency_code' => $info['code'],
];
}
+
/**
* @var array $info
*/
@@ -98,7 +93,7 @@ class BillController extends Controller
];
}
- $data = $this->generator->multiCurrencyPieChart($chartData);
+ $data = $this->generator->multiCurrencyPieChart($chartData);
$cache->store($data);
return response()->json($data);
@@ -107,24 +102,21 @@ class BillController extends Controller
/**
* Shows overview for a single bill.
*
- * @param Bill $bill
- *
- * @return JsonResponse
* @throws FireflyException
*/
public function single(Bill $bill): JsonResponse
{
- $cache = new CacheProperties();
+ $cache = new CacheProperties();
$cache->addProperty('chart.bill.single');
$cache->addProperty($bill->id);
if ($cache->has()) {
return response()->json($cache->get());
}
- $locale = app('steam')->getLocale();
+ $locale = app('steam')->getLocale();
/** @var GroupCollectorInterface $collector */
- $collector = app(GroupCollectorInterface::class);
- $journals = $collector->setBill($bill)->getExtractedJournals();
+ $collector = app(GroupCollectorInterface::class);
+ $journals = $collector->setBill($bill)->getExtractedJournals();
// sort the other way around:
usort(
@@ -164,7 +156,7 @@ class BillController extends Controller
'entries' => [],
],
];
- $currencyId = (int)$bill->transaction_currency_id;
+ $currencyId = $bill->transaction_currency_id;
foreach ($journals as $journal) {
$date = $journal['date']->isoFormat((string)trans('config.month_and_day_js', [], $locale));
$chartData[0]['entries'][$date] = $bill->amount_min; // minimum amount of bill
@@ -174,16 +166,15 @@ class BillController extends Controller
if (!array_key_exists($date, $chartData[2]['entries'])) {
$chartData[2]['entries'][$date] = '0';
}
- $amount = bcmul($journal['amount'], '-1');
+ $amount = bcmul($journal['amount'], '-1');
if ($currencyId === $journal['foreign_currency_id']) {
$amount = bcmul($journal['foreign_amount'], '-1');
}
-
$chartData[2]['entries'][$date] = bcadd($chartData[2]['entries'][$date], $amount); // amount of journal
}
- $data = $this->generator->multiSet($chartData);
+ $data = $this->generator->multiSet($chartData);
$cache->store($data);
return response()->json($data);
diff --git a/app/Http/Controllers/Chart/BudgetController.php b/app/Http/Controllers/Chart/BudgetController.php
index cc77852515..63d8051745 100644
--- a/app/Http/Controllers/Chart/BudgetController.php
+++ b/app/Http/Controllers/Chart/BudgetController.php
@@ -45,12 +45,11 @@ use Illuminate\Support\Collection;
/**
* Class BudgetController.
- *
*/
class BudgetController extends Controller
{
- use DateCalculation;
use AugumentData;
+ use DateCalculation;
protected GeneratorInterface $generator;
protected OperationsRepositoryInterface $opsRepository;
@@ -60,8 +59,6 @@ class BudgetController extends Controller
/**
* BudgetController constructor.
- *
-
*/
public function __construct()
{
@@ -82,18 +79,15 @@ class BudgetController extends Controller
/**
* Shows overview of a single budget.
- *
- * @param Budget $budget
- *
- * @return JsonResponse
*/
public function budget(Budget $budget): JsonResponse
{
/** @var Carbon $start */
- $start = $this->repository->firstUseDate($budget) ?? session('start', today(config('app.timezone')));
+ $start = $this->repository->firstUseDate($budget) ?? session('start', today(config('app.timezone')));
+
/** @var Carbon $end */
- $end = session('end', today(config('app.timezone')));
- $cache = new CacheProperties();
+ $end = session('end', today(config('app.timezone')));
+ $cache = new CacheProperties();
$cache->addProperty($start);
$cache->addProperty($end);
$cache->addProperty('chart.budget.budget');
@@ -111,19 +105,19 @@ class BudgetController extends Controller
$defaultEntries = [];
while ($end >= $loopStart) {
/** @var Carbon $loopEnd */
- $loopEnd = app('navigation')->endOfPeriod($loopStart, $step);
- $spent = $this->opsRepository->sumExpenses($loopStart, $loopEnd, null, $collection);
- $label = trim(app('navigation')->periodShow($loopStart, $step));
+ $loopEnd = app('navigation')->endOfPeriod($loopStart, $step);
+ $spent = $this->opsRepository->sumExpenses($loopStart, $loopEnd, null, $collection);
+ $label = trim(app('navigation')->periodShow($loopStart, $step));
foreach ($spent as $row) {
- $currencyId = $row['currency_id'];
- $currencies[$currencyId] = $currencies[$currencyId] ?? $row; // don't mind the field 'sum'
+ $currencyId = $row['currency_id'];
+ $currencies[$currencyId] ??= $row; // don't mind the field 'sum'
// also store this day's sum:
$currencies[$currencyId]['spent'][$label] = $row['sum'];
}
$defaultEntries[$label] = 0;
// set loop start to the next period:
- $loopStart = clone $loopEnd;
+ $loopStart = clone $loopEnd;
$loopStart->addSecond();
}
// loop all currencies:
@@ -139,7 +133,7 @@ class BudgetController extends Controller
$chartData[$currencyId]['entries'][$label] = bcmul($spent, '-1');
}
}
- $data = $this->generator->multiSet(array_values($chartData));
+ $data = $this->generator->multiSet(array_values($chartData));
$cache->store($data);
return response()->json($data);
@@ -148,11 +142,6 @@ class BudgetController extends Controller
/**
* Shows the amount left in a specific budget limit.
*
- * @param Budget $budget
- * @param BudgetLimit $budgetLimit
- *
- * @return JsonResponse
- *
* @throws FireflyException
*/
public function budgetLimit(Budget $budget, BudgetLimit $budgetLimit): JsonResponse
@@ -161,9 +150,9 @@ class BudgetController extends Controller
throw new FireflyException('This budget limit is not part of this budget.');
}
- $start = clone $budgetLimit->start_date;
- $end = clone $budgetLimit->end_date;
- $cache = new CacheProperties();
+ $start = clone $budgetLimit->start_date;
+ $end = clone $budgetLimit->end_date;
+ $cache = new CacheProperties();
$cache->addProperty($start);
$cache->addProperty($end);
$cache->addProperty('chart.budget.budget.limit');
@@ -173,22 +162,22 @@ class BudgetController extends Controller
if ($cache->has()) {
return response()->json($cache->get());
}
- $locale = app('steam')->getLocale();
- $entries = [];
- $amount = $budgetLimit->amount;
- $budgetCollection = new Collection([$budget]);
- $currency = $budgetLimit->transactionCurrency;
+ $locale = app('steam')->getLocale();
+ $entries = [];
+ $amount = $budgetLimit->amount;
+ $budgetCollection = new Collection([$budget]);
+ $currency = $budgetLimit->transactionCurrency;
while ($start <= $end) {
$current = clone $start;
$expenses = $this->opsRepository->sumExpenses($current, $current, null, $budgetCollection, $currency);
- $spent = $expenses[(int)$currency->id]['sum'] ?? '0';
+ $spent = $expenses[$currency->id]['sum'] ?? '0';
$amount = bcadd($amount, $spent);
$format = $start->isoFormat((string)trans('config.month_and_day_js', [], $locale));
$entries[$format] = $amount;
$start->addDay();
}
- $data = $this->generator->singleSet((string)trans('firefly.left'), $entries);
+ $data = $this->generator->singleSet((string)trans('firefly.left'), $entries);
// add currency symbol from budget limit:
$data['datasets'][0]['currency_symbol'] = $budgetLimit->transactionCurrency->symbol;
$data['datasets'][0]['currency_code'] = $budgetLimit->transactionCurrency->code;
@@ -199,11 +188,6 @@ class BudgetController extends Controller
/**
* Shows how much is spent per asset account.
- *
- * @param Budget $budget
- * @param BudgetLimit|null $budgetLimit
- *
- * @return JsonResponse
*/
public function expenseAsset(Budget $budget, ?BudgetLimit $budgetLimit = null): JsonResponse
{
@@ -214,8 +198,8 @@ class BudgetController extends Controller
$cache->addProperty($budget->id);
$cache->addProperty($budgetLimitId);
$cache->addProperty('chart.budget.expense-asset');
- $start = session('first', today(config('app.timezone'))->startOfYear());
- $end = today();
+ $start = session('first', today(config('app.timezone'))->startOfYear());
+ $end = today();
if (null !== $budgetLimit) {
$start = $budgetLimit->start_date;
@@ -230,14 +214,14 @@ class BudgetController extends Controller
}
$collector->setRange($start, $end);
$collector->setBudget($budget);
- $journals = $collector->getExtractedJournals();
- $result = [];
- $chartData = [];
+ $journals = $collector->getExtractedJournals();
+ $result = [];
+ $chartData = [];
// group by asset account ID:
foreach ($journals as $journal) {
$key = sprintf('%d-%d', (int)$journal['source_account_id'], $journal['currency_id']);
- $result[$key] = $result[$key] ?? [
+ $result[$key] ??= [
'amount' => '0',
'currency_symbol' => $journal['currency_symbol'],
'currency_code' => $journal['currency_code'],
@@ -246,20 +230,20 @@ class BudgetController extends Controller
$result[$key]['amount'] = bcadd($journal['amount'], $result[$key]['amount']);
}
- $names = $this->getAccountNames(array_keys($result));
+ $names = $this->getAccountNames(array_keys($result));
foreach ($result as $combinedId => $info) {
$parts = explode('-', $combinedId);
$assetId = (int)$parts[0];
$title = sprintf('%s (%s)', $names[$assetId] ?? '(empty)', $info['currency_name']);
$chartData[$title]
= [
- 'amount' => $info['amount'],
- 'currency_symbol' => $info['currency_symbol'],
- 'currency_code' => $info['currency_code'],
- ];
+ 'amount' => $info['amount'],
+ 'currency_symbol' => $info['currency_symbol'],
+ 'currency_code' => $info['currency_code'],
+ ];
}
- $data = $this->generator->multiCurrencyPieChart($chartData);
+ $data = $this->generator->multiCurrencyPieChart($chartData);
$cache->store($data);
return response()->json($data);
@@ -267,11 +251,6 @@ class BudgetController extends Controller
/**
* Shows how much is spent per category.
- *
- * @param Budget $budget
- * @param BudgetLimit|null $budgetLimit
- *
- * @return JsonResponse
*/
public function expenseCategory(Budget $budget, ?BudgetLimit $budgetLimit = null): JsonResponse
{
@@ -282,8 +261,8 @@ class BudgetController extends Controller
$cache->addProperty($budget->id);
$cache->addProperty($budgetLimitId);
$cache->addProperty('chart.budget.expense-category');
- $start = session('first', today(config('app.timezone'))->startOfYear());
- $end = today();
+ $start = session('first', today(config('app.timezone'))->startOfYear());
+ $end = today();
if (null !== $budgetLimit) {
$start = $budgetLimit->start_date;
$end = $budgetLimit->end_date;
@@ -297,12 +276,12 @@ class BudgetController extends Controller
}
$collector->setRange($start, $end);
$collector->setBudget($budget)->withCategoryInformation();
- $journals = $collector->getExtractedJournals();
- $result = [];
- $chartData = [];
+ $journals = $collector->getExtractedJournals();
+ $result = [];
+ $chartData = [];
foreach ($journals as $journal) {
$key = sprintf('%d-%d', $journal['category_id'], $journal['currency_id']);
- $result[$key] = $result[$key] ?? [
+ $result[$key] ??= [
'amount' => '0',
'currency_symbol' => $journal['currency_symbol'],
'currency_code' => $journal['currency_code'],
@@ -311,7 +290,7 @@ class BudgetController extends Controller
$result[$key]['amount'] = bcadd($journal['amount'], $result[$key]['amount']);
}
- $names = $this->getCategoryNames(array_keys($result));
+ $names = $this->getCategoryNames(array_keys($result));
foreach ($result as $combinedId => $info) {
$parts = explode('-', $combinedId);
$categoryId = (int)$parts[0];
@@ -322,7 +301,7 @@ class BudgetController extends Controller
'currency_code' => $info['currency_code'],
];
}
- $data = $this->generator->multiCurrencyPieChart($chartData);
+ $data = $this->generator->multiCurrencyPieChart($chartData);
$cache->store($data);
return response()->json($data);
@@ -330,12 +309,6 @@ class BudgetController extends Controller
/**
* Shows how much is spent per expense account.
- *
- *
- * @param Budget $budget
- * @param BudgetLimit|null $budgetLimit
- *
- * @return JsonResponse
*/
public function expenseExpense(Budget $budget, ?BudgetLimit $budgetLimit = null): JsonResponse
{
@@ -346,8 +319,8 @@ class BudgetController extends Controller
$cache->addProperty($budget->id);
$cache->addProperty($budgetLimitId);
$cache->addProperty('chart.budget.expense-expense');
- $start = session('first', today(config('app.timezone'))->startOfYear());
- $end = today();
+ $start = session('first', today(config('app.timezone'))->startOfYear());
+ $end = today();
if (null !== $budgetLimit) {
$start = $budgetLimit->start_date;
$end = $budgetLimit->end_date;
@@ -361,13 +334,14 @@ class BudgetController extends Controller
}
$collector->setRange($start, $end);
$collector->setTypes([TransactionType::WITHDRAWAL])->setBudget($budget)->withAccountInformation();
- $journals = $collector->getExtractedJournals();
- $result = [];
- $chartData = [];
+ $journals = $collector->getExtractedJournals();
+ $result = [];
+ $chartData = [];
+
/** @var array $journal */
foreach ($journals as $journal) {
$key = sprintf('%d-%d', $journal['destination_account_id'], $journal['currency_id']);
- $result[$key] = $result[$key] ?? [
+ $result[$key] ??= [
'amount' => '0',
'currency_symbol' => $journal['currency_symbol'],
'currency_code' => $journal['currency_code'],
@@ -376,7 +350,7 @@ class BudgetController extends Controller
$result[$key]['amount'] = bcadd($journal['amount'], $result[$key]['amount']);
}
- $names = $this->getAccountNames(array_keys($result));
+ $names = $this->getAccountNames(array_keys($result));
foreach ($result as $combinedId => $info) {
$parts = explode('-', $combinedId);
$opposingId = (int)$parts[0];
@@ -389,7 +363,7 @@ class BudgetController extends Controller
];
}
- $data = $this->generator->multiCurrencyPieChart($chartData);
+ $data = $this->generator->multiCurrencyPieChart($chartData);
$cache->store($data);
return response()->json($data);
@@ -397,16 +371,14 @@ class BudgetController extends Controller
/**
* Shows a budget list with spent/left/overspent.
- *
- * @return JsonResponse
*/
public function frontpage(): JsonResponse
{
- $start = session('start', today(config('app.timezone'))->startOfMonth());
- $end = session('end', today(config('app.timezone'))->endOfMonth());
+ $start = session('start', today(config('app.timezone'))->startOfMonth());
+ $end = session('end', today(config('app.timezone'))->endOfMonth());
// chart properties for cache:
- $cache = new CacheProperties();
+ $cache = new CacheProperties();
$cache->addProperty($start);
$cache->addProperty($end);
$cache->addProperty('chart.budget.frontpage');
@@ -419,8 +391,8 @@ class BudgetController extends Controller
$chartGenerator->setStart($start);
$chartGenerator->setEnd($end);
- $chartData = $chartGenerator->generate();
- $data = $this->generator->multiSet($chartData);
+ $chartData = $chartGenerator->generate();
+ $data = $this->generator->multiSet($chartData);
$cache->store($data);
return response()->json($data);
@@ -429,18 +401,14 @@ class BudgetController extends Controller
/**
* Shows a budget overview chart (spent and budgeted).
*
- * @param Budget $budget
- * @param TransactionCurrency $currency
- * @param Collection $accounts
- * @param Carbon $start
- * @param Carbon $end
+ * Suppress warning because this method will be replaced by API calls.
*
- * @return JsonResponse
+ * @SuppressWarnings(PHPMD.ExcessiveParameterList)
*/
public function period(Budget $budget, TransactionCurrency $currency, Collection $accounts, Carbon $start, Carbon $end): JsonResponse
{
// chart properties for cache:
- $cache = new CacheProperties();
+ $cache = new CacheProperties();
$cache->addProperty($start);
$cache->addProperty($end);
$cache->addProperty($accounts);
@@ -469,11 +437,11 @@ class BudgetController extends Controller
],
];
- $currentStart = clone $start;
+ $currentStart = clone $start;
while ($currentStart <= $end) {
- $currentStart = app('navigation')->startOfPeriod($currentStart, $preferredRange);
- $title = $currentStart->isoFormat($titleFormat);
- $currentEnd = app('navigation')->endOfPeriod($currentStart, $preferredRange);
+ $currentStart = app('navigation')->startOfPeriod($currentStart, $preferredRange);
+ $title = $currentStart->isoFormat($titleFormat);
+ $currentEnd = app('navigation')->endOfPeriod($currentStart, $preferredRange);
// default limit is no limit:
$chartData[0]['entries'][$title] = 0;
@@ -482,7 +450,7 @@ class BudgetController extends Controller
$chartData[1]['entries'][$title] = 0;
// get budget limit in this period for this currency.
- $limit = $this->blRepository->find($budget, $currency, $currentStart, $currentEnd);
+ $limit = $this->blRepository->find($budget, $currency, $currentStart, $currentEnd);
if (null !== $limit) {
$chartData[1]['entries'][$title] = app('steam')->bcround($limit->amount, $currency->decimal_places);
}
@@ -492,11 +460,11 @@ class BudgetController extends Controller
$amount = app('steam')->positive($sum[$currency->id]['sum'] ?? '0');
$chartData[0]['entries'][$title] = app('steam')->bcround($amount, $currency->decimal_places);
- $currentStart = clone $currentEnd;
+ $currentStart = clone $currentEnd;
$currentStart->addDay()->startOfDay();
}
- $data = $this->generator->multiSet($chartData);
+ $data = $this->generator->multiSet($chartData);
$cache->store($data);
return response()->json($data);
@@ -504,18 +472,11 @@ class BudgetController extends Controller
/**
* Shows a chart for transactions without a budget.
- *
- * @param TransactionCurrency $currency
- * @param Collection $accounts
- * @param Carbon $start
- * @param Carbon $end
- *
- * @return JsonResponse
*/
public function periodNoBudget(TransactionCurrency $currency, Collection $accounts, Carbon $start, Carbon $end): JsonResponse
{
// chart properties for cache:
- $cache = new CacheProperties();
+ $cache = new CacheProperties();
$cache->addProperty($start);
$cache->addProperty($end);
$cache->addProperty($accounts);
@@ -539,7 +500,7 @@ class BudgetController extends Controller
$currentStart = app('navigation')->addPeriod($currentStart, $preferredRange, 0);
}
- $data = $this->generator->singleSet((string)trans('firefly.spent'), $chartData);
+ $data = $this->generator->singleSet((string)trans('firefly.spent'), $chartData);
$cache->store($data);
return response()->json($data);
diff --git a/app/Http/Controllers/Chart/BudgetReportController.php b/app/Http/Controllers/Chart/BudgetReportController.php
index dcc9758c86..fac020c8e8 100644
--- a/app/Http/Controllers/Chart/BudgetReportController.php
+++ b/app/Http/Controllers/Chart/BudgetReportController.php
@@ -37,7 +37,6 @@ use Illuminate\Support\Collection;
* Separate controller because many helper functions are shared.
*
* Class BudgetReportController
- *
*/
class BudgetReportController extends Controller
{
@@ -52,8 +51,6 @@ class BudgetReportController extends Controller
/**
* BudgetReportController constructor.
- *
-
*/
public function __construct()
{
@@ -70,13 +67,6 @@ class BudgetReportController extends Controller
/**
* Chart that groups the expenses by budget.
- *
- * @param Collection $accounts
- * @param Collection $budgets
- * @param Carbon $start
- * @param Carbon $end
- *
- * @return JsonResponse
*/
public function budgetExpense(Collection $accounts, Collection $budgets, Carbon $start, Carbon $end): JsonResponse
{
@@ -86,8 +76,8 @@ class BudgetReportController extends Controller
// loop expenses.
foreach ($spent as $currency) {
foreach ($currency['budgets'] as $budget) {
- $title = sprintf('%s (%s)', $budget['name'], $currency['currency_name']);
- $result[$title] = $result[$title] ?? [
+ $title = sprintf('%s (%s)', $budget['name'], $currency['currency_name']);
+ $result[$title] ??= [
'amount' => '0',
'currency_symbol' => $currency['currency_symbol'],
'currency_code' => $currency['currency_code'],
@@ -99,20 +89,13 @@ class BudgetReportController extends Controller
}
}
- $data = $this->generator->multiCurrencyPieChart($result);
+ $data = $this->generator->multiCurrencyPieChart($result);
return response()->json($data);
}
/**
* Chart that groups the expenses by budget.
- *
- * @param Collection $accounts
- * @param Collection $budgets
- * @param Carbon $start
- * @param Carbon $end
- *
- * @return JsonResponse
*/
public function categoryExpense(Collection $accounts, Collection $budgets, Carbon $start, Carbon $end): JsonResponse
{
@@ -122,9 +105,9 @@ class BudgetReportController extends Controller
foreach ($spent as $currency) {
foreach ($currency['budgets'] as $budget) {
foreach ($budget['transaction_journals'] as $journal) {
- $categoryName = $journal['category_name'] ?? trans('firefly.no_category');
- $title = sprintf('%s (%s)', $categoryName, $currency['currency_name']);
- $result[$title] = $result[$title] ?? [
+ $categoryName = $journal['category_name'] ?? trans('firefly.no_category');
+ $title = sprintf('%s (%s)', $categoryName, $currency['currency_name']);
+ $result[$title] ??= [
'amount' => '0',
'currency_symbol' => $currency['currency_symbol'],
'currency_code' => $currency['currency_code'],
@@ -136,20 +119,13 @@ class BudgetReportController extends Controller
}
}
- $data = $this->generator->multiCurrencyPieChart($result);
+ $data = $this->generator->multiCurrencyPieChart($result);
return response()->json($data);
}
/**
* Chart that groups expenses by the account.
- *
- * @param Collection $accounts
- * @param Collection $budgets
- * @param Carbon $start
- * @param Carbon $end
- *
- * @return JsonResponse
*/
public function destinationAccountExpense(Collection $accounts, Collection $budgets, Carbon $start, Carbon $end): JsonResponse
{
@@ -160,8 +136,8 @@ class BudgetReportController extends Controller
foreach ($spent as $currency) {
foreach ($currency['budgets'] as $budget) {
foreach ($budget['transaction_journals'] as $journal) {
- $title = sprintf('%s (%s)', $journal['destination_account_name'], $currency['currency_name']);
- $result[$title] = $result[$title] ?? [
+ $title = sprintf('%s (%s)', $journal['destination_account_name'], $currency['currency_name']);
+ $result[$title] ??= [
'amount' => '0',
'currency_symbol' => $currency['currency_symbol'],
'currency_code' => $currency['currency_code'],
@@ -173,20 +149,13 @@ class BudgetReportController extends Controller
}
}
- $data = $this->generator->multiCurrencyPieChart($result);
+ $data = $this->generator->multiCurrencyPieChart($result);
return response()->json($data);
}
/**
* Main overview of a budget in the budget report.
- *
- * @param Collection $accounts
- * @param Budget $budget
- * @param Carbon $start
- * @param Carbon $end
- *
- * @return JsonResponse
*/
public function mainChart(Collection $accounts, Budget $budget, Carbon $start, Carbon $end): JsonResponse
{
@@ -197,8 +166,8 @@ class BudgetReportController extends Controller
// loop expenses.
foreach ($spent as $currency) {
// add things to chart Data for each currency:
- $spentKey = sprintf('%d-spent', $currency['currency_id']);
- $chartData[$spentKey] = $chartData[$spentKey] ?? [
+ $spentKey = sprintf('%d-spent', $currency['currency_id']);
+ $chartData[$spentKey] ??= [
'label' => sprintf(
'%s (%s)',
(string)trans('firefly.spent_in_specific_budget', ['budget' => $budget->name]),
@@ -215,23 +184,17 @@ class BudgetReportController extends Controller
foreach ($currentBudget['transaction_journals'] as $journal) {
$key = $journal['date']->isoFormat($format);
$amount = app('steam')->positive($journal['amount']);
- $chartData[$spentKey]['entries'][$key] = $chartData[$spentKey]['entries'][$key] ?? '0';
+ $chartData[$spentKey]['entries'][$key] ??= '0';
$chartData[$spentKey]['entries'][$key] = bcadd($chartData[$spentKey]['entries'][$key], $amount);
}
}
}
- $data = $this->generator->multiSet($chartData);
+ $data = $this->generator->multiSet($chartData);
return response()->json($data);
}
- /**
- * @param Carbon $start
- * @param Carbon $end
- *
- * @return array
- */
private function makeEntries(Carbon $start, Carbon $end): array
{
$return = [];
@@ -251,13 +214,6 @@ class BudgetReportController extends Controller
/**
* Chart that groups expenses by the account.
- *
- * @param Collection $accounts
- * @param Collection $budgets
- * @param Carbon $start
- * @param Carbon $end
- *
- * @return JsonResponse
*/
public function sourceAccountExpense(Collection $accounts, Collection $budgets, Carbon $start, Carbon $end): JsonResponse
{
@@ -268,8 +224,8 @@ class BudgetReportController extends Controller
foreach ($spent as $currency) {
foreach ($currency['budgets'] as $budget) {
foreach ($budget['transaction_journals'] as $journal) {
- $title = sprintf('%s (%s)', $journal['source_account_name'], $currency['currency_name']);
- $result[$title] = $result[$title] ?? [
+ $title = sprintf('%s (%s)', $journal['source_account_name'], $currency['currency_name']);
+ $result[$title] ??= [
'amount' => '0',
'currency_symbol' => $currency['currency_symbol'],
'currency_code' => $currency['currency_code'],
@@ -281,7 +237,7 @@ class BudgetReportController extends Controller
}
}
- $data = $this->generator->multiCurrencyPieChart($result);
+ $data = $this->generator->multiCurrencyPieChart($result);
return response()->json($data);
}
diff --git a/app/Http/Controllers/Chart/CategoryController.php b/app/Http/Controllers/Chart/CategoryController.php
index f600454d4d..42be033f2b 100644
--- a/app/Http/Controllers/Chart/CategoryController.php
+++ b/app/Http/Controllers/Chart/CategoryController.php
@@ -39,25 +39,21 @@ use FireflyIII\Support\Http\Controllers\ChartGeneration;
use FireflyIII\Support\Http\Controllers\DateCalculation;
use Illuminate\Http\JsonResponse;
use Illuminate\Support\Collection;
-use Psr\Container\ContainerExceptionInterface;
-use Psr\Container\NotFoundExceptionInterface;
/**
* Class CategoryController.
*/
class CategoryController extends Controller
{
- use DateCalculation;
use AugumentData;
use ChartGeneration;
+ use DateCalculation;
/** @var GeneratorInterface Chart generation methods. */
protected $generator;
/**
* CategoryController constructor.
- *
-
*/
public function __construct()
{
@@ -70,28 +66,24 @@ class CategoryController extends Controller
* Show an overview for a category for all time, per month/week/year.
* TODO test method, for category refactor.
*
- * @param Category $category
- *
- * @return JsonResponse
* @throws FireflyException
- * @throws ContainerExceptionInterface
- * @throws NotFoundExceptionInterface
*/
public function all(Category $category): JsonResponse
{
// cache results:
- $cache = new CacheProperties();
+ $cache = new CacheProperties();
$cache->addProperty('chart.category.all');
$cache->addProperty($category->id);
if ($cache->has()) {
return response()->json($cache->get());
}
+
/** @var CategoryRepositoryInterface $repository */
- $repository = app(CategoryRepositoryInterface::class);
- $start = $repository->firstUseDate($category) ?? $this->getDate();
- $range = app('navigation')->getViewRange(false);
- $start = app('navigation')->startOfPeriod($start, $range);
- $end = $this->getDate();
+ $repository = app(CategoryRepositoryInterface::class);
+ $start = $repository->firstUseDate($category) ?? $this->getDate();
+ $range = app('navigation')->getViewRange(false);
+ $start = app('navigation')->startOfPeriod($start, $range);
+ $end = $this->getDate();
/** @var WholePeriodChartGenerator $chartGenerator */
$chartGenerator = app(WholePeriodChartGenerator::class);
@@ -102,9 +94,6 @@ class CategoryController extends Controller
return response()->json($data);
}
- /**
- * @return Carbon
- */
private function getDate(): Carbon
{
return today(config('app.timezone'));
@@ -113,15 +102,13 @@ class CategoryController extends Controller
/**
* Shows the category chart on the front page.
* TODO test method for category refactor.
- *
- * @return JsonResponse
*/
public function frontPage(): JsonResponse
{
- $start = session('start', today(config('app.timezone'))->startOfMonth());
- $end = session('end', today(config('app.timezone'))->endOfMonth());
+ $start = session('start', today(config('app.timezone'))->startOfMonth());
+ $end = session('end', today(config('app.timezone'))->endOfMonth());
// chart properties for cache:
- $cache = new CacheProperties();
+ $cache = new CacheProperties();
$cache->addProperty($start);
$cache->addProperty($end);
$cache->addProperty('chart.category.frontpage');
@@ -140,13 +127,6 @@ class CategoryController extends Controller
/**
* Chart report.
* TODO test method for category refactor.
- *
- * @param Category $category
- * @param Collection $accounts
- * @param Carbon $start
- * @param Carbon $end
- *
- * @return JsonResponse
*/
public function reportPeriod(Category $category, Collection $accounts, Carbon $start, Carbon $end): JsonResponse
{
@@ -159,7 +139,7 @@ class CategoryController extends Controller
if ($cache->has()) {
return response()->json($cache->get());
}
- $data = $this->reportPeriodChart($accounts, $start, $end, $category);
+ $data = $this->reportPeriodChart($accounts, $start, $end, $category);
$cache->store($data);
@@ -168,13 +148,6 @@ class CategoryController extends Controller
/**
* Generate report chart for either with or without category.
- *
- * @param Collection $accounts
- * @param Carbon $start
- * @param Carbon $end
- * @param Category|null $category
- *
- * @return array
*/
private function reportPeriodChart(Collection $accounts, Carbon $start, Carbon $end, ?Category $category): array
{
@@ -186,18 +159,18 @@ class CategoryController extends Controller
$noCatRepository = app(NoCategoryRepositoryInterface::class);
// this gives us all currencies
- $expenses = $noCatRepository->listExpenses($start, $end, $accounts);
- $income = $noCatRepository->listIncome($start, $end, $accounts);
+ $expenses = $noCatRepository->listExpenses($start, $end, $accounts);
+ $income = $noCatRepository->listIncome($start, $end, $accounts);
}
if (null !== $category) {
/** @var OperationsRepositoryInterface $opsRepository */
$opsRepository = app(OperationsRepositoryInterface::class);
- $categoryId = (int)$category->id;
+ $categoryId = $category->id;
// this gives us all currencies
- $collection = new Collection([$category]);
- $expenses = $opsRepository->listExpenses($start, $end, null, $collection);
- $income = $opsRepository->listIncome($start, $end, null, $collection);
+ $collection = new Collection([$category]);
+ $expenses = $opsRepository->listExpenses($start, $end, null, $collection);
+ $income = $opsRepository->listIncome($start, $end, null, $collection);
}
$currencies = array_unique(array_merge(array_keys($income), array_keys($expenses)));
$periods = app('navigation')->listOfPeriods($start, $end);
@@ -211,19 +184,19 @@ class CategoryController extends Controller
$inKey = sprintf('%d-in', $currencyId);
$chartData[$outKey]
= [
- 'label' => sprintf('%s (%s)', (string)trans('firefly.spent'), $currencyInfo['currency_name']),
- 'entries' => [],
- 'type' => 'bar',
- 'backgroundColor' => 'rgba(219, 68, 55, 0.5)', // red
- ];
+ 'label' => sprintf('%s (%s)', (string)trans('firefly.spent'), $currencyInfo['currency_name']),
+ 'entries' => [],
+ 'type' => 'bar',
+ 'backgroundColor' => 'rgba(219, 68, 55, 0.5)', // red
+ ];
$chartData[$inKey]
- = [
- 'label' => sprintf('%s (%s)', (string)trans('firefly.earned'), $currencyInfo['currency_name']),
- 'entries' => [],
- 'type' => 'bar',
- 'backgroundColor' => 'rgba(0, 141, 76, 0.5)', // green
- ];
+ = [
+ 'label' => sprintf('%s (%s)', (string)trans('firefly.earned'), $currencyInfo['currency_name']),
+ 'entries' => [],
+ 'type' => 'bar',
+ 'backgroundColor' => 'rgba(0, 141, 76, 0.5)', // green
+ ];
// loop empty periods:
foreach (array_keys($periods) as $period) {
$label = $periods[$period];
@@ -231,20 +204,20 @@ class CategoryController extends Controller
$chartData[$inKey]['entries'][$label] = '0';
}
// loop income and expenses for this category.:
- $outSet = $expenses[$currencyId]['categories'][$categoryId] ?? ['transaction_journals' => []];
+ $outSet = $expenses[$currencyId]['categories'][$categoryId] ?? ['transaction_journals' => []];
foreach ($outSet['transaction_journals'] as $journal) {
$amount = app('steam')->positive($journal['amount']);
$date = $journal['date']->isoFormat($format);
- $chartData[$outKey]['entries'][$date] = $chartData[$outKey]['entries'][$date] ?? '0';
+ $chartData[$outKey]['entries'][$date] ??= '0';
$chartData[$outKey]['entries'][$date] = bcadd($amount, $chartData[$outKey]['entries'][$date]);
}
- $inSet = $income[$currencyId]['categories'][$categoryId] ?? ['transaction_journals' => []];
+ $inSet = $income[$currencyId]['categories'][$categoryId] ?? ['transaction_journals' => []];
foreach ($inSet['transaction_journals'] as $journal) {
$amount = app('steam')->positive($journal['amount']);
$date = $journal['date']->isoFormat($format);
- $chartData[$inKey]['entries'][$date] = $chartData[$inKey]['entries'][$date] ?? '0';
+ $chartData[$inKey]['entries'][$date] ??= '0';
$chartData[$inKey]['entries'][$date] = bcadd($amount, $chartData[$inKey]['entries'][$date]);
}
}
@@ -255,12 +228,6 @@ class CategoryController extends Controller
/**
* Chart for period for transactions without a category.
* TODO test me.
- *
- * @param Collection $accounts
- * @param Carbon $start
- * @param Carbon $end
- *
- * @return JsonResponse
*/
public function reportPeriodNoCategory(Collection $accounts, Carbon $start, Carbon $end): JsonResponse
{
@@ -272,7 +239,7 @@ class CategoryController extends Controller
if ($cache->has()) {
return response()->json($cache->get());
}
- $data = $this->reportPeriodChart($accounts, $start, $end, null);
+ $data = $this->reportPeriodChart($accounts, $start, $end, null);
$cache->store($data);
@@ -283,24 +250,18 @@ class CategoryController extends Controller
* Chart for a specific period.
* TODO test me, for category refactor.
*
- * @param Category $category
- * @param Carbon $date
- *
- * @return JsonResponse
* @throws FireflyException
- * @throws ContainerExceptionInterface
- * @throws NotFoundExceptionInterface
*/
public function specificPeriod(Category $category, Carbon $date): JsonResponse
{
- $range = app('navigation')->getViewRange(false);
- $start = app('navigation')->startOfPeriod($date, $range);
- $end = session()->get('end');
+ $range = app('navigation')->getViewRange(false);
+ $start = app('navigation')->startOfPeriod($date, $range);
+ $end = session()->get('end');
if ($end < $start) {
[$end, $start] = [$start, $end];
}
- $cache = new CacheProperties();
+ $cache = new CacheProperties();
$cache->addProperty($start);
$cache->addProperty($end);
$cache->addProperty($category->id);
diff --git a/app/Http/Controllers/Chart/CategoryReportController.php b/app/Http/Controllers/Chart/CategoryReportController.php
index 9d23654432..ad34527918 100644
--- a/app/Http/Controllers/Chart/CategoryReportController.php
+++ b/app/Http/Controllers/Chart/CategoryReportController.php
@@ -45,13 +45,12 @@ class CategoryReportController extends Controller
/** @var GeneratorInterface Chart generation methods. */
private $generator;
+
/** @var OperationsRepositoryInterface */
private $opsRepository;
/**
* CategoryReportController constructor.
- *
-
*/
public function __construct()
{
@@ -66,14 +65,6 @@ class CategoryReportController extends Controller
);
}
- /**
- * @param Collection $accounts
- * @param Collection $categories
- * @param Carbon $start
- * @param Carbon $end
- *
- * @return JsonResponse
- */
public function budgetExpense(Collection $accounts, Collection $categories, Carbon $start, Carbon $end): JsonResponse
{
$result = [];
@@ -86,7 +77,7 @@ class CategoryReportController extends Controller
foreach ($category['transaction_journals'] as $journal) {
$objectName = $journal['budget_name'] ?? trans('firefly.no_budget');
$title = sprintf('%s (%s)', $objectName, $currency['currency_name']);
- $result[$title] = $result[$title] ?? [
+ $result[$title] ??= [
'amount' => '0',
'currency_symbol' => $currency['currency_symbol'],
'currency_code' => $currency['currency_code'],
@@ -97,19 +88,11 @@ class CategoryReportController extends Controller
}
}
- $data = $this->generator->multiCurrencyPieChart($result);
+ $data = $this->generator->multiCurrencyPieChart($result);
return response()->json($data);
}
- /**
- * @param Collection $accounts
- * @param Collection $categories
- * @param Carbon $start
- * @param Carbon $end
- *
- * @return JsonResponse
- */
public function categoryExpense(Collection $accounts, Collection $categories, Carbon $start, Carbon $end): JsonResponse
{
$result = [];
@@ -119,8 +102,8 @@ class CategoryReportController extends Controller
foreach ($spent as $currency) {
/** @var array $category */
foreach ($currency['categories'] as $category) {
- $title = sprintf('%s (%s)', $category['name'], $currency['currency_name']);
- $result[$title] = $result[$title] ?? [
+ $title = sprintf('%s (%s)', $category['name'], $currency['currency_name']);
+ $result[$title] ??= [
'amount' => '0',
'currency_symbol' => $currency['currency_symbol'],
'currency_code' => $currency['currency_code'],
@@ -132,19 +115,11 @@ class CategoryReportController extends Controller
}
}
- $data = $this->generator->multiCurrencyPieChart($result);
+ $data = $this->generator->multiCurrencyPieChart($result);
return response()->json($data);
}
- /**
- * @param Collection $accounts
- * @param Collection $categories
- * @param Carbon $start
- * @param Carbon $end
- *
- * @return JsonResponse
- */
public function categoryIncome(Collection $accounts, Collection $categories, Carbon $start, Carbon $end): JsonResponse
{
$result = [];
@@ -154,8 +129,8 @@ class CategoryReportController extends Controller
foreach ($earned as $currency) {
/** @var array $category */
foreach ($currency['categories'] as $category) {
- $title = sprintf('%s (%s)', $category['name'], $currency['currency_name']);
- $result[$title] = $result[$title] ?? [
+ $title = sprintf('%s (%s)', $category['name'], $currency['currency_name']);
+ $result[$title] ??= [
'amount' => '0',
'currency_symbol' => $currency['currency_symbol'],
'currency_code' => $currency['currency_code'],
@@ -167,19 +142,11 @@ class CategoryReportController extends Controller
}
}
- $data = $this->generator->multiCurrencyPieChart($result);
+ $data = $this->generator->multiCurrencyPieChart($result);
return response()->json($data);
}
- /**
- * @param Collection $accounts
- * @param Collection $categories
- * @param Carbon $start
- * @param Carbon $end
- *
- * @return JsonResponse
- */
public function destinationExpense(Collection $accounts, Collection $categories, Carbon $start, Carbon $end): JsonResponse
{
$result = [];
@@ -192,7 +159,7 @@ class CategoryReportController extends Controller
foreach ($category['transaction_journals'] as $journal) {
$objectName = $journal['destination_account_name'] ?? trans('firefly.empty');
$title = sprintf('%s (%s)', $objectName, $currency['currency_name']);
- $result[$title] = $result[$title] ?? [
+ $result[$title] ??= [
'amount' => '0',
'currency_symbol' => $currency['currency_symbol'],
'currency_code' => $currency['currency_code'],
@@ -203,19 +170,11 @@ class CategoryReportController extends Controller
}
}
- $data = $this->generator->multiCurrencyPieChart($result);
+ $data = $this->generator->multiCurrencyPieChart($result);
return response()->json($data);
}
- /**
- * @param Collection $accounts
- * @param Collection $categories
- * @param Carbon $start
- * @param Carbon $end
- *
- * @return JsonResponse
- */
public function destinationIncome(Collection $accounts, Collection $categories, Carbon $start, Carbon $end): JsonResponse
{
$result = [];
@@ -228,7 +187,7 @@ class CategoryReportController extends Controller
foreach ($category['transaction_journals'] as $journal) {
$objectName = $journal['destination_account_name'] ?? trans('firefly.empty');
$title = sprintf('%s (%s)', $objectName, $currency['currency_name']);
- $result[$title] = $result[$title] ?? [
+ $result[$title] ??= [
'amount' => '0',
'currency_symbol' => $currency['currency_symbol'],
'currency_code' => $currency['currency_code'],
@@ -239,20 +198,11 @@ class CategoryReportController extends Controller
}
}
- $data = $this->generator->multiCurrencyPieChart($result);
+ $data = $this->generator->multiCurrencyPieChart($result);
return response()->json($data);
}
- /**
- * @param Collection $accounts
- * @param Category $category
- * @param Carbon $start
- * @param Carbon $end
- *
- * @return JsonResponse
- *
- */
public function mainChart(Collection $accounts, Category $category, Carbon $start, Carbon $end): JsonResponse
{
$chartData = [];
@@ -263,8 +213,8 @@ class CategoryReportController extends Controller
// loop expenses.
foreach ($spent as $currency) {
// add things to chart Data for each currency:
- $spentKey = sprintf('%d-spent', $currency['currency_id']);
- $chartData[$spentKey] = $chartData[$spentKey] ?? [
+ $spentKey = sprintf('%d-spent', $currency['currency_id']);
+ $chartData[$spentKey] ??= [
'label' => sprintf(
'%s (%s)',
(string)trans('firefly.spent_in_specific_category', ['category' => $category->name]),
@@ -281,7 +231,7 @@ class CategoryReportController extends Controller
foreach ($currentCategory['transaction_journals'] as $journal) {
$key = $journal['date']->isoFormat($format);
$amount = app('steam')->positive($journal['amount']);
- $chartData[$spentKey]['entries'][$key] = $chartData[$spentKey]['entries'][$key] ?? '0';
+ $chartData[$spentKey]['entries'][$key] ??= '0';
$chartData[$spentKey]['entries'][$key] = bcadd($chartData[$spentKey]['entries'][$key], $amount);
}
}
@@ -290,8 +240,8 @@ class CategoryReportController extends Controller
// loop income.
foreach ($earned as $currency) {
// add things to chart Data for each currency:
- $spentKey = sprintf('%d-earned', $currency['currency_id']);
- $chartData[$spentKey] = $chartData[$spentKey] ?? [
+ $spentKey = sprintf('%d-earned', $currency['currency_id']);
+ $chartData[$spentKey] ??= [
'label' => sprintf(
'%s (%s)',
(string)trans('firefly.earned_in_specific_category', ['category' => $category->name]),
@@ -308,24 +258,19 @@ class CategoryReportController extends Controller
foreach ($currentCategory['transaction_journals'] as $journal) {
$key = $journal['date']->isoFormat($format);
$amount = app('steam')->positive($journal['amount']);
- $chartData[$spentKey]['entries'][$key] = $chartData[$spentKey]['entries'][$key] ?? '0';
+ $chartData[$spentKey]['entries'][$key] ??= '0';
$chartData[$spentKey]['entries'][$key] = bcadd($chartData[$spentKey]['entries'][$key], $amount);
}
}
}
- $data = $this->generator->multiSet($chartData);
+ $data = $this->generator->multiSet($chartData);
return response()->json($data);
}
/**
* TODO duplicate function
- *
- * @param Carbon $start
- * @param Carbon $end
- *
- * @return array
*/
private function makeEntries(Carbon $start, Carbon $end): array
{
@@ -344,14 +289,6 @@ class CategoryReportController extends Controller
return $return;
}
- /**
- * @param Collection $accounts
- * @param Collection $categories
- * @param Carbon $start
- * @param Carbon $end
- *
- * @return JsonResponse
- */
public function sourceExpense(Collection $accounts, Collection $categories, Carbon $start, Carbon $end): JsonResponse
{
$result = [];
@@ -364,7 +301,7 @@ class CategoryReportController extends Controller
foreach ($category['transaction_journals'] as $journal) {
$objectName = $journal['source_account_name'] ?? trans('firefly.empty');
$title = sprintf('%s (%s)', $objectName, $currency['currency_name']);
- $result[$title] = $result[$title] ?? [
+ $result[$title] ??= [
'amount' => '0',
'currency_symbol' => $currency['currency_symbol'],
'currency_code' => $currency['currency_code'],
@@ -375,19 +312,11 @@ class CategoryReportController extends Controller
}
}
- $data = $this->generator->multiCurrencyPieChart($result);
+ $data = $this->generator->multiCurrencyPieChart($result);
return response()->json($data);
}
- /**
- * @param Collection $accounts
- * @param Collection $categories
- * @param Carbon $start
- * @param Carbon $end
- *
- * @return JsonResponse
- */
public function sourceIncome(Collection $accounts, Collection $categories, Carbon $start, Carbon $end): JsonResponse
{
$result = [];
@@ -400,7 +329,7 @@ class CategoryReportController extends Controller
foreach ($category['transaction_journals'] as $journal) {
$objectName = $journal['source_account_name'] ?? trans('firefly.empty');
$title = sprintf('%s (%s)', $objectName, $currency['currency_name']);
- $result[$title] = $result[$title] ?? [
+ $result[$title] ??= [
'amount' => '0',
'currency_symbol' => $currency['currency_symbol'],
'currency_code' => $currency['currency_code'],
@@ -411,7 +340,7 @@ class CategoryReportController extends Controller
}
}
- $data = $this->generator->multiCurrencyPieChart($result);
+ $data = $this->generator->multiCurrencyPieChart($result);
return response()->json($data);
}
diff --git a/app/Http/Controllers/Chart/DoubleReportController.php b/app/Http/Controllers/Chart/DoubleReportController.php
index 1cda544991..8cf9117732 100644
--- a/app/Http/Controllers/Chart/DoubleReportController.php
+++ b/app/Http/Controllers/Chart/DoubleReportController.php
@@ -33,13 +33,13 @@ use Illuminate\Http\JsonResponse;
use Illuminate\Support\Collection;
/**
- *
* Class DoubleReportController
*/
class DoubleReportController extends Controller
{
/** @var GeneratorInterface Chart generation methods. */
private $generator;
+
/** @var OperationsRepositoryInterface */
private $opsRepository;
@@ -48,8 +48,6 @@ class DoubleReportController extends Controller
/**
* CategoryReportController constructor.
- *
-
*/
public function __construct()
{
@@ -65,14 +63,6 @@ class DoubleReportController extends Controller
);
}
- /**
- * @param Collection $accounts
- * @param Collection $others
- * @param Carbon $start
- * @param Carbon $end
- *
- * @return JsonResponse
- */
public function budgetExpense(Collection $accounts, Collection $others, Carbon $start, Carbon $end): JsonResponse
{
$result = [];
@@ -85,7 +75,7 @@ class DoubleReportController extends Controller
foreach ($currency['transaction_journals'] as $journal) {
$categoryName = $journal['budget_name'] ?? trans('firefly.no_budget');
$title = sprintf('%s (%s)', $categoryName, $currency['currency_name']);
- $result[$title] = $result[$title] ?? [
+ $result[$title] ??= [
'amount' => '0',
'currency_symbol' => $currency['currency_symbol'],
'currency_code' => $currency['currency_code'],
@@ -95,19 +85,11 @@ class DoubleReportController extends Controller
}
}
- $data = $this->generator->multiCurrencyPieChart($result);
+ $data = $this->generator->multiCurrencyPieChart($result);
return response()->json($data);
}
- /**
- * @param Collection $accounts
- * @param Collection $others
- * @param Carbon $start
- * @param Carbon $end
- *
- * @return JsonResponse
- */
public function categoryExpense(Collection $accounts, Collection $others, Carbon $start, Carbon $end): JsonResponse
{
$result = [];
@@ -120,7 +102,7 @@ class DoubleReportController extends Controller
foreach ($currency['transaction_journals'] as $journal) {
$categoryName = $journal['category_name'] ?? trans('firefly.no_category');
$title = sprintf('%s (%s)', $categoryName, $currency['currency_name']);
- $result[$title] = $result[$title] ?? [
+ $result[$title] ??= [
'amount' => '0',
'currency_symbol' => $currency['currency_symbol'],
'currency_code' => $currency['currency_code'],
@@ -130,19 +112,11 @@ class DoubleReportController extends Controller
}
}
- $data = $this->generator->multiCurrencyPieChart($result);
+ $data = $this->generator->multiCurrencyPieChart($result);
return response()->json($data);
}
- /**
- * @param Collection $accounts
- * @param Collection $others
- * @param Carbon $start
- * @param Carbon $end
- *
- * @return JsonResponse
- */
public function categoryIncome(Collection $accounts, Collection $others, Carbon $start, Carbon $end): JsonResponse
{
$result = [];
@@ -155,7 +129,7 @@ class DoubleReportController extends Controller
foreach ($currency['transaction_journals'] as $journal) {
$categoryName = $journal['category_name'] ?? trans('firefly.no_category');
$title = sprintf('%s (%s)', $categoryName, $currency['currency_name']);
- $result[$title] = $result[$title] ?? [
+ $result[$title] ??= [
'amount' => '0',
'currency_symbol' => $currency['currency_symbol'],
'currency_code' => $currency['currency_code'],
@@ -165,29 +139,20 @@ class DoubleReportController extends Controller
}
}
- $data = $this->generator->multiCurrencyPieChart($result);
+ $data = $this->generator->multiCurrencyPieChart($result);
return response()->json($data);
}
- /**
- * @param Collection $accounts
- * @param Account $account
- * @param Carbon $start
- * @param Carbon $end
- *
- * @return JsonResponse
- *
- */
public function mainChart(Collection $accounts, Account $account, Carbon $start, Carbon $end): JsonResponse
{
$chartData = [];
- $opposing = $this->repository->expandWithDoubles(new Collection([$account]));
- $accounts = $accounts->merge($opposing);
- $spent = $this->opsRepository->listExpenses($start, $end, $accounts);
- $earned = $this->opsRepository->listIncome($start, $end, $accounts);
- $format = app('navigation')->preferredCarbonLocalizedFormat($start, $end);
+ $opposing = $this->repository->expandWithDoubles(new Collection([$account]));
+ $accounts = $accounts->merge($opposing);
+ $spent = $this->opsRepository->listExpenses($start, $end, $accounts);
+ $earned = $this->opsRepository->listIncome($start, $end, $accounts);
+ $format = app('navigation')->preferredCarbonLocalizedFormat($start, $end);
// loop expenses.
foreach ($spent as $currency) {
@@ -195,7 +160,7 @@ class DoubleReportController extends Controller
$spentKey = sprintf('%d-spent', $currency['currency_id']);
$name = $this->getCounterpartName($accounts, $account->id, $account->name, $account->iban);
- $chartData[$spentKey] = $chartData[$spentKey] ?? [
+ $chartData[$spentKey] ??= [
'label' => sprintf(
'%s (%s)',
(string)trans('firefly.spent_in_specific_double', ['account' => $name]),
@@ -211,7 +176,7 @@ class DoubleReportController extends Controller
foreach ($currency['transaction_journals'] as $journal) {
$key = $journal['date']->isoFormat($format);
$amount = app('steam')->positive($journal['amount']);
- $chartData[$spentKey]['entries'][$key] = $chartData[$spentKey]['entries'][$key] ?? '0';
+ $chartData[$spentKey]['entries'][$key] ??= '0';
$chartData[$spentKey]['entries'][$key] = bcadd($chartData[$spentKey]['entries'][$key], $amount);
}
}
@@ -221,7 +186,7 @@ class DoubleReportController extends Controller
$earnedKey = sprintf('%d-earned', $currency['currency_id']);
$name = $this->getCounterpartName($accounts, $account->id, $account->name, $account->iban);
- $chartData[$earnedKey] = $chartData[$earnedKey] ?? [
+ $chartData[$earnedKey] ??= [
'label' => sprintf(
'%s (%s)',
(string)trans('firefly.earned_in_specific_double', ['account' => $name]),
@@ -237,25 +202,18 @@ class DoubleReportController extends Controller
foreach ($currency['transaction_journals'] as $journal) {
$key = $journal['date']->isoFormat($format);
$amount = app('steam')->positive($journal['amount']);
- $chartData[$earnedKey]['entries'][$key] = $chartData[$earnedKey]['entries'][$key] ?? '0';
+ $chartData[$earnedKey]['entries'][$key] ??= '0';
$chartData[$earnedKey]['entries'][$key] = bcadd($chartData[$earnedKey]['entries'][$key], $amount);
}
}
- $data = $this->generator->multiSet($chartData);
+ $data = $this->generator->multiSet($chartData);
return response()->json($data);
}
/**
* TODO duplicate function
- *
- * @param Collection $accounts
- * @param int $id
- * @param string $name
- * @param null|string $iban
- *
- * @return string
*/
private function getCounterpartName(Collection $accounts, int $id, string $name, ?string $iban): string
{
@@ -274,11 +232,6 @@ class DoubleReportController extends Controller
/**
* TODO duplicate function
- *
- * @param Carbon $start
- * @param Carbon $end
- *
- * @return array
*/
private function makeEntries(Carbon $start, Carbon $end): array
{
@@ -297,14 +250,6 @@ class DoubleReportController extends Controller
return $return;
}
- /**
- * @param Collection $accounts
- * @param Collection $others
- * @param Carbon $start
- * @param Carbon $end
- *
- * @return JsonResponse
- */
public function tagExpense(Collection $accounts, Collection $others, Carbon $start, Carbon $end): JsonResponse
{
$result = [];
@@ -319,11 +264,11 @@ class DoubleReportController extends Controller
// no tags? also deserves a sport
if (0 === count($journal['tags'])) {
- $includedJournals[] = $journalId;
+ $includedJournals[] = $journalId;
// do something
$tagName = trans('firefly.no_tags');
$title = sprintf('%s (%s)', $tagName, $currency['currency_name']);
- $result[$title] = $result[$title] ?? [
+ $result[$title] ??= [
'amount' => '0',
'currency_symbol' => $currency['currency_symbol'],
'currency_code' => $currency['currency_code'],
@@ -331,17 +276,18 @@ class DoubleReportController extends Controller
$amount = app('steam')->positive($journal['amount']);
$result[$title]['amount'] = bcadd($result[$title]['amount'], $amount);
}
+
// loop each tag:
/** @var array $tag */
foreach ($journal['tags'] as $tag) {
if (in_array($journalId, $includedJournals, true)) {
continue;
}
- $includedJournals[] = $journalId;
+ $includedJournals[] = $journalId;
// do something
$tagName = $tag['name'];
$title = sprintf('%s (%s)', $tagName, $currency['currency_name']);
- $result[$title] = $result[$title] ?? [
+ $result[$title] ??= [
'amount' => '0',
'currency_symbol' => $currency['currency_symbol'],
'currency_code' => $currency['currency_code'],
@@ -352,19 +298,11 @@ class DoubleReportController extends Controller
}
}
- $data = $this->generator->multiCurrencyPieChart($result);
+ $data = $this->generator->multiCurrencyPieChart($result);
return response()->json($data);
}
- /**
- * @param Collection $accounts
- * @param Collection $others
- * @param Carbon $start
- * @param Carbon $end
- *
- * @return JsonResponse
- */
public function tagIncome(Collection $accounts, Collection $others, Carbon $start, Carbon $end): JsonResponse
{
$result = [];
@@ -379,11 +317,11 @@ class DoubleReportController extends Controller
// no tags? also deserves a sport
if (0 === count($journal['tags'])) {
- $includedJournals[] = $journalId;
+ $includedJournals[] = $journalId;
// do something
$tagName = trans('firefly.no_tags');
$title = sprintf('%s (%s)', $tagName, $currency['currency_name']);
- $result[$title] = $result[$title] ?? [
+ $result[$title] ??= [
'amount' => '0',
'currency_symbol' => $currency['currency_symbol'],
'currency_code' => $currency['currency_code'],
@@ -391,17 +329,18 @@ class DoubleReportController extends Controller
$amount = app('steam')->positive($journal['amount']);
$result[$title]['amount'] = bcadd($result[$title]['amount'], $amount);
}
+
// loop each tag:
/** @var array $tag */
foreach ($journal['tags'] as $tag) {
if (in_array($journalId, $includedJournals, true)) {
continue;
}
- $includedJournals[] = $journalId;
+ $includedJournals[] = $journalId;
// do something
$tagName = $tag['name'];
$title = sprintf('%s (%s)', $tagName, $currency['currency_name']);
- $result[$title] = $result[$title] ?? [
+ $result[$title] ??= [
'amount' => '0',
'currency_symbol' => $currency['currency_symbol'],
'currency_code' => $currency['currency_code'],
@@ -412,7 +351,7 @@ class DoubleReportController extends Controller
}
}
- $data = $this->generator->multiCurrencyPieChart($result);
+ $data = $this->generator->multiCurrencyPieChart($result);
return response()->json($data);
}
diff --git a/app/Http/Controllers/Chart/ExpenseReportController.php b/app/Http/Controllers/Chart/ExpenseReportController.php
index 6757e856c4..889a004850 100644
--- a/app/Http/Controllers/Chart/ExpenseReportController.php
+++ b/app/Http/Controllers/Chart/ExpenseReportController.php
@@ -33,7 +33,6 @@ use FireflyIII\Support\Http\Controllers\AugumentData;
use FireflyIII\Support\Http\Controllers\TransactionCalculation;
use Illuminate\Http\JsonResponse;
use Illuminate\Support\Collection;
-use JsonException;
/**
* Separate controller because many helper functions are shared.
@@ -45,15 +44,11 @@ class ExpenseReportController extends Controller
use AugumentData;
use TransactionCalculation;
- /** @var AccountRepositoryInterface The account repository */
- protected $accountRepository;
- /** @var GeneratorInterface Chart generation methods. */
- protected $generator;
+ protected AccountRepositoryInterface $accountRepository;
+ protected GeneratorInterface $generator;
/**
* ExpenseReportController constructor.
- *
-
*/
public function __construct()
{
@@ -73,17 +68,11 @@ class ExpenseReportController extends Controller
*
* TODO this chart is not multi currency aware.
*
- * @param Collection $accounts
- * @param Collection $expense
- * @param Carbon $start
- * @param Carbon $end
- *
- * @return JsonResponse
- * @throws JsonException
+ * @SuppressWarnings(PHPMD.ExcessiveMethodLength)
*/
public function mainChart(Collection $accounts, Collection $expense, Carbon $start, Carbon $end): JsonResponse
{
- $cache = new CacheProperties();
+ $cache = new CacheProperties();
$cache->addProperty('chart.expense.report.main');
$cache->addProperty($accounts);
$cache->addProperty($expense);
@@ -98,9 +87,8 @@ class ExpenseReportController extends Controller
$chartData = [];
$currentStart = clone $start;
$combined = $this->combineAccounts($expense);
- // make "all" set:
- $all = new Collection();
- foreach ($combined as $name => $combination) {
+ $all = new Collection();
+ foreach ($combined as $combination) {
$all = $all->merge($combination);
}
@@ -112,28 +100,28 @@ class ExpenseReportController extends Controller
foreach ($combined as $name => $combination) {
// first is always expense account:
/** @var Account $exp */
- $exp = $combination->first();
- $chartData[$exp->id . '-in'] = [
+ $exp = $combination->first();
+ $chartData[$exp->id.'-in'] = [
'label' => sprintf('%s (%s)', $name, (string)trans('firefly.income')),
'type' => 'bar',
'yAxisID' => 'y-axis-0',
'entries' => [],
];
- $chartData[$exp->id . '-out'] = [
+ $chartData[$exp->id.'-out'] = [
'label' => sprintf('%s (%s)', $name, (string)trans('firefly.expenses')),
'type' => 'bar',
'yAxisID' => 'y-axis-0',
'entries' => [],
];
// total in, total out:
- $chartData[$exp->id . '-total-in'] = [
+ $chartData[$exp->id.'-total-in'] = [
'label' => sprintf('%s (%s)', $name, (string)trans('firefly.sum_of_income')),
'type' => 'line',
'fill' => false,
'yAxisID' => 'y-axis-1',
'entries' => [],
];
- $chartData[$exp->id . '-total-out'] = [
+ $chartData[$exp->id.'-total-out'] = [
'label' => sprintf('%s (%s)', $name, (string)trans('firefly.sum_of_expenses')),
'type' => 'line',
'fill' => false,
@@ -146,30 +134,30 @@ class ExpenseReportController extends Controller
$sumOfExpense = [];
while ($currentStart < $end) {
- $currentEnd = clone $currentStart;
- $currentEnd = $currentEnd->$function();
+ $currentEnd = clone $currentStart;
+ $currentEnd = $currentEnd->{$function}(); // @phpstan-ignore-line
// get expenses grouped by opposing name:
- $expenses = $this->groupByName($this->getExpensesForOpposing($accounts, $all, $currentStart, $currentEnd));
- $income = $this->groupByName($this->getIncomeForOpposing($accounts, $all, $currentStart, $currentEnd));
- $label = $currentStart->isoFormat($format);
+ $expenses = $this->groupByName($this->getExpensesForOpposing($accounts, $all, $currentStart, $currentEnd));
+ $income = $this->groupByName($this->getIncomeForOpposing($accounts, $all, $currentStart, $currentEnd));
+ $label = $currentStart->isoFormat($format);
foreach ($combined as $name => $combination) {
// first is always expense account:
/** @var Account $exp */
- $exp = $combination->first();
- $labelIn = $exp->id . '-in';
- $labelOut = $exp->id . '-out';
- $labelSumIn = $exp->id . '-total-in';
- $labelSumOut = $exp->id . '-total-out';
- $currentIncome = bcmul($income[$name] ?? '0', '-1');
- $currentExpense = $expenses[$name] ?? '0';
+ $exp = $combination->first();
+ $labelIn = $exp->id.'-in';
+ $labelOut = $exp->id.'-out';
+ $labelSumIn = $exp->id.'-total-in';
+ $labelSumOut = $exp->id.'-total-out';
+ $currentIncome = bcmul($income[$name] ?? '0', '-1');
+ $currentExpense = $expenses[$name] ?? '0';
// add to sum:
- $sumOfIncome[$exp->id] = $sumOfIncome[$exp->id] ?? '0';
- $sumOfExpense[$exp->id] = $sumOfExpense[$exp->id] ?? '0';
- $sumOfIncome[$exp->id] = bcadd($sumOfIncome[$exp->id], $currentIncome);
- $sumOfExpense[$exp->id] = bcadd($sumOfExpense[$exp->id], $currentExpense);
+ $sumOfIncome[$exp->id] ??= '0';
+ $sumOfExpense[$exp->id] ??= '0';
+ $sumOfIncome[$exp->id] = bcadd($sumOfIncome[$exp->id], $currentIncome);
+ $sumOfExpense[$exp->id] = bcadd($sumOfExpense[$exp->id], $currentExpense);
// add to chart:
$chartData[$labelIn]['entries'][$label] = $currentIncome;
@@ -177,23 +165,24 @@ class ExpenseReportController extends Controller
$chartData[$labelSumIn]['entries'][$label] = $sumOfIncome[$exp->id];
$chartData[$labelSumOut]['entries'][$label] = $sumOfExpense[$exp->id];
}
+
/** @var Carbon $currentStart */
$currentStart = clone $currentEnd;
$currentStart->addDay();
$currentStart->startOfDay();
}
// remove all empty entries to prevent cluttering:
- $newSet = [];
+ $newSet = [];
foreach ($chartData as $key => $entry) {
// TODO not sure, this is a bad comparison.
- if (0 === !array_sum($entry['entries'])) {
+ if (array_sum($entry['entries']) > 0) {
$newSet[$key] = $entry;
}
}
if (0 === count($newSet)) {
$newSet = $chartData;
}
- $data = $this->generator->multiSet($newSet);
+ $data = $this->generator->multiSet($newSet);
$cache->store($data);
return response()->json($data);
diff --git a/app/Http/Controllers/Chart/PiggyBankController.php b/app/Http/Controllers/Chart/PiggyBankController.php
index 7057f84947..4bf27e2748 100644
--- a/app/Http/Controllers/Chart/PiggyBankController.php
+++ b/app/Http/Controllers/Chart/PiggyBankController.php
@@ -46,8 +46,6 @@ class PiggyBankController extends Controller
/**
* PiggyBankController constructor.
- *
-
*/
public function __construct()
{
@@ -61,42 +59,38 @@ class PiggyBankController extends Controller
*
* TODO this chart is not multi currency aware.
*
- * @param PiggyBankRepositoryInterface $repository
- * @param PiggyBank $piggyBank
- *
- * @return JsonResponse
* @throws FireflyException
*/
public function history(PiggyBankRepositoryInterface $repository, PiggyBank $piggyBank): JsonResponse
{
// chart properties for cache:
- $cache = new CacheProperties();
+ $cache = new CacheProperties();
$cache->addProperty('chart.piggy-bank.history');
$cache->addProperty($piggyBank->id);
if ($cache->has()) {
return response()->json($cache->get());
}
- $set = $repository->getEvents($piggyBank);
- $set = $set->reverse();
- $locale = app('steam')->getLocale();
+ $set = $repository->getEvents($piggyBank);
+ $set = $set->reverse();
+ $locale = app('steam')->getLocale();
// get first event or start date of piggy bank or today
- $startDate = $piggyBank->startdate ?? today(config('app.timezone'));
+ $startDate = $piggyBank->startdate ?? today(config('app.timezone'));
- /** @var PiggyBankEvent|null $firstEvent */
- $firstEvent = $set->first();
- $firstDate = null === $firstEvent ? new Carbon() : $firstEvent->date;
+ /** @var null|PiggyBankEvent $firstEvent */
+ $firstEvent = $set->first();
+ $firstDate = null === $firstEvent ? new Carbon() : $firstEvent->date;
// which ever is older:
- $oldest = $startDate->lt($firstDate) ? $startDate : $firstDate;
- $today = today(config('app.timezone'));
+ $oldest = $startDate->lt($firstDate) ? $startDate : $firstDate;
+ $today = today(config('app.timezone'));
// depending on diff, do something with range of chart.
- $step = $this->calculateStep($oldest, $today);
+ $step = $this->calculateStep($oldest, $today);
- $chartData = [];
+ $chartData = [];
while ($oldest <= $today) {
$filtered = $set->filter(
- function (PiggyBankEvent $event) use ($oldest) {
+ static function (PiggyBankEvent $event) use ($oldest) {
return $event->date->lte($oldest);
}
);
@@ -106,7 +100,7 @@ class PiggyBankController extends Controller
$oldest = app('navigation')->addPeriod($oldest, $step, 0);
}
$finalFiltered = $set->filter(
- function (PiggyBankEvent $event) use ($today) {
+ static function (PiggyBankEvent $event) use ($today) {
return $event->date->lte($today);
}
);
@@ -114,7 +108,7 @@ class PiggyBankController extends Controller
$finalLabel = $today->isoFormat((string)trans('config.month_and_day_js', [], $locale));
$chartData[$finalLabel] = $finalSum;
- $data = $this->generator->singleSet($piggyBank->name, $chartData);
+ $data = $this->generator->singleSet($piggyBank->name, $chartData);
$cache->store($data);
return response()->json($data);
diff --git a/app/Http/Controllers/Chart/ReportController.php b/app/Http/Controllers/Chart/ReportController.php
index 426e84c66b..8ad7bde9d7 100644
--- a/app/Http/Controllers/Chart/ReportController.php
+++ b/app/Http/Controllers/Chart/ReportController.php
@@ -36,8 +36,6 @@ use FireflyIII\Support\Http\Controllers\BasicDataSupport;
use FireflyIII\Support\Http\Controllers\ChartGeneration;
use Illuminate\Http\JsonResponse;
use Illuminate\Support\Collection;
-use Illuminate\Support\Facades\Log;
-use JsonException;
/**
* Class ReportController.
@@ -47,13 +45,10 @@ class ReportController extends Controller
use BasicDataSupport;
use ChartGeneration;
- /** @var GeneratorInterface Chart generation methods. */
- protected $generator;
+ protected GeneratorInterface $generator;
/**
* ReportController constructor.
- *
-
*/
public function __construct()
{
@@ -65,17 +60,11 @@ class ReportController extends Controller
/**
* This chart, by default, is shown on the multi-year and year report pages,
* which means that giving it a 2 week "period" should be enough granularity.
- *
- * @param Collection $accounts
- * @param Carbon $start
- * @param Carbon $end
- *
- * @return JsonResponse
*/
public function netWorth(Collection $accounts, Carbon $start, Carbon $end): JsonResponse
{
// chart properties for cache:
- $cache = new CacheProperties();
+ $cache = new CacheProperties();
$cache->addProperty('chart.report.net-worth');
$cache->addProperty($start);
$cache->addProperty(implode(',', $accounts->pluck('id')->toArray()));
@@ -83,11 +72,12 @@ class ReportController extends Controller
if ($cache->has()) {
return response()->json($cache->get());
}
- $locale = app('steam')->getLocale();
- $current = clone $start;
- $chartData = [];
+ $locale = app('steam')->getLocale();
+ $current = clone $start;
+ $chartData = [];
+
/** @var NetWorthInterface $helper */
- $helper = app(NetWorthInterface::class);
+ $helper = app(NetWorthInterface::class);
$helper->setUser(auth()->user());
// filter accounts on having the preference for being included.
@@ -98,7 +88,7 @@ class ReportController extends Controller
$includeNetWorth = $accountRepository->getMetaValue($account, 'include_net_worth');
$result = null === $includeNetWorth ? true : '1' === $includeNetWorth;
if (false === $result) {
- Log::debug(sprintf('Will not include "%s" in net worth charts.', $account->name));
+ app('log')->debug(sprintf('Will not include "%s" in net worth charts.', $account->name));
}
return $result;
@@ -109,19 +99,22 @@ class ReportController extends Controller
while ($current < $end) {
// get balances by date, grouped by currency.
- $result = $helper->getNetWorthByCurrency($filtered, $current);
+ $result = $helper->byAccounts($filtered, $current);
// loop result, add to array.
/** @var array $netWorthItem */
- foreach ($result as $netWorthItem) {
- $currencyId = $netWorthItem['currency']->id;
- $label = $current->isoFormat((string)trans('config.month_and_day_js', [], $locale));
+ foreach ($result as $key => $netWorthItem) {
+ if ('native' === $key) {
+ continue;
+ }
+ $currencyId = $netWorthItem['currency_id'];
+ $label = $current->isoFormat((string)trans('config.month_and_day_js', [], $locale));
if (!array_key_exists($currencyId, $chartData)) {
$chartData[$currencyId] = [
- 'label' => 'Net worth in ' . $netWorthItem['currency']->name,
+ 'label' => 'Net worth in '.$netWorthItem['currency_name'],
'type' => 'line',
- 'currency_symbol' => $netWorthItem['currency']->symbol,
- 'currency_code' => $netWorthItem['currency']->code,
+ 'currency_symbol' => $netWorthItem['currency_symbol'],
+ 'currency_code' => $netWorthItem['currency_code'],
'entries' => [],
];
}
@@ -130,7 +123,7 @@ class ReportController extends Controller
$current->addDays(7);
}
- $data = $this->generator->multiSet($chartData);
+ $data = $this->generator->multiSet($chartData);
$cache->store($data);
return response()->json($data);
@@ -139,17 +132,12 @@ class ReportController extends Controller
/**
* Shows income and expense, debit/credit: operations.
*
- * @param Collection $accounts
- * @param Carbon $start
- * @param Carbon $end
- *
- * @return JsonResponse
- * @throws JsonException
+ * @SuppressWarnings(PHPMD.ExcessiveMethodLength)
*/
public function operations(Collection $accounts, Carbon $start, Carbon $end): JsonResponse
{
// chart properties for cache:
- $cache = new CacheProperties();
+ $cache = new CacheProperties();
$cache->addProperty('chart.report.operations');
$cache->addProperty($start);
$cache->addProperty($accounts);
@@ -157,60 +145,46 @@ class ReportController extends Controller
if ($cache->has()) {
return response()->json($cache->get());
}
- Log::debug('Going to do operations for accounts ', $accounts->pluck('id')->toArray());
+
+ app('log')->debug('Going to do operations for accounts ', $accounts->pluck('id')->toArray());
$format = app('navigation')->preferredCarbonFormat($start, $end);
$titleFormat = app('navigation')->preferredCarbonLocalizedFormat($start, $end);
$preferredRange = app('navigation')->preferredRangeFormat($start, $end);
$ids = $accounts->pluck('id')->toArray();
+ $data = [];
+ $chartData = [];
- // get journals for entire period:
- $data = [];
- $chartData = [
-
- ];
/** @var GroupCollectorInterface $collector */
- $collector = app(GroupCollectorInterface::class);
+ $collector = app(GroupCollectorInterface::class);
$collector->setRange($start, $end)->withAccountInformation();
$collector->setXorAccounts($accounts);
$collector->setTypes([TransactionType::WITHDRAWAL, TransactionType::DEPOSIT, TransactionType::RECONCILIATION, TransactionType::TRANSFER]);
- $journals = $collector->getExtractedJournals();
+ $journals = $collector->getExtractedJournals();
// loop. group by currency and by period.
/** @var array $journal */
foreach ($journals as $journal) {
- $period = $journal['date']->format($format);
- $currencyId = (int)$journal['currency_id'];
- $data[$currencyId] = $data[$currencyId] ?? [
+ $period = $journal['date']->format($format);
+ $currencyId = (int)$journal['currency_id'];
+ $data[$currencyId] ??= [
'currency_id' => $currencyId,
'currency_symbol' => $journal['currency_symbol'],
'currency_code' => $journal['currency_code'],
'currency_name' => $journal['currency_name'],
'currency_decimal_places' => (int)$journal['currency_decimal_places'],
];
- $data[$currencyId][$period] = $data[$currencyId][$period] ?? [
+ $data[$currencyId][$period] ??= [
'period' => $period,
'spent' => '0',
'earned' => '0',
];
// in our outgoing?
- $key = 'spent';
- $amount = app('steam')->positive($journal['amount']);
+ $key = 'spent';
+ $amount = app('steam')->positive($journal['amount']);
// deposit = incoming
// transfer or reconcile or opening balance, and these accounts are the destination.
- if (
- TransactionType::DEPOSIT === $journal['transaction_type_type']
- ||
-
- (
- (
- TransactionType::TRANSFER === $journal['transaction_type_type']
- || TransactionType::RECONCILIATION === $journal['transaction_type_type']
- || TransactionType::OPENING_BALANCE === $journal['transaction_type_type']
- )
- && in_array($journal['destination_account_id'], $ids, true)
- )
- ) {
+ if (TransactionType::DEPOSIT === $journal['transaction_type_type'] || ((TransactionType::TRANSFER === $journal['transaction_type_type'] || TransactionType::RECONCILIATION === $journal['transaction_type_type'] || TransactionType::OPENING_BALANCE === $journal['transaction_type_type']) && in_array($journal['destination_account_id'], $ids, true))) {
$key = 'earned';
}
$data[$currencyId][$period][$key] = bcadd($data[$currencyId][$period][$key], $amount);
@@ -219,7 +193,7 @@ class ReportController extends Controller
// loop this data, make chart bars for each currency:
/** @var array $currency */
foreach ($data as $currency) {
- $income = [
+ $income = [
'label' => (string)trans('firefly.box_earned_in_currency', ['currency' => $currency['currency_name']]),
'type' => 'bar',
'backgroundColor' => 'rgba(0, 141, 76, 0.5)', // green
@@ -228,7 +202,7 @@ class ReportController extends Controller
'currency_code' => $currency['currency_code'],
'entries' => [],
];
- $expense = [
+ $expense = [
'label' => (string)trans('firefly.box_spent_in_currency', ['currency' => $currency['currency_name']]),
'type' => 'bar',
'backgroundColor' => 'rgba(219, 68, 55, 0.5)', // red
@@ -236,23 +210,28 @@ class ReportController extends Controller
'currency_symbol' => $currency['currency_symbol'],
'currency_code' => $currency['currency_code'],
'entries' => [],
-
];
// loop all possible periods between $start and $end
$currentStart = clone $start;
- while ($currentStart <= $end) {
+ $currentEnd = clone $end;
+
+ // #8374. Sloppy fix for yearly charts. Not really interested in a better fix with v2 layout and all.
+ if ('1Y' === $preferredRange) {
+ $currentEnd = app('navigation')->endOfPeriod($currentEnd, $preferredRange);
+ }
+ while ($currentStart <= $currentEnd) {
$key = $currentStart->format($format);
$title = $currentStart->isoFormat($titleFormat);
- $income['entries'][$title] = app('steam')->bcround(($currency[$key]['earned'] ?? '0'), $currency['currency_decimal_places']);
- $expense['entries'][$title] = app('steam')->bcround(($currency[$key]['spent'] ?? '0'), $currency['currency_decimal_places']);
+ $income['entries'][$title] = app('steam')->bcround($currency[$key]['earned'] ?? '0', $currency['currency_decimal_places']);
+ $expense['entries'][$title] = app('steam')->bcround($currency[$key]['spent'] ?? '0', $currency['currency_decimal_places']);
$currentStart = app('navigation')->addPeriod($currentStart, $preferredRange, 0);
}
- $chartData[] = $income;
- $chartData[] = $expense;
+ $chartData[] = $income;
+ $chartData[] = $expense;
}
- $data = $this->generator->multiSet($chartData);
+ $data = $this->generator->multiSet($chartData);
$cache->store($data);
return response()->json($data);
diff --git a/app/Http/Controllers/Chart/TagReportController.php b/app/Http/Controllers/Chart/TagReportController.php
index 2f3b7db2dd..2d12c01539 100644
--- a/app/Http/Controllers/Chart/TagReportController.php
+++ b/app/Http/Controllers/Chart/TagReportController.php
@@ -49,8 +49,6 @@ class TagReportController extends Controller
/**
* TagReportController constructor.
- *
-
*/
public function __construct()
{
@@ -67,14 +65,6 @@ class TagReportController extends Controller
);
}
- /**
- * @param Collection $accounts
- * @param Collection $tags
- * @param Carbon $start
- * @param Carbon $end
- *
- * @return JsonResponse
- */
public function budgetExpense(Collection $accounts, Collection $tags, Carbon $start, Carbon $end): JsonResponse
{
$result = [];
@@ -87,7 +77,7 @@ class TagReportController extends Controller
foreach ($tag['transaction_journals'] as $journal) {
$objectName = $journal['budget_name'] ?? trans('firefly.no_budget');
$title = sprintf('%s (%s)', $objectName, $currency['currency_name']);
- $result[$title] = $result[$title] ?? [
+ $result[$title] ??= [
'amount' => '0',
'currency_symbol' => $currency['currency_symbol'],
'currency_code' => $currency['currency_code'],
@@ -98,19 +88,11 @@ class TagReportController extends Controller
}
}
- $data = $this->generator->multiCurrencyPieChart($result);
+ $data = $this->generator->multiCurrencyPieChart($result);
return response()->json($data);
}
- /**
- * @param Collection $accounts
- * @param Collection $tags
- * @param Carbon $start
- * @param Carbon $end
- *
- * @return JsonResponse
- */
public function categoryExpense(Collection $accounts, Collection $tags, Carbon $start, Carbon $end): JsonResponse
{
$result = [];
@@ -123,7 +105,7 @@ class TagReportController extends Controller
foreach ($tag['transaction_journals'] as $journal) {
$objectName = $journal['category_name'] ?? trans('firefly.no_category');
$title = sprintf('%s (%s)', $objectName, $currency['currency_name']);
- $result[$title] = $result[$title] ?? [
+ $result[$title] ??= [
'amount' => '0',
'currency_symbol' => $currency['currency_symbol'],
'currency_code' => $currency['currency_code'],
@@ -134,19 +116,11 @@ class TagReportController extends Controller
}
}
- $data = $this->generator->multiCurrencyPieChart($result);
+ $data = $this->generator->multiCurrencyPieChart($result);
return response()->json($data);
}
- /**
- * @param Collection $accounts
- * @param Collection $tags
- * @param Carbon $start
- * @param Carbon $end
- *
- * @return JsonResponse
- */
public function categoryIncome(Collection $accounts, Collection $tags, Carbon $start, Carbon $end): JsonResponse
{
$result = [];
@@ -159,7 +133,7 @@ class TagReportController extends Controller
foreach ($tag['transaction_journals'] as $journal) {
$objectName = $journal['category_name'] ?? trans('firefly.no_category');
$title = sprintf('%s (%s)', $objectName, $currency['currency_name']);
- $result[$title] = $result[$title] ?? [
+ $result[$title] ??= [
'amount' => '0',
'currency_symbol' => $currency['currency_symbol'],
'currency_code' => $currency['currency_code'],
@@ -170,19 +144,11 @@ class TagReportController extends Controller
}
}
- $data = $this->generator->multiCurrencyPieChart($result);
+ $data = $this->generator->multiCurrencyPieChart($result);
return response()->json($data);
}
- /**
- * @param Collection $accounts
- * @param Collection $tags
- * @param Carbon $start
- * @param Carbon $end
- *
- * @return JsonResponse
- */
public function destinationExpense(Collection $accounts, Collection $tags, Carbon $start, Carbon $end): JsonResponse
{
$result = [];
@@ -195,7 +161,7 @@ class TagReportController extends Controller
foreach ($tag['transaction_journals'] as $journal) {
$objectName = $journal['destination_account_name'] ?? trans('firefly.empty');
$title = sprintf('%s (%s)', $objectName, $currency['currency_name']);
- $result[$title] = $result[$title] ?? [
+ $result[$title] ??= [
'amount' => '0',
'currency_symbol' => $currency['currency_symbol'],
'currency_code' => $currency['currency_code'],
@@ -206,19 +172,11 @@ class TagReportController extends Controller
}
}
- $data = $this->generator->multiCurrencyPieChart($result);
+ $data = $this->generator->multiCurrencyPieChart($result);
return response()->json($data);
}
- /**
- * @param Collection $accounts
- * @param Collection $tags
- * @param Carbon $start
- * @param Carbon $end
- *
- * @return JsonResponse
- */
public function destinationIncome(Collection $accounts, Collection $tags, Carbon $start, Carbon $end): JsonResponse
{
$result = [];
@@ -231,7 +189,7 @@ class TagReportController extends Controller
foreach ($tag['transaction_journals'] as $journal) {
$objectName = $journal['destination_account_name'] ?? trans('firefly.empty');
$title = sprintf('%s (%s)', $objectName, $currency['currency_name']);
- $result[$title] = $result[$title] ?? [
+ $result[$title] ??= [
'amount' => '0',
'currency_symbol' => $currency['currency_symbol'],
'currency_code' => $currency['currency_code'],
@@ -242,21 +200,13 @@ class TagReportController extends Controller
}
}
- $data = $this->generator->multiCurrencyPieChart($result);
+ $data = $this->generator->multiCurrencyPieChart($result);
return response()->json($data);
}
/**
* Generate main tag overview chart.
- *
- * @param Collection $accounts
- * @param Tag $tag
- * @param Carbon $start
- * @param Carbon $end
- *
- * @return JsonResponse
- *
*/
public function mainChart(Collection $accounts, Tag $tag, Carbon $start, Carbon $end): JsonResponse
{
@@ -268,8 +218,8 @@ class TagReportController extends Controller
// loop expenses.
foreach ($spent as $currency) {
// add things to chart Data for each currency:
- $spentKey = sprintf('%d-spent', $currency['currency_id']);
- $chartData[$spentKey] = $chartData[$spentKey] ?? [
+ $spentKey = sprintf('%d-spent', $currency['currency_id']);
+ $chartData[$spentKey] ??= [
'label' => sprintf(
'%s (%s)',
(string)trans('firefly.spent_in_specific_tag', ['tag' => $tag->tag]),
@@ -286,7 +236,7 @@ class TagReportController extends Controller
foreach ($currentTag['transaction_journals'] as $journal) {
$key = $journal['date']->isoFormat($format);
$amount = app('steam')->positive($journal['amount']);
- $chartData[$spentKey]['entries'][$key] = $chartData[$spentKey]['entries'][$key] ?? '0';
+ $chartData[$spentKey]['entries'][$key] ??= '0';
$chartData[$spentKey]['entries'][$key] = bcadd($chartData[$spentKey]['entries'][$key], $amount);
}
}
@@ -295,8 +245,8 @@ class TagReportController extends Controller
// loop income.
foreach ($earned as $currency) {
// add things to chart Data for each currency:
- $spentKey = sprintf('%d-earned', $currency['currency_id']);
- $chartData[$spentKey] = $chartData[$spentKey] ?? [
+ $spentKey = sprintf('%d-earned', $currency['currency_id']);
+ $chartData[$spentKey] ??= [
'label' => sprintf(
'%s (%s)',
(string)trans('firefly.earned_in_specific_tag', ['tag' => $tag->tag]),
@@ -313,24 +263,19 @@ class TagReportController extends Controller
foreach ($currentTag['transaction_journals'] as $journal) {
$key = $journal['date']->isoFormat($format);
$amount = app('steam')->positive($journal['amount']);
- $chartData[$spentKey]['entries'][$key] = $chartData[$spentKey]['entries'][$key] ?? '0';
+ $chartData[$spentKey]['entries'][$key] ??= '0';
$chartData[$spentKey]['entries'][$key] = bcadd($chartData[$spentKey]['entries'][$key], $amount);
}
}
}
- $data = $this->generator->multiSet($chartData);
+ $data = $this->generator->multiSet($chartData);
return response()->json($data);
}
/**
* TODO duplicate function
- *
- * @param Carbon $start
- * @param Carbon $end
- *
- * @return array
*/
private function makeEntries(Carbon $start, Carbon $end): array
{
@@ -349,14 +294,6 @@ class TagReportController extends Controller
return $return;
}
- /**
- * @param Collection $accounts
- * @param Collection $tags
- * @param Carbon $start
- * @param Carbon $end
- *
- * @return JsonResponse
- */
public function sourceExpense(Collection $accounts, Collection $tags, Carbon $start, Carbon $end): JsonResponse
{
$result = [];
@@ -369,7 +306,7 @@ class TagReportController extends Controller
foreach ($tag['transaction_journals'] as $journal) {
$objectName = $journal['source_account_name'] ?? trans('firefly.empty');
$title = sprintf('%s (%s)', $objectName, $currency['currency_name']);
- $result[$title] = $result[$title] ?? [
+ $result[$title] ??= [
'amount' => '0',
'currency_symbol' => $currency['currency_symbol'],
'currency_code' => $currency['currency_code'],
@@ -380,19 +317,11 @@ class TagReportController extends Controller
}
}
- $data = $this->generator->multiCurrencyPieChart($result);
+ $data = $this->generator->multiCurrencyPieChart($result);
return response()->json($data);
}
- /**
- * @param Collection $accounts
- * @param Collection $tags
- * @param Carbon $start
- * @param Carbon $end
- *
- * @return JsonResponse
- */
public function sourceIncome(Collection $accounts, Collection $tags, Carbon $start, Carbon $end): JsonResponse
{
$result = [];
@@ -405,7 +334,7 @@ class TagReportController extends Controller
foreach ($tag['transaction_journals'] as $journal) {
$objectName = $journal['source_account_name'] ?? trans('firefly.empty');
$title = sprintf('%s (%s)', $objectName, $currency['currency_name']);
- $result[$title] = $result[$title] ?? [
+ $result[$title] ??= [
'amount' => '0',
'currency_symbol' => $currency['currency_symbol'],
'currency_code' => $currency['currency_code'],
@@ -416,19 +345,11 @@ class TagReportController extends Controller
}
}
- $data = $this->generator->multiCurrencyPieChart($result);
+ $data = $this->generator->multiCurrencyPieChart($result);
return response()->json($data);
}
- /**
- * @param Collection $accounts
- * @param Collection $tags
- * @param Carbon $start
- * @param Carbon $end
- *
- * @return JsonResponse
- */
public function tagExpense(Collection $accounts, Collection $tags, Carbon $start, Carbon $end): JsonResponse
{
$result = [];
@@ -438,8 +359,8 @@ class TagReportController extends Controller
foreach ($spent as $currency) {
/** @var array $tag */
foreach ($currency['tags'] as $tag) {
- $title = sprintf('%s (%s)', $tag['name'], $currency['currency_name']);
- $result[$title] = $result[$title] ?? [
+ $title = sprintf('%s (%s)', $tag['name'], $currency['currency_name']);
+ $result[$title] ??= [
'amount' => '0',
'currency_symbol' => $currency['currency_symbol'],
'currency_code' => $currency['currency_code'],
@@ -450,19 +371,11 @@ class TagReportController extends Controller
}
}
}
- $data = $this->generator->multiCurrencyPieChart($result);
+ $data = $this->generator->multiCurrencyPieChart($result);
return response()->json($data);
}
- /**
- * @param Collection $accounts
- * @param Collection $tags
- * @param Carbon $start
- * @param Carbon $end
- *
- * @return JsonResponse
- */
public function tagIncome(Collection $accounts, Collection $tags, Carbon $start, Carbon $end): JsonResponse
{
$result = [];
@@ -472,8 +385,8 @@ class TagReportController extends Controller
foreach ($earned as $currency) {
/** @var array $tag */
foreach ($currency['tags'] as $tag) {
- $title = sprintf('%s (%s)', $tag['name'], $currency['currency_name']);
- $result[$title] = $result[$title] ?? [
+ $title = sprintf('%s (%s)', $tag['name'], $currency['currency_name']);
+ $result[$title] ??= [
'amount' => '0',
'currency_symbol' => $currency['currency_symbol'],
'currency_code' => $currency['currency_code'],
@@ -484,7 +397,7 @@ class TagReportController extends Controller
}
}
}
- $data = $this->generator->multiCurrencyPieChart($result);
+ $data = $this->generator->multiCurrencyPieChart($result);
return response()->json($data);
}
diff --git a/app/Http/Controllers/Chart/TransactionController.php b/app/Http/Controllers/Chart/TransactionController.php
index ccb349fe75..d587d58024 100644
--- a/app/Http/Controllers/Chart/TransactionController.php
+++ b/app/Http/Controllers/Chart/TransactionController.php
@@ -50,57 +50,51 @@ class TransactionController extends Controller
}
/**
- * @param Carbon $start
- * @param Carbon $end
- *
* @return JsonResponse
*/
public function budgets(Carbon $start, Carbon $end)
{
- $cache = new CacheProperties();
+ $cache = new CacheProperties();
$cache->addProperty($start);
$cache->addProperty($end);
$cache->addProperty('chart.transactions.budgets');
if ($cache->has()) {
return response()->json($cache->get());
}
+
/** @var GroupCollectorInterface $collector */
$collector = app(GroupCollectorInterface::class);
$collector->setRange($start, $end);
$collector->withBudgetInformation();
$collector->setTypes([TransactionType::WITHDRAWAL]);
- $result = $collector->getExtractedJournals();
- $data = [];
+ $result = $collector->getExtractedJournals();
+ $data = [];
// group by category.
/** @var array $journal */
foreach ($result as $journal) {
$budget = $journal['budget_name'] ?? (string)trans('firefly.no_budget');
$title = sprintf('%s (%s)', $budget, $journal['currency_symbol']);
- $data[$title] = $data[$title] ?? [
+ $data[$title] ??= [
'amount' => '0',
'currency_symbol' => $journal['currency_symbol'],
'currency_code' => $journal['currency_code'],
];
$data[$title]['amount'] = bcadd($data[$title]['amount'], $journal['amount']);
}
- $chart = $this->generator->multiCurrencyPieChart($data);
+ $chart = $this->generator->multiCurrencyPieChart($data);
$cache->store($chart);
return response()->json($chart);
}
/**
- * @param string $objectType
- * @param Carbon $start
- * @param Carbon $end
- *
* @return JsonResponse
*/
public function categories(string $objectType, Carbon $start, Carbon $end)
{
- $cache = new CacheProperties();
+ $cache = new CacheProperties();
$cache->addProperty($start);
$cache->addProperty($end);
$cache->addProperty($objectType);
@@ -108,6 +102,7 @@ class TransactionController extends Controller
if ($cache->has()) {
return response()->json($cache->get());
}
+
/** @var GroupCollectorInterface $collector */
$collector = app(GroupCollectorInterface::class);
$collector->setRange($start, $end);
@@ -123,37 +118,33 @@ class TransactionController extends Controller
$collector->setTypes([TransactionType::TRANSFER]);
}
- $result = $collector->getExtractedJournals();
- $data = [];
+ $result = $collector->getExtractedJournals();
+ $data = [];
// group by category.
/** @var array $journal */
foreach ($result as $journal) {
$category = $journal['category_name'] ?? (string)trans('firefly.no_category');
$title = sprintf('%s (%s)', $category, $journal['currency_symbol']);
- $data[$title] = $data[$title] ?? [
+ $data[$title] ??= [
'amount' => '0',
'currency_symbol' => $journal['currency_symbol'],
'currency_code' => $journal['currency_code'],
];
$data[$title]['amount'] = bcadd($data[$title]['amount'], $journal['amount']);
}
- $chart = $this->generator->multiCurrencyPieChart($data);
+ $chart = $this->generator->multiCurrencyPieChart($data);
$cache->store($chart);
return response()->json($chart);
}
/**
- * @param string $objectType
- * @param Carbon $start
- * @param Carbon $end
- *
* @return JsonResponse
*/
public function destinationAccounts(string $objectType, Carbon $start, Carbon $end)
{
- $cache = new CacheProperties();
+ $cache = new CacheProperties();
$cache->addProperty($start);
$cache->addProperty($end);
$cache->addProperty($objectType);
@@ -161,6 +152,7 @@ class TransactionController extends Controller
if ($cache->has()) {
return response()->json($cache->get());
}
+
/** @var GroupCollectorInterface $collector */
$collector = app(GroupCollectorInterface::class);
$collector->setRange($start, $end);
@@ -176,37 +168,33 @@ class TransactionController extends Controller
$collector->setTypes([TransactionType::TRANSFER]);
}
- $result = $collector->getExtractedJournals();
- $data = [];
+ $result = $collector->getExtractedJournals();
+ $data = [];
// group by category.
/** @var array $journal */
foreach ($result as $journal) {
$name = $journal['destination_account_name'];
$title = sprintf('%s (%s)', $name, $journal['currency_symbol']);
- $data[$title] = $data[$title] ?? [
+ $data[$title] ??= [
'amount' => '0',
'currency_symbol' => $journal['currency_symbol'],
'currency_code' => $journal['currency_code'],
];
$data[$title]['amount'] = bcadd($data[$title]['amount'], $journal['amount']);
}
- $chart = $this->generator->multiCurrencyPieChart($data);
+ $chart = $this->generator->multiCurrencyPieChart($data);
$cache->store($chart);
return response()->json($chart);
}
/**
- * @param string $objectType
- * @param Carbon $start
- * @param Carbon $end
- *
* @return JsonResponse
*/
public function sourceAccounts(string $objectType, Carbon $start, Carbon $end)
{
- $cache = new CacheProperties();
+ $cache = new CacheProperties();
$cache->addProperty($start);
$cache->addProperty($end);
$cache->addProperty($objectType);
@@ -214,6 +202,7 @@ class TransactionController extends Controller
if ($cache->has()) {
return response()->json($cache->get());
}
+
/** @var GroupCollectorInterface $collector */
$collector = app(GroupCollectorInterface::class);
$collector->setRange($start, $end);
@@ -229,22 +218,22 @@ class TransactionController extends Controller
$collector->setTypes([TransactionType::TRANSFER]);
}
- $result = $collector->getExtractedJournals();
- $data = [];
+ $result = $collector->getExtractedJournals();
+ $data = [];
// group by category.
/** @var array $journal */
foreach ($result as $journal) {
$name = $journal['source_account_name'];
$title = sprintf('%s (%s)', $name, $journal['currency_symbol']);
- $data[$title] = $data[$title] ?? [
+ $data[$title] ??= [
'amount' => '0',
'currency_symbol' => $journal['currency_symbol'],
'currency_code' => $journal['currency_code'],
];
$data[$title]['amount'] = bcadd($data[$title]['amount'], $journal['amount']);
}
- $chart = $this->generator->multiCurrencyPieChart($data);
+ $chart = $this->generator->multiCurrencyPieChart($data);
$cache->store($chart);
return response()->json($chart);
diff --git a/app/Http/Controllers/Controller.php b/app/Http/Controllers/Controller.php
index f77fc7ccef..2c086c4057 100644
--- a/app/Http/Controllers/Controller.php
+++ b/app/Http/Controllers/Controller.php
@@ -29,19 +29,20 @@ use Illuminate\Foundation\Auth\Access\AuthorizesRequests;
use Illuminate\Foundation\Bus\DispatchesJobs;
use Illuminate\Foundation\Validation\ValidatesRequests;
use Illuminate\Routing\Controller as BaseController;
-use Route;
/**
* Class Controller.
*
+ * @SuppressWarnings(PHPMD.CouplingBetweenObjects)
+ * @SuppressWarnings(PHPMD.NumberOfChildren)
*/
abstract class Controller extends BaseController
{
use AuthorizesRequests;
use DispatchesJobs;
- use ValidatesRequests;
use RequestInformation;
use UserNavigation;
+ use ValidatesRequests;
protected string $dateTimeFormat;
protected string $monthAndDayFormat;
@@ -50,14 +51,12 @@ abstract class Controller extends BaseController
/**
* Controller constructor.
- *
-
*/
public function __construct()
{
// is site a demo site?
$isDemoSiteConfig = app('fireflyconfig')->get('is_demo_site', config('firefly.configuration.is_demo_site', false));
- $isDemoSite = $isDemoSiteConfig ? $isDemoSiteConfig->data : false;
+ $isDemoSite = (bool)$isDemoSiteConfig->data;
app('view')->share('IS_DEMO_SITE', $isDemoSite);
app('view')->share('DEMO_USERNAME', config('firefly.demo_username'));
app('view')->share('DEMO_PASSWORD', config('firefly.demo_password'));
@@ -67,25 +66,25 @@ abstract class Controller extends BaseController
app('view')->share('featuringWebhooks', true === config('firefly.feature_flags.webhooks') && true === config('firefly.allow_webhooks'));
// share custom auth guard info.
- $authGuard = config('firefly.authentication_guard');
- $logoutUrl = config('firefly.custom_logout_url');
+ $authGuard = config('firefly.authentication_guard');
+ $logoutUrl = config('firefly.custom_logout_url');
app('view')->share('authGuard', $authGuard);
app('view')->share('logoutUrl', $logoutUrl);
// upload size
- $maxFileSize = app('steam')->phpBytes(ini_get('upload_max_filesize'));
- $maxPostSize = app('steam')->phpBytes(ini_get('post_max_size'));
- $uploadSize = min($maxFileSize, $maxPostSize);
+ $maxFileSize = app('steam')->phpBytes((string)ini_get('upload_max_filesize'));
+ $maxPostSize = app('steam')->phpBytes((string)ini_get('post_max_size'));
+ $uploadSize = min($maxFileSize, $maxPostSize);
app('view')->share('uploadSize', $uploadSize);
// share is alpha, is beta
- $isAlpha = false;
+ $isAlpha = false;
if (str_contains(config('firefly.version'), 'alpha')) {
$isAlpha = true;
}
- $isBeta = false;
+ $isBeta = false;
if (str_contains(config('firefly.version'), 'beta')) {
$isBeta = true;
}
@@ -95,7 +94,7 @@ abstract class Controller extends BaseController
$this->middleware(
function ($request, $next): mixed {
- $locale = app('steam')->getLocale();
+ $locale = app('steam')->getLocale();
// translations for specific strings:
$this->monthFormat = (string)trans('config.month_js', [], $locale);
$this->monthAndDayFormat = (string)trans('config.month_and_day_js', [], $locale);
@@ -112,7 +111,7 @@ abstract class Controller extends BaseController
app('view')->share('locale', $locale);
app('view')->share('shownDemo', $shownDemo);
app('view')->share('current_route_name', $page);
- app('view')->share('original_route_name', Route::currentRouteName());
+ app('view')->share('original_route_name', \Route::currentRouteName());
}
app('view')->share('darkMode', $darkMode);
diff --git a/app/Http/Controllers/CurrencyController.php b/app/Http/Controllers/CurrencyController.php
deleted file mode 100644
index 5834d3e547..0000000000
--- a/app/Http/Controllers/CurrencyController.php
+++ /dev/null
@@ -1,435 +0,0 @@
-.
- */
-declare(strict_types=1);
-
-namespace FireflyIII\Http\Controllers;
-
-use FireflyIII\Exceptions\FireflyException;
-use FireflyIII\Http\Requests\CurrencyFormRequest;
-use FireflyIII\Models\TransactionCurrency;
-use FireflyIII\Repositories\Currency\CurrencyRepositoryInterface;
-use FireflyIII\Repositories\User\UserRepositoryInterface;
-use FireflyIII\User;
-use Illuminate\Contracts\View\Factory;
-use Illuminate\Http\JsonResponse;
-use Illuminate\Http\RedirectResponse;
-use Illuminate\Http\Request;
-use Illuminate\Pagination\LengthAwarePaginator;
-use Illuminate\Routing\Redirector;
-use Illuminate\Support\Facades\Log;
-use Illuminate\View\View;
-use Psr\Container\ContainerExceptionInterface;
-use Psr\Container\NotFoundExceptionInterface;
-
-/**
- * Class CurrencyController.
- */
-class CurrencyController extends Controller
-{
- protected CurrencyRepositoryInterface $repository;
- protected UserRepositoryInterface $userRepository;
-
- /**
- * CurrencyController constructor.
- *
-
- */
- public function __construct()
- {
- parent::__construct();
-
- $this->middleware(
- function ($request, $next) {
- app('view')->share('title', (string)trans('firefly.currencies'));
- app('view')->share('mainTitleIcon', 'fa-usd');
- $this->repository = app(CurrencyRepositoryInterface::class);
- $this->userRepository = app(UserRepositoryInterface::class);
-
- return $next($request);
- }
- );
- }
-
- /**
- * Create a currency.
- *
- * @param Request $request
- *
- * @return Factory|RedirectResponse|Redirector|View
- */
- public function create(Request $request)
- {
- /** @var User $user */
- $user = auth()->user();
- if (!$this->userRepository->hasRole($user, 'owner')) {
- $request->session()->flash('error', (string)trans('firefly.ask_site_owner', ['owner' => e(config('firefly.site_owner'))]));
-
- return redirect(route('currencies.index'));
- }
-
- $subTitleIcon = 'fa-plus';
- $subTitle = (string)trans('firefly.create_currency');
-
- // put previous url in session if not redirect from store (not "create another").
- if (true !== session('currencies.create.fromStore')) {
- $this->rememberPreviousUrl('currencies.create.url');
- }
- $request->session()->forget('currencies.create.fromStore');
-
- Log::channel('audit')->info('Create new currency.');
-
- return view('currencies.create', compact('subTitleIcon', 'subTitle'));
- }
-
- /**
- * Make currency the default currency.
- *
- * @param Request $request
- *
- * @return RedirectResponse|Redirector
- * @throws FireflyException
- */
- public function defaultCurrency(Request $request)
- {
- $currencyId = (int)$request->get('id');
- if ($currencyId > 0) {
- // valid currency?
- $currency = $this->repository->find($currencyId);
- if (null !== $currency) {
- app('preferences')->set('currencyPreference', $currency->code);
- app('preferences')->mark();
- Log::channel('audit')->info(sprintf('Make %s the default currency.', $currency->code));
-
- $this->repository->enable($currency);
- $request->session()->flash('success', (string)trans('firefly.new_default_currency', ['name' => $currency->name]));
-
- return redirect(route('currencies.index'));
- }
- }
-
- return redirect(route('currencies.index'));
- }
-
- /**
- * Deletes a currency.
- *
- * @param Request $request
- * @param TransactionCurrency $currency
- *
- * @return Factory|RedirectResponse|Redirector|View
- */
- public function delete(Request $request, TransactionCurrency $currency)
- {
- /** @var User $user */
- $user = auth()->user();
- if (!$this->userRepository->hasRole($user, 'owner')) {
- $request->session()->flash('error', (string)trans('firefly.ask_site_owner', ['owner' => e(config('firefly.site_owner'))]));
- Log::channel('audit')->info(sprintf('Tried to visit page to delete currency %s but is not site owner.', $currency->code));
-
- return redirect(route('currencies.index'));
- }
-
- if ($this->repository->currencyInUse($currency)) {
- $location = $this->repository->currencyInUseAt($currency);
- $message = (string)trans(sprintf('firefly.cannot_disable_currency_%s', $location), ['name' => e($currency->name)]);
- $request->session()->flash('error', $message);
- Log::channel('audit')->info(sprintf('Tried to visit page to delete currency %s but currency is in use.', $currency->code));
-
- return redirect(route('currencies.index'));
- }
-
- // put previous url in session
- $this->rememberPreviousUrl('currencies.delete.url');
- $subTitle = (string)trans('form.delete_currency', ['name' => $currency->name]);
- Log::channel('audit')->info(sprintf('Visit page to delete currency %s.', $currency->code));
-
- return view('currencies.delete', compact('currency', 'subTitle'));
- }
-
- /**
- * Destroys a currency.
- *
- * @param Request $request
- * @param TransactionCurrency $currency
- *
- * @return RedirectResponse|Redirector
- */
- public function destroy(Request $request, TransactionCurrency $currency)
- {
- /** @var User $user */
- $user = auth()->user();
- if (!$this->userRepository->hasRole($user, 'owner')) {
- $request->session()->flash('error', (string)trans('firefly.ask_site_owner', ['owner' => e(config('firefly.site_owner'))]));
- Log::channel('audit')->info(sprintf('Tried to delete currency %s but is not site owner.', $currency->code));
-
- return redirect(route('currencies.index'));
- }
-
- if ($this->repository->currencyInUse($currency)) {
- $request->session()->flash('error', (string)trans('firefly.cannot_delete_currency', ['name' => e($currency->name)]));
- Log::channel('audit')->info(sprintf('Tried to delete currency %s but is in use.', $currency->code));
-
- return redirect(route('currencies.index'));
- }
-
- if ($this->repository->isFallbackCurrency($currency)) {
- $request->session()->flash('error', (string)trans('firefly.cannot_delete_fallback_currency', ['name' => e($currency->name)]));
- Log::channel('audit')->info(sprintf('Tried to delete currency %s but is FALLBACK.', $currency->code));
-
- return redirect(route('currencies.index'));
- }
-
- Log::channel('audit')->info(sprintf('Deleted currency %s.', $currency->code));
- $this->repository->destroy($currency);
-
- $request->session()->flash('success', (string)trans('firefly.deleted_currency', ['name' => $currency->name]));
-
- return redirect($this->getPreviousUrl('currencies.delete.url'));
- }
-
- /**
- * @param Request $request
- *
- * @return JsonResponse
- * @throws FireflyException
- */
- public function disableCurrency(Request $request): JsonResponse
- {
- $currencyId = (int)$request->get('id');
- $currency = $this->repository->find($currencyId);
-
- // valid currency?
- if (null === $currency) {
- return response()->json([]);
- }
-
- app('preferences')->mark();
-
- // user must be "owner"
- /** @var User $user */
- $user = auth()->user();
- if (!$this->userRepository->hasRole($user, 'owner')) {
- $request->session()->flash('error', (string)trans('firefly.ask_site_owner', ['owner' => e(config('firefly.site_owner'))]));
- Log::channel('audit')->info(sprintf('Tried to disable currency %s but is not site owner.', $currency->code));
- return response()->json([]);
- }
-
- // currency cannot be in use.
- if ($this->repository->currencyInUse($currency)) {
- $location = $this->repository->currencyInUseAt($currency);
- $message = (string)trans(sprintf('firefly.cannot_disable_currency_%s', $location), ['name' => e($currency->name)]);
-
- $request->session()->flash('error', $message);
- Log::channel('audit')->info(sprintf('Tried to disable currency %s but is in use.', $currency->code));
- return response()->json([]);
- }
-
- // currency disabled!
- $this->repository->disable($currency);
- Log::channel('audit')->info(sprintf('Disabled currency %s.', $currency->code));
-
- $this->repository->ensureMinimalEnabledCurrencies();
-
- // extra warning
- if ('EUR' === $currency->code) {
- session()->flash('warning', (string)trans('firefly.disable_EUR_side_effects'));
- }
-
- session()->flash('success', (string)trans('firefly.currency_is_now_disabled', ['name' => $currency->name]));
- return response()->json([]);
- }
-
- /**
- * Edit a currency.
- *
- * @param Request $request
- * @param TransactionCurrency $currency
- *
- * @return Factory|RedirectResponse|Redirector|View
- */
- public function edit(Request $request, TransactionCurrency $currency)
- {
- /** @var User $user */
- $user = auth()->user();
- if (!$this->userRepository->hasRole($user, 'owner')) {
- $request->session()->flash('error', (string)trans('firefly.ask_site_owner', ['owner' => e(config('firefly.site_owner'))]));
- Log::channel('audit')->info(sprintf('Tried to edit currency %s but is not owner.', $currency->code));
-
- return redirect(route('currencies.index'));
- }
-
- $subTitleIcon = 'fa-pencil';
- $subTitle = (string)trans('breadcrumbs.edit_currency', ['name' => $currency->name]);
- $currency->symbol = htmlentities($currency->symbol);
-
- // code to handle active-checkboxes
- $hasOldInput = null !== $request->old('_token');
- $preFilled = [
- 'enabled' => $hasOldInput ? (bool)$request->old('enabled') : $currency->enabled,
- ];
-
- $request->session()->flash('preFilled', $preFilled);
- Log::channel('audit')->info('Edit currency.', $currency->toArray());
-
- // put previous url in session if not redirect from store (not "return_to_edit").
- if (true !== session('currencies.edit.fromUpdate')) {
- $this->rememberPreviousUrl('currencies.edit.url');
- }
- $request->session()->forget('currencies.edit.fromUpdate');
-
- return view('currencies.edit', compact('currency', 'subTitle', 'subTitleIcon'));
- }
-
- /**
- * @param Request $request
- *
- * @return JsonResponse
- */
- public function enableCurrency(Request $request): JsonResponse
- {
- $currencyId = (int)$request->get('id');
- if ($currencyId > 0) {
- // valid currency?
- $currency = $this->repository->find($currencyId);
- if (null !== $currency) {
- app('preferences')->mark();
-
- $this->repository->enable($currency);
- session()->flash('success', (string)trans('firefly.currency_is_now_enabled', ['name' => $currency->name]));
- Log::channel('audit')->info(sprintf('Enabled currency %s.', $currency->code));
- }
- }
-
- return response()->json([]);
- }
-
- /**
- * Show overview of currencies.
- *
- * @param Request $request
- *
- * @return Factory|View
- * @throws ContainerExceptionInterface
- * @throws NotFoundExceptionInterface
- */
- public function index(Request $request)
- {
- /** @var User $user */
- $user = auth()->user();
- $page = 0 === (int)$request->get('page') ? 1 : (int)$request->get('page');
- $pageSize = (int)app('preferences')->get('listPageSize', 50)->data;
- $collection = $this->repository->getAll();
- $total = $collection->count();
- $collection = $collection->slice(($page - 1) * $pageSize, $pageSize);
- $currencies = new LengthAwarePaginator($collection, $total, $pageSize, $page);
- $currencies->setPath(route('currencies.index'));
-
- $defaultCurrency = $this->repository->getCurrencyByPreference(app('preferences')->get('currencyPreference', config('firefly.default_currency', 'EUR')));
- $isOwner = true;
- if (!$this->userRepository->hasRole($user, 'owner')) {
- $request->session()->flash('info', (string)trans('firefly.ask_site_owner', ['owner' => config('firefly.site_owner')]));
- $isOwner = false;
- }
-
- return view('currencies.index', compact('currencies', 'defaultCurrency', 'isOwner'));
- }
-
- /**
- * Store new currency.
- *
- * @param CurrencyFormRequest $request
- *
- * @return $this|RedirectResponse|Redirector
- */
- public function store(CurrencyFormRequest $request)
- {
- /** @var User $user */
- $user = auth()->user();
- $data = $request->getCurrencyData();
- if (!$this->userRepository->hasRole($user, 'owner')) {
- Log::error('User ' . auth()->user()->id . ' is not admin, but tried to store a currency.');
- Log::channel('audit')->info('Tried to create (POST) currency without admin rights.', $data);
-
- return redirect($this->getPreviousUrl('currencies.create.url'));
- }
-
- $data['enabled'] = true;
- try {
- $currency = $this->repository->store($data);
- } catch (FireflyException $e) {
- Log::error($e->getMessage());
- Log::channel('audit')->info('Could not store (POST) currency without admin rights.', $data);
- $request->session()->flash('error', (string)trans('firefly.could_not_store_currency'));
- $currency = null;
- }
- $redirect = redirect($this->getPreviousUrl('currencies.create.url'));
-
- if (null !== $currency) {
- $request->session()->flash('success', (string)trans('firefly.created_currency', ['name' => $currency->name]));
- Log::channel('audit')->info('Created (POST) currency.', $data);
- if (1 === (int)$request->get('create_another')) {
- $request->session()->put('currencies.create.fromStore', true);
-
- $redirect = redirect(route('currencies.create'))->withInput();
- }
- }
-
- return $redirect;
- }
-
- /**
- * Updates a currency.
- *
- * @param CurrencyFormRequest $request
- * @param TransactionCurrency $currency
- *
- * @return RedirectResponse|Redirector
- */
- public function update(CurrencyFormRequest $request, TransactionCurrency $currency)
- {
- /** @var User $user */
- $user = auth()->user();
- $data = $request->getCurrencyData();
-
- if (false === $data['enabled'] && $this->repository->currencyInUse($currency)) {
- $data['enabled'] = true;
- }
- if (!$this->userRepository->hasRole($user, 'owner')) {
- $request->session()->flash('error', (string)trans('firefly.ask_site_owner', ['owner' => e(config('firefly.site_owner'))]));
- Log::channel('audit')->info('Tried to update (POST) currency without admin rights.', $data);
-
- return redirect(route('currencies.index'));
- }
- $currency = $this->repository->update($currency, $data);
- Log::channel('audit')->info('Updated (POST) currency.', $data);
- $request->session()->flash('success', (string)trans('firefly.updated_currency', ['name' => $currency->name]));
- app('preferences')->mark();
-
- if (1 === (int)$request->get('return_to_edit')) {
- $request->session()->put('currencies.edit.fromUpdate', true);
-
- return redirect(route('currencies.edit', [$currency->id]));
- }
-
- return redirect($this->getPreviousUrl('currencies.edit.url'));
- }
-}
diff --git a/app/Http/Controllers/DebugController.php b/app/Http/Controllers/DebugController.php
index c4fc690fe1..44116553ce 100644
--- a/app/Http/Controllers/DebugController.php
+++ b/app/Http/Controllers/DebugController.php
@@ -24,8 +24,6 @@ declare(strict_types=1);
namespace FireflyIII\Http\Controllers;
use Carbon\Carbon;
-use DB;
-use Exception;
use FireflyIII\Exceptions\FireflyException;
use FireflyIII\Http\Middleware\IsDemoUser;
use FireflyIII\Models\AccountType;
@@ -40,12 +38,9 @@ use Illuminate\Support\Facades\Artisan;
use Illuminate\Support\Facades\Log;
use Illuminate\View\View;
use Monolog\Handler\RotatingFileHandler;
-use Psr\Container\ContainerExceptionInterface;
-use Psr\Container\NotFoundExceptionInterface;
/**
* Class DebugController
- *
*/
class DebugController extends Controller
{
@@ -53,8 +48,6 @@ class DebugController extends Controller
/**
* DebugController constructor.
- *
-
*/
public function __construct()
{
@@ -69,44 +62,45 @@ class DebugController extends Controller
*/
public function displayError(): void
{
- Log::debug('This is a test message at the DEBUG level.');
- Log::info('This is a test message at the INFO level.');
+ app('log')->debug('This is a test message at the DEBUG level.');
+ app('log')->info('This is a test message at the INFO level.');
Log::notice('This is a test message at the NOTICE level.');
app('log')->warning('This is a test message at the WARNING level.');
- Log::error('This is a test message at the ERROR level.');
+ app('log')->error('This is a test message at the ERROR level.');
Log::critical('This is a test message at the CRITICAL level.');
Log::alert('This is a test message at the ALERT level.');
Log::emergency('This is a test message at the EMERGENCY level.');
+
throw new FireflyException('A very simple test error.');
}
/**
* Clear log and session.
*
- * @param Request $request
+ * @return Redirector|RedirectResponse
*
- * @return RedirectResponse|Redirector
* @throws FireflyException
*/
public function flush(Request $request)
{
app('preferences')->mark();
$request->session()->forget(['start', 'end', '_previous', 'viewRange', 'range', 'is_custom_range', 'temp-mfa-secret', 'temp-mfa-codes']);
- Log::debug('Call cache:clear...');
+ app('log')->debug('Call cache:clear...');
Artisan::call('cache:clear');
- Log::debug('Call config:clear...');
+ app('log')->debug('Call config:clear...');
Artisan::call('config:clear');
- Log::debug('Call route:clear...');
+ app('log')->debug('Call route:clear...');
Artisan::call('route:clear');
- Log::debug('Call twig:clean...');
+ app('log')->debug('Call twig:clean...');
+
try {
Artisan::call('twig:clean');
- } catch (Exception $e) { // intentional generic exception
+ } catch (\Exception $e) { // intentional generic exception
throw new FireflyException($e->getMessage(), 0, $e);
}
- Log::debug('Call view:clear...');
+ app('log')->debug('Call view:clear...');
Artisan::call('view:clear');
return redirect(route('index'));
@@ -115,19 +109,18 @@ class DebugController extends Controller
/**
* Show debug info.
*
- * @param Request $request
- *
* @return Factory|View
+ *
* @throws FireflyException
*/
- public function index(Request $request)
+ public function index()
{
- $table = $this->generateTable();
- $table = str_replace(["\n", "\t", ' '], '', $table);
- $now = now(config('app.timezone'))->format('Y-m-d H:i:s');
+ $table = $this->generateTable();
+ $table = str_replace(["\n", "\t", ' '], '', $table);
+ $now = now(config('app.timezone'))->format('Y-m-d H:i:s');
// get latest log file:
- $logger = Log::driver();
+ $logger = Log::driver();
// PHPstan doesn't recognize the method because of its polymorphic nature.
$handlers = $logger->getHandlers(); // @phpstan-ignore-line
$logContent = '';
@@ -141,15 +134,12 @@ class DebugController extends Controller
}
if ('' !== $logContent) {
// last few lines
- $logContent = 'Truncated from this point <----|' . substr($logContent, -16384);
+ $logContent = 'Truncated from this point <----|'.substr((string)$logContent, -16384);
}
return view('debug', compact('table', 'now', 'logContent'));
}
- /**
- * @return string
- */
private function generateTable(): string
{
// system information:
@@ -161,20 +151,20 @@ class DebugController extends Controller
return (string)view('partials.debug-table', compact('system', 'docker', 'app', 'user'));
}
- /**
- * @return array
- */
private function getSystemInformation(): array
{
- $maxFileSize = app('steam')->phpBytes(ini_get('upload_max_filesize'));
- $maxPostSize = app('steam')->phpBytes(ini_get('post_max_size'));
- $drivers = DB::availableDrivers();
- $currentDriver = DB::getDriverName();
+ $maxFileSize = app('steam')->phpBytes((string)ini_get('upload_max_filesize'));
+ $maxPostSize = app('steam')->phpBytes((string)ini_get('post_max_size'));
+ $drivers = \DB::availableDrivers();
+ $currentDriver = \DB::getDriverName();
+
return [
'db_version' => app('fireflyconfig')->get('db_version', 1)->data,
'php_version' => PHP_VERSION,
'php_os' => PHP_OS,
- 'interface' => PHP_SAPI,
+ 'uname' => php_uname('m'),
+ 'interface' => \PHP_SAPI,
+ 'bits' => \PHP_INT_SIZE * 8,
'bcscale' => bcscale(),
'display_errors' => ini_get('display_errors'),
'error_reporting' => $this->errorReporting((int)ini_get('error_reporting')),
@@ -184,9 +174,6 @@ class DebugController extends Controller
];
}
- /**
- * @return array
- */
private function getBuildInfo(): array
{
$return = [
@@ -195,23 +182,25 @@ class DebugController extends Controller
'build_date' => '(unknown)',
'base_build' => '(unknown)',
'base_build_date' => '(unknown)',
-
];
+
try {
if (file_exists('/var/www/counter-main.txt')) {
- $return['build'] = trim(file_get_contents('/var/www/counter-main.txt'));
+ $return['build'] = trim((string)file_get_contents('/var/www/counter-main.txt'));
+ app('log')->debug(sprintf('build is now "%s"', $return['build']));
}
- } catch (Exception $e) { // generic catch for open basedir.
- Log::debug('Could not check build counter, but thats ok.');
- Log::warning($e->getMessage());
+ } catch (\Exception $e) { // @phpstan-ignore-line
+ app('log')->debug('Could not check build counter, but thats ok.');
+ app('log')->warning($e->getMessage());
}
+
try {
if (file_exists('/var/www/build-date-main.txt')) {
- $return['build_date'] = trim(file_get_contents('/var/www/build-date-main.txt'));
+ $return['build_date'] = trim((string)file_get_contents('/var/www/build-date-main.txt'));
}
- } catch (Exception $e) { // generic catch for open basedir.
- Log::debug('Could not check build date, but thats ok.');
- Log::warning($e->getMessage());
+ } catch (\Exception $e) { // @phpstan-ignore-line
+ app('log')->debug('Could not check build date, but thats ok.');
+ app('log')->warning($e->getMessage());
}
if ('' !== (string)env('BASE_IMAGE_BUILD')) {
$return['base_build'] = env('BASE_IMAGE_BUILD');
@@ -219,15 +208,13 @@ class DebugController extends Controller
if ('' !== (string)env('BASE_IMAGE_DATE')) {
$return['base_build_date'] = env('BASE_IMAGE_DATE');
}
+
return $return;
}
- /**
- * @return array
- */
private function getAppInfo(): array
{
- $userGuard = config('auth.defaults.guard');
+ $userGuard = config('auth.defaults.guard');
$config = app('fireflyconfig')->get('last_rt_job', 0);
$lastTime = (int)$config->data;
@@ -236,7 +223,7 @@ class DebugController extends Controller
if ($lastTime > 0) {
$carbon = Carbon::createFromTimestamp($lastTime);
$lastCronjob = $carbon->format('Y-m-d H:i:s');
- $lastCronjobAgo = $carbon->locale('en')->diffForHumans();
+ $lastCronjobAgo = $carbon->locale('en')->diffForHumans(); // @phpstan-ignore-line
}
return [
@@ -244,42 +231,37 @@ class DebugController extends Controller
'audit_log_channel' => envNonEmpty('AUDIT_LOG_CHANNEL', '(empty)'),
'default_language' => (string)config('firefly.default_language'),
'default_locale' => (string)config('firefly.default_locale'),
- 'remote_header' => $userGuard === 'remote_user_guard' ? config('auth.guard_header') : 'N/A',
- 'remote_mail_header' => $userGuard === 'remote_user_guard' ? config('auth.guard_email') : 'N/A',
- 'stateful_domains' => join(', ', config('sanctum.stateful')),
+ 'remote_header' => 'remote_user_guard' === $userGuard ? config('auth.guard_header') : 'N/A',
+ 'remote_mail_header' => 'remote_user_guard' === $userGuard ? config('auth.guard_email') : 'N/A',
+ 'stateful_domains' => implode(', ', config('sanctum.stateful')),
// the dates for the cron job are based on the recurring cron job's times.
// any of the cron jobs will do, they always run at the same time.
// but this job is the oldest, so the biggest chance it ran once
- 'last_cronjob' => $lastCronjob,
- 'last_cronjob_ago' => $lastCronjobAgo,
+ 'last_cronjob' => $lastCronjob,
+ 'last_cronjob_ago' => $lastCronjobAgo,
];
}
- /**
- * @return array
- * @throws ContainerExceptionInterface
- * @throws NotFoundExceptionInterface
- */
private function getuserInfo(): array
{
- $userFlags = $this->getUserFlags();
+ $userFlags = $this->getUserFlags();
// user info
- $userAgent = request()->header('user-agent');
+ $userAgent = request()->header('user-agent');
// set languages, see what happens:
- $original = setlocale(LC_ALL, 0);
+ $original = setlocale(LC_ALL, '0');
$localeAttempts = [];
$parts = app('steam')->getLocaleArray(app('steam')->getLocale());
foreach ($parts as $code) {
- $code = trim($code);
- Log::debug(sprintf('Trying to set %s', $code));
+ $code = trim($code);
+ app('log')->debug(sprintf('Trying to set %s', $code));
$result = setlocale(LC_ALL, $code);
$localeAttempts[$code] = $result === $code;
}
- setlocale(LC_ALL, $original);
+ setlocale(LC_ALL, (string)$original);
return [
'user_id' => auth()->user()->id,
@@ -293,14 +275,12 @@ class DebugController extends Controller
];
}
- /**
- * @return string
- */
private function getUserFlags(): string
{
$flags = [];
+
/** @var User $user */
- $user = auth()->user();
+ $user = auth()->user();
// has liabilities
if ($user->accounts()->accountTypeIn([AccountType::DEBT, AccountType::LOAN, AccountType::MORTGAGE])->count() > 0) {
@@ -313,8 +293,8 @@ class DebugController extends Controller
}
// has stored reconciliations
- $type = TransactionType::whereType(TransactionType::RECONCILIATION)->first();
- if ($user->transactionJournals()->where('transaction_type_id', $type->id)->count()) {
+ $type = TransactionType::whereType(TransactionType::RECONCILIATION)->first();
+ if ($user->transactionJournals()->where('transaction_type_id', $type->id)->count() > 0) {
$flags[] = ':ledger:';
}
@@ -339,15 +319,14 @@ class DebugController extends Controller
if ($user->bills()->count() > 0) {
$flags[] = ':email:';
}
- return join(' ', $flags);
+
+ return implode(' ', $flags);
}
/**
* Flash all types of messages.
*
- * @param Request $request
- *
- * @return RedirectResponse|Redirector
+ * @return Redirector|RedirectResponse
*/
public function testFlash(Request $request)
{
@@ -358,5 +337,4 @@ class DebugController extends Controller
return redirect(route('home'));
}
-
}
diff --git a/app/Http/Controllers/Export/IndexController.php b/app/Http/Controllers/Export/IndexController.php
index 0c1e84f4a3..91da4e515e 100644
--- a/app/Http/Controllers/Export/IndexController.php
+++ b/app/Http/Controllers/Export/IndexController.php
@@ -30,10 +30,9 @@ use FireflyIII\Http\Middleware\IsDemoUser;
use FireflyIII\Repositories\Journal\JournalRepositoryInterface;
use FireflyIII\Support\Export\ExportDataGenerator;
use Illuminate\Contracts\View\Factory;
+use Illuminate\Http\RedirectResponse;
use Illuminate\Http\Response as LaravelResponse;
use Illuminate\View\View;
-use Psr\Container\ContainerExceptionInterface;
-use Psr\Container\NotFoundExceptionInterface;
/**
* Class IndexController
@@ -44,8 +43,6 @@ class IndexController extends Controller
/**
* IndexController constructor.
- *
-
*/
public function __construct()
{
@@ -65,13 +62,16 @@ class IndexController extends Controller
}
/**
- * @return LaravelResponse
* @throws FireflyException
- * @throws ContainerExceptionInterface
- * @throws NotFoundExceptionInterface
*/
- public function export(): LaravelResponse
+ public function export(): LaravelResponse|RedirectResponse
{
+ if (auth()->user()->hasRole('demo')) {
+ session()->flash('info', (string)trans('firefly.demo_user_export'));
+
+ return redirect(route('export.index'));
+ }
+
/** @var ExportDataGenerator $generator */
$generator = app(ExportDataGenerator::class);
$generator->setUser(auth()->user());
@@ -81,28 +81,30 @@ class IndexController extends Controller
// get first transaction in DB:
$firstDate = today(config('app.timezone'));
$firstDate->subYear();
- $journal = $this->journalRepository->firstNull();
+ $journal = $this->journalRepository->firstNull();
if (null !== $journal) {
$firstDate = clone $journal->date;
}
$generator->setStart($firstDate);
- $result = $generator->export();
+ $result = $generator->export();
+
+ $name = sprintf('%s_transaction_export.csv', date('Y_m_d'));
+ $quoted = sprintf('"%s"', addcslashes($name, '"\\'));
- $name = sprintf('%s_transaction_export.csv', date('Y_m_d'));
- $quoted = sprintf('"%s"', addcslashes($name, '"\\'));
// headers for CSV file.
/** @var LaravelResponse $response */
- $response = response($result['transactions']);
+ $response = response($result['transactions']);
$response
->header('Content-Description', 'File Transfer')
->header('Content-Type', 'text/x-csv')
- ->header('Content-Disposition', 'attachment; filename=' . $quoted)
- //->header('Content-Transfer-Encoding', 'binary')
+ ->header('Content-Disposition', 'attachment; filename='.$quoted)
+ // ->header('Content-Transfer-Encoding', 'binary')
->header('Connection', 'Keep-Alive')
->header('Expires', '0')
->header('Cache-Control', 'must-revalidate, post-check=0, pre-check=0')
->header('Pragma', 'public')
- ->header('Content-Length', strlen($result['transactions']));
+ ->header('Content-Length', (string)strlen($result['transactions']))
+ ;
// return CSV file made from 'transactions' array.
return $response;
diff --git a/app/Http/Controllers/HomeController.php b/app/Http/Controllers/HomeController.php
index 90e27d3c18..cfda4df609 100644
--- a/app/Http/Controllers/HomeController.php
+++ b/app/Http/Controllers/HomeController.php
@@ -25,7 +25,6 @@ namespace FireflyIII\Http\Controllers;
use Carbon\Carbon;
use Carbon\Exceptions\InvalidFormatException;
-use Exception;
use FireflyIII\Events\RequestedVersionCheckStatus;
use FireflyIII\Exceptions\FireflyException;
use FireflyIII\Helpers\Collector\GroupCollectorInterface;
@@ -46,8 +45,6 @@ class HomeController extends Controller
{
/**
* HomeController constructor.
- *
-
*/
public function __construct()
{
@@ -60,50 +57,58 @@ class HomeController extends Controller
/**
* Change index date range.
*
- * @param Request $request
- *
- * @return JsonResponse
- * @throws Exception
+ * @throws \Exception
*/
public function dateRange(Request $request): JsonResponse
{
+ $stringStart = '';
+ $stringEnd = '';
+
try {
$stringStart = e((string)$request->get('start'));
$start = Carbon::createFromFormat('Y-m-d', $stringStart);
} catch (InvalidFormatException $e) {
- Log::error(sprintf('Start: could not parse date string "%s" so ignore it.', $stringStart));
+ app('log')->error(sprintf('Start: could not parse date string "%s" so ignore it.', $stringStart));
$start = Carbon::now()->startOfMonth();
}
+
try {
$stringEnd = e((string)$request->get('end'));
$end = Carbon::createFromFormat('Y-m-d', $stringEnd);
} catch (InvalidFormatException $e) {
- Log::error(sprintf('End could not parse date string "%s" so ignore it.', $stringEnd));
+ app('log')->error(sprintf('End could not parse date string "%s" so ignore it.', $stringEnd));
$end = Carbon::now()->endOfMonth();
}
+ if (false === $start) {
+ $start = Carbon::now()->startOfMonth();
+ }
+ if (false === $end) {
+ $end = Carbon::now()->endOfMonth();
+ }
+
$label = $request->get('label');
$isCustomRange = false;
- Log::debug('Received dateRange', ['start' => $stringStart, 'end' => $stringEnd, 'label' => $request->get('label')]);
+ app('log')->debug('Received dateRange', ['start' => $stringStart, 'end' => $stringEnd, 'label' => $request->get('label')]);
// check if the label is "everything" or "Custom range" which will betray
// a possible problem with the budgets.
if ($label === (string)trans('firefly.everything') || $label === (string)trans('firefly.customRange')) {
$isCustomRange = true;
- Log::debug('Range is now marked as "custom".');
+ app('log')->debug('Range is now marked as "custom".');
}
- $diff = $start->diffInDays($end) + 1;
+ $diff = $start->diffInDays($end) + 1;
if ($diff > 50) {
$request->session()->flash('warning', (string)trans('firefly.warning_much_data', ['days' => $diff]));
}
$request->session()->put('is_custom_range', $isCustomRange);
- Log::debug(sprintf('Set is_custom_range to %s', var_export($isCustomRange, true)));
+ app('log')->debug(sprintf('Set is_custom_range to %s', var_export($isCustomRange, true)));
$request->session()->put('start', $start);
- Log::debug(sprintf('Set start to %s', $start->format('Y-m-d H:i:s')));
+ app('log')->debug(sprintf('Set start to %s', $start->format('Y-m-d H:i:s')));
$request->session()->put('end', $end);
- Log::debug(sprintf('Set end to %s', $end->format('Y-m-d H:i:s')));
+ app('log')->debug(sprintf('Set end to %s', $end->format('Y-m-d H:i:s')));
return response()->json(['ok' => 'ok']);
}
@@ -111,37 +116,37 @@ class HomeController extends Controller
/**
* Show index.
*
- * @param AccountRepositoryInterface $repository
- *
- * @return mixed
* @throws FireflyException
*/
public function index(AccountRepositoryInterface $repository): mixed
{
- if ('v3' === config('firefly.layout')) {
- return view('pwa');
- }
- $types = config('firefly.accountTypesByIdentifier.asset');
- $count = $repository->count($types);
+ $types = config('firefly.accountTypesByIdentifier.asset');
+ $count = $repository->count($types);
Log::channel('audit')->info('User visits homepage.');
if (0 === $count) {
return redirect(route('new-user.index'));
}
- $subTitle = (string)trans('firefly.welcome_back');
- $transactions = [];
- $frontPage = app('preferences')->getFresh('frontPageAccounts', $repository->getAccountsByType([AccountType::ASSET])->pluck('id')->toArray());
+ $subTitle = (string)trans('firefly.welcome_back');
+ $transactions = [];
+ $frontPage = app('preferences')->getFresh('frontPageAccounts', $repository->getAccountsByType([AccountType::ASSET])->pluck('id')->toArray());
+ $frontPageArray = $frontPage->data;
+ if (!is_array($frontPageArray)) {
+ $frontPageArray = [];
+ }
+
/** @var Carbon $start */
- $start = session('start', today(config('app.timezone'))->startOfMonth());
+ $start = session('start', today(config('app.timezone'))->startOfMonth());
+
/** @var Carbon $end */
- $end = session('end', today(config('app.timezone'))->endOfMonth());
- $accounts = $repository->getAccountsById($frontPage->data);
- $today = today(config('app.timezone'));
+ $end = session('end', today(config('app.timezone'))->endOfMonth());
+ $accounts = $repository->getAccountsById($frontPageArray);
+ $today = today(config('app.timezone'));
// sort frontpage accounts by order
- $accounts = $accounts->sortBy('order');
+ $accounts = $accounts->sortBy('order');
- Log::debug('Frontpage accounts are ', $frontPage->data);
+ app('log')->debug('Frontpage accounts are ', $frontPageArray);
/** @var BillRepositoryInterface $billRepository */
$billRepository = app(BillRepositoryInterface::class);
@@ -149,14 +154,14 @@ class HomeController extends Controller
// collect groups for each transaction.
foreach ($accounts as $account) {
/** @var GroupCollectorInterface $collector */
- $collector = app(GroupCollectorInterface::class);
+ $collector = app(GroupCollectorInterface::class);
$collector->setAccounts(new Collection([$account]))->withAccountInformation()->setRange($start, $end)->setLimit(10)->setPage(1);
$set = $collector->getExtractedJournals();
$transactions[] = ['transactions' => $set, 'account' => $account];
}
/** @var User $user */
- $user = auth()->user();
+ $user = auth()->user();
event(new RequestedVersionCheckStatus($user));
return view('index', compact('count', 'subTitle', 'transactions', 'billCount', 'start', 'end', 'today'));
diff --git a/app/Http/Controllers/JavascriptController.php b/app/Http/Controllers/JavascriptController.php
index bdb002df78..f7068f2751 100644
--- a/app/Http/Controllers/JavascriptController.php
+++ b/app/Http/Controllers/JavascriptController.php
@@ -29,13 +29,10 @@ use FireflyIII\Models\Account;
use FireflyIII\Models\AccountType;
use FireflyIII\Models\TransactionCurrency;
use FireflyIII\Repositories\Account\AccountRepositoryInterface;
-use FireflyIII\Repositories\Currency\CurrencyRepositoryInterface;
+use FireflyIII\Repositories\UserGroups\Currency\CurrencyRepositoryInterface;
use FireflyIII\Support\Http\Controllers\GetConfigurationData;
use Illuminate\Http\Request;
use Illuminate\Http\Response;
-use JsonException;
-use Psr\Container\ContainerExceptionInterface;
-use Psr\Container\NotFoundExceptionInterface;
/**
* Class JavascriptController.
@@ -46,23 +43,14 @@ class JavascriptController extends Controller
/**
* Show info about accounts.
- *
- * @param AccountRepositoryInterface $repository
- * @param CurrencyRepositoryInterface $currencyRepository
- *
- * @return Response
- * @throws ContainerExceptionInterface
- * @throws NotFoundExceptionInterface
*/
- public function accounts(AccountRepositoryInterface $repository, CurrencyRepositoryInterface $currencyRepository): Response
+ public function accounts(AccountRepositoryInterface $repository): Response
{
- $accounts = $repository->getAccountsByType(
+ $accounts = $repository->getAccountsByType(
[AccountType::DEFAULT, AccountType::ASSET, AccountType::DEBT, AccountType::LOAN, AccountType::MORTGAGE, AccountType::CREDITCARD]
);
- $preference = app('preferences')->get('currencyPreference', config('firefly.default_currency', 'EUR'));
- $default = $currencyRepository->findByCodeNull((string)$preference->data);
-
- $data = ['accounts' => []];
+ $default = app('amount')->getDefaultCurrency();
+ $data = ['accounts' => []];
/** @var Account $account */
foreach ($accounts as $account) {
@@ -75,20 +63,18 @@ class JavascriptController extends Controller
return response()
->view('javascript.accounts', $data)
- ->header('Content-Type', 'text/javascript');
+ ->header('Content-Type', 'text/javascript')
+ ;
}
/**
* Get info about currencies.
- *
- * @param CurrencyRepositoryInterface $repository
- *
- * @return Response
*/
public function currencies(CurrencyRepositoryInterface $repository): Response
{
$currencies = $repository->get();
$data = ['currencies' => []];
+
/** @var TransactionCurrency $currency */
foreach ($currencies as $currency) {
$currencyId = $currency->id;
@@ -98,26 +84,19 @@ class JavascriptController extends Controller
return response()
->view('javascript.currencies', $data)
- ->header('Content-Type', 'text/javascript');
+ ->header('Content-Type', 'text/javascript')
+ ;
}
/**
* Show some common variables to be used in scripts.
*
- * @param Request $request
- * @param AccountRepositoryInterface $repository
- * @param CurrencyRepositoryInterface $currencyRepository
- *
- * @return Response
* @throws FireflyException
- * @throws JsonException
- * @throws ContainerExceptionInterface
- * @throws NotFoundExceptionInterface
- */
- public function variables(Request $request, AccountRepositoryInterface $repository, CurrencyRepositoryInterface $currencyRepository): Response
+ * */
+ public function variables(Request $request, AccountRepositoryInterface $repository): Response
{
- $account = $repository->find((int)$request->get('account'));
- $currency = app('amount')->getDefaultCurrency();
+ $account = $repository->find((int)$request->get('account'));
+ $currency = app('amount')->getDefaultCurrency();
if (null !== $account) {
$currency = $repository->getAccountCurrency($account) ?? $currency;
}
@@ -129,7 +108,7 @@ class JavascriptController extends Controller
$dateRange = $this->getDateRangeConfig();
$uid = substr(hash('sha256', sprintf('%s-%s-%s', (string)config('app.key'), auth()->user()->id, auth()->user()->email)), 0, 12);
- $data = [
+ $data = [
'currencyCode' => $currency->code,
'currencySymbol' => $currency->symbol,
'accountingLocaleInfo' => $accounting,
@@ -143,30 +122,29 @@ class JavascriptController extends Controller
return response()
->view('javascript.variables', $data)
- ->header('Content-Type', 'text/javascript');
+ ->header('Content-Type', 'text/javascript')
+ ;
}
/**
* Bit of a hack but OK.
- *
- * @param Request $request
- *
- * @return Response
*/
- public function variablesV2(Request $request): Response
+ public function variablesV2(): Response
{
/** @var Carbon $start */
$start = clone session('start', today(config('app.timezone'))->startOfMonth());
- /** @var Carbon $end */
- $end = clone session('end', today(config('app.timezone'))->endOfMonth());
- $data = [
+ /** @var Carbon $end */
+ $end = clone session('end', today(config('app.timezone'))->endOfMonth());
+
+ $data = [
'start' => $start->format('Y-m-d'),
'end' => $end->format('Y-m-d'),
];
return response()
->view('v2.javascript.variables', $data)
- ->header('Content-Type', 'text/javascript');
+ ->header('Content-Type', 'text/javascript')
+ ;
}
}
diff --git a/app/Http/Controllers/Json/AutoCompleteController.php b/app/Http/Controllers/Json/AutoCompleteController.php
index f77c76c8e2..b749d626ad 100644
--- a/app/Http/Controllers/Json/AutoCompleteController.php
+++ b/app/Http/Controllers/Json/AutoCompleteController.php
@@ -28,6 +28,4 @@ use FireflyIII\Http\Controllers\Controller;
/**
* Class AutoCompleteController.
*/
-class AutoCompleteController extends Controller
-{
-}
+class AutoCompleteController extends Controller {}
diff --git a/app/Http/Controllers/Json/BoxController.php b/app/Http/Controllers/Json/BoxController.php
index c47451fa71..9b29489e83 100644
--- a/app/Http/Controllers/Json/BoxController.php
+++ b/app/Http/Controllers/Json/BoxController.php
@@ -30,62 +30,67 @@ use FireflyIII\Http\Controllers\Controller;
use FireflyIII\Models\Account;
use FireflyIII\Models\AccountType;
use FireflyIII\Models\AvailableBudget;
-use FireflyIII\Models\TransactionCurrency;
use FireflyIII\Models\TransactionType;
use FireflyIII\Repositories\Account\AccountRepositoryInterface;
use FireflyIII\Repositories\Budget\AvailableBudgetRepositoryInterface;
use FireflyIII\Repositories\Budget\OperationsRepositoryInterface;
-use FireflyIII\Repositories\Currency\CurrencyRepositoryInterface;
+use FireflyIII\Repositories\UserGroups\Currency\CurrencyRepositoryInterface;
use FireflyIII\Support\CacheProperties;
+use FireflyIII\Support\Http\Controllers\DateCalculation;
use Illuminate\Http\JsonResponse;
-use Illuminate\Support\Facades\Log;
/**
* Class BoxController.
*/
class BoxController extends Controller
{
+ use DateCalculation;
+
/**
* This box has three types of info to display:
* 0) If the user has available amount this period and has overspent: overspent box.
* 1) If the user has available amount this period and has NOT overspent: left to spend box.
* 2) if the user has no available amount set this period: spent per day
*
- * @return JsonResponse
+ * @SuppressWarnings(PHPMD.ExcessiveMethodLength)
*/
public function available(): JsonResponse
{
app('log')->debug('Now in available()');
- /** @var OperationsRepositoryInterface $opsRepository */
- $opsRepository = app(OperationsRepositoryInterface::class);
- /** @var AvailableBudgetRepositoryInterface $abRepository */
- $abRepository = app(AvailableBudgetRepositoryInterface::class);
- $abRepository->cleanup();
- /** @var Carbon $start */
- $start = session('start', today(config('app.timezone'))->startOfMonth());
- /** @var Carbon $end */
- $end = session('end', today(config('app.timezone'))->endOfMonth());
- $today = today(config('app.timezone'));
- $display = 2; // see method docs.
- $boxTitle = (string)trans('firefly.spent');
- $cache = new CacheProperties();
+ /** @var OperationsRepositoryInterface $opsRepository */
+ $opsRepository = app(OperationsRepositoryInterface::class);
+
+ /** @var AvailableBudgetRepositoryInterface $abRepository */
+ $abRepository = app(AvailableBudgetRepositoryInterface::class);
+ $abRepository->cleanup();
+
+ /** @var Carbon $start */
+ $start = session('start', today(config('app.timezone'))->startOfMonth());
+
+ /** @var Carbon $end */
+ $end = session('end', today(config('app.timezone'))->endOfMonth());
+ $today = today(config('app.timezone'));
+ $display = 2; // see method docs.
+ $boxTitle = (string)trans('firefly.spent');
+
+ $cache = new CacheProperties();
$cache->addProperty($start);
$cache->addProperty($end);
$cache->addProperty($today);
$cache->addProperty('box-available');
if ($cache->has()) {
- //return response()->json($cache->get());
+ return response()->json($cache->get());
}
$leftPerDayAmount = '0';
$leftToSpendAmount = '0';
- $currency = app('amount')->getDefaultCurrency();
+ $currency = app('amount')->getDefaultCurrency();
app('log')->debug(sprintf('Default currency is %s', $currency->code));
- $availableBudgets = $abRepository->getAvailableBudgetsByExactDate($start, $end);
+ $availableBudgets = $abRepository->getAvailableBudgetsByExactDate($start, $end);
app('log')->debug(sprintf('Found %d available budget(s)', $availableBudgets->count()));
- $availableBudgets = $availableBudgets->filter(
- static function (AvailableBudget $availableBudget) use ($currency) {
+ $availableBudgets = $availableBudgets->filter(
+ static function (AvailableBudget $availableBudget) use ($currency) { // @phpstan-ignore-line
if ($availableBudget->transaction_currency_id === $currency->id) {
app('log')->debug(sprintf(
'Will include AB #%d: from %s-%s amount %s',
@@ -94,6 +99,7 @@ class BoxController extends Controller
$availableBudget->end_date->format('Y-m-d'),
$availableBudget->amount
));
+
return $availableBudget;
}
@@ -103,13 +109,13 @@ class BoxController extends Controller
app('log')->debug(sprintf('Filtered back to %d available budgets', $availableBudgets->count()));
// spent in this period, in budgets, for default currency.
// also calculate spent per day.
- $spent = $opsRepository->sumExpenses($start, $end, null, null, $currency);
- $spentAmount = $spent[(int)$currency->id]['sum'] ?? '0';
+ $spent = $opsRepository->sumExpenses($start, $end, null, null, $currency);
+ $spentAmount = $spent[$currency->id]['sum'] ?? '0';
app('log')->debug(sprintf('Spent for default currency for all budgets in this period: %s', $spentAmount));
- $days = $today->between($start, $end) ? $today->diffInDays($start) + 1 : $end->diffInDays($start) + 1;
+ $days = $today->between($start, $end) ? $today->diffInDays($start) + 1 : $end->diffInDays($start) + 1;
app('log')->debug(sprintf('Number of days left: %d', $days));
- $spentPerDay = bcdiv($spentAmount, (string)$days);
+ $spentPerDay = bcdiv($spentAmount, (string)$days);
app('log')->debug(sprintf('Available to spend per day: %s', $spentPerDay));
if ($availableBudgets->count() > 0) {
$display = 0; // assume user overspent
@@ -119,17 +125,17 @@ class BoxController extends Controller
// calculate with available budget.
$leftToSpendAmount = bcadd($totalAvailableSum, $spentAmount);
app('log')->debug(sprintf('So left to spend is %s', $leftToSpendAmount));
- if (1 === bccomp($leftToSpendAmount, '0')) {
- app('log')->debug(sprintf('Left to spend is positive!'));
+ if (bccomp($leftToSpendAmount, '0') >= 0) {
+ app('log')->debug('Left to spend is positive or zero!');
$boxTitle = (string)trans('firefly.left_to_spend');
- $days = $today->diffInDays($end) + 1;
- $display = 1; // not overspent
- $leftPerDayAmount = bcdiv($leftToSpendAmount, (string)$days);
+ $activeDaysLeft = $this->activeDaysLeft($start, $end); // see method description.
+ $display = 1; // not overspent
+ $leftPerDayAmount = bcdiv($leftToSpendAmount, (string)$activeDaysLeft);
app('log')->debug(sprintf('Left to spend per day is %s', $leftPerDayAmount));
}
}
- $return = [
+ $return = [
'display' => $display,
'spent_total' => app('amount')->formatAnything($currency, $spentAmount, false),
'spent_per_day' => app('amount')->formatAnything($currency, $spentPerDay, false),
@@ -141,24 +147,22 @@ class BoxController extends Controller
$cache->store($return);
app('log')->debug('Now done with available()');
+
return response()->json($return);
}
/**
* Current total balance.
- *
- * @param CurrencyRepositoryInterface $repository
- *
- * @return JsonResponse
*/
public function balance(CurrencyRepositoryInterface $repository): JsonResponse
{
// Cache result, return cache if present.
/** @var Carbon $start */
- $start = session('start', today(config('app.timezone'))->startOfMonth());
+ $start = session('start', today(config('app.timezone'))->startOfMonth());
+
/** @var Carbon $end */
- $end = session('end', today(config('app.timezone'))->endOfMonth());
- $cache = new CacheProperties();
+ $end = session('end', today(config('app.timezone'))->endOfMonth());
+ $cache = new CacheProperties();
$cache->addProperty($start);
$cache->addProperty($end);
$cache->addProperty('box-balance');
@@ -166,24 +170,26 @@ class BoxController extends Controller
return response()->json($cache->get());
}
// prep some arrays:
- $incomes = [];
- $expenses = [];
- $sums = [];
- $currency = app('amount')->getDefaultCurrency();
+ $incomes = [];
+ $expenses = [];
+ $sums = [];
+ $currency = app('amount')->getDefaultCurrency();
// collect income of user:
/** @var GroupCollectorInterface $collector */
$collector = app(GroupCollectorInterface::class);
$collector->setRange($start, $end)
- ->setTypes([TransactionType::DEPOSIT]);
- $set = $collector->getExtractedJournals();
+ ->setTypes([TransactionType::DEPOSIT])
+ ;
+ $set = $collector->getExtractedJournals();
+
/** @var array $journal */
foreach ($set as $journal) {
$currencyId = (int)$journal['currency_id'];
$amount = $journal['amount'] ?? '0';
- $incomes[$currencyId] = $incomes[$currencyId] ?? '0';
+ $incomes[$currencyId] ??= '0';
$incomes[$currencyId] = bcadd($incomes[$currencyId], app('steam')->positive($amount));
- $sums[$currencyId] = $sums[$currencyId] ?? '0';
+ $sums[$currencyId] ??= '0';
$sums[$currencyId] = bcadd($sums[$currencyId], app('steam')->positive($amount));
}
@@ -191,19 +197,21 @@ class BoxController extends Controller
/** @var GroupCollectorInterface $collector */
$collector = app(GroupCollectorInterface::class);
$collector->setRange($start, $end)
- ->setTypes([TransactionType::WITHDRAWAL]);
- $set = $collector->getExtractedJournals();
+ ->setTypes([TransactionType::WITHDRAWAL])
+ ;
+ $set = $collector->getExtractedJournals();
+
/** @var array $journal */
foreach ($set as $journal) {
$currencyId = (int)$journal['currency_id'];
- $expenses[$currencyId] = $expenses[$currencyId] ?? '0';
+ $expenses[$currencyId] ??= '0';
$expenses[$currencyId] = bcadd($expenses[$currencyId], $journal['amount'] ?? '0');
- $sums[$currencyId] = $sums[$currencyId] ?? '0';
+ $sums[$currencyId] ??= '0';
$sums[$currencyId] = bcadd($sums[$currencyId], $journal['amount']);
}
// format amounts:
- $keys = array_keys($sums);
+ $keys = array_keys($sums);
foreach ($keys as $currencyId) {
$currency = $repository->find($currencyId);
$sums[$currencyId] = app('amount')->formatAnything($currency, $sums[$currencyId], false);
@@ -217,7 +225,7 @@ class BoxController extends Controller
$expenses[$currency->id] = app('amount')->formatAnything($currency, '0', false);
}
- $response = [
+ $response = [
'incomes' => $incomes,
'expenses' => $expenses,
'sums' => $sums,
@@ -231,12 +239,10 @@ class BoxController extends Controller
/**
* Total user net worth.
- *
- * @return JsonResponse
*/
public function netWorth(): JsonResponse
{
- $date = today(config('app.timezone'))->endOfDay();
+ $date = today(config('app.timezone'))->endOfDay();
// start and end in the future? use $end
if ($this->notInSessionRange($date)) {
@@ -245,7 +251,7 @@ class BoxController extends Controller
}
/** @var NetWorthInterface $netWorthHelper */
- $netWorthHelper = app(NetWorthInterface::class);
+ $netWorthHelper = app(NetWorthInterface::class);
$netWorthHelper->setUser(auth()->user());
/** @var AccountRepositoryInterface $accountRepository */
@@ -253,29 +259,30 @@ class BoxController extends Controller
$allAccounts = $accountRepository->getActiveAccountsByType(
[AccountType::DEFAULT, AccountType::ASSET, AccountType::LOAN, AccountType::DEBT, AccountType::MORTGAGE]
);
- Log::debug(sprintf('Found %d accounts.', $allAccounts->count()));
+ app('log')->debug(sprintf('Found %d accounts.', $allAccounts->count()));
// filter list on preference of being included.
- $filtered = $allAccounts->filter(
- function (Account $account) use ($accountRepository) {
+ $filtered = $allAccounts->filter(
+ static function (Account $account) use ($accountRepository) {
$includeNetWorth = $accountRepository->getMetaValue($account, 'include_net_worth');
$result = null === $includeNetWorth ? true : '1' === $includeNetWorth;
if (false === $result) {
- Log::debug(sprintf('Will not include "%s" in net worth charts.', $account->name));
+ app('log')->debug(sprintf('Will not include "%s" in net worth charts.', $account->name));
}
return $result;
}
);
- $netWorthSet = $netWorthHelper->getNetWorthByCurrency($filtered, $date);
- $return = [];
- foreach ($netWorthSet as $data) {
- /** @var TransactionCurrency $currency */
- $currency = $data['currency'];
- $return[$currency->id] = app('amount')->formatAnything($currency, $data['balance'], false);
+ $netWorthSet = $netWorthHelper->byAccounts($filtered, $date);
+ $return = [];
+ foreach ($netWorthSet as $key => $data) {
+ if ('native' === $key) {
+ continue;
+ }
+ $return[$data['currency_id']] = app('amount')->formatFlat($data['currency_symbol'], $data['currency_decimal_places'], $data['balance'], false);
}
- $return = [
+ $return = [
'net_worths' => array_values($return),
];
diff --git a/app/Http/Controllers/Json/BudgetController.php b/app/Http/Controllers/Json/BudgetController.php
index bbad8baef0..10479402f3 100644
--- a/app/Http/Controllers/Json/BudgetController.php
+++ b/app/Http/Controllers/Json/BudgetController.php
@@ -46,8 +46,6 @@ class BudgetController extends Controller
/**
* IndexController constructor.
- *
-
*/
public function __construct()
{
@@ -67,13 +65,6 @@ class BudgetController extends Controller
);
}
- /**
- * @param TransactionCurrency $currency
- * @param Carbon $start
- * @param Carbon $end
- *
- * @return JsonResponse
- */
public function getBudgetInformation(TransactionCurrency $currency, Carbon $start, Carbon $end): JsonResponse
{
$budgeted = $this->blRepository->budgeted($start, $end, $currency);
diff --git a/app/Http/Controllers/Json/FrontpageController.php b/app/Http/Controllers/Json/FrontpageController.php
index 3ae35b987e..372ee79425 100644
--- a/app/Http/Controllers/Json/FrontpageController.php
+++ b/app/Http/Controllers/Json/FrontpageController.php
@@ -28,8 +28,6 @@ use FireflyIII\Http\Controllers\Controller;
use FireflyIII\Models\PiggyBank;
use FireflyIII\Repositories\PiggyBank\PiggyBankRepositoryInterface;
use Illuminate\Http\JsonResponse;
-use Illuminate\Support\Facades\Log;
-use Throwable;
/**
* Class FrontpageController.
@@ -39,26 +37,24 @@ class FrontpageController extends Controller
/**
* Piggy bank pie chart.
*
- * @param PiggyBankRepositoryInterface $repository
- *
- * @return JsonResponse
* @throws FireflyException
*/
public function piggyBanks(PiggyBankRepositoryInterface $repository): JsonResponse
{
$set = $repository->getPiggyBanks();
$info = [];
+
/** @var PiggyBank $piggyBank */
foreach ($set as $piggyBank) {
$amount = $repository->getCurrentAmount($piggyBank);
if (1 === bccomp($amount, '0')) {
// percentage!
- $pct = 0;
+ $pct = 0;
if (0 !== bccomp($piggyBank->targetamount, '0')) {
$pct = (int)bcmul(bcdiv($amount, $piggyBank->targetamount), '100');
}
- $entry = [
+ $entry = [
'id' => $piggyBank->id,
'name' => $piggyBank->name,
'amount' => $amount,
@@ -73,10 +69,11 @@ class FrontpageController extends Controller
if (0 !== count($info)) {
try {
$html = view('json.piggy-banks', compact('info'))->render();
- } catch (Throwable $e) {
- Log::error(sprintf('Cannot render json.piggy-banks: %s', $e->getMessage()));
- Log::error($e->getTraceAsString());
+ } catch (\Throwable $e) {
+ app('log')->error(sprintf('Cannot render json.piggy-banks: %s', $e->getMessage()));
+ app('log')->error($e->getTraceAsString());
$html = 'Could not render view.';
+
throw new FireflyException($html, 0, $e);
}
}
diff --git a/app/Http/Controllers/Json/IntroController.php b/app/Http/Controllers/Json/IntroController.php
index 7b98747d9c..741455cf9e 100644
--- a/app/Http/Controllers/Json/IntroController.php
+++ b/app/Http/Controllers/Json/IntroController.php
@@ -27,7 +27,6 @@ use FireflyIII\Exceptions\FireflyException;
use FireflyIII\Http\Controllers\Controller;
use FireflyIII\Support\Http\Controllers\GetConfigurationData;
use Illuminate\Http\JsonResponse;
-use Illuminate\Support\Facades\Log;
/**
* Class IntroController.
@@ -38,20 +37,15 @@ class IntroController extends Controller
/**
* Returns the introduction wizard for a page.
- *
- * @param string $route
- * @param string|null $specificPage
- *
- * @return JsonResponse
*/
public function getIntroSteps(string $route, string $specificPage = null): JsonResponse
{
- Log::debug(sprintf('getIntroSteps for route "%s" and page "%s"', $route, $specificPage));
- $specificPage = $specificPage ?? '';
+ app('log')->debug(sprintf('getIntroSteps for route "%s" and page "%s"', $route, $specificPage));
+ $specificPage ??= '';
$steps = $this->getBasicSteps($route);
$specificSteps = $this->getSpecificSteps($route, $specificPage);
if (0 === count($specificSteps)) {
- Log::debug(sprintf('No specific steps for route "%s" and page "%s"', $route, $specificPage));
+ app('log')->debug(sprintf('No specific steps for route "%s" and page "%s"', $route, $specificPage));
return response()->json($steps);
}
@@ -61,8 +55,8 @@ class IntroController extends Controller
// remove last step:
array_pop($steps);
// merge arrays and add last step again
- $steps = array_merge($steps, $specificSteps);
- $steps[] = $lastStep;
+ $steps = array_merge($steps, $specificSteps);
+ $steps[] = $lastStep;
}
if (!$this->hasOutroStep($route)) {
$steps = array_merge($steps, $specificSteps);
@@ -73,25 +67,21 @@ class IntroController extends Controller
/**
* Returns true if there is a general outro step.
- *
- * @param string $route
- *
- * @return bool
*/
public function hasOutroStep(string $route): bool
{
$routeKey = str_replace('.', '_', $route);
- Log::debug(sprintf('Has outro step for route %s', $routeKey));
+ app('log')->debug(sprintf('Has outro step for route %s', $routeKey));
$elements = config(sprintf('intro.%s', $routeKey));
if (!is_array($elements)) {
return false;
}
- $hasStep = array_key_exists('outro', $elements);
+ $hasStep = array_key_exists('outro', $elements);
- Log::debug('Elements is array', $elements);
- Log::debug('Keys is', array_keys($elements));
- Log::debug(sprintf('Keys has "outro": %s', var_export($hasStep, true)));
+ app('log')->debug('Elements is array', $elements);
+ app('log')->debug('Keys is', array_keys($elements));
+ app('log')->debug(sprintf('Keys has "outro": %s', var_export($hasStep, true)));
return $hasStep;
}
@@ -99,21 +89,17 @@ class IntroController extends Controller
/**
* Enable the boxes for a specific page again.
*
- * @param string $route
- * @param string|null $specialPage
- *
- * @return JsonResponse
* @throws FireflyException
*/
public function postEnable(string $route, string $specialPage = null): JsonResponse
{
- $specialPage = $specialPage ?? '';
- $route = str_replace('.', '_', $route);
- $key = 'shown_demo_' . $route;
+ $specialPage ??= '';
+ $route = str_replace('.', '_', $route);
+ $key = 'shown_demo_'.$route;
if ('' !== $specialPage) {
- $key .= '_' . $specialPage;
+ $key .= '_'.$specialPage;
}
- Log::debug(sprintf('Going to mark the following route as NOT done: %s with special "%s" (%s)', $route, $specialPage, $key));
+ app('log')->debug(sprintf('Going to mark the following route as NOT done: %s with special "%s" (%s)', $route, $specialPage, $key));
app('preferences')->set($key, false);
app('preferences')->mark();
@@ -123,20 +109,16 @@ class IntroController extends Controller
/**
* Set that you saw them.
*
- * @param string $route
- * @param string|null $specialPage
- *
- * @return JsonResponse
* @throws FireflyException
*/
public function postFinished(string $route, string $specialPage = null): JsonResponse
{
- $specialPage = $specialPage ?? '';
- $key = 'shown_demo_' . $route;
+ $specialPage ??= '';
+ $key = 'shown_demo_'.$route;
if ('' !== $specialPage) {
- $key .= '_' . $specialPage;
+ $key .= '_'.$specialPage;
}
- Log::debug(sprintf('Going to mark the following route as done: %s with special "%s" (%s)', $route, $specialPage, $key));
+ app('log')->debug(sprintf('Going to mark the following route as done: %s with special "%s" (%s)', $route, $specialPage, $key));
app('preferences')->set($key, true);
return response()->json(['result' => sprintf('Reported demo watched for route "%s" (%s): %s.', $route, $specialPage, $key)]);
diff --git a/app/Http/Controllers/Json/ReconcileController.php b/app/Http/Controllers/Json/ReconcileController.php
index d9d2bc1136..51cbdb743e 100644
--- a/app/Http/Controllers/Json/ReconcileController.php
+++ b/app/Http/Controllers/Json/ReconcileController.php
@@ -34,12 +34,8 @@ use FireflyIII\Repositories\Account\AccountRepositoryInterface;
use Illuminate\Http\JsonResponse;
use Illuminate\Http\Request;
use Illuminate\Support\Collection;
-use Illuminate\Support\Facades\Log;
-use JsonException;
-use Throwable;
/**
- *
* Class ReconcileController
*/
class ReconcileController extends Controller
@@ -48,8 +44,6 @@ class ReconcileController extends Controller
/**
* ReconcileController constructor.
- *
-
*/
public function __construct()
{
@@ -70,14 +64,7 @@ class ReconcileController extends Controller
/**
* Overview of reconciliation.
*
- * @param Request $request
- * @param Account|null $account
- * @param Carbon|null $start
- * @param Carbon|null $end
- *
- * @return JsonResponse
* @throws FireflyException
- * @throws JsonException
*/
public function overview(Request $request, Account $account = null, Carbon $start = null, Carbon $end = null): JsonResponse
{
@@ -100,29 +87,30 @@ class ReconcileController extends Controller
$clearedJournals = [];
$clearedIds = $request->get('cleared') ?? [];
$journals = [];
- /* Collect all submitted journals */
+ // Collect all submitted journals
if (count($selectedIds) > 0) {
/** @var GroupCollectorInterface $collector */
$collector = app(GroupCollectorInterface::class);
$collector->setJournalIds($selectedIds);
- $journals = $collector->getExtractedJournals();
+ $journals = $collector->getExtractedJournals();
}
- /* Collect all journals already reconciled */
+ // Collect all journals already reconciled
if (count($clearedIds) > 0) {
/** @var GroupCollectorInterface $collector */
- $collector = app(GroupCollectorInterface::class);
+ $collector = app(GroupCollectorInterface::class);
$collector->setJournalIds($clearedIds);
$clearedJournals = $collector->getExtractedJournals();
}
- Log::debug('Start transaction loop');
+ app('log')->debug('Start transaction loop');
+
/** @var array $journal */
foreach ($journals as $journal) {
$amount = $this->processJournal($account, $accountCurrency, $journal, $amount);
}
- Log::debug(sprintf('Final amount is %s', $amount));
- Log::debug('End transaction loop');
+ app('log')->debug(sprintf('Final amount is %s', $amount));
+ app('log')->debug('End transaction loop');
/** @var array $journal */
foreach ($clearedJournals as $journal) {
@@ -130,11 +118,11 @@ class ReconcileController extends Controller
$clearedAmount = $this->processJournal($account, $accountCurrency, $journal, $clearedAmount);
}
}
- $difference = bcadd(bcadd(bcsub($startBalance, $endBalance), $clearedAmount), $amount);
- $diffCompare = bccomp($difference, '0');
- $countCleared = count($clearedJournals);
+ $difference = bcadd(bcadd(bcsub($startBalance, $endBalance), $clearedAmount), $amount);
+ $diffCompare = bccomp($difference, '0');
+ $countCleared = count($clearedJournals);
- $reconSum = bcadd(bcadd($startBalance, $amount), $clearedAmount);
+ $reconSum = bcadd(bcadd($startBalance, $amount), $clearedAmount);
try {
$view = view(
@@ -155,14 +143,15 @@ class ReconcileController extends Controller
'selectedIds'
)
)->render();
- } catch (Throwable $e) {
- Log::debug(sprintf('View error: %s', $e->getMessage()));
- Log::error($e->getTraceAsString());
+ } catch (\Throwable $e) {
+ app('log')->debug(sprintf('View error: %s', $e->getMessage()));
+ app('log')->error($e->getTraceAsString());
$view = sprintf('Could not render accounts.reconcile.overview: %s', $e->getMessage());
+
throw new FireflyException($view, 0, $e);
}
- $return = [
+ $return = [
'post_url' => $route,
'html' => $view,
];
@@ -171,17 +160,64 @@ class ReconcileController extends Controller
}
/**
- * @param Account $account
- * @param TransactionCurrency $currency
- * @param array $journal
- * @param string $amount
+ * Returns a list of transactions in a modal.
*
- * @return string
+ * @return JsonResponse
+ *
+ * @throws FireflyException
*/
+ public function transactions(Account $account, Carbon $start = null, Carbon $end = null)
+ {
+ if (null === $start || null === $end) {
+ throw new FireflyException('Invalid dates submitted.');
+ }
+ if ($end->lt($start)) {
+ [$end, $start] = [$start, $end];
+ }
+ $startDate = clone $start;
+ $startDate->subDay();
+
+ $currency = $this->accountRepos->getAccountCurrency($account) ?? app('amount')->getDefaultCurrency();
+ $startBalance = app('steam')->bcround(app('steam')->balance($account, $startDate), $currency->decimal_places);
+ $endBalance = app('steam')->bcround(app('steam')->balance($account, $end), $currency->decimal_places);
+
+ // get the transactions
+ $selectionStart = clone $start;
+ $selectionStart->subDays(3);
+ $selectionEnd = clone $end;
+ $selectionEnd->addDays(3);
+
+ // grab transactions:
+ /** @var GroupCollectorInterface $collector */
+ $collector = app(GroupCollectorInterface::class);
+
+ $collector->setAccounts(new Collection([$account]))
+ ->setRange($selectionStart, $selectionEnd)
+ ->withBudgetInformation()->withCategoryInformation()->withAccountInformation()
+ ;
+ $array = $collector->getExtractedJournals();
+ $journals = $this->processTransactions($account, $array);
+
+ try {
+ $html = view(
+ 'accounts.reconcile.transactions',
+ compact('account', 'journals', 'currency', 'start', 'end', 'selectionStart', 'selectionEnd')
+ )->render();
+ } catch (\Throwable $e) {
+ app('log')->debug(sprintf('Could not render: %s', $e->getMessage()));
+ app('log')->error($e->getTraceAsString());
+ $html = sprintf('Could not render accounts.reconcile.transactions: %s', $e->getMessage());
+
+ throw new FireflyException($html, 0, $e);
+ }
+
+ return response()->json(['html' => $html, 'startBalance' => $startBalance, 'endBalance' => $endBalance]);
+ }
+
private function processJournal(Account $account, TransactionCurrency $currency, array $journal, string $amount): string
{
- $toAdd = '0';
- Log::debug(sprintf('User submitted %s #%d: "%s"', $journal['transaction_type_type'], $journal['transaction_journal_id'], $journal['description']));
+ $toAdd = '0';
+ app('log')->debug(sprintf('User submitted %s #%d: "%s"', $journal['transaction_type_type'], $journal['transaction_journal_id'], $journal['description']));
// not much magic below we need to cover using tests.
@@ -202,85 +238,23 @@ class ReconcileController extends Controller
}
}
-
- Log::debug(sprintf('Going to add %s to %s', $toAdd, $amount));
+ app('log')->debug(sprintf('Going to add %s to %s', $toAdd, $amount));
$amount = bcadd($amount, $toAdd);
- Log::debug(sprintf('Result is %s', $amount));
+ app('log')->debug(sprintf('Result is %s', $amount));
return $amount;
}
- /**
- * Returns a list of transactions in a modal.
- *
- * @param Account $account
- * @param Carbon|null $start
- * @param Carbon|null $end
- *
- * @return JsonResponse
- * @throws FireflyException
- * @throws JsonException
- */
- public function transactions(Account $account, Carbon $start = null, Carbon $end = null)
- {
- if (null === $start || null === $end) {
- throw new FireflyException('Invalid dates submitted.');
- }
- if ($end->lt($start)) {
- [$end, $start] = [$start, $end];
- }
- $startDate = clone $start;
- $startDate->subDay();
-
- $currency = $this->accountRepos->getAccountCurrency($account) ?? app('amount')->getDefaultCurrency();
- $startBalance = app('steam')->bcround(app('steam')->balance($account, $startDate), $currency->decimal_places);
- $endBalance = app('steam')->bcround(app('steam')->balance($account, $end), $currency->decimal_places);
-
- // get the transactions
- $selectionStart = clone $start;
- $selectionStart->subDays(3);
- $selectionEnd = clone $end;
- $selectionEnd->addDays(3);
-
- // grab transactions:
- /** @var GroupCollectorInterface $collector */
- $collector = app(GroupCollectorInterface::class);
-
- $collector->setAccounts(new Collection([$account]))
- ->setRange($selectionStart, $selectionEnd)
- ->withBudgetInformation()->withCategoryInformation()->withAccountInformation();
- $array = $collector->getExtractedJournals();
- $journals = $this->processTransactions($account, $array);
-
- try {
- $html = view(
- 'accounts.reconcile.transactions',
- compact('account', 'journals', 'currency', 'start', 'end', 'selectionStart', 'selectionEnd')
- )->render();
- } catch (Throwable $e) {
- Log::debug(sprintf('Could not render: %s', $e->getMessage()));
- Log::error($e->getTraceAsString());
- $html = sprintf('Could not render accounts.reconcile.transactions: %s', $e->getMessage());
- throw new FireflyException($html, 0, $e);
- }
-
- return response()->json(['html' => $html, 'startBalance' => $startBalance, 'endBalance' => $endBalance]);
- }
-
/**
* "fix" amounts to make it easier on the reconciliation overview:
- *
- * @param Account $account
- * @param array $array
- *
- * @return array
*/
private function processTransactions(Account $account, array $array): array
{
$journals = [];
+
/** @var array $journal */
foreach ($array as $journal) {
- $inverse = false;
+ $inverse = false;
if (TransactionType::DEPOSIT === $journal['transaction_type_type']) {
$inverse = true;
@@ -303,7 +277,6 @@ class ReconcileController extends Controller
}
}
-
$journals[] = $journal;
}
diff --git a/app/Http/Controllers/Json/RecurrenceController.php b/app/Http/Controllers/Json/RecurrenceController.php
index f7dbd0678d..6bd19c6013 100644
--- a/app/Http/Controllers/Json/RecurrenceController.php
+++ b/app/Http/Controllers/Json/RecurrenceController.php
@@ -31,7 +31,6 @@ use FireflyIII\Models\RecurrenceRepetition;
use FireflyIII\Repositories\Recurring\RecurringRepositoryInterface;
use Illuminate\Http\JsonResponse;
use Illuminate\Http\Request;
-use Illuminate\Support\Facades\Log;
/**
* Class RecurrenceController
@@ -42,8 +41,6 @@ class RecurrenceController extends Controller
/**
* RecurrenceController constructor.
- *
-
*/
public function __construct()
{
@@ -62,24 +59,32 @@ class RecurrenceController extends Controller
/**
* Shows all events for a repetition. Used in calendar.
*
- * @param Request $request
- *
- * @return JsonResponse
+ * @SuppressWarnings(PHPMD.NPathComplexity)
+ * @SuppressWarnings(PHPMD.CyclomaticComplexity)
*
* @throws FireflyException
*/
public function events(Request $request): JsonResponse
{
- $occurrences = [];
- $return = [];
- $start = Carbon::createFromFormat('Y-m-d', $request->get('start'));
- $end = Carbon::createFromFormat('Y-m-d', $request->get('end'));
- $firstDate = Carbon::createFromFormat('Y-m-d', $request->get('first_date'));
- $endDate = '' !== (string)$request->get('end_date') ? Carbon::createFromFormat('Y-m-d', $request->get('end_date')) : null;
- $endsAt = (string)$request->get('ends');
- $repetitionType = explode(',', $request->get('type'))[0];
- $repetitions = (int)$request->get('reps');
- $repetitionMoment = '';
+ $occurrences = [];
+ $return = [];
+ $start = Carbon::createFromFormat('Y-m-d', $request->get('start'));
+ $end = Carbon::createFromFormat('Y-m-d', $request->get('end'));
+ $firstDate = Carbon::createFromFormat('Y-m-d', $request->get('first_date'));
+ $endDate = '' !== (string)$request->get('end_date') ? Carbon::createFromFormat('Y-m-d', $request->get('end_date')) : null;
+ $endsAt = (string)$request->get('ends');
+ $repetitionType = explode(',', $request->get('type'))[0];
+ $repetitions = (int)$request->get('reps');
+ $weekend = (int)$request->get('weekend');
+ $repetitionMoment = '';
+ $skip = (int)$request->get('skip');
+ $skip = $skip < 0 || $skip > 31 ? 0 : $skip;
+ $weekend = $weekend < 1 || $weekend > 4 ? 1 : $weekend;
+
+ if (false === $start || false === $end || false === $firstDate || false === $endDate) {
+ return response()->json();
+ }
+
$start->startOfDay();
// if $firstDate is beyond $end, simply return an empty array.
@@ -87,7 +92,7 @@ class RecurrenceController extends Controller
return response()->json();
}
// if $firstDate is beyond start, use that one:
- $actualStart = clone $firstDate;
+ $actualStart = clone $firstDate;
if ('weekly' === $repetitionType || 'monthly' === $repetitionType) {
$repetitionMoment = explode(',', $request->get('type'))[1] ?? '1';
@@ -102,8 +107,8 @@ class RecurrenceController extends Controller
$repetition = new RecurrenceRepetition();
$repetition->repetition_type = $repetitionType;
$repetition->repetition_moment = $repetitionMoment;
- $repetition->repetition_skip = (int)$request->get('skip');
- $repetition->weekend = (int)$request->get('weekend');
+ $repetition->repetition_skip = $skip;
+ $repetition->weekend = $weekend;
$actualEnd = clone $end;
if ('until_date' === $endsAt) {
@@ -122,7 +127,7 @@ class RecurrenceController extends Controller
foreach ($occurrences as $current) {
if ($current->gte($start)) {
$event = [
- 'id' => $repetitionType . $firstDate->format('Ymd'),
+ 'id' => $repetitionType.$firstDate->format('Ymd'),
'title' => 'X',
'allDay' => true,
'start' => $current->format('Y-m-d'),
@@ -139,29 +144,30 @@ class RecurrenceController extends Controller
/**
* Suggests repetition moments.
- *
- * @param Request $request
- *
- * @return JsonResponse
*/
public function suggest(Request $request): JsonResponse
{
- $string = '' === (string)$request->get('date') ? date('Y-m-d') : (string)$request->get('date');
- $today = today(config('app.timezone'))->startOfDay();
+ $string = '' === (string)$request->get('date') ? date('Y-m-d') : (string)$request->get('date');
+ $today = today(config('app.timezone'))->startOfDay();
+
try {
- $date = Carbon::createFromFormat('Y-m-d', $string, config('app.timezone'))->startOfDay();
+ $date = Carbon::createFromFormat('Y-m-d', $string, config('app.timezone'));
} catch (InvalidFormatException $e) {
$date = Carbon::today(config('app.timezone'));
}
+ if (false === $date) {
+ return response()->json();
+ }
+ $date->startOfDay();
$preSelected = (string)$request->get('pre_select');
$locale = app('steam')->getLocale();
- Log::debug(sprintf('date = %s, today = %s. date > today? %s', $date->toAtomString(), $today->toAtomString(), var_export($date > $today, true)));
- Log::debug(sprintf('past = true? %s', var_export('true' === (string)$request->get('past'), true)));
+ app('log')->debug(sprintf('date = %s, today = %s. date > today? %s', $date->toAtomString(), $today->toAtomString(), var_export($date > $today, true)));
+ app('log')->debug(sprintf('past = true? %s', var_export('true' === (string)$request->get('past'), true)));
- $result = [];
+ $result = [];
if ($date > $today || 'true' === (string)$request->get('past')) {
- Log::debug('Will fill dropdown.');
+ app('log')->debug('Will fill dropdown.');
$weekly = sprintf('weekly,%s', $date->dayOfWeekIso);
$monthly = sprintf('monthly,%s', $date->day);
$dayOfWeek = (string)trans(sprintf('config.dow_%s', $date->dayOfWeekIso));
@@ -188,7 +194,7 @@ class RecurrenceController extends Controller
],
];
}
- Log::debug('Dropdown is', $result);
+ app('log')->debug('Dropdown is', $result);
return response()->json($result);
}
diff --git a/app/Http/Controllers/Json/RuleController.php b/app/Http/Controllers/Json/RuleController.php
index 9a2a9d6d1f..f0abfea161 100644
--- a/app/Http/Controllers/Json/RuleController.php
+++ b/app/Http/Controllers/Json/RuleController.php
@@ -27,8 +27,6 @@ use FireflyIII\Exceptions\FireflyException;
use FireflyIII\Http\Controllers\Controller;
use Illuminate\Http\JsonResponse;
use Illuminate\Http\Request;
-use Illuminate\Support\Facades\Log;
-use Throwable;
/**
* Class RuleController
@@ -38,9 +36,6 @@ class RuleController extends Controller
/**
* Render HTML form for rule action.
*
- * @param Request $request
- *
- * @return JsonResponse
* @throws FireflyException
*/
public function action(Request $request): JsonResponse
@@ -49,14 +44,16 @@ class RuleController extends Controller
$keys = array_keys(config('firefly.rule-actions'));
$actions = [];
foreach ($keys as $key) {
- $actions[$key] = (string)trans('firefly.rule_action_' . $key . '_choice');
+ $actions[$key] = (string)trans('firefly.rule_action_'.$key.'_choice');
}
+
try {
$view = view('rules.partials.action', compact('actions', 'count'))->render();
- } catch (Throwable $e) {
- Log::error(sprintf('Cannot render rules.partials.action: %s', $e->getMessage()));
- Log::error($e->getTraceAsString());
+ } catch (\Throwable $e) {
+ app('log')->error(sprintf('Cannot render rules.partials.action: %s', $e->getMessage()));
+ app('log')->error($e->getTraceAsString());
$view = 'Could not render view.';
+
throw new FireflyException($view, 0, $e);
}
@@ -66,9 +63,6 @@ class RuleController extends Controller
/**
* Render HTML for rule trigger.
*
- * @param Request $request
- *
- * @return JsonResponse
* @throws FireflyException
*/
public function trigger(Request $request): JsonResponse
@@ -85,10 +79,11 @@ class RuleController extends Controller
try {
$view = view('rules.partials.trigger', compact('triggers', 'count'))->render();
- } catch (Throwable $e) {
- Log::error(sprintf('Cannot render rules.partials.trigger: %s', $e->getMessage()));
- Log::error($e->getTraceAsString());
+ } catch (\Throwable $e) {
+ app('log')->error(sprintf('Cannot render rules.partials.trigger: %s', $e->getMessage()));
+ app('log')->error($e->getTraceAsString());
$view = 'Could not render view.';
+
throw new FireflyException($view, 0, $e);
}
diff --git a/app/Http/Controllers/NewUserController.php b/app/Http/Controllers/NewUserController.php
index 5ba5d4fd12..18b422872b 100644
--- a/app/Http/Controllers/NewUserController.php
+++ b/app/Http/Controllers/NewUserController.php
@@ -27,7 +27,7 @@ use FireflyIII\Exceptions\FireflyException;
use FireflyIII\Http\Requests\NewUserFormRequest;
use FireflyIII\Models\AccountType;
use FireflyIII\Repositories\Account\AccountRepositoryInterface;
-use FireflyIII\Repositories\Currency\CurrencyRepositoryInterface;
+use FireflyIII\Repositories\UserGroups\Currency\CurrencyRepositoryInterface;
use FireflyIII\Support\Http\Controllers\CreateStuff;
use Illuminate\Contracts\View\Factory;
use Illuminate\Http\RedirectResponse;
@@ -41,8 +41,7 @@ class NewUserController extends Controller
{
use CreateStuff;
- /** @var AccountRepositoryInterface The account repository */
- private $repository;
+ private AccountRepositoryInterface $repository;
/**
* NewUserController constructor.
@@ -63,15 +62,15 @@ class NewUserController extends Controller
/**
* Form the user gets when he has no data in the system.
*
- * @return RedirectResponse|Redirector|Factory|View
+ * @return Factory|Redirector|RedirectResponse|View
*/
public function index()
{
app('view')->share('title', (string)trans('firefly.welcome'));
app('view')->share('mainTitleIcon', 'fa-fire');
- $types = config('firefly.accountTypesByIdentifier.asset');
- $count = $this->repository->count($types);
+ $types = config('firefly.accountTypesByIdentifier.asset');
+ $count = $this->repository->count($types);
$languages = [];
@@ -85,15 +84,13 @@ class NewUserController extends Controller
/**
* Store his new settings.
*
- * @param NewUserFormRequest $request
- * @param CurrencyRepositoryInterface $currencyRepository
+ * @return Redirector|RedirectResponse
*
- * @return RedirectResponse|Redirector
* @throws FireflyException
*/
public function submit(NewUserFormRequest $request, CurrencyRepositoryInterface $currencyRepository)
{
- $language = $request->convertString('language');
+ $language = $request->convertString('language');
if (!array_key_exists($language, config('firefly.languages'))) {
$language = 'en_US';
}
@@ -101,11 +98,11 @@ class NewUserController extends Controller
// set language preference:
app('preferences')->set('language', $language);
// Store currency preference from input:
- $currency = $currencyRepository->find((int)$request->input('amount_currency_id_bank_balance'));
+ $currency = $currencyRepository->find((int)$request->input('amount_currency_id_bank_balance'));
// if is null, set to EUR:
if (null === $currency) {
- $currency = $currencyRepository->findByCodeNull('EUR');
+ $currency = $currencyRepository->findByCode('EUR');
}
$currencyRepository->enable($currency);
@@ -114,10 +111,10 @@ class NewUserController extends Controller
$this->createCashWalletAccount($currency, $language); // create cash wallet account
// store currency preference:
- app('preferences')->set('currencyPreference', $currency->code);
+ $currencyRepository->makeDefault($currency);
// store frontpage preferences:
- $accounts = $this->repository->getAccountsByType([AccountType::ASSET])->pluck('id')->toArray();
+ $accounts = $this->repository->getAccountsByType([AccountType::ASSET])->pluck('id')->toArray();
app('preferences')->set('frontPageAccounts', $accounts);
// mark.
diff --git a/app/Http/Controllers/ObjectGroup/DeleteController.php b/app/Http/Controllers/ObjectGroup/DeleteController.php
index c0a3b41ecd..f9115ec7f4 100644
--- a/app/Http/Controllers/ObjectGroup/DeleteController.php
+++ b/app/Http/Controllers/ObjectGroup/DeleteController.php
@@ -40,8 +40,6 @@ class DeleteController extends Controller
/**
* PiggyBankController constructor.
- *
-
*/
public function __construct()
{
@@ -62,8 +60,6 @@ class DeleteController extends Controller
/**
* Delete a piggy bank.
*
- * @param ObjectGroup $objectGroup
- *
* @return Factory|View
*/
public function delete(ObjectGroup $objectGroup)
@@ -79,10 +75,6 @@ class DeleteController extends Controller
/**
* Destroy the piggy bank.
- *
- * @param ObjectGroup $objectGroup
- *
- * @return RedirectResponse
*/
public function destroy(ObjectGroup $objectGroup): RedirectResponse
{
diff --git a/app/Http/Controllers/ObjectGroup/EditController.php b/app/Http/Controllers/ObjectGroup/EditController.php
index 507804d773..e85ffac6a6 100644
--- a/app/Http/Controllers/ObjectGroup/EditController.php
+++ b/app/Http/Controllers/ObjectGroup/EditController.php
@@ -43,8 +43,6 @@ class EditController extends Controller
/**
* PiggyBankController constructor.
- *
-
*/
public function __construct()
{
@@ -65,8 +63,6 @@ class EditController extends Controller
/**
* Edit an object group.
*
- * @param ObjectGroup $objectGroup
- *
* @return Factory|View
*/
public function edit(ObjectGroup $objectGroup)
@@ -85,10 +81,7 @@ class EditController extends Controller
/**
* Update a piggy bank.
*
- * @param ObjectGroupFormRequest $request
- * @param ObjectGroup $objectGroup
- *
- * @return Application|RedirectResponse|Redirector
+ * @return Application|Redirector|RedirectResponse
*/
public function update(ObjectGroupFormRequest $request, ObjectGroup $objectGroup)
{
@@ -98,7 +91,7 @@ class EditController extends Controller
session()->flash('success', (string)trans('firefly.updated_object_group', ['title' => $objectGroup->title]));
app('preferences')->mark();
- $redirect = redirect($this->getPreviousUrl('object-groups.edit.url'));
+ $redirect = redirect($this->getPreviousUrl('object-groups.edit.url'));
if (1 === (int)$request->get('return_to_edit')) {
session()->put('object-groups.edit.fromUpdate', true);
diff --git a/app/Http/Controllers/ObjectGroup/IndexController.php b/app/Http/Controllers/ObjectGroup/IndexController.php
index 7f48d4240c..168b3ea601 100644
--- a/app/Http/Controllers/ObjectGroup/IndexController.php
+++ b/app/Http/Controllers/ObjectGroup/IndexController.php
@@ -31,7 +31,6 @@ use Illuminate\Contracts\View\Factory;
use Illuminate\Contracts\View\View;
use Illuminate\Http\JsonResponse;
use Illuminate\Http\Request;
-use Illuminate\Support\Facades\Log;
/**
* Class IndexController
@@ -42,8 +41,6 @@ class IndexController extends Controller
/**
* IndexController constructor.
- *
-
*/
public function __construct()
{
@@ -75,14 +72,11 @@ class IndexController extends Controller
}
/**
- * @param Request $request
- * @param ObjectGroup $objectGroup
- *
* @return JsonResponse
*/
public function setOrder(Request $request, ObjectGroup $objectGroup)
{
- Log::debug(sprintf('Found object group #%d "%s"', $objectGroup->id, $objectGroup->title));
+ app('log')->debug(sprintf('Found object group #%d "%s"', $objectGroup->id, $objectGroup->title));
$newOrder = (int)$request->get('order');
$this->repository->setOrder($objectGroup, $newOrder);
diff --git a/app/Http/Controllers/PiggyBank/AmountController.php b/app/Http/Controllers/PiggyBank/AmountController.php
index ec59780b2e..28085daa06 100644
--- a/app/Http/Controllers/PiggyBank/AmountController.php
+++ b/app/Http/Controllers/PiggyBank/AmountController.php
@@ -32,7 +32,6 @@ use FireflyIII\Repositories\PiggyBank\PiggyBankRepositoryInterface;
use Illuminate\Contracts\View\Factory;
use Illuminate\Http\RedirectResponse;
use Illuminate\Http\Request;
-use Illuminate\Support\Facades\Log;
use Illuminate\View\View;
/**
@@ -45,8 +44,6 @@ class AmountController extends Controller
/**
* PiggyBankController constructor.
- *
-
*/
public function __construct()
{
@@ -68,8 +65,6 @@ class AmountController extends Controller
/**
* Add money to piggy bank.
*
- * @param PiggyBank $piggyBank
- *
* @return Factory|View
*/
public function add(PiggyBank $piggyBank)
@@ -81,7 +76,7 @@ class AmountController extends Controller
$leftToSave = bcsub($piggyBank->targetamount, $savedSoFar);
$maxAmount = min($leftOnAccount, $leftToSave);
}
- $currency = $this->accountRepos->getAccountCurrency($piggyBank->account) ?? app('amount')->getDefaultCurrency();
+ $currency = $this->accountRepos->getAccountCurrency($piggyBank->account) ?? app('amount')->getDefaultCurrency();
return view('piggy-banks.add', compact('piggyBank', 'maxAmount', 'currency'));
}
@@ -89,8 +84,6 @@ class AmountController extends Controller
/**
* Add money to piggy bank (for mobile devices).
*
- * @param PiggyBank $piggyBank
- *
* @return Factory|View
*/
public function addMobile(PiggyBank $piggyBank)
@@ -105,18 +98,13 @@ class AmountController extends Controller
$leftToSave = bcsub($piggyBank->targetamount, $savedSoFar);
$maxAmount = min($leftOnAccount, $leftToSave);
}
- $currency = $this->accountRepos->getAccountCurrency($piggyBank->account) ?? app('amount')->getDefaultCurrency();
+ $currency = $this->accountRepos->getAccountCurrency($piggyBank->account) ?? app('amount')->getDefaultCurrency();
return view('piggy-banks.add-mobile', compact('piggyBank', 'maxAmount', 'currency'));
}
/**
* Add money to piggy bank.
- *
- * @param Request $request
- * @param PiggyBank $piggyBank
- *
- * @return RedirectResponse
*/
public function postAdd(Request $request, PiggyBank $piggyBank): RedirectResponse
{
@@ -140,7 +128,7 @@ class AmountController extends Controller
return redirect(route('piggy-banks.index'));
}
- Log::error('Cannot add ' . $amount . ' because canAddAmount returned false.');
+ app('log')->error('Cannot add '.$amount.' because canAddAmount returned false.');
session()->flash(
'error',
(string)trans(
@@ -154,11 +142,6 @@ class AmountController extends Controller
/**
* Remove money from piggy bank.
- *
- * @param Request $request
- * @param PiggyBank $piggyBank
- *
- * @return RedirectResponse
*/
public function postRemove(Request $request, PiggyBank $piggyBank): RedirectResponse
{
@@ -181,7 +164,7 @@ class AmountController extends Controller
return redirect(route('piggy-banks.index'));
}
- $amount = (string)$request->get('amount');
+ $amount = (string)$request->get('amount');
session()->flash(
'error',
@@ -197,8 +180,6 @@ class AmountController extends Controller
/**
* Remove money from piggy bank form.
*
- * @param PiggyBank $piggyBank
- *
* @return Factory|View
*/
public function remove(PiggyBank $piggyBank)
@@ -212,8 +193,6 @@ class AmountController extends Controller
/**
* Remove money from piggy bank (for mobile devices).
*
- * @param PiggyBank $piggyBank
- *
* @return Factory|View
*/
public function removeMobile(PiggyBank $piggyBank)
diff --git a/app/Http/Controllers/PiggyBank/CreateController.php b/app/Http/Controllers/PiggyBank/CreateController.php
index 66c3a8d518..92aac833d9 100644
--- a/app/Http/Controllers/PiggyBank/CreateController.php
+++ b/app/Http/Controllers/PiggyBank/CreateController.php
@@ -32,6 +32,7 @@ use FireflyIII\Repositories\PiggyBank\PiggyBankRepositoryInterface;
use Illuminate\Contracts\View\Factory;
use Illuminate\Http\RedirectResponse;
use Illuminate\Routing\Redirector;
+use Illuminate\Support\Facades\Log;
use Illuminate\View\View;
/**
@@ -44,8 +45,6 @@ class CreateController extends Controller
/**
* PiggyBankController constructor.
- *
-
*/
public function __construct()
{
@@ -86,14 +85,13 @@ class CreateController extends Controller
/**
* Store a new piggy bank.
*
- * @param PiggyBankStoreRequest $request
+ * @return Redirector|RedirectResponse
*
- * @return RedirectResponse|Redirector
* @throws FireflyException
*/
public function store(PiggyBankStoreRequest $request)
{
- $data = $request->getPiggyBankData();
+ $data = $request->getPiggyBankData();
if (null === $data['startdate']) {
$data['startdate'] = today(config('app.timezone'));
}
@@ -103,19 +101,20 @@ class CreateController extends Controller
app('preferences')->mark();
// store attachment(s):
- /** @var array $files */
- $files = $request->hasFile('attachments') ? $request->file('attachments') : null;
+ /** @var null|array $files */
+ $files = $request->hasFile('attachments') ? $request->file('attachments') : null;
if (null !== $files && !auth()->user()->hasRole('demo')) {
$this->attachments->saveAttachmentsForModel($piggyBank, $files);
}
if (null !== $files && auth()->user()->hasRole('demo')) {
+ Log::channel('audit')->warning(sprintf('The demo user is trying to upload attachments in %s.', __METHOD__));
session()->flash('info', (string)trans('firefly.no_att_demo_user'));
}
if (count($this->attachments->getMessages()->get('attachments')) > 0) {
$request->session()->flash('info', $this->attachments->getMessages()->get('attachments'));
}
- $redirect = redirect($this->getPreviousUrl('piggy-banks.create.url'));
+ $redirect = redirect($this->getPreviousUrl('piggy-banks.create.url'));
if (1 === (int)$request->get('create_another')) {
session()->put('piggy-banks.create.fromStore', true);
diff --git a/app/Http/Controllers/PiggyBank/DeleteController.php b/app/Http/Controllers/PiggyBank/DeleteController.php
index 45d17de6a1..754b62f01d 100644
--- a/app/Http/Controllers/PiggyBank/DeleteController.php
+++ b/app/Http/Controllers/PiggyBank/DeleteController.php
@@ -40,8 +40,6 @@ class DeleteController extends Controller
/**
* PiggyBankController constructor.
- *
-
*/
public function __construct()
{
@@ -62,8 +60,6 @@ class DeleteController extends Controller
/**
* Delete a piggy bank.
*
- * @param PiggyBank $piggyBank
- *
* @return Factory|View
*/
public function delete(PiggyBank $piggyBank)
@@ -78,10 +74,6 @@ class DeleteController extends Controller
/**
* Destroy the piggy bank.
- *
- * @param PiggyBank $piggyBank
- *
- * @return RedirectResponse
*/
public function destroy(PiggyBank $piggyBank): RedirectResponse
{
diff --git a/app/Http/Controllers/PiggyBank/EditController.php b/app/Http/Controllers/PiggyBank/EditController.php
index 45b1db77fa..c0a2de083e 100644
--- a/app/Http/Controllers/PiggyBank/EditController.php
+++ b/app/Http/Controllers/PiggyBank/EditController.php
@@ -24,7 +24,6 @@ declare(strict_types=1);
namespace FireflyIII\Http\Controllers\PiggyBank;
-use Amount;
use FireflyIII\Helpers\Attachments\AttachmentHelperInterface;
use FireflyIII\Http\Controllers\Controller;
use FireflyIII\Http\Requests\PiggyBankUpdateRequest;
@@ -34,6 +33,7 @@ use FireflyIII\Repositories\PiggyBank\PiggyBankRepositoryInterface;
use Illuminate\Contracts\View\Factory;
use Illuminate\Http\RedirectResponse;
use Illuminate\Routing\Redirector;
+use Illuminate\Support\Facades\Log;
use Illuminate\View\View;
/**
@@ -47,8 +47,6 @@ class EditController extends Controller
/**
* PiggyBankController constructor.
- *
-
*/
public function __construct()
{
@@ -62,6 +60,7 @@ class EditController extends Controller
$this->attachments = app(AttachmentHelperInterface::class);
$this->piggyRepos = app(PiggyBankRepositoryInterface::class);
$this->accountRepository = app(AccountRepositoryInterface::class);
+
return $next($request);
}
);
@@ -70,8 +69,6 @@ class EditController extends Controller
/**
* Edit a piggy bank.
*
- * @param PiggyBank $piggyBank
- *
* @return Factory|View
*/
public function edit(PiggyBank $piggyBank)
@@ -80,20 +77,20 @@ class EditController extends Controller
$subTitleIcon = 'fa-pencil';
$note = $piggyBank->notes()->first();
// Flash some data to fill the form.
- $targetDate = $piggyBank->targetdate?->format('Y-m-d');
- $startDate = $piggyBank->startdate?->format('Y-m-d');
- $currency = $this->accountRepository->getAccountCurrency($piggyBank->account);
+ $targetDate = $piggyBank->targetdate?->format('Y-m-d');
+ $startDate = $piggyBank->startdate?->format('Y-m-d');
+ $currency = $this->accountRepository->getAccountCurrency($piggyBank->account);
if (null === $currency) {
- $currency = Amount::getDefaultCurrency();
+ $currency = app('amount')->getDefaultCurrency();
}
- $preFilled = [
+ $preFilled = [
'name' => $piggyBank->name,
'account_id' => $piggyBank->account_id,
'targetamount' => app('steam')->bcround($piggyBank->targetamount, $currency->decimal_places),
'targetdate' => $targetDate,
'startdate' => $startDate,
- 'object_group' => $piggyBank->objectGroups->first() ? $piggyBank->objectGroups->first()->title : '',
+ 'object_group' => null !== $piggyBank->objectGroups->first() ? $piggyBank->objectGroups->first()->title : '',
'notes' => null === $note ? '' : $note->text,
];
if (0 === bccomp($piggyBank->targetamount, '0')) {
@@ -113,10 +110,7 @@ class EditController extends Controller
/**
* Update a piggy bank.
*
- * @param PiggyBankUpdateRequest $request
- * @param PiggyBank $piggyBank
- *
- * @return RedirectResponse|Redirector
+ * @return Redirector|RedirectResponse
*/
public function update(PiggyBankUpdateRequest $request, PiggyBank $piggyBank)
{
@@ -127,19 +121,20 @@ class EditController extends Controller
app('preferences')->mark();
// store new attachment(s):
- /** @var array $files */
- $files = $request->hasFile('attachments') ? $request->file('attachments') : null;
+ /** @var null|array $files */
+ $files = $request->hasFile('attachments') ? $request->file('attachments') : null;
if (null !== $files && !auth()->user()->hasRole('demo')) {
$this->attachments->saveAttachmentsForModel($piggyBank, $files);
}
if (null !== $files && auth()->user()->hasRole('demo')) {
+ Log::channel('audit')->warning(sprintf('The demo user is trying to upload attachments in %s.', __METHOD__));
session()->flash('info', (string)trans('firefly.no_att_demo_user'));
}
if (count($this->attachments->getMessages()->get('attachments')) > 0) {
$request->session()->flash('info', $this->attachments->getMessages()->get('attachments'));
}
- $redirect = redirect($this->getPreviousUrl('piggy-banks.edit.url'));
+ $redirect = redirect($this->getPreviousUrl('piggy-banks.edit.url'));
if (1 === (int)$request->get('return_to_edit')) {
session()->put('piggy-banks.edit.fromUpdate', true);
diff --git a/app/Http/Controllers/PiggyBank/IndexController.php b/app/Http/Controllers/PiggyBank/IndexController.php
index fb0412e1cd..72396eb20d 100644
--- a/app/Http/Controllers/PiggyBank/IndexController.php
+++ b/app/Http/Controllers/PiggyBank/IndexController.php
@@ -36,7 +36,6 @@ use Illuminate\Contracts\View\Factory;
use Illuminate\Http\JsonResponse;
use Illuminate\Http\Request;
use Illuminate\View\View;
-use JsonException;
use Symfony\Component\HttpFoundation\ParameterBag;
/**
@@ -50,8 +49,6 @@ class IndexController extends Controller
/**
* PiggyBankController constructor.
- *
-
*/
public function __construct()
{
@@ -74,52 +71,52 @@ class IndexController extends Controller
*
* TODO very complicated function.
*
- * @param Request $request
- *
* @return Factory|View
+ *
* @throws FireflyException
- * @throws JsonException
*/
- public function index(Request $request)
+ public function index()
{
$this->cleanupObjectGroups();
$this->piggyRepos->resetOrder();
- $collection = $this->piggyRepos->getPiggyBanks();
- $accounts = [];
+ $collection = $this->piggyRepos->getPiggyBanks();
+ $accounts = [];
+
/** @var Carbon $end */
- $end = session('end', today(config('app.timezone'))->endOfMonth());
+ $end = session('end', today(config('app.timezone'))->endOfMonth());
// transform piggies using the transformer:
- $parameters = new ParameterBag();
+ $parameters = new ParameterBag();
$parameters->set('end', $end);
// make piggy bank groups:
- $piggyBanks = [];
+ $piggyBanks = [];
/** @var PiggyBankTransformer $transformer */
- $transformer = app(PiggyBankTransformer::class);
+ $transformer = app(PiggyBankTransformer::class);
$transformer->setParameters(new ParameterBag());
/** @var AccountTransformer $accountTransformer */
$accountTransformer = app(AccountTransformer::class);
$accountTransformer->setParameters($parameters);
+
/** @var PiggyBank $piggy */
foreach ($collection as $piggy) {
- $array = $transformer->transform($piggy);
- $groupOrder = (int)$array['object_group_order'];
+ $array = $transformer->transform($piggy);
+ $groupOrder = (int)$array['object_group_order'];
// make group array if necessary:
- $piggyBanks[$groupOrder] = $piggyBanks[$groupOrder] ?? [
+ $piggyBanks[$groupOrder] ??= [
'object_group_id' => $array['object_group_id'] ?? 0,
'object_group_title' => $array['object_group_title'] ?? trans('firefly.default_group_title_name'),
'piggy_banks' => [],
];
- $account = $accountTransformer->transform($piggy->account);
- $accountId = (int)$account['id'];
- $array['attachments'] = $this->piggyRepos->getAttachments($piggy);
+ $account = $accountTransformer->transform($piggy->account);
+ $accountId = (int)$account['id'];
+ $array['attachments'] = $this->piggyRepos->getAttachments($piggy);
if (!array_key_exists($accountId, $accounts)) {
// create new:
- $accounts[$accountId] = $account;
+ $accounts[$accountId] = $account;
// add some interesting details:
$accounts[$accountId]['left'] = $accounts[$accountId]['current_balance'];
@@ -137,26 +134,21 @@ class IndexController extends Controller
$piggyBanks[$groupOrder]['piggy_banks'][] = $array;
}
// do a bunch of summaries.
- $piggyBanks = $this->makeSums($piggyBanks);
+ $piggyBanks = $this->makeSums($piggyBanks);
ksort($piggyBanks);
return view('piggy-banks.index', compact('piggyBanks', 'accounts'));
}
- /**
- * @param array $piggyBanks
- *
- * @return array
- */
private function makeSums(array $piggyBanks): array
{
$sums = [];
foreach ($piggyBanks as $groupOrder => $group) {
$groupId = $group['object_group_id'];
foreach ($group['piggy_banks'] as $piggy) {
- $currencyId = $piggy['currency_id'];
- $sums[$groupId][$currencyId] = $sums[$groupId][$currencyId] ?? [
+ $currencyId = $piggy['currency_id'];
+ $sums[$groupId][$currencyId] ??= [
'target' => '0',
'saved' => '0',
'left_to_save' => '0',
@@ -186,11 +178,6 @@ class IndexController extends Controller
/**
* Set the order of a piggy bank.
- *
- * @param Request $request
- * @param PiggyBank $piggyBank
- *
- * @return JsonResponse
*/
public function setOrder(Request $request, PiggyBank $piggyBank): JsonResponse
{
diff --git a/app/Http/Controllers/PiggyBank/ShowController.php b/app/Http/Controllers/PiggyBank/ShowController.php
index d9ff1f9e36..2fd69286ae 100644
--- a/app/Http/Controllers/PiggyBank/ShowController.php
+++ b/app/Http/Controllers/PiggyBank/ShowController.php
@@ -32,7 +32,6 @@ use FireflyIII\Repositories\PiggyBank\PiggyBankRepositoryInterface;
use FireflyIII\Transformers\PiggyBankTransformer;
use Illuminate\Contracts\View\Factory;
use Illuminate\View\View;
-use JsonException;
use Symfony\Component\HttpFoundation\ParameterBag;
/**
@@ -44,8 +43,6 @@ class ShowController extends Controller
/**
* PiggyBankController constructor.
- *
-
*/
public function __construct()
{
@@ -66,18 +63,16 @@ class ShowController extends Controller
/**
* Show a single piggy bank.
*
- * @param PiggyBank $piggyBank
- *
* @return Factory|View
+ *
* @throws FireflyException
- * @throws JsonException
*/
public function show(PiggyBank $piggyBank)
{
/** @var Carbon $end */
- $end = session('end', today(config('app.timezone'))->endOfMonth());
+ $end = session('end', today(config('app.timezone'))->endOfMonth());
// transform piggies using the transformer:
- $parameters = new ParameterBag();
+ $parameters = new ParameterBag();
$parameters->set('end', $end);
/** @var PiggyBankTransformer $transformer */
diff --git a/app/Http/Controllers/Popup/ReportController.php b/app/Http/Controllers/Popup/ReportController.php
index e8e65940d0..1d4ae33507 100644
--- a/app/Http/Controllers/Popup/ReportController.php
+++ b/app/Http/Controllers/Popup/ReportController.php
@@ -31,7 +31,6 @@ use Illuminate\Http\Request;
/**
* Class ReportController.
- *
*/
class ReportController extends Controller
{
@@ -40,9 +39,6 @@ class ReportController extends Controller
/**
* Generate popup view.
*
- * @param Request $request
- *
- * @return JsonResponse
* @throws FireflyException
*/
public function general(Request $request): JsonResponse
@@ -53,7 +49,7 @@ class ReportController extends Controller
app('view')->share('start', $attributes['startDate']);
app('view')->share('end', $attributes['endDate']);
- $html = match ($attributes['location']) {
+ $html = match ($attributes['location']) {
default => sprintf('Firefly III cannot handle "%s"-popups.', $attributes['location']),
'budget-spent-amount' => $this->budgetSpentAmount($attributes),
'expense-entry' => $this->expenseEntry($attributes),
@@ -61,6 +57,7 @@ class ReportController extends Controller
'category-entry' => $this->categoryEntry($attributes),
'budget-entry' => $this->budgetEntry($attributes),
};
+
return response()->json(['html' => $html]);
}
}
diff --git a/app/Http/Controllers/PreferencesController.php b/app/Http/Controllers/PreferencesController.php
index aec2828524..e5d1974824 100644
--- a/app/Http/Controllers/PreferencesController.php
+++ b/app/Http/Controllers/PreferencesController.php
@@ -33,11 +33,7 @@ use Illuminate\Contracts\View\Factory;
use Illuminate\Http\RedirectResponse;
use Illuminate\Http\Request;
use Illuminate\Routing\Redirector;
-use Illuminate\Support\Facades\Log;
use Illuminate\View\View;
-use JsonException;
-use Psr\Container\ContainerExceptionInterface;
-use Psr\Container\NotFoundExceptionInterface;
/**
* Class PreferencesController.
@@ -46,15 +42,13 @@ class PreferencesController extends Controller
{
/**
* PreferencesController constructor.
- *
-
*/
public function __construct()
{
parent::__construct();
$this->middleware(
- function ($request, $next) {
+ static function ($request, $next) {
app('view')->share('title', (string)trans('firefly.preferences'));
app('view')->share('mainTitleIcon', 'fa-gear');
@@ -66,24 +60,20 @@ class PreferencesController extends Controller
/**
* Show overview of preferences.
*
- * @param AccountRepositoryInterface $repository
- *
* @return Factory|View
+ *
* @throws FireflyException
- * @throws ContainerExceptionInterface
- * @throws NotFoundExceptionInterface
*/
public function index(AccountRepositoryInterface $repository)
{
- $accounts = $repository->getAccountsByType([AccountType::DEFAULT, AccountType::ASSET, AccountType::LOAN, AccountType::DEBT, AccountType::MORTGAGE]);
- $isDocker = env('IS_DOCKER', false);
+ $accounts = $repository->getAccountsByType([AccountType::DEFAULT, AccountType::ASSET, AccountType::LOAN, AccountType::DEBT, AccountType::MORTGAGE]);
+ $isDocker = env('IS_DOCKER', false);
+ $groupedAccounts = [];
- // group accounts
- $groupedAccounts = [];
/** @var Account $account */
foreach ($accounts as $account) {
- $type = $account->accountType->type;
- $role = sprintf('opt_group_%s', $repository->getMetaValue($account, 'account_role'));
+ $type = $account->accountType->type;
+ $role = sprintf('opt_group_%s', $repository->getMetaValue($account, 'account_role'));
if (in_array($type, [AccountType::MORTGAGE, AccountType::DEBT, AccountType::LOAN], true)) {
$role = sprintf('opt_group_l_%s', $type);
@@ -92,27 +82,35 @@ class PreferencesController extends Controller
if ('opt_group_' === $role) {
$role = 'opt_group_defaultAsset';
}
- $groupedAccounts[trans(sprintf('firefly.%s', $role))][$account->id] = $account->name;
+ $groupedAccounts[(string)trans(sprintf('firefly.%s', $role))][$account->id] = $account->name;
}
ksort($groupedAccounts);
- $accountIds = $accounts->pluck('id')->toArray();
- $viewRange = app('navigation')->getViewRange(false);
- $frontPageAccounts = app('preferences')->get('frontPageAccounts', $accountIds);
- $language = app('steam')->getLanguage();
- $languages = config('firefly.languages');
- $locale = app('preferences')->get('locale', config('firefly.default_locale', 'equal'))->data;
- $listPageSize = app('preferences')->get('listPageSize', 50)->data;
- $darkMode = app('preferences')->get('darkMode', 'browser')->data;
- $slackUrl = app('preferences')->get('slack_webhook_url', '')->data;
- $customFiscalYear = app('preferences')->get('customFiscalYear', 0)->data;
- $fiscalYearStartStr = app('preferences')->get('fiscalYearStart', '01-01')->data;
- $fiscalYearStart = date('Y') . '-' . $fiscalYearStartStr;
- $tjOptionalFields = app('preferences')->get('transaction_journal_optional_fields', [])->data;
- $availableDarkModes = config('firefly.available_dark_modes');
+ /** @var array $accountIds */
+ $accountIds = $accounts->pluck('id')->toArray();
+ $viewRange = app('navigation')->getViewRange(false);
+ $frontPageAccountsPref = app('preferences')->get('frontPageAccounts', $accountIds);
+ $frontPageAccounts = $frontPageAccountsPref->data;
+ if (!is_array($frontPageAccounts)) {
+ $frontPageAccounts = $accountIds;
+ }
+ $language = app('steam')->getLanguage();
+ $languages = config('firefly.languages');
+ $locale = app('preferences')->get('locale', config('firefly.default_locale', 'equal'))->data;
+ $listPageSize = app('preferences')->get('listPageSize', 50)->data;
+ $darkMode = app('preferences')->get('darkMode', 'browser')->data;
+ $slackUrl = app('preferences')->get('slack_webhook_url', '')->data;
+ $customFiscalYear = app('preferences')->get('customFiscalYear', 0)->data;
+ $fiscalYearStartStr = app('preferences')->get('fiscalYearStart', '01-01')->data;
+ if (is_array($fiscalYearStartStr)) {
+ $fiscalYearStartStr = '01-01';
+ }
+ $fiscalYearStart = sprintf('%s-%s', date('Y'), (string)$fiscalYearStartStr);
+ $tjOptionalFields = app('preferences')->get('transaction_journal_optional_fields', [])->data;
+ $availableDarkModes = config('firefly.available_dark_modes');
// notification preferences (single value for each):
- $notifications = [];
+ $notifications = [];
foreach (config('firefly.available_notifications') as $notification) {
$notifications[$notification] = app('preferences')->get(sprintf('notification_%s', $notification), true)->data;
}
@@ -122,57 +120,37 @@ class PreferencesController extends Controller
// list of locales also has "equal" which makes it equal to whatever the language is.
try {
- $locales = json_decode(file_get_contents(resource_path(sprintf('lang/%s/locales.json', $language))), true, 512, JSON_THROW_ON_ERROR);
- } catch (JsonException $e) {
- Log::error($e->getMessage());
+ $locales = json_decode((string)file_get_contents(resource_path(sprintf('lang/%s/locales.json', $language))), true, 512, JSON_THROW_ON_ERROR);
+ } catch (\JsonException $e) {
+ app('log')->error($e->getMessage());
$locales = [];
}
- $locales = ['equal' => (string)trans('firefly.equal_to_language')] + $locales;
+ $locales = ['equal' => (string)trans('firefly.equal_to_language')] + $locales;
// an important fallback is that the frontPageAccount array gets refilled automatically
// when it turns up empty.
- if (0 === count($frontPageAccounts->data)) {
+ if (0 === count($frontPageAccounts)) {
$frontPageAccounts = $accountIds;
}
// for the demo user, the slackUrl is automatically emptied.
- // this isn't really secure but it means that the demo site has a semi-secret
+ // this isn't really secure, but it means that the demo site has a semi-secret
// slackUrl.
if (auth()->user()->hasRole('demo')) {
$slackUrl = '';
}
- return view(
- 'preferences.index',
- compact(
- 'language',
- 'groupedAccounts',
- 'isDocker',
- 'frontPageAccounts',
- 'languages',
- 'darkMode',
- 'availableDarkModes',
- 'notifications',
- 'slackUrl',
- 'locales',
- 'locale',
- 'tjOptionalFields',
- 'viewRange',
- 'customFiscalYear',
- 'listPageSize',
- 'fiscalYearStart'
- )
- );
+ return view('preferences.index', compact('language', 'groupedAccounts', 'isDocker', 'frontPageAccounts', 'languages', 'darkMode', 'availableDarkModes', 'notifications', 'slackUrl', 'locales', 'locale', 'tjOptionalFields', 'viewRange', 'customFiscalYear', 'listPageSize', 'fiscalYearStart'));
}
/**
* Store new preferences.
*
- * @param Request $request
+ * @return Redirector|RedirectResponse
*
- * @return RedirectResponse|Redirector
* @throws FireflyException
- * @throws ContainerExceptionInterface
- * @throws NotFoundExceptionInterface
+ *
+ * @SuppressWarnings(PHPMD.ExcessiveMethodLength)
+ * @SuppressWarnings(PHPMD.NPathComplexity)
*/
public function postIndex(Request $request)
{
@@ -186,7 +164,7 @@ class PreferencesController extends Controller
}
// extract notifications:
- $all = $request->all();
+ $all = $request->all();
foreach (config('firefly.available_notifications') as $option) {
$key = sprintf('notification_%s', $option);
if (array_key_exists($key, $all)) {
@@ -204,7 +182,6 @@ class PreferencesController extends Controller
session()->forget('end');
session()->forget('range');
-
// slack URL:
if (!auth()->user()->hasRole('demo')) {
$url = (string)$request->get('slackUrl');
@@ -217,26 +194,25 @@ class PreferencesController extends Controller
}
// custom fiscal year
- $customFiscalYear = 1 === (int)$request->get('customFiscalYear');
- $string = strtotime((string)$request->get('fiscalYearStart'));
+ $customFiscalYear = 1 === (int)$request->get('customFiscalYear');
+ $string = strtotime((string)$request->get('fiscalYearStart'));
if (false !== $string) {
$fiscalYearStart = date('m-d', $string);
app('preferences')->set('customFiscalYear', $customFiscalYear);
app('preferences')->set('fiscalYearStart', $fiscalYearStart);
}
-
// save page size:
app('preferences')->set('listPageSize', 50);
- $listPageSize = (int)$request->get('listPageSize');
+ $listPageSize = (int)$request->get('listPageSize');
if ($listPageSize > 0 && $listPageSize < 1337) {
app('preferences')->set('listPageSize', $listPageSize);
}
// language:
/** @var Preference $currentLang */
- $currentLang = app('preferences')->get('language', 'en_US');
- $lang = $request->get('language');
+ $currentLang = app('preferences')->get('language', 'en_US');
+ $lang = $request->get('language');
if (array_key_exists($lang, config('firefly.languages'))) {
app('preferences')->set('language', $lang);
}
@@ -253,8 +229,8 @@ class PreferencesController extends Controller
}
// optional fields for transactions:
- $setOptions = $request->get('tj') ?? [];
- $optionalTj = [
+ $setOptions = $request->get('tj') ?? [];
+ $optionalTj = [
'interest_date' => array_key_exists('interest_date', $setOptions),
'book_date' => array_key_exists('book_date', $setOptions),
'process_date' => array_key_exists('process_date', $setOptions),
@@ -271,7 +247,7 @@ class PreferencesController extends Controller
app('preferences')->set('transaction_journal_optional_fields', $optionalTj);
// dark mode
- $darkMode = $request->get('darkMode') ?? 'browser';
+ $darkMode = $request->get('darkMode') ?? 'browser';
if (in_array($darkMode, config('firefly.available_dark_modes'), true)) {
app('preferences')->set('darkMode', $darkMode);
}
diff --git a/app/Http/Controllers/ProfileController.php b/app/Http/Controllers/ProfileController.php
index 59b624fac6..858114a198 100644
--- a/app/Http/Controllers/ProfileController.php
+++ b/app/Http/Controllers/ProfileController.php
@@ -24,8 +24,6 @@ declare(strict_types=1);
namespace FireflyIII\Http\Controllers;
use Auth;
-use DB;
-use Exception;
use FireflyIII\Events\UserChangedEmail;
use FireflyIII\Exceptions\FireflyException;
use FireflyIII\Exceptions\ValidationException;
@@ -36,11 +34,8 @@ use FireflyIII\Http\Requests\ProfileFormRequest;
use FireflyIII\Http\Requests\TokenFormRequest;
use FireflyIII\Models\Preference;
use FireflyIII\Repositories\User\UserRepositoryInterface;
-use FireflyIII\Support\Facades\Preferences;
use FireflyIII\Support\Http\Controllers\CreateStuff;
use FireflyIII\User;
-use Google2FA;
-use Hash;
use Illuminate\Auth\AuthenticationException;
use Illuminate\Contracts\Auth\Guard;
use Illuminate\Contracts\Foundation\Application;
@@ -49,21 +44,17 @@ use Illuminate\Http\RedirectResponse;
use Illuminate\Http\Request;
use Illuminate\Routing\Redirector;
use Illuminate\Support\Collection;
-use Illuminate\Support\Facades\Log;
use Illuminate\View\View;
use Laravel\Passport\ClientRepository;
use PragmaRX\Google2FA\Exceptions\IncompatibleWithGoogleAuthenticatorException;
use PragmaRX\Google2FA\Exceptions\InvalidCharactersException;
use PragmaRX\Google2FA\Exceptions\SecretKeyTooShortException;
use PragmaRX\Recovery\Recovery;
-use Psr\Container\ContainerExceptionInterface;
-use Psr\Container\NotFoundExceptionInterface;
/**
* Class ProfileController.
*
* @method Guard guard()
- *
*/
class ProfileController extends Controller
{
@@ -73,8 +64,6 @@ class ProfileController extends Controller
/**
* ProfileController constructor.
- *
-
*/
public function __construct()
{
@@ -90,7 +79,7 @@ class ProfileController extends Controller
);
$authGuard = config('firefly.authentication_guard');
$this->internalAuth = 'web' === $authGuard;
- Log::debug(sprintf('ProfileController::__construct(). Authentication guard is "%s"', $authGuard));
+ app('log')->debug(sprintf('ProfileController::__construct(). Authentication guard is "%s"', $authGuard));
$this->middleware(IsDemoUser::class)->except(['index']);
}
@@ -98,16 +87,11 @@ class ProfileController extends Controller
/**
* View that generates a 2FA code for the user.
*
- * @param Request $request
- *
- * @return Factory|View|RedirectResponse
* @throws IncompatibleWithGoogleAuthenticatorException
* @throws InvalidCharactersException
* @throws SecretKeyTooShortException
- * @throws ContainerExceptionInterface
- * @throws NotFoundExceptionInterface
*/
- public function code(Request $request): Factory | View | RedirectResponse
+ public function code(Request $request): Factory|RedirectResponse|View
{
if (!$this->internalAuth) {
$request->session()->flash('error', trans('firefly.external_user_mgt_disabled'));
@@ -115,14 +99,14 @@ class ProfileController extends Controller
return redirect(route('profile.index'));
}
$domain = $this->getDomain();
- $secretPreference = Preferences::get('temp-mfa-secret');
- $codesPreference = Preferences::get('temp-mfa-codes');
+ $secretPreference = app('preferences')->get('temp-mfa-secret');
+ $codesPreference = app('preferences')->get('temp-mfa-codes');
// generate secret if not in session
if (null === $secretPreference) {
// generate secret + store + flash
- $secret = Google2FA::generateSecretKey();
- Preferences::set('temp-mfa-secret', $secret);
+ $secret = \Google2FA::generateSecretKey();
+ app('preferences')->set('temp-mfa-secret', $secret);
}
// re-use secret if in session
@@ -130,25 +114,31 @@ class ProfileController extends Controller
// get secret from session and flash
$secret = $secretPreference->data;
}
+ if (is_array($secret)) {
+ $secret = '';
+ }
// generate recovery codes if not in session:
- $recoveryCodes = '';
+ $recoveryCodes = '';
if (null === $codesPreference) {
// generate codes + store + flash:
$recovery = app(Recovery::class);
$recoveryCodes = $recovery->lowercase()->setCount(8)->setBlocks(2)->setChars(6)->toArray();
- Preferences::set('temp-mfa-codes', $recoveryCodes);
+ app('preferences')->set('temp-mfa-codes', $recoveryCodes);
}
// get codes from session if present already:
if (null !== $codesPreference) {
$recoveryCodes = $codesPreference->data;
}
+ if (!is_array($recoveryCodes)) {
+ $recoveryCodes = [];
+ }
- $codes = implode("\r\n", $recoveryCodes);
+ $codes = implode("\r\n", $recoveryCodes);
- $image = Google2FA::getQRCodeInline($domain, auth()->user()->email, $secret);
+ $image = \Google2FA::getQRCodeInline($domain, auth()->user()->email, (string)$secret);
return view('profile.code', compact('image', 'secret', 'codes'));
}
@@ -156,22 +146,19 @@ class ProfileController extends Controller
/**
* Screen to confirm email change.
*
- * @param UserRepositoryInterface $repository
- * @param string $token
- *
- * @return RedirectResponse|Redirector
- *
* @throws FireflyException
*/
- public function confirmEmailChange(UserRepositoryInterface $repository, string $token): RedirectResponse | Redirector
+ public function confirmEmailChange(UserRepositoryInterface $repository, string $token): Redirector|RedirectResponse
{
if (!$this->internalAuth) {
throw new FireflyException(trans('firefly.external_user_mgt_disabled'));
}
+
// find preference with this token value.
/** @var Collection $set */
$set = app('preferences')->findByName('email_change_confirm_token');
$user = null;
+
/** @var Preference $preference */
foreach ($set as $preference) {
if ($preference->data === $token) {
@@ -192,12 +179,8 @@ class ProfileController extends Controller
/**
* Delete your account view.
- *
- * @param Request $request
- *
- * @return View|RedirectResponse
*/
- public function deleteAccount(Request $request): View | RedirectResponse
+ public function deleteAccount(Request $request): RedirectResponse|View
{
if (!$this->internalAuth) {
$request->session()->flash('error', trans('firefly.external_user_mgt_disabled'));
@@ -213,23 +196,23 @@ class ProfileController extends Controller
/**
* Delete 2FA routine.
- *
*/
- public function deleteCode(Request $request): RedirectResponse | Redirector
+ public function deleteCode(Request $request): Redirector|RedirectResponse
{
if (!$this->internalAuth) {
$request->session()->flash('error', trans('firefly.external_user_mgt_disabled'));
return redirect(route('profile.index'));
}
+
/** @var UserRepositoryInterface $repository */
$repository = app(UserRepositoryInterface::class);
/** @var User $user */
- $user = auth()->user();
+ $user = auth()->user();
- Preferences::delete('temp-mfa-secret');
- Preferences::delete('temp-mfa-codes');
+ app('preferences')->delete('temp-mfa-secret');
+ app('preferences')->delete('temp-mfa-codes');
$repository->setMFACode($user, null);
app('preferences')->mark();
@@ -241,9 +224,8 @@ class ProfileController extends Controller
/**
* Enable 2FA screen.
- *
*/
- public function enable2FA(Request $request): RedirectResponse | Redirector
+ public function enable2FA(Request $request): Redirector|RedirectResponse
{
if (!$this->internalAuth) {
$request->session()->flash('error', trans('firefly.external_user_mgt_disabled'));
@@ -270,30 +252,31 @@ class ProfileController extends Controller
/**
* Index for profile.
*
- * @return Factory|View
* @throws FireflyException
- * @throws ContainerExceptionInterface
- * @throws NotFoundExceptionInterface
*/
- public function index(): Factory | View
+ public function index(): Factory|View
{
/** @var User $user */
$user = auth()->user();
$isInternalAuth = $this->internalAuth;
- $count = DB::table('oauth_clients')->where('personal_access_client', true)->whereNull('user_id')->count();
+ $count = \DB::table('oauth_clients')->where('personal_access_client', true)->whereNull('user_id')->count();
$subTitle = $user->email;
$userId = $user->id;
$enabled2FA = null !== $user->mfa_secret;
- $mfaBackupCount = count(app('preferences')->get('mfa_recovery', [])->data);
+ $recoveryData = app('preferences')->get('mfa_recovery', [])->data;
+ if (!is_array($recoveryData)) {
+ $recoveryData = [];
+ }
+ $mfaBackupCount = count($recoveryData);
$this->createOAuthKeys();
if (0 === $count) {
/** @var ClientRepository $repository */
$repository = app(ClientRepository::class);
- $repository->createPersonalAccessClient(null, config('app.name') . ' Personal Access Client', 'http://localhost');
+ $repository->createPersonalAccessClient(null, config('app.name').' Personal Access Client', 'http://localhost');
}
- $accessToken = app('preferences')->get('access_token');
+ $accessToken = app('preferences')->get('access_token');
if (null === $accessToken) {
$token = $user->generateAccessToken();
$accessToken = app('preferences')->set('access_token', $token);
@@ -305,10 +288,7 @@ class ProfileController extends Controller
);
}
- /**
- * @return Factory|View|RedirectResponse
- */
- public function logoutOtherSessions(): Factory | View | RedirectResponse
+ public function logoutOtherSessions(): Factory|RedirectResponse|View
{
if (!$this->internalAuth) {
session()->flash('info', (string)trans('firefly.external_auth_disabled'));
@@ -320,12 +300,9 @@ class ProfileController extends Controller
}
/**
- * @param Request $request
- *
- * @return Factory|View|RedirectResponse
* @throws FireflyException
*/
- public function newBackupCodes(Request $request): Factory | View | RedirectResponse
+ public function newBackupCodes(Request $request): Factory|RedirectResponse|View
{
if (!$this->internalAuth) {
$request->session()->flash('error', trans('firefly.external_user_mgt_disabled'));
@@ -336,10 +313,11 @@ class ProfileController extends Controller
// generate recovery codes:
$recovery = app(Recovery::class);
$recoveryCodes = $recovery->lowercase()
- ->setCount(8) // Generate 8 codes
- ->setBlocks(2) // Every code must have 7 blocks
- ->setChars(6) // Each block must have 16 chars
- ->toArray();
+ ->setCount(8) // Generate 8 codes
+ ->setBlocks(2) // Every code must have 7 blocks
+ ->setChars(6) // Each block must have 16 chars
+ ->toArray()
+ ;
$codes = implode("\r\n", $recoveryCodes);
app('preferences')->set('mfa_recovery', $recoveryCodes);
@@ -350,13 +328,8 @@ class ProfileController extends Controller
/**
* Submit the change email form.
- *
- * @param EmailFormRequest $request
- * @param UserRepositoryInterface $repository
- *
- * @return Factory|RedirectResponse|Redirector
*/
- public function postChangeEmail(EmailFormRequest $request, UserRepositoryInterface $repository): Factory | RedirectResponse | Redirector
+ public function postChangeEmail(EmailFormRequest $request, UserRepositoryInterface $repository): Factory|Redirector|RedirectResponse
{
if (!$this->internalAuth) {
$request->session()->flash('error', trans('firefly.external_user_mgt_disabled'));
@@ -376,7 +349,7 @@ class ProfileController extends Controller
$existing = $repository->findByEmail($newEmail);
if (null !== $existing) {
// force user logout.
- Auth::guard()->logout(); // @phpstan-ignore-line (does not recognize function)
+ \Auth::guard()->logout(); // @phpstan-ignore-line (does not recognize function)
$request->session()->invalidate();
session()->flash('success', (string)trans('firefly.email_changed'));
@@ -390,7 +363,7 @@ class ProfileController extends Controller
event(new UserChangedEmail($user, $newEmail, $oldEmail));
// force user logout.
- Auth::guard()->logout(); // @phpstan-ignore-line (does not recognize function)
+ \Auth::guard()->logout(); // @phpstan-ignore-line (does not recognize function)
$request->session()->invalidate();
session()->flash('success', (string)trans('firefly.email_changed'));
@@ -399,12 +372,8 @@ class ProfileController extends Controller
/**
* Change your email address.
- *
- * @param Request $request
- *
- * @return Factory|RedirectResponse|View
*/
- public function changeEmail(Request $request): Factory | RedirectResponse | View
+ public function changeEmail(Request $request): Factory|RedirectResponse|View
{
if (!$this->internalAuth) {
$request->session()->flash('error', trans('firefly.external_user_mgt_disabled'));
@@ -423,10 +392,7 @@ class ProfileController extends Controller
/**
* Submit change password form.
*
- * @param ProfileFormRequest $request
- * @param UserRepositoryInterface $repository
- *
- * @return RedirectResponse|Redirector
+ * @return Redirector|RedirectResponse
*/
public function postChangePassword(ProfileFormRequest $request, UserRepositoryInterface $repository)
{
@@ -439,8 +405,10 @@ class ProfileController extends Controller
// the request has already validated both new passwords must be equal.
$current = $request->get('current_password');
$new = $request->get('new_password');
+
/** @var User $user */
- $user = auth()->user();
+ $user = auth()->user();
+
try {
$this->validatePassword($user, $current, $new);
} catch (ValidationException $e) {
@@ -458,9 +426,7 @@ class ProfileController extends Controller
/**
* Change your password.
*
- * @param Request $request
- *
- * @return Factory|RedirectResponse|Redirector|View
+ * @return Factory|Redirector|RedirectResponse|View
*/
public function changePassword(Request $request)
{
@@ -480,12 +446,9 @@ class ProfileController extends Controller
/**
* Submit 2FA for the first time.
*
- * @param TokenFormRequest $request
+ * @return Redirector|RedirectResponse
*
- * @return RedirectResponse|Redirector
* @throws FireflyException
- * @throws ContainerExceptionInterface
- * @throws NotFoundExceptionInterface
*/
public function postCode(TokenFormRequest $request)
{
@@ -496,21 +459,28 @@ class ProfileController extends Controller
}
/** @var User $user */
- $user = auth()->user();
+ $user = auth()->user();
+
/** @var UserRepositoryInterface $repository */
$repository = app(UserRepositoryInterface::class);
- $secret = Preferences::get('temp-mfa-secret')?->data;
+ $secret = app('preferences')->get('temp-mfa-secret')?->data;
+ if (is_array($secret)) {
+ $secret = null;
+ }
+ if (is_int($secret)) {
+ $secret = (string)$secret;
+ }
$repository->setMFACode($user, $secret);
- Preferences::delete('temp-mfa-secret');
- Preferences::delete('temp-mfa-codes');
+ app('preferences')->delete('temp-mfa-secret');
+ app('preferences')->delete('temp-mfa-codes');
session()->flash('success', (string)trans('firefly.saved_preferences'));
app('preferences')->mark();
// also save the code so replay attack is prevented.
- $mfaCode = $request->get('code');
+ $mfaCode = $request->get('code');
$this->addToMFAHistory($mfaCode);
// save backup codes in preferences:
@@ -518,7 +488,7 @@ class ProfileController extends Controller
// make sure MFA is logged out.
if ('testing' !== config('app.env')) {
- Google2FA::logout();
+ \Google2FA::logout();
}
// drop all info from session:
@@ -530,11 +500,7 @@ class ProfileController extends Controller
/**
* TODO duplicate code.
*
- * @param string $mfaCode
- *
* @throws FireflyException
- * @throws ContainerExceptionInterface
- * @throws NotFoundExceptionInterface
*/
private function addToMFAHistory(string $mfaCode): void
{
@@ -575,10 +541,7 @@ class ProfileController extends Controller
/**
* Submit delete account.
*
- * @param UserRepositoryInterface $repository
- * @param DeleteAccountFormRequest $request
- *
- * @return RedirectResponse|Redirector
+ * @return Redirector|RedirectResponse
*/
public function postDeleteAccount(UserRepositoryInterface $repository, DeleteAccountFormRequest $request)
{
@@ -588,14 +551,15 @@ class ProfileController extends Controller
return redirect(route('profile.index'));
}
- if (!Hash::check($request->get('password'), auth()->user()->password)) {
+ if (!\Hash::check($request->get('password'), auth()->user()->password)) {
session()->flash('error', (string)trans('firefly.invalid_password'));
return redirect(route('profile.delete-account'));
}
+
/** @var User $user */
$user = auth()->user();
- Log::info(sprintf('User #%d has opted to delete their account', auth()->user()->id));
+ app('log')->info(sprintf('User #%d has opted to delete their account', auth()->user()->id));
// make repository delete user:
auth()->logout();
session()->flush();
@@ -605,9 +569,8 @@ class ProfileController extends Controller
}
/**
- * @param Request $request
+ * @return Application|Redirector|RedirectResponse
*
- * @return Application|RedirectResponse|Redirector
* @throws AuthenticationException
*/
public function postLogoutOtherSessions(Request $request)
@@ -621,8 +584,8 @@ class ProfileController extends Controller
'email' => auth()->user()->email,
'password' => $request->get('password'),
];
- if (Auth::once($creds)) {
- Auth::logoutOtherDevices($request->get('password'));
+ if (\Auth::once($creds)) {
+ \Auth::logoutOtherDevices($request->get('password'));
session()->flash('info', (string)trans('firefly.other_sessions_logged_out'));
return redirect(route('profile.index'));
@@ -635,10 +598,9 @@ class ProfileController extends Controller
/**
* Regenerate access token.
*
- * @param Request $request
+ * @return Redirector|RedirectResponse
*
- * @return RedirectResponse|Redirector
- * @throws Exception
+ * @throws \Exception
*/
public function regenerate(Request $request)
{
@@ -660,11 +622,7 @@ class ProfileController extends Controller
/**
* Undo change of user email address.
*
- * @param UserRepositoryInterface $repository
- * @param string $token
- * @param string $hash
- *
- * @return RedirectResponse|Redirector
+ * @return Redirector|RedirectResponse
*
* @throws FireflyException
*/
@@ -675,8 +633,9 @@ class ProfileController extends Controller
}
// find preference with this token value.
- $set = app('preferences')->findByName('email_change_undo_token');
- $user = null;
+ $set = app('preferences')->findByName('email_change_undo_token');
+ $user = null;
+
/** @var Preference $preference */
foreach ($set as $preference) {
if ($preference->data === $token) {
@@ -688,13 +647,15 @@ class ProfileController extends Controller
}
// found user.which email address to return to?
- $set = app('preferences')->beginsWith($user, 'previous_email_');
+ $set = app('preferences')->beginsWith($user, 'previous_email_');
+
/** @var string $match */
$match = null;
foreach ($set as $entry) {
$hashed = hash('sha256', sprintf('%s%s', (string)config('app.key'), $entry->data));
if ($hashed === $hash) {
$match = $entry->data;
+
break;
}
}
diff --git a/app/Http/Controllers/Recurring/CreateController.php b/app/Http/Controllers/Recurring/CreateController.php
index ac51114be3..af0aa56cc1 100644
--- a/app/Http/Controllers/Recurring/CreateController.php
+++ b/app/Http/Controllers/Recurring/CreateController.php
@@ -37,10 +37,10 @@ use Illuminate\Contracts\View\Factory;
use Illuminate\Http\RedirectResponse;
use Illuminate\Http\Request;
use Illuminate\Routing\Redirector;
+use Illuminate\Support\Facades\Log;
use Illuminate\View\View;
/**
- *
* Class CreateController
*/
class CreateController extends Controller
@@ -52,8 +52,6 @@ class CreateController extends Controller
/**
* CreateController constructor.
- *
-
*/
public function __construct()
{
@@ -79,8 +77,6 @@ class CreateController extends Controller
/**
* Create a new recurring transaction.
*
- * @param Request $request
- *
* @return Factory|View
*/
public function create(Request $request)
@@ -97,19 +93,19 @@ class CreateController extends Controller
$this->rememberPreviousUrl('recurring.create.url');
}
$request->session()->forget('recurring.create.fromStore');
- $repetitionEnds = [
+ $repetitionEnds = [
'forever' => (string)trans('firefly.repeat_forever'),
'until_date' => (string)trans('firefly.repeat_until_date'),
'times' => (string)trans('firefly.repeat_times'),
];
- $weekendResponses = [
+ $weekendResponses = [
RecurrenceRepetition::WEEKEND_DO_NOTHING => (string)trans('firefly.do_nothing'),
RecurrenceRepetition::WEEKEND_SKIP_CREATION => (string)trans('firefly.skip_transaction'),
RecurrenceRepetition::WEEKEND_TO_FRIDAY => (string)trans('firefly.jump_to_friday'),
RecurrenceRepetition::WEEKEND_TO_MONDAY => (string)trans('firefly.jump_to_monday'),
];
- $hasOldInput = null !== $request->old('_token'); // flash some data
- $preFilled = [
+ $hasOldInput = null !== $request->old('_token'); // flash some data
+ $preFilled = [
'first_date' => $tomorrow->format('Y-m-d'),
'transaction_type' => $hasOldInput ? $request->old('transaction_type') : 'withdrawal',
'active' => $hasOldInput ? (bool)$request->old('active') : true,
@@ -124,10 +120,9 @@ class CreateController extends Controller
}
/**
- * @param Request $request
- * @param TransactionJournal $journal
- *
* @return Factory|\Illuminate\Contracts\View\View
+ *
+ * @SuppressWarnings(PHPMD.ExcessiveMethodLength)
*/
public function createFromJournal(Request $request, TransactionJournal $journal)
{
@@ -143,31 +138,31 @@ class CreateController extends Controller
$this->rememberPreviousUrl('recurring.create.url');
}
$request->session()->forget('recurring.create.fromStore');
- $repetitionEnds = [
+ $repetitionEnds = [
'forever' => (string)trans('firefly.repeat_forever'),
'until_date' => (string)trans('firefly.repeat_until_date'),
'times' => (string)trans('firefly.repeat_times'),
];
- $weekendResponses = [
+ $weekendResponses = [
RecurrenceRepetition::WEEKEND_DO_NOTHING => (string)trans('firefly.do_nothing'),
RecurrenceRepetition::WEEKEND_SKIP_CREATION => (string)trans('firefly.skip_transaction'),
RecurrenceRepetition::WEEKEND_TO_FRIDAY => (string)trans('firefly.jump_to_friday'),
RecurrenceRepetition::WEEKEND_TO_MONDAY => (string)trans('firefly.jump_to_monday'),
];
-
// fill prefilled with journal info
- $type = strtolower($journal->transactionType->type);
+ $type = strtolower($journal->transactionType->type);
/** @var Transaction $source */
- $source = $journal->transactions()->where('amount', '<', 0)->first();
+ $source = $journal->transactions()->where('amount', '<', 0)->first();
+
/** @var Transaction $dest */
- $dest = $journal->transactions()->where('amount', '>', 0)->first();
- $category = $journal->categories()->first() ? $journal->categories()->first()->name : '';
- $budget = $journal->budgets()->first() ? $journal->budgets()->first()->id : 0;
- $bill = $journal->bill ? $journal->bill->id : 0;
- $hasOldInput = null !== $request->old('_token'); // flash some data
- $preFilled = [];
+ $dest = $journal->transactions()->where('amount', '>', 0)->first();
+ $category = null !== $journal->categories()->first() ? $journal->categories()->first()->name : '';
+ $budget = null !== $journal->budgets()->first() ? $journal->budgets()->first()->id : 0;
+ $bill = null !== $journal->bill ? $journal->bill->id : 0;
+ $hasOldInput = null !== $request->old('_token'); // flash some data
+ $preFilled = [];
if (true === $hasOldInput) {
$preFilled = [
'title' => $request->old('title'),
@@ -221,14 +216,14 @@ class CreateController extends Controller
/**
* Store a recurring transaction.
*
- * @param RecurrenceFormRequest $request
+ * @return Redirector|RedirectResponse
*
- * @return RedirectResponse|Redirector
* @throws FireflyException
*/
public function store(RecurrenceFormRequest $request)
{
- $data = $request->getAll();
+ $data = $request->getAll();
+
try {
$recurrence = $this->recurring->store($data);
} catch (FireflyException $e) {
@@ -236,17 +231,19 @@ class CreateController extends Controller
return redirect(route('recurring.create'))->withInput();
}
+ Log::channel('audit')->info('Stored new recurrence.', $data);
$request->session()->flash('success', (string)trans('firefly.stored_new_recurrence', ['title' => $recurrence->title]));
app('preferences')->mark();
// store attachment(s):
- /** @var array $files */
- $files = $request->hasFile('attachments') ? $request->file('attachments') : null;
+ /** @var null|array $files */
+ $files = $request->hasFile('attachments') ? $request->file('attachments') : null;
if (null !== $files && !auth()->user()->hasRole('demo')) {
$this->attachments->saveAttachmentsForModel($recurrence, $files);
}
if (null !== $files && auth()->user()->hasRole('demo')) {
+ Log::channel('audit')->warning(sprintf('The demo user is trying to upload attachments in %s.', __METHOD__));
session()->flash('info', (string)trans('firefly.no_att_demo_user'));
}
diff --git a/app/Http/Controllers/Recurring/DeleteController.php b/app/Http/Controllers/Recurring/DeleteController.php
index 829ae2b9fe..e1495e0995 100644
--- a/app/Http/Controllers/Recurring/DeleteController.php
+++ b/app/Http/Controllers/Recurring/DeleteController.php
@@ -42,8 +42,6 @@ class DeleteController extends Controller
/**
* DeleteController constructor.
- *
-
*/
public function __construct()
{
@@ -65,13 +63,11 @@ class DeleteController extends Controller
/**
* Delete a recurring transaction form.
*
- * @param Recurrence $recurrence
- *
* @return Factory|View
*/
public function delete(Recurrence $recurrence)
{
- $subTitle = (string)trans('firefly.delete_recurring', ['title' => $recurrence->title]);
+ $subTitle = (string)trans('firefly.delete_recurring', ['title' => $recurrence->title]);
// put previous url in session
$this->rememberPreviousUrl('recurrences.delete.url');
@@ -83,16 +79,12 @@ class DeleteController extends Controller
/**
* Destroy the recurring transaction.
*
- * @param RecurringRepositoryInterface $repository
- * @param Request $request
- * @param Recurrence $recurrence
- *
- * @return RedirectResponse|Redirector
+ * @return Redirector|RedirectResponse
*/
public function destroy(RecurringRepositoryInterface $repository, Request $request, Recurrence $recurrence)
{
$repository->destroy($recurrence);
- $request->session()->flash('success', (string)trans('firefly.' . 'recurrence_deleted', ['title' => $recurrence->title]));
+ $request->session()->flash('success', (string)trans('firefly.recurrence_deleted', ['title' => $recurrence->title]));
app('preferences')->mark();
return redirect($this->getPreviousUrl('recurrences.delete.url'));
diff --git a/app/Http/Controllers/Recurring/EditController.php b/app/Http/Controllers/Recurring/EditController.php
index f61ae3ac60..7cf6578904 100644
--- a/app/Http/Controllers/Recurring/EditController.php
+++ b/app/Http/Controllers/Recurring/EditController.php
@@ -37,11 +37,11 @@ use Illuminate\Contracts\View\Factory;
use Illuminate\Http\RedirectResponse;
use Illuminate\Http\Request;
use Illuminate\Routing\Redirector;
+use Illuminate\Support\Facades\Log;
use Illuminate\View\View;
use Symfony\Component\HttpFoundation\ParameterBag;
/**
- *
* Class EditController
*/
class EditController extends Controller
@@ -53,8 +53,6 @@ class EditController extends Controller
/**
* EditController constructor.
- *
-
*/
public function __construct()
{
@@ -80,34 +78,31 @@ class EditController extends Controller
/**
* Edit a recurring transaction.
*
- * @param Request $request
- * @param Recurrence $recurrence
- *
* @return Factory|View
- * @throws FireflyException
*
+ * @throws FireflyException
*/
public function edit(Request $request, Recurrence $recurrence)
{
// TODO this should be in the repository.
- $count = $recurrence->recurrenceTransactions()->count();
+ $count = $recurrence->recurrenceTransactions()->count();
if (0 === $count) {
throw new FireflyException('This recurring transaction has no meta-data. You will have to delete it and recreate it. Sorry!');
}
/** @var RecurrenceTransformer $transformer */
- $transformer = app(RecurrenceTransformer::class);
+ $transformer = app(RecurrenceTransformer::class);
$transformer->setParameters(new ParameterBag());
- $array = $transformer->transform($recurrence);
- $budgets = app('expandedform')->makeSelectListWithEmpty($this->budgetRepos->getActiveBudgets());
- $bills = app('expandedform')->makeSelectListWithEmpty($this->billRepository->getActiveBills());
+ $array = $transformer->transform($recurrence);
+ $budgets = app('expandedform')->makeSelectListWithEmpty($this->budgetRepos->getActiveBudgets());
+ $bills = app('expandedform')->makeSelectListWithEmpty($this->billRepository->getActiveBills());
/** @var RecurrenceRepetition $repetition */
- $repetition = $recurrence->recurrenceRepetitions()->first();
- $currentRepType = $repetition->repetition_type;
+ $repetition = $recurrence->recurrenceRepetitions()->first();
+ $currentRepType = $repetition->repetition_type;
if ('' !== $repetition->repetition_moment) {
- $currentRepType .= ',' . $repetition->repetition_moment;
+ $currentRepType .= ','.$repetition->repetition_moment;
}
// put previous url in session if not redirect from store (not "return_to_edit").
@@ -116,8 +111,8 @@ class EditController extends Controller
}
$request->session()->forget('recurrences.edit.fromUpdate');
- $repetitionEnd = 'forever';
- $repetitionEnds = [
+ $repetitionEnd = 'forever';
+ $repetitionEnds = [
'forever' => (string)trans('firefly.repeat_forever'),
'until_date' => (string)trans('firefly.repeat_until_date'),
'times' => (string)trans('firefly.repeat_times'),
@@ -129,7 +124,7 @@ class EditController extends Controller
$repetitionEnd = 'times';
}
- $weekendResponses = [
+ $weekendResponses = [
RecurrenceRepetition::WEEKEND_DO_NOTHING => (string)trans('firefly.do_nothing'),
RecurrenceRepetition::WEEKEND_SKIP_CREATION => (string)trans('firefly.skip_transaction'),
RecurrenceRepetition::WEEKEND_TO_FRIDAY => (string)trans('firefly.jump_to_friday'),
@@ -167,25 +162,26 @@ class EditController extends Controller
/**
* Update the recurring transaction.
*
- * @param RecurrenceFormRequest $request
- * @param Recurrence $recurrence
+ * @return Redirector|RedirectResponse
*
- * @return RedirectResponse|Redirector
* @throws FireflyException
*/
public function update(RecurrenceFormRequest $request, Recurrence $recurrence)
{
- $data = $request->getAll();
+ $data = $request->getAll();
$this->recurring->update($recurrence, $data);
$request->session()->flash('success', (string)trans('firefly.updated_recurrence', ['title' => $recurrence->title]));
+ Log::channel('audit')->info(sprintf('Updated recurrence #%d.', $recurrence->id), $data);
// store new attachment(s):
- $files = $request->hasFile('attachments') ? $request->file('attachments') : null;
+ /** @var null|array $files */
+ $files = $request->hasFile('attachments') ? $request->file('attachments') : null;
if (null !== $files && !auth()->user()->hasRole('demo')) {
$this->attachments->saveAttachmentsForModel($recurrence, $files);
}
if (null !== $files && auth()->user()->hasRole('demo')) {
+ Log::channel('audit')->warning(sprintf('The demo user is trying to upload attachments in %s.', __METHOD__));
session()->flash('info', (string)trans('firefly.no_att_demo_user'));
}
diff --git a/app/Http/Controllers/Recurring/IndexController.php b/app/Http/Controllers/Recurring/IndexController.php
index c7af4775b4..ed2e3775ba 100644
--- a/app/Http/Controllers/Recurring/IndexController.php
+++ b/app/Http/Controllers/Recurring/IndexController.php
@@ -34,12 +34,9 @@ use Illuminate\Contracts\View\Factory;
use Illuminate\Http\Request;
use Illuminate\Pagination\LengthAwarePaginator;
use Illuminate\View\View;
-use Psr\Container\ContainerExceptionInterface;
-use Psr\Container\NotFoundExceptionInterface;
use Symfony\Component\HttpFoundation\ParameterBag;
/**
- *
* Class IndexController
*/
class IndexController extends Controller
@@ -50,8 +47,6 @@ class IndexController extends Controller
/**
* IndexController constructor.
- *
-
*/
public function __construct()
{
@@ -74,20 +69,17 @@ class IndexController extends Controller
* TODO the notes of a recurrence are pretty pointless at this moment.
* Show all recurring transactions.
*
- * @param Request $request
- *
* @return Factory|View
+ *
* @throws FireflyException
- * @throws ContainerExceptionInterface
- * @throws NotFoundExceptionInterface
*/
public function index(Request $request)
{
- $page = 0 === (int)$request->get('page') ? 1 : (int)$request->get('page');
- $pageSize = (int)app('preferences')->get('listPageSize', 50)->data;
- $collection = $this->recurringRepos->get();
- $today = today(config('app.timezone'));
- $year = today(config('app.timezone'));
+ $page = 0 === (int)$request->get('page') ? 1 : (int)$request->get('page');
+ $pageSize = (int)app('preferences')->get('listPageSize', 50)->data;
+ $collection = $this->recurringRepos->get();
+ $today = today(config('app.timezone'));
+ $year = today(config('app.timezone'));
// split collection
$total = $collection->count();
@@ -97,7 +89,8 @@ class IndexController extends Controller
$transformer = app(RecurrenceTransformer::class);
$transformer->setParameters(new ParameterBag());
- $recurring = [];
+ $recurring = [];
+
/** @var Recurrence $recurrence */
foreach ($recurrences as $recurrence) {
$year->addYear();
@@ -111,7 +104,7 @@ class IndexController extends Controller
$array['repeat_until'] = null === $array['repeat_until'] ? null : new Carbon($array['repeat_until']);
$array['latest_date'] = null === $array['latest_date'] ? null : new Carbon($array['latest_date']);
// lazy but OK
- $array['attachments'] = $recurrence->attachments()->count();
+ $array['attachments'] = $recurrence->attachments()->count();
// make carbon objects out of occurrences
foreach ($array['repetitions'] as $repIndex => $repetition) {
@@ -120,11 +113,11 @@ class IndexController extends Controller
}
}
- $recurring[] = $array;
+ $recurring[] = $array;
}
- $paginator = new LengthAwarePaginator($recurring, $total, $pageSize, $page);
+ $paginator = new LengthAwarePaginator($recurring, $total, $pageSize, $page);
$paginator->setPath(route('recurring.index'));
- $today = today(config('app.timezone'));
+ $today = today(config('app.timezone'));
$this->verifyRecurringCronJob();
diff --git a/app/Http/Controllers/Recurring/ShowController.php b/app/Http/Controllers/Recurring/ShowController.php
index fa9b4a2445..09863759f1 100644
--- a/app/Http/Controllers/Recurring/ShowController.php
+++ b/app/Http/Controllers/Recurring/ShowController.php
@@ -38,7 +38,6 @@ use Illuminate\View\View;
use Symfony\Component\HttpFoundation\ParameterBag;
/**
- *
* Class ShowController
*/
class ShowController extends Controller
@@ -50,8 +49,6 @@ class ShowController extends Controller
/**
* IndexController constructor.
- *
-
*/
public function __construct()
{
@@ -74,16 +71,16 @@ class ShowController extends Controller
/**
* Show a single recurring transaction.
*
- * @param Recurrence $recurrence
- *
* @return Factory|View
+ *
* @throws FireflyException
*/
public function show(Recurrence $recurrence)
{
- $repos = app(AttachmentRepositoryInterface::class);
+ $repos = app(AttachmentRepositoryInterface::class);
+
/** @var RecurrenceTransformer $transformer */
- $transformer = app(RecurrenceTransformer::class);
+ $transformer = app(RecurrenceTransformer::class);
$transformer->setParameters(new ParameterBag());
$array = $transformer->transform($recurrence);
@@ -108,15 +105,15 @@ class ShowController extends Controller
$attachments = $recurrence->attachments()->get();
$array['attachments'] = [];
$attachmentTransformer = app(AttachmentTransformer::class);
+
/** @var Attachment $attachment */
foreach ($attachments as $attachment) {
$item = $attachmentTransformer->transform($attachment);
$item['file_exists'] = $repos->exists($attachment); // TODO this should be part of the transformer
$array['attachments'][] = $item;
-
}
- $subTitle = (string)trans('firefly.overview_for_recurrence', ['title' => $recurrence->title]);
+ $subTitle = (string)trans('firefly.overview_for_recurrence', ['title' => $recurrence->title]);
return view('recurring.show', compact('recurrence', 'subTitle', 'array', 'groups', 'today'));
}
diff --git a/app/Http/Controllers/Recurring/TriggerController.php b/app/Http/Controllers/Recurring/TriggerController.php
index 173f9e5375..77d5357274 100644
--- a/app/Http/Controllers/Recurring/TriggerController.php
+++ b/app/Http/Controllers/Recurring/TriggerController.php
@@ -1,6 +1,5 @@
getAll();
- $date = $all['date'];
+ $all = $request->getAll();
+ $date = $all['date'];
// grab the date from the last time the recurrence fired:
- $backupDate = $recurrence->latest_date;
+ $backupDate = $recurrence->latest_date;
// fire the recurring cron job on the given date, then post-date the created transaction.
- Log::info(sprintf('Trigger: will now fire recurring cron job task for date "%s".', $date->format('Y-m-d H:i:s')));
+ app('log')->info(sprintf('Trigger: will now fire recurring cron job task for date "%s".', $date->format('Y-m-d H:i:s')));
+
/** @var CreateRecurringTransactions $job */
- $job = app(CreateRecurringTransactions::class);
+ $job = app(CreateRecurringTransactions::class);
$job->setRecurrences(new Collection([$recurrence]));
$job->setDate($date);
$job->setForce(false);
$job->handle();
- Log::debug('Done with recurrence.');
+ app('log')->debug('Done with recurrence.');
+
+ $groups = $job->getGroups();
- $groups = $job->getGroups();
/** @var TransactionGroup $group */
foreach ($groups as $group) {
/** @var TransactionJournal $journal */
foreach ($group->transactionJournals as $journal) {
- Log::debug(sprintf('Set date of journal #%d to today!', $journal->id));
+ app('log')->debug(sprintf('Set date of journal #%d to today!', $journal->id));
$journal->date = today(config('app.timezone'));
$journal->save();
}
@@ -87,7 +81,6 @@ class TriggerController extends Controller
$request->session()->flash('success_url', route('transactions.show', [$first->id]));
}
-
return redirect(route('recurring.show', [$recurrence->id]));
}
}
diff --git a/app/Http/Controllers/Report/AccountController.php b/app/Http/Controllers/Report/AccountController.php
index 323f289fa7..d99ec61237 100644
--- a/app/Http/Controllers/Report/AccountController.php
+++ b/app/Http/Controllers/Report/AccountController.php
@@ -29,8 +29,6 @@ use FireflyIII\Http\Controllers\Controller;
use FireflyIII\Repositories\Account\AccountTaskerInterface;
use FireflyIII\Support\CacheProperties;
use Illuminate\Support\Collection;
-use Illuminate\Support\Facades\Log;
-use Throwable;
/**
* Class AccountController.
@@ -40,17 +38,12 @@ class AccountController extends Controller
/**
* Show partial overview for account balances.
*
- * @param Collection $accounts
- * @param Carbon $start
- * @param Carbon $end
- *
- * @return string
* @throws FireflyException
*/
public function general(Collection $accounts, Carbon $start, Carbon $end): string
{
// chart properties for cache:
- $cache = new CacheProperties();
+ $cache = new CacheProperties();
$cache->addProperty($start);
$cache->addProperty($end);
$cache->addProperty('account-report');
@@ -62,12 +55,14 @@ class AccountController extends Controller
/** @var AccountTaskerInterface $accountTasker */
$accountTasker = app(AccountTaskerInterface::class);
$accountReport = $accountTasker->getAccountReport($accounts, $start, $end);
+
try {
$result = view('reports.partials.accounts', compact('accountReport'))->render();
- } catch (Throwable $e) {
- Log::error(sprintf('Could not render reports.partials.accounts: %s', $e->getMessage()));
- Log::error($e->getTraceAsString());
+ } catch (\Throwable $e) {
+ app('log')->error(sprintf('Could not render reports.partials.accounts: %s', $e->getMessage()));
+ app('log')->error($e->getTraceAsString());
$result = 'Could not render view.';
+
throw new FireflyException($result, 0, $e);
}
diff --git a/app/Http/Controllers/Report/BalanceController.php b/app/Http/Controllers/Report/BalanceController.php
index b5f17b782c..1810a47d48 100644
--- a/app/Http/Controllers/Report/BalanceController.php
+++ b/app/Http/Controllers/Report/BalanceController.php
@@ -32,8 +32,6 @@ use FireflyIII\Models\Budget;
use FireflyIII\Models\TransactionType;
use FireflyIII\Repositories\Budget\BudgetRepositoryInterface;
use Illuminate\Support\Collection;
-use Illuminate\Support\Facades\Log;
-use Throwable;
/**
* Class BalanceController.
@@ -62,19 +60,17 @@ class BalanceController extends Controller
/**
* Show overview of budget balances.
*
- * @param Collection $accounts
- * @param Carbon $start
- * @param Carbon $end
- *
* @return string
+ *
* @throws FireflyException
*/
public function general(Collection $accounts, Carbon $start, Carbon $end)
{
- $report = [
+ $report = [
'budgets' => [],
'accounts' => [],
];
+
/** @var Account $account */
foreach ($accounts as $account) {
$report['accounts'][$account->id] = [
@@ -89,23 +85,26 @@ class BalanceController extends Controller
/** @var Budget $budget */
foreach ($budgets as $budget) {
- $budgetId = $budget->id;
- $report['budgets'][$budgetId] = [
+ $budgetId = $budget->id;
+ $report['budgets'][$budgetId] = [
'budget_id' => $budgetId,
'budget_name' => $budget->name,
'spent' => [], // per account
'sums' => [], // per currency
];
- $spent = [];
+ $spent = [];
+
/** @var GroupCollectorInterface $collector */
- $collector = app(GroupCollectorInterface::class);
- $journals = $collector->setRange($start, $end)->setSourceAccounts($accounts)->setTypes([TransactionType::WITHDRAWAL])->setBudget($budget)
- ->getExtractedJournals();
+ $collector = app(GroupCollectorInterface::class);
+ $journals = $collector->setRange($start, $end)->setSourceAccounts($accounts)->setTypes([TransactionType::WITHDRAWAL])->setBudget($budget)
+ ->getExtractedJournals()
+ ;
+
/** @var array $journal */
foreach ($journals as $journal) {
- $sourceAccount = $journal['source_account_id'];
- $currencyId = $journal['currency_id'];
- $spent[$sourceAccount] = $spent[$sourceAccount] ?? [
+ $sourceAccount = $journal['source_account_id'];
+ $currencyId = $journal['currency_id'];
+ $spent[$sourceAccount] ??= [
'source_account_id' => $sourceAccount,
'currency_id' => $journal['currency_id'],
'currency_code' => $journal['currency_code'],
@@ -114,10 +113,10 @@ class BalanceController extends Controller
'currency_decimal_places' => $journal['currency_decimal_places'],
'spent' => '0',
];
- $spent[$sourceAccount]['spent'] = bcadd($spent[$sourceAccount]['spent'], $journal['amount']);
+ $spent[$sourceAccount]['spent'] = bcadd($spent[$sourceAccount]['spent'], $journal['amount']);
// also fix sum:
- $report['sums'][$budgetId][$currencyId] = $report['sums'][$budgetId][$currencyId] ?? [
+ $report['sums'][$budgetId][$currencyId] ??= [
'sum' => '0',
'currency_id' => $journal['currency_id'],
'currency_code' => $journal['currency_code'],
@@ -125,8 +124,8 @@ class BalanceController extends Controller
'currency_symbol' => $journal['currency_symbol'],
'currency_decimal_places' => $journal['currency_decimal_places'],
];
- $report['sums'][$budgetId][$currencyId]['sum'] = bcadd($report['sums'][$budgetId][$currencyId]['sum'], $journal['amount']);
- $report['accounts'][$sourceAccount]['sum'] = bcadd($report['accounts'][$sourceAccount]['sum'], $journal['amount']);
+ $report['sums'][$budgetId][$currencyId]['sum'] = bcadd($report['sums'][$budgetId][$currencyId]['sum'], $journal['amount']);
+ $report['accounts'][$sourceAccount]['sum'] = bcadd($report['accounts'][$sourceAccount]['sum'], $journal['amount']);
// add currency info for account sum
$report['accounts'][$sourceAccount]['currency_id'] = $journal['currency_id'];
@@ -138,12 +137,14 @@ class BalanceController extends Controller
$report['budgets'][$budgetId]['spent'] = $spent;
// get transactions in budget
}
+
try {
$result = view('reports.partials.balance', compact('report'))->render();
- } catch (Throwable $e) {
- Log::error(sprintf('Could not render reports.partials.balance: %s', $e->getMessage()));
- Log::error($e->getTraceAsString());
+ } catch (\Throwable $e) {
+ app('log')->error(sprintf('Could not render reports.partials.balance: %s', $e->getMessage()));
+ app('log')->error($e->getTraceAsString());
$result = 'Could not render view.';
+
throw new FireflyException($result, 0, $e);
}
diff --git a/app/Http/Controllers/Report/BillController.php b/app/Http/Controllers/Report/BillController.php
index bc143c05ff..66c910b904 100644
--- a/app/Http/Controllers/Report/BillController.php
+++ b/app/Http/Controllers/Report/BillController.php
@@ -29,8 +29,6 @@ use FireflyIII\Helpers\Report\ReportHelperInterface;
use FireflyIII\Http\Controllers\Controller;
use FireflyIII\Support\CacheProperties;
use Illuminate\Support\Collection;
-use Illuminate\Support\Facades\Log;
-use Throwable;
/**
* Class BillController
@@ -38,16 +36,13 @@ use Throwable;
class BillController extends Controller
{
/**
- * @param Collection $accounts
- * @param Carbon $start
- * @param Carbon $end
- *
* @return mixed|string
+ *
* @throws FireflyException
*/
public function overview(Collection $accounts, Carbon $start, Carbon $end) // chart properties for cache:
{
- $cache = new CacheProperties();
+ $cache = new CacheProperties();
$cache->addProperty($start);
$cache->addProperty($end);
$cache->addProperty('bill-report');
@@ -55,15 +50,18 @@ class BillController extends Controller
if ($cache->has()) {
return $cache->get();
}
+
/** @var ReportHelperInterface $helper */
$helper = app(ReportHelperInterface::class);
$report = $helper->getBillReport($accounts, $start, $end);
+
try {
$result = view('reports.partials.bills', compact('report'))->render();
- } catch (Throwable $e) {
- Log::error(sprintf('Could not render reports.partials.budgets: %s', $e->getMessage()));
- Log::error($e->getTraceAsString());
+ } catch (\Throwable $e) {
+ app('log')->error(sprintf('Could not render reports.partials.budgets: %s', $e->getMessage()));
+ app('log')->error($e->getTraceAsString());
$result = 'Could not render view.';
+
throw new FireflyException($result, 0, $e);
}
diff --git a/app/Http/Controllers/Report/BudgetController.php b/app/Http/Controllers/Report/BudgetController.php
index e4d3dea46d..9e95e2ba43 100644
--- a/app/Http/Controllers/Report/BudgetController.php
+++ b/app/Http/Controllers/Report/BudgetController.php
@@ -34,10 +34,7 @@ use FireflyIII\Support\Http\Controllers\BasicDataSupport;
use FireflyIII\Support\Report\Budget\BudgetReportGenerator;
use Illuminate\Contracts\View\Factory;
use Illuminate\Support\Collection;
-use Illuminate\Support\Facades\Log;
use Illuminate\View\View;
-use JsonException;
-use Throwable;
/**
* Class BudgetController.
@@ -50,8 +47,6 @@ class BudgetController extends Controller
/**
* ExpenseReportController constructor.
- *
-
*/
public function __construct()
{
@@ -68,14 +63,9 @@ class BudgetController extends Controller
/**
* Partial used in the budget report.
*
- * @param Collection $accounts
- * @param Collection $budgets
- * @param Carbon $start
- * @param Carbon $end
- *
* @return Factory|View
+ *
* @throws FireflyException
- * @throws JsonException
*/
public function accountPerBudget(Collection $accounts, Collection $budgets, Carbon $start, Carbon $end)
{
@@ -89,17 +79,12 @@ class BudgetController extends Controller
$generator->setEnd($end);
$generator->accountPerBudget();
- $report = $generator->getReport();
+ $report = $generator->getReport();
return view('reports.budget.partials.account-per-budget', compact('report', 'budgets'));
}
/**
- * @param Collection $accounts
- * @param Collection $budgets
- * @param Carbon $start
- * @param Carbon $end
- *
* @return Factory|View
*/
public function accounts(Collection $accounts, Collection $budgets, Carbon $start, Carbon $end)
@@ -107,10 +92,11 @@ class BudgetController extends Controller
$spent = $this->opsRepository->listExpenses($start, $end, $accounts, $budgets);
$report = [];
$sums = [];
+
/** @var Account $account */
foreach ($accounts as $account) {
- $accountId = $account->id;
- $report[$accountId] = $report[$accountId] ?? [
+ $accountId = $account->id;
+ $report[$accountId] ??= [
'name' => $account->name,
'id' => $account->id,
'iban' => $account->iban,
@@ -120,8 +106,8 @@ class BudgetController extends Controller
// loop expenses.
foreach ($spent as $currency) {
- $currencyId = $currency['currency_id'];
- $sums[$currencyId] = $sums[$currencyId] ?? [
+ $currencyId = $currency['currency_id'];
+ $sums[$currencyId] ??= [
'currency_id' => $currency['currency_id'],
'currency_symbol' => $currency['currency_symbol'],
'currency_name' => $currency['currency_name'],
@@ -131,7 +117,7 @@ class BudgetController extends Controller
foreach ($currency['budgets'] as $budget) {
foreach ($budget['transaction_journals'] as $journal) {
$sourceAccountId = $journal['source_account_id'];
- $report[$sourceAccountId]['currencies'][$currencyId] = $report[$sourceAccountId]['currencies'][$currencyId] ?? [
+ $report[$sourceAccountId]['currencies'][$currencyId] ??= [
'currency_id' => $currency['currency_id'],
'currency_symbol' => $currency['currency_symbol'],
'currency_name' => $currency['currency_name'],
@@ -151,24 +137,20 @@ class BudgetController extends Controller
}
/**
- * @param Collection $accounts
- * @param Collection $budgets
- * @param Carbon $start
- * @param Carbon $end
- *
* @return string
+ *
* @throws FireflyException
*/
public function avgExpenses(Collection $accounts, Collection $budgets, Carbon $start, Carbon $end)
{
- $spent = $this->opsRepository->listExpenses($start, $end, $accounts, $budgets);
- $result = [];
+ $spent = $this->opsRepository->listExpenses($start, $end, $accounts, $budgets);
+ $result = [];
foreach ($spent as $currency) {
foreach ($currency['budgets'] as $budget) {
foreach ($budget['transaction_journals'] as $journal) {
- $destinationId = $journal['destination_account_id'];
- $key = sprintf('%d-%d', $destinationId, $currency['currency_id']);
- $result[$key] = $result[$key] ?? [
+ $destinationId = $journal['destination_account_id'];
+ $key = sprintf('%d-%d', $destinationId, $currency['currency_id']);
+ $result[$key] ??= [
'transactions' => 0,
'sum' => '0',
'avg' => '0',
@@ -180,7 +162,7 @@ class BudgetController extends Controller
'currency_symbol' => $currency['currency_symbol'],
'currency_decimal_places' => $currency['currency_decimal_places'],
];
- $result[$key]['transactions']++;
+ ++$result[$key]['transactions'];
$result[$key]['sum'] = bcadd($journal['amount'], $result[$key]['sum']);
$result[$key]['avg'] = bcdiv($result[$key]['sum'], (string)$result[$key]['transactions']);
$result[$key]['avg_float'] = (float)$result[$key]['avg']; // intentional float
@@ -194,10 +176,11 @@ class BudgetController extends Controller
try {
$result = view('reports.budget.partials.avg-expenses', compact('result'))->render();
- } catch (Throwable $e) {
- Log::error(sprintf('Could not render reports.partials.budget-period: %s', $e->getMessage()));
+ } catch (\Throwable $e) {
+ app('log')->error(sprintf('Could not render reports.partials.budget-period: %s', $e->getMessage()));
$result = sprintf('Could not render view: %s', $e->getMessage());
- Log::error($e->getTraceAsString());
+ app('log')->error($e->getTraceAsString());
+
throw new FireflyException($result, 0, $e);
}
@@ -205,11 +188,6 @@ class BudgetController extends Controller
}
/**
- * @param Collection $accounts
- * @param Collection $budgets
- * @param Carbon $start
- * @param Carbon $end
- *
* @return Factory|View
*/
public function budgets(Collection $accounts, Collection $budgets, Carbon $start, Carbon $end)
@@ -217,38 +195,39 @@ class BudgetController extends Controller
$spent = $this->opsRepository->listExpenses($start, $end, $accounts, $budgets);
$sums = [];
$report = [];
+
/** @var Budget $budget */
foreach ($budgets as $budget) {
- $budgetId = $budget->id;
- $report[$budgetId] = $report[$budgetId] ?? [
+ $budgetId = $budget->id;
+ $report[$budgetId] ??= [
'name' => $budget->name,
'id' => $budget->id,
'currencies' => [],
];
}
foreach ($spent as $currency) {
- $currencyId = $currency['currency_id'];
- $sums[$currencyId] = $sums[$currencyId] ?? [
+ $currencyId = $currency['currency_id'];
+ $sums[$currencyId] ??= [
'currency_id' => $currency['currency_id'],
'currency_symbol' => $currency['currency_symbol'],
'currency_name' => $currency['currency_name'],
'currency_decimal_places' => $currency['currency_decimal_places'],
'sum' => '0',
];
+
/** @var array $budget */
foreach ($currency['budgets'] as $budget) {
$budgetId = $budget['id'];
foreach ($budget['transaction_journals'] as $journal) {
// add currency info to report array:
- $report[$budgetId]['currencies'][$currencyId] = $report[$budgetId]['currencies'][$currencyId] ?? [
+ $report[$budgetId]['currencies'][$currencyId] ??= [
'sum' => '0',
'sum_pct' => '0',
'currency_id' => $currency['currency_id'],
'currency_symbol' => $currency['currency_symbol'],
'currency_name' => $currency['currency_name'],
'currency_decimal_places' => $currency['currency_decimal_places'],
-
];
$report[$budgetId]['currencies'][$currencyId]['sum'] = bcadd($report[$budgetId]['currencies'][$currencyId]['sum'], $journal['amount']);
$sums[$currencyId]['sum'] = bcadd($sums[$currencyId]['sum'], $journal['amount']);
@@ -259,9 +238,9 @@ class BudgetController extends Controller
// loop again to get percentages.
foreach ($report as $budgetId => $data) {
foreach ($data['currencies'] as $currencyId => $dataX) {
- $sum = $dataX['sum'] ?? '0';
- $total = $sums[$currencyId]['sum'] ?? '0';
- $pct = '0';
+ $sum = $dataX['sum'];
+ $total = $sums[$currencyId]['sum'] ?? '0';
+ $pct = '0';
if (0 !== bccomp($sum, '0') && 0 !== bccomp($total, '9')) {
$pct = round((float)bcmul(bcdiv($sum, $total), '100')); // intentional float
}
@@ -275,13 +254,9 @@ class BudgetController extends Controller
/**
* Show partial overview of budgets.
*
- * @param Collection $accounts
- * @param Carbon $start
- * @param Carbon $end
- *
* @return string
+ *
* @throws FireflyException
- * @throws JsonException
*/
public function general(Collection $accounts, Carbon $start, Carbon $end)
{
@@ -294,7 +269,7 @@ class BudgetController extends Controller
$generator->setEnd($end);
$generator->general();
- $report = $generator->getReport();
+ $report = $generator->getReport();
return view('reports.partials.budgets', compact('report'))->render();
}
@@ -302,16 +277,13 @@ class BudgetController extends Controller
/**
* Show budget overview for a period.
*
- * @param Collection $accounts
- * @param Carbon $start
- * @param Carbon $end
- *
* @return mixed|string
+ *
* @throws FireflyException
*/
public function period(Collection $accounts, Carbon $start, Carbon $end)
{
- $cache = new CacheProperties();
+ $cache = new CacheProperties();
$cache->addProperty($start);
$cache->addProperty($end);
$cache->addProperty('budget-period-report');
@@ -323,17 +295,17 @@ class BudgetController extends Controller
$periods = app('navigation')->listOfPeriods($start, $end);
$keyFormat = app('navigation')->preferredCarbonFormat($start, $end);
// list expenses for budgets in account(s)
- $expenses = $this->opsRepository->listExpenses($start, $end, $accounts);
+ $expenses = $this->opsRepository->listExpenses($start, $end, $accounts);
- $report = [];
+ $report = [];
foreach ($expenses as $currency) {
foreach ($currency['budgets'] as $budget) {
$count = 0;
foreach ($budget['transaction_journals'] as $journal) {
- $count++;
+ ++$count;
$key = sprintf('%d-%d', $budget['id'], $currency['currency_id']);
$dateKey = $journal['date']->format($keyFormat);
- $report[$key] = $report[$key] ?? [
+ $report[$key] ??= [
'id' => $budget['id'],
'name' => sprintf('%s (%s)', $budget['name'], $currency['currency_name']),
'sum' => '0',
@@ -344,19 +316,21 @@ class BudgetController extends Controller
'currency_decimal_places' => $currency['currency_decimal_places'],
'entries' => [],
];
- $report[$key]['entries'][$dateKey] = $report[$key] ['entries'][$dateKey] ?? '0';
- $report[$key]['entries'][$dateKey] = bcadd($journal['amount'], $report[$key] ['entries'][$dateKey]);
- $report[$key]['sum'] = bcadd($report[$key] ['sum'], $journal['amount']);
+ $report[$key]['entries'][$dateKey] ??= '0';
+ $report[$key]['entries'][$dateKey] = bcadd($journal['amount'], $report[$key]['entries'][$dateKey]);
+ $report[$key]['sum'] = bcadd($report[$key]['sum'], $journal['amount']);
$report[$key]['avg'] = bcdiv($report[$key]['sum'], (string)count($periods));
}
}
}
+
try {
$result = view('reports.partials.budget-period', compact('report', 'periods'))->render();
- } catch (Throwable $e) {
- Log::error(sprintf('Could not render reports.partials.budget-period: %s', $e->getMessage()));
- Log::error($e->getTraceAsString());
+ } catch (\Throwable $e) {
+ app('log')->error(sprintf('Could not render reports.partials.budget-period: %s', $e->getMessage()));
+ app('log')->error($e->getTraceAsString());
$result = 'Could not render view.';
+
throw new FireflyException($result, 0, $e);
}
@@ -366,18 +340,14 @@ class BudgetController extends Controller
}
/**
- * @param Collection $accounts
- * @param Collection $budgets
- * @param Carbon $start
- * @param Carbon $end
- *
* @return string
+ *
* @throws FireflyException
*/
public function topExpenses(Collection $accounts, Collection $budgets, Carbon $start, Carbon $end)
{
- $spent = $this->opsRepository->listExpenses($start, $end, $accounts, $budgets);
- $result = [];
+ $spent = $this->opsRepository->listExpenses($start, $end, $accounts, $budgets);
+ $result = [];
foreach ($spent as $currency) {
foreach ($currency['budgets'] as $budget) {
foreach ($budget['transaction_journals'] as $journal) {
@@ -407,9 +377,10 @@ class BudgetController extends Controller
try {
$result = view('reports.budget.partials.top-expenses', compact('result'))->render();
- } catch (Throwable $e) {
- Log::error(sprintf('Could not render reports.partials.budget-period: %s', $e->getMessage()));
+ } catch (\Throwable $e) {
+ app('log')->error(sprintf('Could not render reports.partials.budget-period: %s', $e->getMessage()));
$result = sprintf('Could not render view: %s', $e->getMessage());
+
throw new FireflyException($result, 0, $e);
}
diff --git a/app/Http/Controllers/Report/CategoryController.php b/app/Http/Controllers/Report/CategoryController.php
index bced1f2231..c3560c2219 100644
--- a/app/Http/Controllers/Report/CategoryController.php
+++ b/app/Http/Controllers/Report/CategoryController.php
@@ -35,9 +35,7 @@ use FireflyIII\Support\Http\Controllers\BasicDataSupport;
use FireflyIII\Support\Report\Category\CategoryReportGenerator;
use Illuminate\Contracts\View\Factory;
use Illuminate\Support\Collection;
-use Illuminate\Support\Facades\Log;
use Illuminate\View\View;
-use Throwable;
/**
* Class CategoryController.
@@ -51,8 +49,6 @@ class CategoryController extends Controller
/**
* ExpenseReportController constructor.
- *
-
*/
public function __construct()
{
@@ -68,11 +64,6 @@ class CategoryController extends Controller
}
/**
- * @param Collection $accounts
- * @param Collection $categories
- * @param Carbon $start
- * @param Carbon $end
- *
* @return Factory|View
*/
public function accountPerCategory(Collection $accounts, Collection $categories, Carbon $start, Carbon $end)
@@ -80,10 +71,11 @@ class CategoryController extends Controller
$spent = $this->opsRepository->listExpenses($start, $end, $accounts, $categories);
$earned = $this->opsRepository->listIncome($start, $end, $accounts, $categories);
$report = [];
+
/** @var Account $account */
foreach ($accounts as $account) {
- $accountId = $account->id;
- $report[$accountId] = $report[$accountId] ?? [
+ $accountId = $account->id;
+ $report[$accountId] ??= [
'name' => $account->name,
'id' => $account->id,
'iban' => $account->iban,
@@ -98,8 +90,8 @@ class CategoryController extends Controller
/** @var array $category */
foreach ($currency['categories'] as $category) {
foreach ($category['transaction_journals'] as $journal) {
- $sourceAccountId = $journal['source_account_id'];
- $report[$sourceAccountId]['currencies'][$currencyId] = $report[$sourceAccountId]['currencies'][$currencyId] ?? [
+ $sourceAccountId = $journal['source_account_id'];
+ $report[$sourceAccountId]['currencies'][$currencyId] ??= [
'currency_id' => $currency['currency_id'],
'currency_symbol' => $currency['currency_symbol'],
'currency_name' => $currency['currency_name'],
@@ -108,13 +100,11 @@ class CategoryController extends Controller
];
$report[$sourceAccountId]['currencies'][$currencyId]['categories'][$category['id']]
- = $report[$sourceAccountId]['currencies'][$currencyId]['categories'][$category['id']]
- ??
- [
- 'spent' => '0',
- 'earned' => '0',
- 'sum' => '0',
- ];
+ ??= [
+ 'spent' => '0',
+ 'earned' => '0',
+ 'sum' => '0',
+ ];
$report[$sourceAccountId]['currencies'][$currencyId]['categories'][$category['id']]['spent'] = bcadd(
$report[$sourceAccountId]['currencies'][$currencyId]['categories'][$category['id']]['spent'],
$journal['amount']
@@ -135,22 +125,19 @@ class CategoryController extends Controller
foreach ($category['transaction_journals'] as $journal) {
$destinationId = $journal['destination_account_id'];
$report[$destinationId]['currencies'][$currencyId]
- = $report[$destinationId]['currencies'][$currencyId]
- ?? [
- 'currency_id' => $currency['currency_id'],
- 'currency_symbol' => $currency['currency_symbol'],
- 'currency_name' => $currency['currency_name'],
- 'currency_decimal_places' => $currency['currency_decimal_places'],
- 'categories' => [],
- ];
+ ??= [
+ 'currency_id' => $currency['currency_id'],
+ 'currency_symbol' => $currency['currency_symbol'],
+ 'currency_name' => $currency['currency_name'],
+ 'currency_decimal_places' => $currency['currency_decimal_places'],
+ 'categories' => [],
+ ];
$report[$destinationId]['currencies'][$currencyId]['categories'][$category['id']]
- = $report[$destinationId]['currencies'][$currencyId]['categories'][$category['id']]
- ??
- [
- 'spent' => '0',
- 'earned' => '0',
- 'sum' => '0',
- ];
+ ??= [
+ 'spent' => '0',
+ 'earned' => '0',
+ 'sum' => '0',
+ ];
$report[$destinationId]['currencies'][$currencyId]['categories'][$category['id']]['earned'] = bcadd(
$report[$destinationId]['currencies'][$currencyId]['categories'][$category['id']]['earned'],
$journal['amount']
@@ -167,12 +154,9 @@ class CategoryController extends Controller
}
/**
- * @param Collection $accounts
- * @param Collection $categories
- * @param Carbon $start
- * @param Carbon $end
- *
* @return Factory|View
+ *
+ * @SuppressWarnings(PHPMD.ExcessiveMethodLength)
*/
public function accounts(Collection $accounts, Collection $categories, Carbon $start, Carbon $end)
{
@@ -180,10 +164,11 @@ class CategoryController extends Controller
$earned = $this->opsRepository->listIncome($start, $end, $accounts, $categories);
$report = [];
$sums = [];
+
/** @var Account $account */
foreach ($accounts as $account) {
- $accountId = $account->id;
- $report[$accountId] = $report[$accountId] ?? [
+ $accountId = $account->id;
+ $report[$accountId] ??= [
'name' => $account->name,
'id' => $account->id,
'iban' => $account->iban,
@@ -193,8 +178,8 @@ class CategoryController extends Controller
// loop expenses.
foreach ($spent as $currency) {
- $currencyId = $currency['currency_id'];
- $sums[$currencyId] = $sums[$currencyId] ?? [
+ $currencyId = $currency['currency_id'];
+ $sums[$currencyId] ??= [
'currency_id' => $currency['currency_id'],
'currency_symbol' => $currency['currency_symbol'],
'currency_name' => $currency['currency_name'],
@@ -206,7 +191,7 @@ class CategoryController extends Controller
foreach ($currency['categories'] as $category) {
foreach ($category['transaction_journals'] as $journal) {
$sourceAccountId = $journal['source_account_id'];
- $report[$sourceAccountId]['currencies'][$currencyId] = $report[$sourceAccountId]['currencies'][$currencyId] ?? [
+ $report[$sourceAccountId]['currencies'][$currencyId] ??= [
'currency_id' => $currency['currency_id'],
'currency_symbol' => $currency['currency_symbol'],
'currency_name' => $currency['currency_name'],
@@ -231,8 +216,8 @@ class CategoryController extends Controller
// loop income.
foreach ($earned as $currency) {
- $currencyId = $currency['currency_id'];
- $sums[$currencyId] = $sums[$currencyId] ?? [
+ $currencyId = $currency['currency_id'];
+ $sums[$currencyId] ??= [
'currency_id' => $currency['currency_id'],
'currency_symbol' => $currency['currency_symbol'],
'currency_name' => $currency['currency_name'],
@@ -244,7 +229,7 @@ class CategoryController extends Controller
foreach ($currency['categories'] as $category) {
foreach ($category['transaction_journals'] as $journal) {
$destinationAccountId = $journal['destination_account_id'];
- $report[$destinationAccountId]['currencies'][$currencyId] = $report[$destinationAccountId]['currencies'][$currencyId] ?? [
+ $report[$destinationAccountId]['currencies'][$currencyId] ??= [
'currency_id' => $currency['currency_id'],
'currency_symbol' => $currency['currency_symbol'],
'currency_name' => $currency['currency_name'],
@@ -271,24 +256,20 @@ class CategoryController extends Controller
}
/**
- * @param Collection $accounts
- * @param Collection $categories
- * @param Carbon $start
- * @param Carbon $end
- *
* @return string
+ *
* @throws FireflyException
*/
public function avgExpenses(Collection $accounts, Collection $categories, Carbon $start, Carbon $end)
{
- $spent = $this->opsRepository->listExpenses($start, $end, $accounts, $categories);
- $result = [];
+ $spent = $this->opsRepository->listExpenses($start, $end, $accounts, $categories);
+ $result = [];
foreach ($spent as $currency) {
foreach ($currency['categories'] as $category) {
foreach ($category['transaction_journals'] as $journal) {
- $destinationId = $journal['destination_account_id'];
- $key = sprintf('%d-%d', $destinationId, $currency['currency_id']);
- $result[$key] = $result[$key] ?? [
+ $destinationId = $journal['destination_account_id'];
+ $key = sprintf('%d-%d', $destinationId, $currency['currency_id']);
+ $result[$key] ??= [
'transactions' => 0,
'sum' => '0',
'avg' => '0',
@@ -300,7 +281,7 @@ class CategoryController extends Controller
'currency_symbol' => $currency['currency_symbol'],
'currency_decimal_places' => $currency['currency_decimal_places'],
];
- $result[$key]['transactions']++;
+ ++$result[$key]['transactions'];
$result[$key]['sum'] = bcadd($journal['amount'], $result[$key]['sum']);
$result[$key]['avg'] = bcdiv($result[$key]['sum'], (string)$result[$key]['transactions']);
$result[$key]['avg_float'] = (float)$result[$key]['avg']; // intentional float
@@ -314,9 +295,10 @@ class CategoryController extends Controller
try {
$result = view('reports.category.partials.avg-expenses', compact('result'))->render();
- } catch (Throwable $e) {
- Log::error(sprintf('Could not render reports.partials.budget-period: %s', $e->getMessage()));
+ } catch (\Throwable $e) {
+ app('log')->error(sprintf('Could not render reports.partials.budget-period: %s', $e->getMessage()));
$result = sprintf('Could not render view: %s', $e->getMessage());
+
throw new FireflyException($result, 0, $e);
}
@@ -324,24 +306,20 @@ class CategoryController extends Controller
}
/**
- * @param Collection $accounts
- * @param Collection $categories
- * @param Carbon $start
- * @param Carbon $end
- *
* @return string
+ *
* @throws FireflyException
*/
public function avgIncome(Collection $accounts, Collection $categories, Carbon $start, Carbon $end)
{
- $spent = $this->opsRepository->listIncome($start, $end, $accounts, $categories);
- $result = [];
+ $spent = $this->opsRepository->listIncome($start, $end, $accounts, $categories);
+ $result = [];
foreach ($spent as $currency) {
foreach ($currency['categories'] as $category) {
foreach ($category['transaction_journals'] as $journal) {
- $sourceId = $journal['source_account_id'];
- $key = sprintf('%d-%d', $sourceId, $currency['currency_id']);
- $result[$key] = $result[$key] ?? [
+ $sourceId = $journal['source_account_id'];
+ $key = sprintf('%d-%d', $sourceId, $currency['currency_id']);
+ $result[$key] ??= [
'transactions' => 0,
'sum' => '0',
'avg' => '0',
@@ -353,7 +331,7 @@ class CategoryController extends Controller
'currency_symbol' => $currency['currency_symbol'],
'currency_decimal_places' => $currency['currency_decimal_places'],
];
- $result[$key]['transactions']++;
+ ++$result[$key]['transactions'];
$result[$key]['sum'] = bcadd($journal['amount'], $result[$key]['sum']);
$result[$key]['avg'] = bcdiv($result[$key]['sum'], (string)$result[$key]['transactions']);
$result[$key]['avg_float'] = (float)$result[$key]['avg'];
@@ -367,9 +345,10 @@ class CategoryController extends Controller
try {
$result = view('reports.category.partials.avg-income', compact('result'))->render();
- } catch (Throwable $e) {
- Log::error(sprintf('Could not render reports.partials.budget-period: %s', $e->getMessage()));
+ } catch (\Throwable $e) {
+ app('log')->error(sprintf('Could not render reports.partials.budget-period: %s', $e->getMessage()));
$result = sprintf('Could not render view: %s', $e->getMessage());
+
throw new FireflyException($result, 0, $e);
}
@@ -377,12 +356,9 @@ class CategoryController extends Controller
}
/**
- * @param Collection $accounts
- * @param Collection $categories
- * @param Carbon $start
- * @param Carbon $end
- *
* @return Factory|View
+ *
+ * @SuppressWarnings(PHPMD.ExcessiveMethodLength)
*/
public function categories(Collection $accounts, Collection $categories, Carbon $start, Carbon $end)
{
@@ -390,18 +366,19 @@ class CategoryController extends Controller
$earned = $this->opsRepository->listIncome($start, $end, $accounts, $categories);
$sums = [];
$report = [];
+
/** @var Category $category */
foreach ($categories as $category) {
- $categoryId = $category->id;
- $report[$categoryId] = $report[$categoryId] ?? [
+ $categoryId = $category->id;
+ $report[$categoryId] ??= [
'name' => $category->name,
'id' => $category->id,
'currencies' => [],
];
}
foreach ($spent as $currency) {
- $currencyId = $currency['currency_id'];
- $sums[$currencyId] = $sums[$currencyId] ?? [
+ $currencyId = $currency['currency_id'];
+ $sums[$currencyId] ??= [
'currency_id' => $currency['currency_id'],
'currency_symbol' => $currency['currency_symbol'],
'currency_name' => $currency['currency_name'],
@@ -410,13 +387,14 @@ class CategoryController extends Controller
'spent_sum' => '0',
'total_sum' => '0',
];
+
/** @var array $category */
foreach ($currency['categories'] as $category) {
$categoryId = $category['id'];
foreach ($category['transaction_journals'] as $journal) {
// add currency info to report array:
- $report[$categoryId]['currencies'][$currencyId] = $report[$categoryId]['currencies'][$currencyId] ?? [
+ $report[$categoryId]['currencies'][$currencyId] ??= [
'spent' => '0',
'earned' => '0',
'sum' => '0',
@@ -434,15 +412,15 @@ class CategoryController extends Controller
$journal['amount']
);
- $sums[$currencyId]['spent_sum'] = bcadd($sums[$currencyId]['spent_sum'], $journal['amount']);
- $sums[$currencyId]['total_sum'] = bcadd($sums[$currencyId]['total_sum'], $journal['amount']);
+ $sums[$currencyId]['spent_sum'] = bcadd($sums[$currencyId]['spent_sum'], $journal['amount']);
+ $sums[$currencyId]['total_sum'] = bcadd($sums[$currencyId]['total_sum'], $journal['amount']);
}
}
}
foreach ($earned as $currency) {
- $currencyId = $currency['currency_id'];
- $sums[$currencyId] = $sums[$currencyId] ?? [
+ $currencyId = $currency['currency_id'];
+ $sums[$currencyId] ??= [
'currency_id' => $currency['currency_id'],
'currency_symbol' => $currency['currency_symbol'],
'currency_name' => $currency['currency_name'],
@@ -451,13 +429,14 @@ class CategoryController extends Controller
'spent_sum' => '0',
'total_sum' => '0',
];
+
/** @var array $category */
foreach ($currency['categories'] as $category) {
$categoryId = $category['id'];
foreach ($category['transaction_journals'] as $journal) {
// add currency info to report array:
- $report[$categoryId]['currencies'][$currencyId] = $report[$categoryId]['currencies'][$currencyId] ?? [
+ $report[$categoryId]['currencies'][$currencyId] ??= [
'spent' => '0',
'earned' => '0',
'sum' => '0',
@@ -475,8 +454,8 @@ class CategoryController extends Controller
$journal['amount']
);
- $sums[$currencyId]['earned_sum'] = bcadd($sums[$currencyId]['earned_sum'], $journal['amount']);
- $sums[$currencyId]['total_sum'] = bcadd($sums[$currencyId]['total_sum'], $journal['amount']);
+ $sums[$currencyId]['earned_sum'] = bcadd($sums[$currencyId]['earned_sum'], $journal['amount']);
+ $sums[$currencyId]['total_sum'] = bcadd($sums[$currencyId]['total_sum'], $journal['amount']);
}
}
}
@@ -487,16 +466,13 @@ class CategoryController extends Controller
/**
* Show overview of expenses in category.
*
- * @param Collection $accounts
- * @param Carbon $start
- * @param Carbon $end
- *
* @return mixed|string
+ *
* @throws FireflyException
*/
public function expenses(Collection $accounts, Carbon $start, Carbon $end)
{
- $cache = new CacheProperties();
+ $cache = new CacheProperties();
$cache->addProperty($start);
$cache->addProperty($end);
$cache->addProperty('category-period-expenses-report');
@@ -507,7 +483,7 @@ class CategoryController extends Controller
// depending on the carbon format (a reliable way to determine the general date difference)
// change the "listOfPeriods" call so the entire period gets included correctly.
- $format = app('navigation')->preferredCarbonFormat($start, $end);
+ $format = app('navigation')->preferredCarbonFormat($start, $end);
if ('Y' === $format) {
$start->startOfYear();
@@ -523,8 +499,8 @@ class CategoryController extends Controller
foreach ([$with, $without] as $set) {
foreach ($set as $currencyId => $currencyRow) {
foreach ($currencyRow['categories'] as $categoryId => $categoryRow) {
- $key = sprintf('%d-%d', $currencyId, $categoryId);
- $data[$key] = $data[$key] ?? [
+ $key = sprintf('%d-%d', $currencyId, $categoryId);
+ $data[$key] ??= [
'id' => $categoryRow['id'],
'title' => sprintf('%s (%s)', $categoryRow['name'], $currencyRow['currency_name']),
'currency_id' => $currencyRow['currency_id'],
@@ -534,11 +510,10 @@ class CategoryController extends Controller
'currency_decimal_places' => $currencyRow['currency_decimal_places'],
'sum' => '0',
'entries' => [],
-
];
foreach ($categoryRow['transaction_journals'] as $journal) {
$date = $journal['date']->format($format);
- $data[$key]['entries'][$date] = $data[$key]['entries'][$date] ?? '0';
+ $data[$key]['entries'][$date] ??= '0';
$data[$key]['entries'][$date] = bcadd($data[$key]['entries'][$date], $journal['amount']);
$data[$key]['sum'] = bcadd($data[$key]['sum'], $journal['amount']);
}
@@ -548,17 +523,17 @@ class CategoryController extends Controller
$cache->store($data);
- $report = $data;
+ $report = $data;
try {
$result = view('reports.partials.category-period', compact('report', 'periods'))->render();
- } catch (Throwable $e) {
- Log::error(sprintf('Could not render category::expenses: %s', $e->getMessage()));
+ } catch (\Throwable $e) {
+ app('log')->error(sprintf('Could not render category::expenses: %s', $e->getMessage()));
$result = sprintf('An error prevented Firefly III from rendering: %s. Apologies.', $e->getMessage());
+
throw new FireflyException($result, 0, $e);
}
-
$cache->store($result);
return $result;
@@ -567,17 +542,11 @@ class CategoryController extends Controller
/**
* Show overview of income in category.
*
- * @param Collection $accounts
- *
- * @param Carbon $start
- * @param Carbon $end
- *
- * @return string
* @throws FireflyException
*/
public function income(Collection $accounts, Carbon $start, Carbon $end): string
{
- $cache = new CacheProperties();
+ $cache = new CacheProperties();
$cache->addProperty($start);
$cache->addProperty($end);
$cache->addProperty('category-period-income-report');
@@ -588,7 +557,7 @@ class CategoryController extends Controller
// depending on the carbon format (a reliable way to determine the general date difference)
// change the "listOfPeriods" call so the entire period gets included correctly.
- $format = app('navigation')->preferredCarbonFormat($start, $end);
+ $format = app('navigation')->preferredCarbonFormat($start, $end);
if ('Y' === $format) {
$start->startOfYear();
@@ -604,8 +573,8 @@ class CategoryController extends Controller
foreach ([$with, $without] as $set) {
foreach ($set as $currencyId => $currencyRow) {
foreach ($currencyRow['categories'] as $categoryId => $categoryRow) {
- $key = sprintf('%d-%d', $currencyId, $categoryId);
- $data[$key] = $data[$key] ?? [
+ $key = sprintf('%d-%d', $currencyId, $categoryId);
+ $data[$key] ??= [
'id' => $categoryRow['id'],
'title' => sprintf('%s (%s)', $categoryRow['name'], $currencyRow['currency_name']),
'currency_id' => $currencyRow['currency_id'],
@@ -615,11 +584,10 @@ class CategoryController extends Controller
'currency_decimal_places' => $currencyRow['currency_decimal_places'],
'sum' => '0',
'entries' => [],
-
];
foreach ($categoryRow['transaction_journals'] as $journal) {
$date = $journal['date']->format($format);
- $data[$key]['entries'][$date] = $data[$key]['entries'][$date] ?? '0';
+ $data[$key]['entries'][$date] ??= '0';
$data[$key]['entries'][$date] = bcadd($data[$key]['entries'][$date], $journal['amount']);
$data[$key]['sum'] = bcadd($data[$key]['sum'], $journal['amount']);
}
@@ -627,17 +595,17 @@ class CategoryController extends Controller
}
}
- $report = $data;
+ $report = $data;
try {
$result = view('reports.partials.category-period', compact('report', 'periods'))->render();
- } catch (Throwable $e) {
- Log::error(sprintf('Could not render category::expenses: %s', $e->getMessage()));
+ } catch (\Throwable $e) {
+ app('log')->error(sprintf('Could not render category::expenses: %s', $e->getMessage()));
$result = sprintf('An error prevented Firefly III from rendering: %s. Apologies.', $e->getMessage());
+
throw new FireflyException($result, 0, $e);
}
-
$cache->store($result);
return $result;
@@ -646,17 +614,12 @@ class CategoryController extends Controller
/**
* Show overview of category transactions on the default report.
*
- * @param Collection $accounts
- * @param Carbon $start
- * @param Carbon $end
- *
- * @return string
* @throws FireflyException
*/
public function operations(Collection $accounts, Carbon $start, Carbon $end): string
{
// chart properties for cache:
- $cache = new CacheProperties();
+ $cache = new CacheProperties();
$cache->addProperty($start);
$cache->addProperty($end);
$cache->addProperty('category-report');
@@ -671,15 +634,15 @@ class CategoryController extends Controller
$generator->setStart($start);
$generator->setEnd($end);
$generator->operations();
- $report = $generator->getReport();
-
+ $report = $generator->getReport();
try {
- $result = (string)view('reports.partials.categories', compact('report'))->render();
+ $result = view('reports.partials.categories', compact('report'))->render();
$cache->store($result);
- } catch (Throwable $e) {
- Log::error(sprintf('Could not render category::expenses: %s', $e->getMessage()));
+ } catch (\Throwable $e) {
+ app('log')->error(sprintf('Could not render category::expenses: %s', $e->getMessage()));
$result = sprintf('An error prevented Firefly III from rendering: %s. Apologies.', $e->getMessage());
+
throw new FireflyException($result, 0, $e);
}
@@ -687,18 +650,14 @@ class CategoryController extends Controller
}
/**
- * @param Collection $accounts
- * @param Collection $categories
- * @param Carbon $start
- * @param Carbon $end
- *
* @return string
+ *
* @throws FireflyException
*/
public function topExpenses(Collection $accounts, Collection $categories, Carbon $start, Carbon $end)
{
- $spent = $this->opsRepository->listExpenses($start, $end, $accounts, $categories);
- $result = [];
+ $spent = $this->opsRepository->listExpenses($start, $end, $accounts, $categories);
+ $result = [];
foreach ($spent as $currency) {
foreach ($currency['categories'] as $category) {
foreach ($category['transaction_journals'] as $journal) {
@@ -728,9 +687,10 @@ class CategoryController extends Controller
try {
$result = view('reports.category.partials.top-expenses', compact('result'))->render();
- } catch (Throwable $e) {
- Log::debug(sprintf('Could not render reports.partials.budget-period: %s', $e->getMessage()));
+ } catch (\Throwable $e) {
+ app('log')->debug(sprintf('Could not render reports.partials.budget-period: %s', $e->getMessage()));
$result = sprintf('Could not render view: %s', $e->getMessage());
+
throw new FireflyException($e->getMessage(), 0, $e);
}
@@ -738,18 +698,14 @@ class CategoryController extends Controller
}
/**
- * @param Collection $accounts
- * @param Collection $categories
- * @param Carbon $start
- * @param Carbon $end
- *
* @return string
+ *
* @throws FireflyException
*/
public function topIncome(Collection $accounts, Collection $categories, Carbon $start, Carbon $end)
{
- $spent = $this->opsRepository->listIncome($start, $end, $accounts, $categories);
- $result = [];
+ $spent = $this->opsRepository->listIncome($start, $end, $accounts, $categories);
+ $result = [];
foreach ($spent as $currency) {
foreach ($currency['categories'] as $category) {
foreach ($category['transaction_journals'] as $journal) {
@@ -779,9 +735,10 @@ class CategoryController extends Controller
try {
$result = view('reports.category.partials.top-income', compact('result'))->render();
- } catch (Throwable $e) {
- Log::debug(sprintf('Could not render reports.partials.budget-period: %s', $e->getMessage()));
+ } catch (\Throwable $e) {
+ app('log')->debug(sprintf('Could not render reports.partials.budget-period: %s', $e->getMessage()));
$result = sprintf('Could not render view: %s', $e->getMessage());
+
throw new FireflyException($e->getMessage(), 0, $e);
}
diff --git a/app/Http/Controllers/Report/DoubleController.php b/app/Http/Controllers/Report/DoubleController.php
index c72eb63732..9477589868 100644
--- a/app/Http/Controllers/Report/DoubleController.php
+++ b/app/Http/Controllers/Report/DoubleController.php
@@ -32,28 +32,20 @@ use FireflyIII\Repositories\Account\OperationsRepositoryInterface;
use FireflyIII\Support\Http\Controllers\AugumentData;
use Illuminate\Contracts\View\Factory;
use Illuminate\Support\Collection;
-use Illuminate\Support\Facades\Log;
use Illuminate\View\View;
-use Throwable;
/**
* Class DoubleController
- *
*/
class DoubleController extends Controller
{
use AugumentData;
- /** @var AccountRepositoryInterface The account repository */
- protected $accountRepository;
-
- /** @var OperationsRepositoryInterface */
- private $opsRepository;
+ protected AccountRepositoryInterface $accountRepository;
+ private OperationsRepositoryInterface $opsRepository;
/**
* Constructor for ExpenseController
- *
-
*/
public function __construct()
{
@@ -71,12 +63,8 @@ class DoubleController extends Controller
}
/**
- * @param Collection $accounts
- * @param Collection $doubles
- * @param Carbon $start
- * @param Carbon $end
- *
* @return string
+ *
* @throws FireflyException
*/
public function avgExpenses(Collection $accounts, Collection $doubles, Carbon $start, Carbon $end)
@@ -87,9 +75,9 @@ class DoubleController extends Controller
$result = [];
foreach ($spent as $currency) {
foreach ($currency['transaction_journals'] as $journal) {
- $sourceId = $journal['source_account_id'];
- $key = sprintf('%d-%d', $sourceId, $currency['currency_id']);
- $result[$key] = $result[$key] ?? [
+ $sourceId = $journal['source_account_id'];
+ $key = sprintf('%d-%d', $sourceId, $currency['currency_id']);
+ $result[$key] ??= [
'transactions' => 0,
'sum' => '0',
'avg' => '0',
@@ -101,7 +89,7 @@ class DoubleController extends Controller
'currency_symbol' => $currency['currency_symbol'],
'currency_decimal_places' => $currency['currency_decimal_places'],
];
- $result[$key]['transactions']++;
+ ++$result[$key]['transactions'];
$result[$key]['sum'] = bcadd($journal['amount'], $result[$key]['sum']);
$result[$key]['avg'] = bcdiv($result[$key]['sum'], (string)$result[$key]['transactions']);
$result[$key]['avg_float'] = (float)$result[$key]['avg'];
@@ -109,14 +97,15 @@ class DoubleController extends Controller
}
// sort by amount_float
// sort temp array by amount.
- $amounts = array_column($result, 'avg_float');
+ $amounts = array_column($result, 'avg_float');
array_multisort($amounts, SORT_ASC, $result);
try {
$result = view('reports.double.partials.avg-expenses', compact('result'))->render();
- } catch (Throwable $e) {
- Log::error(sprintf('Could not render reports.partials.budget-period: %s', $e->getMessage()));
+ } catch (\Throwable $e) {
+ app('log')->error(sprintf('Could not render reports.partials.budget-period: %s', $e->getMessage()));
$result = sprintf('Could not render view: %s', $e->getMessage());
+
throw new FireflyException($e->getMessage(), 0, $e);
}
@@ -124,12 +113,8 @@ class DoubleController extends Controller
}
/**
- * @param Collection $accounts
- * @param Collection $doubles
- * @param Carbon $start
- * @param Carbon $end
- *
* @return string
+ *
* @throws FireflyException
*/
public function avgIncome(Collection $accounts, Collection $doubles, Carbon $start, Carbon $end)
@@ -140,9 +125,9 @@ class DoubleController extends Controller
$result = [];
foreach ($spent as $currency) {
foreach ($currency['transaction_journals'] as $journal) {
- $destinationId = $journal['destination_account_id'];
- $key = sprintf('%d-%d', $destinationId, $currency['currency_id']);
- $result[$key] = $result[$key] ?? [
+ $destinationId = $journal['destination_account_id'];
+ $key = sprintf('%d-%d', $destinationId, $currency['currency_id']);
+ $result[$key] ??= [
'transactions' => 0,
'sum' => '0',
'avg' => '0',
@@ -154,7 +139,7 @@ class DoubleController extends Controller
'currency_symbol' => $currency['currency_symbol'],
'currency_decimal_places' => $currency['currency_decimal_places'],
];
- $result[$key]['transactions']++;
+ ++$result[$key]['transactions'];
$result[$key]['sum'] = bcadd($journal['amount'], $result[$key]['sum']);
$result[$key]['avg'] = bcdiv($result[$key]['sum'], (string)$result[$key]['transactions']);
$result[$key]['avg_float'] = (float)$result[$key]['avg'];
@@ -162,14 +147,15 @@ class DoubleController extends Controller
}
// sort by amount_float
// sort temp array by amount.
- $amounts = array_column($result, 'avg_float');
+ $amounts = array_column($result, 'avg_float');
array_multisort($amounts, SORT_DESC, $result);
try {
$result = view('reports.double.partials.avg-income', compact('result'))->render();
- } catch (Throwable $e) {
- Log::error(sprintf('Could not render reports.partials.budget-period: %s', $e->getMessage()));
+ } catch (\Throwable $e) {
+ app('log')->error(sprintf('Could not render reports.partials.budget-period: %s', $e->getMessage()));
$result = sprintf('Could not render view: %s', $e->getMessage());
+
throw new FireflyException($e->getMessage(), 0, $e);
}
@@ -177,12 +163,9 @@ class DoubleController extends Controller
}
/**
- * @param Collection $accounts
- * @param Collection $double
- * @param Carbon $start
- * @param Carbon $end
- *
* @return Factory|View
+ *
+ * @SuppressWarnings(PHPMD.ExcessiveMethodLength)
*/
public function operations(Collection $accounts, Collection $double, Carbon $start, Carbon $end)
{
@@ -191,15 +174,15 @@ class DoubleController extends Controller
$report = [];
$sums = [];
// see what happens when we collect transactions.
- $spent = $this->opsRepository->listExpenses($start, $end, $together);
- $earned = $this->opsRepository->listIncome($start, $end, $together);
+ $spent = $this->opsRepository->listExpenses($start, $end, $together);
+ $earned = $this->opsRepository->listIncome($start, $end, $together);
// group and list per account name (as long as its not in accounts, only in double)
/** @var array $currency */
foreach ($spent as $currency) {
$currencyId = $currency['currency_id'];
- $sums[$currencyId] = $sums[$currencyId] ?? [
+ $sums[$currencyId] ??= [
'spent' => '0',
'earned' => '0',
'sum' => '0',
@@ -212,12 +195,12 @@ class DoubleController extends Controller
/** @var array $journal */
foreach ($currency['transaction_journals'] as $journal) {
- $destId = $journal['destination_account_id'];
- $destName = $journal['destination_account_name'];
- $destIban = $journal['destination_account_iban'];
- $genericName = $this->getCounterpartName($withCounterpart, $destId, $destName, $destIban);
- $objectName = sprintf('%s (%s)', $genericName, $currency['currency_name']);
- $report[$objectName] = $report[$objectName] ?? [
+ $destId = $journal['destination_account_id'];
+ $destName = $journal['destination_account_name'];
+ $destIban = $journal['destination_account_iban'];
+ $genericName = $this->getCounterpartName($withCounterpart, $destId, $destName, $destIban);
+ $objectName = sprintf('%s (%s)', $genericName, $currency['currency_name']);
+ $report[$objectName] ??= [
'dest_name' => '',
'dest_iban' => '',
'source_name' => '',
@@ -236,10 +219,10 @@ class DoubleController extends Controller
$report[$objectName]['dest_iban'] = $destIban;
// add amounts:
- $report[$objectName]['spent'] = bcadd($report[$objectName]['spent'], $journal['amount']);
- $report[$objectName]['sum'] = bcadd($report[$objectName]['sum'], $journal['amount']);
- $sums[$currencyId]['spent'] = bcadd($sums[$currencyId]['spent'], $journal['amount']);
- $sums[$currencyId]['sum'] = bcadd($sums[$currencyId]['sum'], $journal['amount']);
+ $report[$objectName]['spent'] = bcadd($report[$objectName]['spent'], $journal['amount']);
+ $report[$objectName]['sum'] = bcadd($report[$objectName]['sum'], $journal['amount']);
+ $sums[$currencyId]['spent'] = bcadd($sums[$currencyId]['spent'], $journal['amount']);
+ $sums[$currencyId]['sum'] = bcadd($sums[$currencyId]['sum'], $journal['amount']);
}
}
@@ -247,7 +230,7 @@ class DoubleController extends Controller
foreach ($earned as $currency) {
$currencyId = $currency['currency_id'];
- $sums[$currencyId] = $sums[$currencyId] ?? [
+ $sums[$currencyId] ??= [
'spent' => '0',
'earned' => '0',
'sum' => '0',
@@ -260,12 +243,12 @@ class DoubleController extends Controller
/** @var array $journal */
foreach ($currency['transaction_journals'] as $journal) {
- $sourceId = $journal['source_account_id'];
- $sourceName = $journal['source_account_name'];
- $sourceIban = $journal['source_account_iban'];
- $genericName = $this->getCounterpartName($withCounterpart, $sourceId, $sourceName, $sourceIban);
- $objectName = sprintf('%s (%s)', $genericName, $currency['currency_name']);
- $report[$objectName] = $report[$objectName] ?? [
+ $sourceId = $journal['source_account_id'];
+ $sourceName = $journal['source_account_name'];
+ $sourceIban = $journal['source_account_iban'];
+ $genericName = $this->getCounterpartName($withCounterpart, $sourceId, $sourceName, $sourceIban);
+ $objectName = sprintf('%s (%s)', $genericName, $currency['currency_name']);
+ $report[$objectName] ??= [
'dest_name' => '',
'dest_iban' => '',
'source_name' => '',
@@ -285,10 +268,10 @@ class DoubleController extends Controller
$report[$objectName]['source_iban'] = $sourceIban;
// add amounts:
- $report[$objectName]['earned'] = bcadd($report[$objectName]['earned'], $journal['amount']);
- $report[$objectName]['sum'] = bcadd($report[$objectName]['sum'], $journal['amount']);
- $sums[$currencyId]['earned'] = bcadd($sums[$currencyId]['earned'], $journal['amount']);
- $sums[$currencyId]['sum'] = bcadd($sums[$currencyId]['sum'], $journal['amount']);
+ $report[$objectName]['earned'] = bcadd($report[$objectName]['earned'], $journal['amount']);
+ $report[$objectName]['sum'] = bcadd($report[$objectName]['sum'], $journal['amount']);
+ $sums[$currencyId]['earned'] = bcadd($sums[$currencyId]['earned'], $journal['amount']);
+ $sums[$currencyId]['sum'] = bcadd($sums[$currencyId]['sum'], $journal['amount']);
}
}
@@ -297,13 +280,6 @@ class DoubleController extends Controller
/**
* TODO this method is duplicated.
- *
- * @param Collection $accounts
- * @param int $id
- * @param string $name
- * @param string|null $iban
- *
- * @return string
*/
private function getCounterpartName(Collection $accounts, int $id, string $name, ?string $iban): string
{
@@ -321,11 +297,6 @@ class DoubleController extends Controller
}
/**
- * @param Collection $accounts
- * @param Collection $double
- * @param Carbon $start
- * @param Carbon $end
- *
* @return Factory|View
*/
public function operationsPerAsset(Collection $accounts, Collection $double, Carbon $start, Carbon $end)
@@ -335,15 +306,15 @@ class DoubleController extends Controller
$report = [];
$sums = [];
// see what happens when we collect transactions.
- $spent = $this->opsRepository->listExpenses($start, $end, $together);
- $earned = $this->opsRepository->listIncome($start, $end, $together);
+ $spent = $this->opsRepository->listExpenses($start, $end, $together);
+ $earned = $this->opsRepository->listIncome($start, $end, $together);
// group and list per account name (as long as its not in accounts, only in double)
/** @var array $currency */
foreach ($spent as $currency) {
$currencyId = $currency['currency_id'];
- $sums[$currencyId] = $sums[$currencyId] ?? [
+ $sums[$currencyId] ??= [
'spent' => '0',
'earned' => '0',
'sum' => '0',
@@ -356,8 +327,8 @@ class DoubleController extends Controller
/** @var array $journal */
foreach ($currency['transaction_journals'] as $journal) {
- $objectName = sprintf('%s (%s)', $journal['source_account_name'], $currency['currency_name']);
- $report[$objectName] = $report[$objectName] ?? [
+ $objectName = sprintf('%s (%s)', $journal['source_account_name'], $currency['currency_name']);
+ $report[$objectName] ??= [
'account_id' => $journal['source_account_id'],
'account_name' => $objectName,
'currency_id' => $currency['currency_id'],
@@ -382,7 +353,7 @@ class DoubleController extends Controller
foreach ($earned as $currency) {
$currencyId = $currency['currency_id'];
- $sums[$currencyId] = $sums[$currencyId] ?? [
+ $sums[$currencyId] ??= [
'spent' => '0',
'earned' => '0',
'sum' => '0',
@@ -395,8 +366,8 @@ class DoubleController extends Controller
/** @var array $journal */
foreach ($currency['transaction_journals'] as $journal) {
- $objectName = sprintf('%s (%s)', $journal['destination_account_name'], $currency['currency_name']);
- $report[$objectName] = $report[$objectName] ?? [
+ $objectName = sprintf('%s (%s)', $journal['destination_account_name'], $currency['currency_name']);
+ $report[$objectName] ??= [
'account_id' => $journal['destination_account_id'],
'account_name' => $objectName,
'currency_id' => $currency['currency_id'],
@@ -421,12 +392,8 @@ class DoubleController extends Controller
}
/**
- * @param Collection $accounts
- * @param Collection $doubles
- * @param Carbon $start
- * @param Carbon $end
- *
* @return string
+ *
* @throws FireflyException
*/
public function topExpenses(Collection $accounts, Collection $doubles, Carbon $start, Carbon $end)
@@ -457,14 +424,15 @@ class DoubleController extends Controller
}
// sort by amount_float
// sort temp array by amount.
- $amounts = array_column($result, 'amount_float');
+ $amounts = array_column($result, 'amount_float');
array_multisort($amounts, SORT_ASC, $result);
try {
$result = view('reports.double.partials.top-expenses', compact('result'))->render();
- } catch (Throwable $e) {
- Log::error(sprintf('Could not render reports.partials.budget-period: %s', $e->getMessage()));
+ } catch (\Throwable $e) {
+ app('log')->error(sprintf('Could not render reports.partials.budget-period: %s', $e->getMessage()));
$result = sprintf('Could not render view: %s', $e->getMessage());
+
throw new FireflyException($e->getMessage(), 0, $e);
}
@@ -472,12 +440,8 @@ class DoubleController extends Controller
}
/**
- * @param Collection $accounts
- * @param Collection $doubles
- * @param Carbon $start
- * @param Carbon $end
- *
* @return string
+ *
* @throws FireflyException
*/
public function topIncome(Collection $accounts, Collection $doubles, Carbon $start, Carbon $end)
@@ -508,14 +472,15 @@ class DoubleController extends Controller
}
// sort by amount_float
// sort temp array by amount.
- $amounts = array_column($result, 'amount_float');
+ $amounts = array_column($result, 'amount_float');
array_multisort($amounts, SORT_DESC, $result);
try {
$result = view('reports.double.partials.top-income', compact('result'))->render();
- } catch (Throwable $e) {
- Log::error(sprintf('Could not render reports.partials.budget-period: %s', $e->getMessage()));
+ } catch (\Throwable $e) {
+ app('log')->error(sprintf('Could not render reports.partials.budget-period: %s', $e->getMessage()));
$result = sprintf('Could not render view: %s', $e->getMessage());
+
throw new FireflyException($e->getMessage(), 0, $e);
}
diff --git a/app/Http/Controllers/Report/OperationsController.php b/app/Http/Controllers/Report/OperationsController.php
index 9eb7d89b40..de27b13d04 100644
--- a/app/Http/Controllers/Report/OperationsController.php
+++ b/app/Http/Controllers/Report/OperationsController.php
@@ -29,8 +29,6 @@ use FireflyIII\Http\Controllers\Controller;
use FireflyIII\Repositories\Account\AccountTaskerInterface;
use FireflyIII\Support\CacheProperties;
use Illuminate\Support\Collection;
-use Illuminate\Support\Facades\Log;
-use Throwable;
/**
* Class OperationsController.
@@ -42,8 +40,6 @@ class OperationsController extends Controller
/**
* OperationsController constructor.
- *
-
*/
public function __construct()
{
@@ -62,17 +58,14 @@ class OperationsController extends Controller
/**
* View of income and expense.
*
- * @param Collection $accounts
- * @param Carbon $start
- * @param Carbon $end
- *
* @return mixed|string
+ *
* @throws FireflyException
*/
public function expenses(Collection $accounts, Carbon $start, Carbon $end)
{
// chart properties for cache:
- $cache = new CacheProperties();
+ $cache = new CacheProperties();
$cache->addProperty($start);
$cache->addProperty($end);
$cache->addProperty('expense-report');
@@ -82,12 +75,14 @@ class OperationsController extends Controller
}
$report = $this->tasker->getExpenseReport($start, $end, $accounts);
$type = 'expense-entry';
+
try {
$result = view('reports.partials.income-expenses', compact('report', 'type'))->render();
- } catch (Throwable $e) {
- Log::error(sprintf('Could not render reports.partials.income-expense: %s', $e->getMessage()));
- Log::error($e->getTraceAsString());
+ } catch (\Throwable $e) {
+ app('log')->error(sprintf('Could not render reports.partials.income-expense: %s', $e->getMessage()));
+ app('log')->error($e->getTraceAsString());
$result = 'Could not render view.';
+
throw new FireflyException($result, 0, $e);
}
@@ -99,17 +94,12 @@ class OperationsController extends Controller
/**
* View of income.
*
- * @param Collection $accounts
- * @param Carbon $start
- * @param Carbon $end
- *
- * @return string
* @throws FireflyException
*/
public function income(Collection $accounts, Carbon $start, Carbon $end): string
{
// chart properties for cache:
- $cache = new CacheProperties();
+ $cache = new CacheProperties();
$cache->addProperty($start);
$cache->addProperty($end);
$cache->addProperty('income-report');
@@ -119,12 +109,14 @@ class OperationsController extends Controller
}
$report = $this->tasker->getIncomeReport($start, $end, $accounts);
$type = 'income-entry';
+
try {
$result = view('reports.partials.income-expenses', compact('report', 'type'))->render();
- } catch (Throwable $e) {
- Log::error(sprintf('Could not render reports.partials.income-expenses: %s', $e->getMessage()));
- Log::error($e->getTraceAsString());
+ } catch (\Throwable $e) {
+ app('log')->error(sprintf('Could not render reports.partials.income-expenses: %s', $e->getMessage()));
+ app('log')->error($e->getTraceAsString());
$result = 'Could not render view.';
+
throw new FireflyException($result, 0, $e);
}
@@ -136,17 +128,14 @@ class OperationsController extends Controller
/**
* Overview of income and expense.
*
- * @param Collection $accounts
- * @param Carbon $start
- * @param Carbon $end
- *
* @return mixed|string
+ *
* @throws FireflyException
*/
public function operations(Collection $accounts, Carbon $start, Carbon $end)
{
// chart properties for cache:
- $cache = new CacheProperties();
+ $cache = new CacheProperties();
$cache->addProperty($start);
$cache->addProperty($end);
$cache->addProperty('inc-exp-report');
@@ -163,7 +152,7 @@ class OperationsController extends Controller
/** @var int $currencyId */
foreach ($keys as $currencyId) {
$currencyInfo = $incomes['sums'][$currencyId] ?? $expenses['sums'][$currencyId];
- $sums[$currencyId] = $sums[$currencyId] ?? [
+ $sums[$currencyId] ??= [
'currency_id' => $currencyId,
'currency_name' => $currencyInfo['currency_name'],
'currency_code' => $currencyInfo['currency_code'],
@@ -178,10 +167,11 @@ class OperationsController extends Controller
try {
$result = view('reports.partials.operations', compact('sums'))->render();
- } catch (Throwable $e) {
- Log::error(sprintf('Could not render reports.partials.operations: %s', $e->getMessage()));
- Log::error($e->getTraceAsString());
+ } catch (\Throwable $e) {
+ app('log')->error(sprintf('Could not render reports.partials.operations: %s', $e->getMessage()));
+ app('log')->error($e->getTraceAsString());
$result = 'Could not render view.';
+
throw new FireflyException($result, 0, $e);
}
$cache->store($result);
diff --git a/app/Http/Controllers/Report/TagController.php b/app/Http/Controllers/Report/TagController.php
index 8b43ead1db..a245845f82 100644
--- a/app/Http/Controllers/Report/TagController.php
+++ b/app/Http/Controllers/Report/TagController.php
@@ -31,12 +31,9 @@ use FireflyIII\Models\Tag;
use FireflyIII\Repositories\Tag\OperationsRepositoryInterface;
use Illuminate\Contracts\View\Factory;
use Illuminate\Support\Collection;
-use Illuminate\Support\Facades\Log;
use Illuminate\View\View;
-use Throwable;
/**
- *
* Class TagController
*/
class TagController extends Controller
@@ -45,8 +42,6 @@ class TagController extends Controller
/**
* ExpenseReportController constructor.
- *
-
*/
public function __construct()
{
@@ -61,22 +56,20 @@ class TagController extends Controller
}
/**
- * @param Collection $accounts
- * @param Collection $tags
- * @param Carbon $start
- * @param Carbon $end
- *
* @return Factory|View
+ *
+ * @SuppressWarnings(PHPMD.ExcessiveMethodLength)
*/
public function accountPerTag(Collection $accounts, Collection $tags, Carbon $start, Carbon $end)
{
$spent = $this->opsRepository->listExpenses($start, $end, $accounts, $tags);
$earned = $this->opsRepository->listIncome($start, $end, $accounts, $tags);
$report = [];
+
/** @var Account $account */
foreach ($accounts as $account) {
- $accountId = $account->id;
- $report[$accountId] = $report[$accountId] ?? [
+ $accountId = $account->id;
+ $report[$accountId] ??= [
'name' => $account->name,
'id' => $account->id,
'iban' => $account->iban,
@@ -90,9 +83,10 @@ class TagController extends Controller
/** @var array $tag */
foreach ($currency['tags'] as $tag) {
+ $tagId = $tag['id'];
foreach ($tag['transaction_journals'] as $journal) {
- $sourceAccountId = $journal['source_account_id'];
- $report[$sourceAccountId]['currencies'][$currencyId] = $report[$sourceAccountId]['currencies'][$currencyId] ?? [
+ $sourceAccountId = $journal['source_account_id'];
+ $report[$sourceAccountId]['currencies'][$currencyId] ??= [
'currency_id' => $currency['currency_id'],
'currency_symbol' => $currency['currency_symbol'],
'currency_name' => $currency['currency_name'],
@@ -100,20 +94,18 @@ class TagController extends Controller
'tags' => [],
];
- $report[$sourceAccountId]['currencies'][$currencyId]['tags'][$tag['id']]
- = $report[$sourceAccountId]['currencies'][$currencyId]['tags'][$tag['id']]
- ??
- [
- 'spent' => '0',
- 'earned' => '0',
- 'sum' => '0',
- ];
- $report[$sourceAccountId]['currencies'][$currencyId]['tags'][$tag['id']]['spent'] = bcadd(
- $report[$sourceAccountId]['currencies'][$currencyId]['tags'][$tag['id']]['spent'],
+ $report[$sourceAccountId]['currencies'][$currencyId]['tags'][$tagId]
+ ??= [
+ 'spent' => '0',
+ 'earned' => '0',
+ 'sum' => '0',
+ ];
+ $report[$sourceAccountId]['currencies'][$currencyId]['tags'][$tagId]['spent'] = bcadd(
+ $report[$sourceAccountId]['currencies'][$currencyId]['tags'][$tagId]['spent'],
$journal['amount']
);
- $report[$sourceAccountId]['currencies'][$currencyId]['tags'][$tag['id']]['sum'] = bcadd(
- $report[$sourceAccountId]['currencies'][$currencyId]['tags'][$tag['id']]['sum'],
+ $report[$sourceAccountId]['currencies'][$currencyId]['tags'][$tagId]['sum'] = bcadd(
+ $report[$sourceAccountId]['currencies'][$currencyId]['tags'][$tagId]['sum'],
$journal['amount']
);
}
@@ -125,31 +117,29 @@ class TagController extends Controller
/** @var array $tag */
foreach ($currency['tags'] as $tag) {
+ $tagId = $tag['id'];
foreach ($tag['transaction_journals'] as $journal) {
- $destinationId = $journal['destination_account_id'];
+ $destinationId = $journal['destination_account_id'];
$report[$destinationId]['currencies'][$currencyId]
- = $report[$destinationId]['currencies'][$currencyId]
- ?? [
- 'currency_id' => $currency['currency_id'],
- 'currency_symbol' => $currency['currency_symbol'],
- 'currency_name' => $currency['currency_name'],
- 'currency_decimal_places' => $currency['currency_decimal_places'],
- 'tags' => [],
- ];
- $report[$destinationId]['currencies'][$currencyId]['tags'][$tag['id']]
- = $report[$destinationId]['currencies'][$currencyId]['tags'][$tag['id']]
- ??
- [
- 'spent' => '0',
- 'earned' => '0',
- 'sum' => '0',
- ];
- $report[$destinationId]['currencies'][$currencyId]['tags'][$tag['id']]['earned'] = bcadd(
- $report[$destinationId]['currencies'][$currencyId]['tags'][$tag['id']]['earned'],
+ ??= [
+ 'currency_id' => $currency['currency_id'],
+ 'currency_symbol' => $currency['currency_symbol'],
+ 'currency_name' => $currency['currency_name'],
+ 'currency_decimal_places' => $currency['currency_decimal_places'],
+ 'tags' => [],
+ ];
+ $report[$destinationId]['currencies'][$currencyId]['tags'][$tagId]
+ ??= [
+ 'spent' => '0',
+ 'earned' => '0',
+ 'sum' => '0',
+ ];
+ $report[$destinationId]['currencies'][$currencyId]['tags'][$tagId]['earned'] = bcadd(
+ $report[$destinationId]['currencies'][$currencyId]['tags'][$tagId]['earned'],
$journal['amount']
);
- $report[$destinationId]['currencies'][$currencyId]['tags'][$tag['id']]['sum'] = bcadd(
- $report[$destinationId]['currencies'][$currencyId]['tags'][$tag['id']]['sum'],
+ $report[$destinationId]['currencies'][$currencyId]['tags'][$tagId]['sum'] = bcadd(
+ $report[$destinationId]['currencies'][$currencyId]['tags'][$tagId]['sum'],
$journal['amount']
);
}
@@ -160,12 +150,9 @@ class TagController extends Controller
}
/**
- * @param Collection $accounts
- * @param Collection $tags
- * @param Carbon $start
- * @param Carbon $end
- *
* @return Factory|View
+ *
+ * @SuppressWarnings(PHPMD.ExcessiveMethodLength)
*/
public function accounts(Collection $accounts, Collection $tags, Carbon $start, Carbon $end)
{
@@ -173,10 +160,11 @@ class TagController extends Controller
$earned = $this->opsRepository->listIncome($start, $end, $accounts, $tags);
$report = [];
$sums = [];
+
/** @var Account $account */
foreach ($accounts as $account) {
- $accountId = $account->id;
- $report[$accountId] = $report[$accountId] ?? [
+ $accountId = $account->id;
+ $report[$accountId] ??= [
'name' => $account->name,
'id' => $account->id,
'iban' => $account->iban,
@@ -186,8 +174,8 @@ class TagController extends Controller
// loop expenses.
foreach ($spent as $currency) {
- $currencyId = $currency['currency_id'];
- $sums[$currencyId] = $sums[$currencyId] ?? [
+ $currencyId = $currency['currency_id'];
+ $sums[$currencyId] ??= [
'currency_id' => $currency['currency_id'],
'currency_symbol' => $currency['currency_symbol'],
'currency_name' => $currency['currency_name'],
@@ -199,7 +187,7 @@ class TagController extends Controller
foreach ($currency['tags'] as $tag) {
foreach ($tag['transaction_journals'] as $journal) {
$sourceAccountId = $journal['source_account_id'];
- $report[$sourceAccountId]['currencies'][$currencyId] = $report[$sourceAccountId]['currencies'][$currencyId] ?? [
+ $report[$sourceAccountId]['currencies'][$currencyId] ??= [
'currency_id' => $currency['currency_id'],
'currency_symbol' => $currency['currency_symbol'],
'currency_name' => $currency['currency_name'],
@@ -224,8 +212,8 @@ class TagController extends Controller
// loop income.
foreach ($earned as $currency) {
- $currencyId = $currency['currency_id'];
- $sums[$currencyId] = $sums[$currencyId] ?? [
+ $currencyId = $currency['currency_id'];
+ $sums[$currencyId] ??= [
'currency_id' => $currency['currency_id'],
'currency_symbol' => $currency['currency_symbol'],
'currency_name' => $currency['currency_name'],
@@ -237,7 +225,7 @@ class TagController extends Controller
foreach ($currency['tags'] as $tag) {
foreach ($tag['transaction_journals'] as $journal) {
$destinationAccountId = $journal['destination_account_id'];
- $report[$destinationAccountId]['currencies'][$currencyId] = $report[$destinationAccountId]['currencies'][$currencyId] ?? [
+ $report[$destinationAccountId]['currencies'][$currencyId] ??= [
'currency_id' => $currency['currency_id'],
'currency_symbol' => $currency['currency_symbol'],
'currency_name' => $currency['currency_name'],
@@ -264,24 +252,20 @@ class TagController extends Controller
}
/**
- * @param Collection $accounts
- * @param Collection $tags
- * @param Carbon $start
- * @param Carbon $end
- *
* @return string
+ *
* @throws FireflyException
*/
public function avgExpenses(Collection $accounts, Collection $tags, Carbon $start, Carbon $end)
{
- $spent = $this->opsRepository->listExpenses($start, $end, $accounts, $tags);
- $result = [];
+ $spent = $this->opsRepository->listExpenses($start, $end, $accounts, $tags);
+ $result = [];
foreach ($spent as $currency) {
foreach ($currency['tags'] as $tag) {
foreach ($tag['transaction_journals'] as $journal) {
- $destinationId = $journal['destination_account_id'];
- $key = sprintf('%d-%d', $destinationId, $currency['currency_id']);
- $result[$key] = $result[$key] ?? [
+ $destinationId = $journal['destination_account_id'];
+ $key = sprintf('%d-%d', $destinationId, $currency['currency_id']);
+ $result[$key] ??= [
'transactions' => 0,
'sum' => '0',
'avg' => '0',
@@ -293,7 +277,7 @@ class TagController extends Controller
'currency_symbol' => $currency['currency_symbol'],
'currency_decimal_places' => $currency['currency_decimal_places'],
];
- $result[$key]['transactions']++;
+ ++$result[$key]['transactions'];
$result[$key]['sum'] = bcadd($journal['amount'], $result[$key]['sum']);
$result[$key]['avg'] = bcdiv($result[$key]['sum'], (string)$result[$key]['transactions']);
$result[$key]['avg_float'] = (float)$result[$key]['avg'];
@@ -307,9 +291,10 @@ class TagController extends Controller
try {
$result = view('reports.tag.partials.avg-expenses', compact('result'))->render();
- } catch (Throwable $e) {
- Log::debug(sprintf('Could not render reports.partials.budget-period: %s', $e->getMessage()));
+ } catch (\Throwable $e) {
+ app('log')->debug(sprintf('Could not render reports.partials.budget-period: %s', $e->getMessage()));
$result = sprintf('Could not render view: %s', $e->getMessage());
+
throw new FireflyException($result, 0, $e);
}
@@ -317,24 +302,20 @@ class TagController extends Controller
}
/**
- * @param Collection $accounts
- * @param Collection $tags
- * @param Carbon $start
- * @param Carbon $end
- *
* @return string
+ *
* @throws FireflyException
*/
public function avgIncome(Collection $accounts, Collection $tags, Carbon $start, Carbon $end)
{
- $spent = $this->opsRepository->listIncome($start, $end, $accounts, $tags);
- $result = [];
+ $spent = $this->opsRepository->listIncome($start, $end, $accounts, $tags);
+ $result = [];
foreach ($spent as $currency) {
foreach ($currency['tags'] as $tag) {
foreach ($tag['transaction_journals'] as $journal) {
- $sourceId = $journal['source_account_id'];
- $key = sprintf('%d-%d', $sourceId, $currency['currency_id']);
- $result[$key] = $result[$key] ?? [
+ $sourceId = $journal['source_account_id'];
+ $key = sprintf('%d-%d', $sourceId, $currency['currency_id']);
+ $result[$key] ??= [
'transactions' => 0,
'sum' => '0',
'avg' => '0',
@@ -346,7 +327,7 @@ class TagController extends Controller
'currency_symbol' => $currency['currency_symbol'],
'currency_decimal_places' => $currency['currency_decimal_places'],
];
- $result[$key]['transactions']++;
+ ++$result[$key]['transactions'];
$result[$key]['sum'] = bcadd($journal['amount'], $result[$key]['sum']);
$result[$key]['avg'] = bcdiv($result[$key]['sum'], (string)$result[$key]['transactions']);
$result[$key]['avg_float'] = (float)$result[$key]['avg'];
@@ -360,9 +341,10 @@ class TagController extends Controller
try {
$result = view('reports.tag.partials.avg-income', compact('result'))->render();
- } catch (Throwable $e) {
- Log::debug(sprintf('Could not render reports.partials.budget-period: %s', $e->getMessage()));
+ } catch (\Throwable $e) {
+ app('log')->debug(sprintf('Could not render reports.partials.budget-period: %s', $e->getMessage()));
$result = sprintf('Could not render view: %s', $e->getMessage());
+
throw new FireflyException($result, 0, $e);
}
@@ -370,12 +352,9 @@ class TagController extends Controller
}
/**
- * @param Collection $accounts
- * @param Collection $tags
- * @param Carbon $start
- * @param Carbon $end
- *
* @return Factory|View
+ *
+ * @SuppressWarnings(PHPMD.ExcessiveMethodLength)
*/
public function tags(Collection $accounts, Collection $tags, Carbon $start, Carbon $end)
{
@@ -383,18 +362,19 @@ class TagController extends Controller
$earned = $this->opsRepository->listIncome($start, $end, $accounts, $tags);
$sums = [];
$report = [];
+
/** @var Tag $tag */
foreach ($tags as $tag) {
- $tagId = $tag->id;
- $report[$tagId] = $report[$tagId] ?? [
+ $tagId = $tag->id;
+ $report[$tagId] ??= [
'name' => $tag->tag,
'id' => $tag->id,
'currencies' => [],
];
}
foreach ($spent as $currency) {
- $currencyId = $currency['currency_id'];
- $sums[$currencyId] = $sums[$currencyId] ?? [
+ $currencyId = $currency['currency_id'];
+ $sums[$currencyId] ??= [
'currency_id' => $currency['currency_id'],
'currency_symbol' => $currency['currency_symbol'],
'currency_name' => $currency['currency_name'],
@@ -403,39 +383,36 @@ class TagController extends Controller
'spent_sum' => '0',
'total_sum' => '0',
];
+
/** @var array $tag */
foreach ($currency['tags'] as $tag) {
$tagId = $tag['id'];
-
+ if (!array_key_exists($tagId, $report)) {
+ continue;
+ }
foreach ($tag['transaction_journals'] as $journal) {
// add currency info to report array:
- $report[$tagId]['currencies'][$currencyId] = $report[$tagId]['currencies'][$currencyId] ?? [
+ $report[$tagId]['currencies'][$currencyId] ??= [
'spent' => '0',
'earned' => '0',
+ $tagId => $tagId,
'sum' => '0',
'currency_id' => $currency['currency_id'],
'currency_symbol' => $currency['currency_symbol'],
'currency_name' => $currency['currency_name'],
'currency_decimal_places' => $currency['currency_decimal_places'],
];
- $report[$tagId]['currencies'][$currencyId]['spent'] = bcadd(
- $report[$tagId]['currencies'][$currencyId]['spent'],
- $journal['amount']
- );
- $report[$tagId]['currencies'][$currencyId]['sum'] = bcadd(
- $report[$tagId]['currencies'][$currencyId]['sum'],
- $journal['amount']
- );
-
- $sums[$currencyId]['spent_sum'] = bcadd($sums[$currencyId]['spent_sum'], $journal['amount']);
- $sums[$currencyId]['total_sum'] = bcadd($sums[$currencyId]['total_sum'], $journal['amount']);
+ $report[$tagId]['currencies'][$currencyId]['spent'] = bcadd($report[$tagId]['currencies'][$currencyId]['spent'], $journal['amount']);
+ $report[$tagId]['currencies'][$currencyId]['sum'] = bcadd($report[$tagId]['currencies'][$currencyId]['sum'], $journal['amount']);
+ $sums[$currencyId]['spent_sum'] = bcadd($sums[$currencyId]['spent_sum'], $journal['amount']);
+ $sums[$currencyId]['total_sum'] = bcadd($sums[$currencyId]['total_sum'], $journal['amount']);
}
}
}
foreach ($earned as $currency) {
- $currencyId = $currency['currency_id'];
- $sums[$currencyId] = $sums[$currencyId] ?? [
+ $currencyId = $currency['currency_id'];
+ $sums[$currencyId] ??= [
'currency_id' => $currency['currency_id'],
'currency_symbol' => $currency['currency_symbol'],
'currency_name' => $currency['currency_name'],
@@ -444,32 +421,29 @@ class TagController extends Controller
'spent_sum' => '0',
'total_sum' => '0',
];
+
/** @var array $tag */
foreach ($currency['tags'] as $tag) {
$tagId = $tag['id'];
-
+ if (!array_key_exists($tagId, $report)) {
+ continue;
+ }
foreach ($tag['transaction_journals'] as $journal) {
// add currency info to report array:
- $report[$tagId]['currencies'][$currencyId] = $report[$tagId]['currencies'][$currencyId] ?? [
+ $report[$tagId]['currencies'][$currencyId] ??= [
'spent' => '0',
'earned' => '0',
'sum' => '0',
+ $tagId => $tagId,
'currency_id' => $currency['currency_id'],
'currency_symbol' => $currency['currency_symbol'],
'currency_name' => $currency['currency_name'],
'currency_decimal_places' => $currency['currency_decimal_places'],
];
- $report[$tagId]['currencies'][$currencyId]['earned'] = bcadd(
- $report[$tagId]['currencies'][$currencyId]['earned'],
- $journal['amount']
- );
- $report[$tagId]['currencies'][$currencyId]['sum'] = bcadd(
- $report[$tagId]['currencies'][$currencyId]['sum'],
- $journal['amount']
- );
-
- $sums[$currencyId]['earned_sum'] = bcadd($sums[$currencyId]['earned_sum'], $journal['amount']);
- $sums[$currencyId]['total_sum'] = bcadd($sums[$currencyId]['total_sum'], $journal['amount']);
+ $report[$tagId]['currencies'][$currencyId]['earned'] = bcadd($report[$tagId]['currencies'][$currencyId]['earned'], $journal['amount']);
+ $report[$tagId]['currencies'][$currencyId]['sum'] = bcadd($report[$tagId]['currencies'][$currencyId]['sum'], $journal['amount']);
+ $sums[$currencyId]['earned_sum'] = bcadd($sums[$currencyId]['earned_sum'], $journal['amount']);
+ $sums[$currencyId]['total_sum'] = bcadd($sums[$currencyId]['total_sum'], $journal['amount']);
}
}
}
@@ -478,18 +452,14 @@ class TagController extends Controller
}
/**
- * @param Collection $accounts
- * @param Collection $tags
- * @param Carbon $start
- * @param Carbon $end
- *
* @return string
+ *
* @throws FireflyException
*/
public function topExpenses(Collection $accounts, Collection $tags, Carbon $start, Carbon $end)
{
- $spent = $this->opsRepository->listExpenses($start, $end, $accounts, $tags);
- $result = [];
+ $spent = $this->opsRepository->listExpenses($start, $end, $accounts, $tags);
+ $result = [];
foreach ($spent as $currency) {
foreach ($currency['tags'] as $tag) {
foreach ($tag['transaction_journals'] as $journal) {
@@ -519,9 +489,10 @@ class TagController extends Controller
try {
$result = view('reports.tag.partials.top-expenses', compact('result'))->render();
- } catch (Throwable $e) {
- Log::debug(sprintf('Could not render reports.partials.budget-period: %s', $e->getMessage()));
+ } catch (\Throwable $e) {
+ app('log')->debug(sprintf('Could not render reports.partials.budget-period: %s', $e->getMessage()));
$result = sprintf('Could not render view: %s', $e->getMessage());
+
throw new FireflyException($result, 0, $e);
}
@@ -529,18 +500,14 @@ class TagController extends Controller
}
/**
- * @param Collection $accounts
- * @param Collection $tags
- * @param Carbon $start
- * @param Carbon $end
- *
* @return string
+ *
* @throws FireflyException
*/
public function topIncome(Collection $accounts, Collection $tags, Carbon $start, Carbon $end)
{
- $spent = $this->opsRepository->listIncome($start, $end, $accounts, $tags);
- $result = [];
+ $spent = $this->opsRepository->listIncome($start, $end, $accounts, $tags);
+ $result = [];
foreach ($spent as $currency) {
foreach ($currency['tags'] as $tag) {
foreach ($tag['transaction_journals'] as $journal) {
@@ -570,9 +537,10 @@ class TagController extends Controller
try {
$result = view('reports.tag.partials.top-income', compact('result'))->render();
- } catch (Throwable $e) {
- Log::debug(sprintf('Could not render reports.partials.budget-period: %s', $e->getMessage()));
+ } catch (\Throwable $e) {
+ app('log')->debug(sprintf('Could not render reports.partials.budget-period: %s', $e->getMessage()));
$result = sprintf('Could not render view: %s', $e->getMessage());
+
throw new FireflyException($result, 0, $e);
}
diff --git a/app/Http/Controllers/ReportController.php b/app/Http/Controllers/ReportController.php
index 029dce0424..67d8344fee 100644
--- a/app/Http/Controllers/ReportController.php
+++ b/app/Http/Controllers/ReportController.php
@@ -38,24 +38,17 @@ use Illuminate\Http\JsonResponse;
use Illuminate\Http\RedirectResponse;
use Illuminate\Routing\Redirector;
use Illuminate\Support\Collection;
-use Illuminate\Support\Facades\Log;
use Illuminate\View\View;
-use Psr\Container\ContainerExceptionInterface;
-use Psr\Container\NotFoundExceptionInterface;
/**
* Class ReportController.
- *
*/
class ReportController extends Controller
{
use RenderPartialViews;
- /** @var ReportHelperInterface Helper interface. */
- protected $helper;
-
- /** @var BudgetRepositoryInterface The budget repository */
- private $repository;
+ protected ReportHelperInterface $helper;
+ private BudgetRepositoryInterface $repository;
/**
* ReportController constructor.
@@ -80,11 +73,7 @@ class ReportController extends Controller
/**
* Show audit report.
*
- * @param Collection $accounts
- * @param Carbon $start
- * @param Carbon $end
- *
- * @return Factory|View|string
+ * @return Factory|string|View
*
* @throws FireflyException
*/
@@ -115,12 +104,7 @@ class ReportController extends Controller
/**
* Show budget report.
*
- * @param Collection $accounts
- * @param Collection $budgets
- * @param Carbon $start
- * @param Carbon $end
- *
- * @return Factory|View|string
+ * @return Factory|string|View
*
* @throws FireflyException
*/
@@ -152,12 +136,7 @@ class ReportController extends Controller
/**
* Show category report.
*
- * @param Collection $accounts
- * @param Collection $categories
- * @param Carbon $start
- * @param Carbon $end
- *
- * @return Factory|View|string
+ * @return Factory|string|View
*
* @throws FireflyException
*/
@@ -189,11 +168,7 @@ class ReportController extends Controller
/**
* Show default report.
*
- * @param Collection $accounts
- * @param Carbon $start
- * @param Carbon $end
- *
- * @return Factory|View|string
+ * @return Factory|string|View
*
* @throws FireflyException
*/
@@ -225,12 +200,8 @@ class ReportController extends Controller
/**
* Show account report.
*
- * @param Collection $accounts
- * @param Collection $expense
- * @param Carbon $start
- * @param Carbon $end
- *
* @return string
+ *
* @throws FireflyException
*/
public function doubleReport(Collection $accounts, Collection $expense, Carbon $start, Carbon $end)
@@ -262,11 +233,7 @@ class ReportController extends Controller
/**
* Show index.
*
- * @param AccountRepositoryInterface $repository
- *
* @return Factory|View
- * @throws ContainerExceptionInterface
- * @throws NotFoundExceptionInterface
*/
public function index(AccountRepositoryInterface $repository)
{
@@ -279,11 +246,12 @@ class ReportController extends Controller
);
// group accounts by role:
- $groupedAccounts = [];
+ $groupedAccounts = [];
+
/** @var Account $account */
foreach ($accounts as $account) {
- $type = $account->accountType->type;
- $role = sprintf('opt_group_%s', $repository->getMetaValue($account, 'account_role'));
+ $type = $account->accountType->type;
+ $role = sprintf('opt_group_%s', $repository->getMetaValue($account, 'account_role'));
if (in_array($type, [AccountType::MORTGAGE, AccountType::DEBT, AccountType::LOAN], true)) {
$role = sprintf('opt_group_l_%s', $type);
@@ -292,11 +260,11 @@ class ReportController extends Controller
if ('opt_group_' === $role) {
$role = 'opt_group_defaultAsset';
}
- $groupedAccounts[trans(sprintf('firefly.%s', $role))][$account->id] = $account;
+ $groupedAccounts[(string)trans(sprintf('firefly.%s', $role))][$account->id] = $account;
}
ksort($groupedAccounts);
- $accountList = implode(',', $accounts->pluck('id')->toArray());
+ $accountList = implode(',', $accounts->pluck('id')->toArray());
$this->repository->cleanupBudgets();
return view('reports.index', compact('months', 'accounts', 'start', 'accountList', 'groupedAccounts', 'customFiscalYear'));
@@ -305,9 +273,8 @@ class ReportController extends Controller
/**
* Show options for reports.
*
- * @param string $reportType
- *
* @return JsonResponse
+ *
* @throws FireflyException
*/
public function options(string $reportType)
@@ -326,14 +293,9 @@ class ReportController extends Controller
/**
* Process the submit of report.
*
- * @param ReportFormRequest $request
- *
- * @return RedirectResponse|Redirector
- *
* @throws FireflyException
- *
*/
- public function postIndex(ReportFormRequest $request)
+ public function postIndex(ReportFormRequest $request): Redirector|RedirectResponse|View
{
// report type:
$reportType = $request->get('report_type');
@@ -346,7 +308,7 @@ class ReportController extends Controller
$double = implode(',', $request->getDoubleList()->pluck('id')->toArray());
if (0 === $request->getAccountList()->count()) {
- Log::debug('Account count is zero');
+ app('log')->debug('Account count is zero');
session()->flash('error', (string)trans('firefly.select_at_least_one_account'));
return redirect(route('reports.index'));
@@ -380,7 +342,7 @@ class ReportController extends Controller
return view('error')->with('message', (string)trans('firefly.end_after_start_date'));
}
- $url = match ($reportType) {
+ $url = match ($reportType) {
default => route('reports.report.default', [$accounts, $start, $end]),
'category' => route('reports.report.category', [$accounts, $categories, $start, $end]),
'audit' => route('reports.report.audit', [$accounts, $start, $end]),
@@ -395,12 +357,8 @@ class ReportController extends Controller
/**
* Get a tag report.
*
- * @param Collection $accounts
- * @param Collection $tags
- * @param Carbon $start
- * @param Carbon $end
+ * @return Factory|string|View
*
- * @return Factory|View|string
* @throws FireflyException
*/
public function tagReport(Collection $accounts, Collection $tags, Carbon $start, Carbon $end)
diff --git a/app/Http/Controllers/Rule/CreateController.php b/app/Http/Controllers/Rule/CreateController.php
index eb42aa0b03..6d35df8e28 100644
--- a/app/Http/Controllers/Rule/CreateController.php
+++ b/app/Http/Controllers/Rule/CreateController.php
@@ -45,15 +45,13 @@ use Illuminate\View\View;
*/
class CreateController extends Controller
{
- use RuleManagement;
use ModelInformation;
+ use RuleManagement;
private RuleRepositoryInterface $ruleRepos;
/**
* RuleController constructor.
- *
-
*/
public function __construct()
{
@@ -74,39 +72,39 @@ class CreateController extends Controller
/**
* Create a new rule. It will be stored under the given $ruleGroup.
*
- * @param Request $request
- * @param RuleGroup|null $ruleGroup
- *
* @return Factory|View
+ *
* @throws FireflyException
*/
public function create(Request $request, RuleGroup $ruleGroup = null)
{
$this->createDefaultRuleGroup();
- $preFilled = [
+ $preFilled = [
'strict' => true,
];
- $oldTriggers = [];
- $oldActions = [];
+ $oldTriggers = [];
+ $oldActions = [];
// build triggers from query, if present.
- $query = (string)$request->get('from_query');
+ $query = (string)$request->get('from_query');
if ('' !== $query) {
- $search = app(SearchInterface::class);
+ $search = app(SearchInterface::class);
$search->parseQuery($query);
- $words = $search->getWordsAsString();
- $operators = $search->getOperators()->toArray();
+ $words = $search->getWordsAsString();
+ $operators = $search->getOperators()->toArray();
if ('' !== $words) {
session()->flash('warning', trans('firefly.rule_from_search_words', ['string' => $words]));
$operators[] = [
'type' => 'description_contains',
- 'value' => $words];
+ 'value' => $words,
+ ];
}
$oldTriggers = $this->parseFromOperators($operators);
}
+ // var_dump($oldTriggers);exit;
// restore actions and triggers from old input:
- if ($request->old()) {
+ if (is_array($request->old()) && count($request->old()) > 0) {
$oldTriggers = $this->getPreviousTriggers($request);
$oldActions = $this->getPreviousActions($request);
}
@@ -116,7 +114,7 @@ class CreateController extends Controller
$subTitleIcon = 'fa-clone';
// title depends on whether or not there is a rule group:
- $subTitle = (string)trans('firefly.make_new_rule_no_group');
+ $subTitle = (string)trans('firefly.make_new_rule_no_group');
if (null !== $ruleGroup) {
$subTitle = (string)trans('firefly.make_new_rule', ['title' => $ruleGroup->title]);
}
@@ -139,10 +137,8 @@ class CreateController extends Controller
/**
* Create a new rule. It will be stored under the given $ruleGroup.
*
- * @param Request $request
- * @param Bill $bill
- *
* @return Factory|View
+ *
* @throws FireflyException
*/
public function createFromBill(Request $request, Bill $bill)
@@ -150,7 +146,7 @@ class CreateController extends Controller
$request->session()->flash('info', (string)trans('firefly.instructions_rule_from_bill', ['name' => e($bill->name)]));
$this->createDefaultRuleGroup();
- $preFilled = [
+ $preFilled = [
'strict' => true,
'title' => (string)trans('firefly.new_rule_for_bill_title', ['name' => $bill->name]),
'description' => (string)trans('firefly.new_rule_for_bill_description', ['name' => $bill->name]),
@@ -159,11 +155,11 @@ class CreateController extends Controller
// make triggers and actions from the bill itself.
// get triggers and actions for bill:
- $oldTriggers = $this->getTriggersForBill($bill);
- $oldActions = $this->getActionsForBill($bill);
+ $oldTriggers = $this->getTriggersForBill($bill);
+ $oldActions = $this->getActionsForBill($bill);
// restore actions and triggers from old input:
- if ($request->old()) {
+ if (null !== $request->old() && is_array($request->old()) && count($request->old()) > 0) {
$oldTriggers = $this->getPreviousTriggers($request);
$oldActions = $this->getPreviousActions($request);
}
@@ -172,8 +168,8 @@ class CreateController extends Controller
$actionCount = count($oldActions);
$subTitleIcon = 'fa-clone';
- // title depends on whether or not there is a rule group:
- $subTitle = (string)trans('firefly.make_new_rule_no_group');
+ // title depends on whether there is a rule group:
+ $subTitle = (string)trans('firefly.make_new_rule_no_group');
// flash old data
$request->session()->flash('preFilled', $preFilled);
@@ -191,10 +187,8 @@ class CreateController extends Controller
}
/**
- * @param Request $request
- * @param TransactionJournal $journal
- *
* @return Factory|\Illuminate\Contracts\View\View
+ *
* @throws FireflyException
*/
public function createFromJournal(Request $request, TransactionJournal $journal)
@@ -205,20 +199,20 @@ class CreateController extends Controller
$subTitle = (string)trans('firefly.make_new_rule_no_group');
// get triggers and actions for journal.
- $oldTriggers = $this->getTriggersForJournal($journal);
- $oldActions = [];
+ $oldTriggers = $this->getTriggersForJournal($journal);
+ $oldActions = [];
$this->createDefaultRuleGroup();
// collect pre-filled information:
- $preFilled = [
+ $preFilled = [
'strict' => true,
'title' => (string)trans('firefly.new_rule_for_journal_title', ['description' => $journal->description]),
'description' => (string)trans('firefly.new_rule_for_journal_description', ['description' => $journal->description]),
];
// restore actions and triggers from old input:
- if ($request->old()) {
+ if (null !== $request->old() && is_array($request->old()) && count($request->old()) > 0) {
$oldTriggers = $this->getPreviousTriggers($request);
$oldActions = $this->getPreviousActions($request);
}
@@ -241,11 +235,6 @@ class CreateController extends Controller
);
}
- /**
- * @param Request $request
- *
- * @return JsonResponse
- */
public function duplicate(Request $request): JsonResponse
{
$ruleId = (int)$request->get('id');
@@ -260,16 +249,13 @@ class CreateController extends Controller
/**
* Store the new rule.
*
- * @param RuleFormRequest $request
- *
- * @return RedirectResponse|Redirector
- *
+ * @return Redirector|RedirectResponse
*/
public function store(RuleFormRequest $request)
{
- $data = $request->getRuleData();
+ $data = $request->getRuleData();
- $rule = $this->ruleRepos->store($data);
+ $rule = $this->ruleRepos->store($data);
session()->flash('success', (string)trans('firefly.stored_new_rule', ['title' => $rule->title]));
app('preferences')->mark();
diff --git a/app/Http/Controllers/Rule/DeleteController.php b/app/Http/Controllers/Rule/DeleteController.php
index 5f208b1735..73e5e04f01 100644
--- a/app/Http/Controllers/Rule/DeleteController.php
+++ b/app/Http/Controllers/Rule/DeleteController.php
@@ -40,8 +40,6 @@ class DeleteController extends Controller
/**
* RuleController constructor.
- *
-
*/
public function __construct()
{
@@ -62,8 +60,6 @@ class DeleteController extends Controller
/**
* Delete a given rule.
*
- * @param Rule $rule
- *
* @return Factory|View
*/
public function delete(Rule $rule)
@@ -78,10 +74,6 @@ class DeleteController extends Controller
/**
* Actually destroy the given rule.
- *
- * @param Rule $rule
- *
- * @return RedirectResponse
*/
public function destroy(Rule $rule): RedirectResponse
{
diff --git a/app/Http/Controllers/Rule/EditController.php b/app/Http/Controllers/Rule/EditController.php
index de93bb2839..a4412d17ab 100644
--- a/app/Http/Controllers/Rule/EditController.php
+++ b/app/Http/Controllers/Rule/EditController.php
@@ -36,24 +36,20 @@ use Illuminate\Contracts\View\Factory;
use Illuminate\Http\RedirectResponse;
use Illuminate\Http\Request;
use Illuminate\Routing\Redirector;
-use Illuminate\Support\Facades\Log;
use Illuminate\View\View;
-use Throwable;
/**
* Class EditController
*/
class EditController extends Controller
{
- use RuleManagement;
use RenderPartialViews;
+ use RuleManagement;
private RuleRepositoryInterface $ruleRepos;
/**
* RuleController constructor.
- *
-
*/
public function __construct()
{
@@ -74,26 +70,24 @@ class EditController extends Controller
/**
* Edit a rule.
*
- * @param Request $request
- * @param Rule $rule
- *
* @return Factory|View
+ *
* @throws FireflyException
*/
public function edit(Request $request, Rule $rule)
{
- $triggerCount = 0;
- $actionCount = 0;
- $oldActions = [];
- $oldTriggers = [];
+ $triggerCount = 0;
+ $actionCount = 0;
+ $oldActions = [];
+ $oldTriggers = [];
// build triggers from query, if present.
- $query = (string)$request->get('from_query');
+ $query = (string)$request->get('from_query');
if ('' !== $query) {
- $search = app(SearchInterface::class);
+ $search = app(SearchInterface::class);
$search->parseQuery($query);
- $words = $search->getWordsAsString();
- $operators = $search->getOperators()->toArray();
+ $words = $search->getWordsAsString();
+ $operators = $search->getOperators()->toArray();
if ('' !== $words) {
session()->flash('warning', trans('firefly.rule_from_search_words', ['string' => $words]));
$operators[] = ['type' => 'description_contains', 'value' => $words];
@@ -101,12 +95,12 @@ class EditController extends Controller
$oldTriggers = $this->parseFromOperators($operators);
}
// has old input?
- if (count($request->old()) > 0) {
+ if (null !== $request->old() && is_array($request->old()) && count($request->old()) > 0) {
$oldTriggers = $this->getPreviousTriggers($request);
$oldActions = $this->getPreviousActions($request);
}
- $triggerCount = count($oldTriggers);
- $actionCount = count($oldActions);
+ $triggerCount = count($oldTriggers);
+ $actionCount = count($oldActions);
// overrule old input and query data when it has no rule data:
if (0 === $triggerCount && 0 === $actionCount) {
@@ -116,12 +110,11 @@ class EditController extends Controller
$actionCount = count($oldActions);
}
- $hasOldInput = null !== $request->old('_token');
- $preFilled = [
+ $hasOldInput = null !== $request->old('_token');
+ $preFilled = [
'active' => $hasOldInput ? (bool)$request->old('active') : $rule->active,
'stop_processing' => $hasOldInput ? (bool)$request->old('stop_processing') : $rule->stop_processing,
'strict' => $hasOldInput ? (bool)$request->old('strict') : $rule->strict,
-
];
// get rule trigger for update / store-journal:
@@ -140,9 +133,6 @@ class EditController extends Controller
}
/**
- * @param array $submittedOperators
- *
- * @return array
* @throws FireflyException
*/
private function parseFromOperators(array $submittedOperators): array
@@ -158,7 +148,7 @@ class EditController extends Controller
}
asort($triggers);
- $index = 0;
+ $index = 0;
foreach ($submittedOperators as $operator) {
try {
$renderedEntries[] = view(
@@ -171,13 +161,14 @@ class EditController extends Controller
'triggers' => $triggers,
]
)->render();
- } catch (Throwable $e) {
+ } catch (\Throwable $e) {
$message = sprintf('Throwable was thrown in getPreviousTriggers(): %s', $e->getMessage());
- Log::debug($message);
- Log::error($e->getTraceAsString());
+ app('log')->debug($message);
+ app('log')->error($e->getTraceAsString());
+
throw new FireflyException($message, 0, $e);
}
- $index++;
+ ++$index;
}
return $renderedEntries;
@@ -186,14 +177,11 @@ class EditController extends Controller
/**
* Update the rule.
*
- * @param RuleFormRequest $request
- * @param Rule $rule
- *
- * @return RedirectResponse|Redirector
+ * @return Redirector|RedirectResponse
*/
public function update(RuleFormRequest $request, Rule $rule)
{
- $data = $request->getRuleData();
+ $data = $request->getRuleData();
$this->ruleRepos->update($rule, $data);
diff --git a/app/Http/Controllers/Rule/IndexController.php b/app/Http/Controllers/Rule/IndexController.php
index f4dec56a96..d86f902c36 100644
--- a/app/Http/Controllers/Rule/IndexController.php
+++ b/app/Http/Controllers/Rule/IndexController.php
@@ -47,8 +47,6 @@ class IndexController extends Controller
/**
* RuleController constructor.
- *
-
*/
public function __construct()
{
@@ -79,26 +77,14 @@ class IndexController extends Controller
return view('rules.index', compact('ruleGroups'));
}
- /**
- * @param Request $request
- * @param Rule $rule
- * @param RuleGroup $ruleGroup
- *
- * @return JsonResponse
- */
public function moveRule(Request $request, Rule $rule, RuleGroup $ruleGroup): JsonResponse
{
$order = (int)$request->get('order');
- $this->ruleRepos->moveRule($rule, $ruleGroup, (int)$order);
+ $this->ruleRepos->moveRule($rule, $ruleGroup, $order);
return response()->json([]);
}
- /**
- * @param Rule $rule
- *
- * @return RedirectResponse
- */
public function search(Rule $rule): RedirectResponse
{
$route = route('search.index');
diff --git a/app/Http/Controllers/Rule/SelectController.php b/app/Http/Controllers/Rule/SelectController.php
index 89a3317702..c03a823ee3 100644
--- a/app/Http/Controllers/Rule/SelectController.php
+++ b/app/Http/Controllers/Rule/SelectController.php
@@ -32,19 +32,15 @@ use FireflyIII\Models\Rule;
use FireflyIII\Models\RuleTrigger;
use FireflyIII\Support\Http\Controllers\RuleManagement;
use FireflyIII\TransactionRules\Engine\RuleEngineInterface;
-use FireflyIII\TransactionRules\TransactionMatcher;
use FireflyIII\User;
use Illuminate\Contracts\View\Factory;
use Illuminate\Http\JsonResponse;
use Illuminate\Http\RedirectResponse;
use Illuminate\Support\Collection;
-use Illuminate\Support\Facades\Log;
use Illuminate\View\View;
-use Throwable;
/**
* Class SelectController.
- *
*/
class SelectController extends Controller
{
@@ -58,7 +54,7 @@ class SelectController extends Controller
parent::__construct();
$this->middleware(
- function ($request, $next) {
+ static function ($request, $next) {
app('view')->share('title', (string)trans('firefly.rules'));
app('view')->share('mainTitleIcon', 'fa-random');
@@ -69,20 +65,15 @@ class SelectController extends Controller
/**
* Execute the given rule on a set of existing transactions.
- *
- * @param SelectTransactionsRequest $request
- * @param Rule $rule
- *
- * @return RedirectResponse
*/
public function execute(SelectTransactionsRequest $request, Rule $rule): RedirectResponse
{
// Get parameters specified by the user
/** @var User $user */
- $user = auth()->user();
- $accounts = implode(',', $request->get('accounts'));
- $startDate = new Carbon($request->get('start'));
- $endDate = new Carbon($request->get('end'));
+ $user = auth()->user();
+ $accounts = implode(',', $request->get('accounts'));
+ $startDate = new Carbon($request->get('start'));
+ $endDate = new Carbon($request->get('end'));
// create new rule engine:
$newRuleEngine = app(RuleEngineInterface::class);
@@ -96,21 +87,17 @@ class SelectController extends Controller
// set rules:
$newRuleEngine->setRules(new Collection([$rule]));
$newRuleEngine->fire();
- $resultCount = $newRuleEngine->getResults();
+ $resultCount = $newRuleEngine->getResults();
- session()->flash('success', (string)trans_choice('firefly.applied_rule_selection', $resultCount, ['title' => $rule->title]));
+ session()->flash('success', trans_choice('firefly.applied_rule_selection', $resultCount, ['title' => $rule->title]));
return redirect()->route('rules.index');
}
/**
* View to select transactions by a rule.
- *
- * @param Rule $rule
- *
- * @return Factory|View
*/
- public function selectTransactions(Rule $rule)
+ public function selectTransactions(Rule $rule): Factory|RedirectResponse|View
{
if (false === $rule->active) {
session()->flash('warning', trans('firefly.cannot_fire_inactive_rules'));
@@ -129,20 +116,19 @@ class SelectController extends Controller
* This method allows the user to test a certain set of rule triggers. The rule triggers are passed along
* using the URL parameters (GET), and are usually put there using a Javascript thing.
*
- * @param TestRuleFormRequest $request
- *
- * @return JsonResponse
* @throws FireflyException
*/
public function testTriggers(TestRuleFormRequest $request): JsonResponse
{
// build fake rule
- $rule = new Rule();
- $triggers = new Collection();
- $rule->strict = '1' === $request->get('strict');
+ $rule = new Rule();
+
+ /** @var \Illuminate\Database\Eloquent\Collection $triggers */
+ $triggers = new Collection();
+ $rule->strict = '1' === $request->get('strict');
// build trigger array from response
- $textTriggers = $this->getValidTriggerList($request);
+ $textTriggers = $this->getValidTriggerList($request);
// warn if nothing.
if (0 === count($textTriggers)) {
@@ -150,9 +136,13 @@ class SelectController extends Controller
}
foreach ($textTriggers as $textTrigger) {
+ $needsContext = config(sprintf('search.operators.%s.needs_context', $textTrigger['type'])) ?? true;
$trigger = new RuleTrigger();
$trigger->trigger_type = $textTrigger['type'];
$trigger->trigger_value = $textTrigger['value'];
+ if (false === $needsContext) {
+ $trigger->trigger_value = 'true';
+ }
$trigger->stop_processing = $textTrigger['stop_processing'];
if ($textTrigger['prohibited']) {
$trigger->trigger_type = sprintf('-%s', $textTrigger['type']);
@@ -164,28 +154,30 @@ class SelectController extends Controller
// create new rule engine:
/** @var RuleEngineInterface $newRuleEngine */
- $newRuleEngine = app(RuleEngineInterface::class);
+ $newRuleEngine = app(RuleEngineInterface::class);
// set rules:
$newRuleEngine->setRules(new Collection([$rule]));
$newRuleEngine->setRefreshTriggers(false);
- $collection = $newRuleEngine->find();
- $collection = $collection->slice(0, 20);
+ $collection = $newRuleEngine->find();
+ $collection = $collection->slice(0, 20);
// Warn the user if only a subset of transactions is returned
- $warning = '';
+ $warning = '';
if (0 === count($collection)) {
$warning = (string)trans('firefly.warning_no_matching_transactions');
}
// Return json response
- $view = 'ERROR, see logs.';
+ $view = 'ERROR, see logs.';
+
try {
$view = view('list.journals-array-tiny', ['groups' => $collection])->render();
- } catch (Throwable $exception) {
- Log::error(sprintf('Could not render view in testTriggers(): %s', $exception->getMessage()));
- Log::error($exception->getTraceAsString());
+ } catch (\Throwable $exception) {
+ app('log')->error(sprintf('Could not render view in testTriggers(): %s', $exception->getMessage()));
+ app('log')->error($exception->getTraceAsString());
$view = sprintf('Could not render list.journals-tiny: %s', $exception->getMessage());
+
throw new FireflyException($view, 0, $exception);
}
@@ -196,14 +188,11 @@ class SelectController extends Controller
* This method allows the user to test a certain set of rule triggers. The rule triggers are grabbed from
* the rule itself.
*
- * @param Rule $rule
- *
- * @return JsonResponse
* @throws FireflyException
*/
public function testTriggersByRule(Rule $rule): JsonResponse
{
- $triggers = $rule->ruleTriggers;
+ $triggers = $rule->ruleTriggers;
if (0 === count($triggers)) {
return response()->json(['html' => '', 'warning' => (string)trans('firefly.warning_no_valid_triggers')]);
@@ -213,22 +202,24 @@ class SelectController extends Controller
// set rules:
$newRuleEngine->setRules(new Collection([$rule]));
- $collection = $newRuleEngine->find();
- $collection = $collection->slice(0, 20);
+ $collection = $newRuleEngine->find();
+ $collection = $collection->slice(0, 20);
- $warning = '';
+ $warning = '';
if (0 === count($collection)) {
$warning = (string)trans('firefly.warning_no_matching_transactions');
}
// Return json response
- $view = 'ERROR, see logs.';
+ $view = 'ERROR, see logs.';
+
try {
$view = view('list.journals-array-tiny', ['groups' => $collection])->render();
- } catch (Throwable $exception) {
+ } catch (\Throwable $exception) {
$message = sprintf('Could not render view in testTriggersByRule(): %s', $exception->getMessage());
- Log::error($message);
- Log::error($exception->getTraceAsString());
+ app('log')->error($message);
+ app('log')->error($exception->getTraceAsString());
+
throw new FireflyException($message, 0, $exception);
}
diff --git a/app/Http/Controllers/RuleGroup/CreateController.php b/app/Http/Controllers/RuleGroup/CreateController.php
index c6d667d66c..c8f5bd7810 100644
--- a/app/Http/Controllers/RuleGroup/CreateController.php
+++ b/app/Http/Controllers/RuleGroup/CreateController.php
@@ -41,8 +41,6 @@ class CreateController extends Controller
/**
* CreateController constructor.
- *
-
*/
public function __construct()
{
@@ -82,9 +80,7 @@ class CreateController extends Controller
/**
* Store the rule group.
*
- * @param RuleGroupFormRequest $request
- *
- * @return RedirectResponse|Redirector
+ * @return Redirector|RedirectResponse
*/
public function store(RuleGroupFormRequest $request)
{
@@ -94,7 +90,7 @@ class CreateController extends Controller
session()->flash('success', (string)trans('firefly.created_new_rule_group', ['title' => $ruleGroup->title]));
app('preferences')->mark();
- $redirect = redirect($this->getPreviousUrl('rule-groups.create.url'));
+ $redirect = redirect($this->getPreviousUrl('rule-groups.create.url'));
if (1 === (int)$request->get('create_another')) {
session()->put('rule-groups.create.fromStore', true);
diff --git a/app/Http/Controllers/RuleGroup/DeleteController.php b/app/Http/Controllers/RuleGroup/DeleteController.php
index c488a609c7..0b42b5eee3 100644
--- a/app/Http/Controllers/RuleGroup/DeleteController.php
+++ b/app/Http/Controllers/RuleGroup/DeleteController.php
@@ -42,8 +42,6 @@ class DeleteController extends Controller
/**
* DeleteController constructor.
- *
-
*/
public function __construct()
{
@@ -64,8 +62,6 @@ class DeleteController extends Controller
/**
* Delete a rule group.
*
- * @param RuleGroup $ruleGroup
- *
* @return Factory|View
*/
public function delete(RuleGroup $ruleGroup)
@@ -81,14 +77,11 @@ class DeleteController extends Controller
/**
* Actually destroy the rule group.
*
- * @param Request $request
- * @param RuleGroup $ruleGroup
- *
- * @return RedirectResponse|Redirector
+ * @return Redirector|RedirectResponse
*/
public function destroy(Request $request, RuleGroup $ruleGroup)
{
- $title = $ruleGroup->title;
+ $title = $ruleGroup->title;
/** @var RuleGroup $moveTo */
$moveTo = $this->repository->find((int)$request->get('move_rules_before_delete'));
diff --git a/app/Http/Controllers/RuleGroup/EditController.php b/app/Http/Controllers/RuleGroup/EditController.php
index 828fd3d0c2..67c18f8467 100644
--- a/app/Http/Controllers/RuleGroup/EditController.php
+++ b/app/Http/Controllers/RuleGroup/EditController.php
@@ -43,8 +43,6 @@ class EditController extends Controller
/**
* EditController constructor.
- *
-
*/
public function __construct()
{
@@ -65,14 +63,11 @@ class EditController extends Controller
/**
* Edit a rule group.
*
- * @param Request $request
- * @param RuleGroup $ruleGroup
- *
* @return Factory|View
*/
public function edit(Request $request, RuleGroup $ruleGroup)
{
- $subTitle = (string)trans('firefly.edit_rule_group', ['title' => $ruleGroup->title]);
+ $subTitle = (string)trans('firefly.edit_rule_group', ['title' => $ruleGroup->title]);
$hasOldInput = null !== $request->old('_token');
$preFilled = [
@@ -90,10 +85,6 @@ class EditController extends Controller
/**
* Move a rule group in either direction.
- *
- * @param Request $request
- *
- * @return JsonResponse
*/
public function moveGroup(Request $request): JsonResponse
{
@@ -103,34 +94,32 @@ class EditController extends Controller
$direction = $request->get('direction');
if ('down' === $direction) {
$maxOrder = $this->repository->maxOrder();
- $order = (int)$ruleGroup->order;
+ $order = $ruleGroup->order;
if ($order < $maxOrder) {
$newOrder = $order + 1;
$this->repository->setOrder($ruleGroup, $newOrder);
}
}
if ('up' === $direction) {
- $order = (int)$ruleGroup->order;
+ $order = $ruleGroup->order;
if ($order > 1) {
$newOrder = $order - 1;
$this->repository->setOrder($ruleGroup, $newOrder);
}
}
}
+
return new JsonResponse(['OK']);
}
/**
* Update the rule group.
*
- * @param RuleGroupFormRequest $request
- * @param RuleGroup $ruleGroup
- *
- * @return $this|RedirectResponse|Redirector
+ * @return $this|Redirector|RedirectResponse
*/
public function update(RuleGroupFormRequest $request, RuleGroup $ruleGroup)
{
- $data = [
+ $data = [
'title' => $request->convertString('title'),
'description' => $request->stringWithNewlines('description'),
'active' => 1 === (int)$request->input('active'),
diff --git a/app/Http/Controllers/RuleGroup/ExecutionController.php b/app/Http/Controllers/RuleGroup/ExecutionController.php
index be6285e55f..bf8e67759a 100644
--- a/app/Http/Controllers/RuleGroup/ExecutionController.php
+++ b/app/Http/Controllers/RuleGroup/ExecutionController.php
@@ -24,7 +24,6 @@ declare(strict_types=1);
namespace FireflyIII\Http\Controllers\RuleGroup;
use Carbon\Carbon;
-use Exception;
use FireflyIII\Http\Controllers\Controller;
use FireflyIII\Http\Requests\SelectTransactionsRequest;
use FireflyIII\Models\RuleGroup;
@@ -44,8 +43,6 @@ class ExecutionController extends Controller
/**
* ExecutionController constructor.
- *
-
*/
public function __construct()
{
@@ -66,21 +63,17 @@ class ExecutionController extends Controller
/**
* Execute the given rulegroup on a set of existing transactions.
*
- * @param SelectTransactionsRequest $request
- * @param RuleGroup $ruleGroup
- *
- * @return RedirectResponse
- * @throws Exception
+ * @throws \Exception
*/
public function execute(SelectTransactionsRequest $request, RuleGroup $ruleGroup): RedirectResponse
{
// Get parameters specified by the user
/** @var User $user */
- $user = auth()->user();
- $accounts = implode(',', $request->get('accounts'));
- $startDate = new Carbon($request->get('start'));
- $endDate = new Carbon($request->get('end'));
- $rules = $this->ruleGroupRepository->getActiveRules($ruleGroup);
+ $user = auth()->user();
+ $accounts = implode(',', $request->get('accounts'));
+ $startDate = new Carbon($request->get('start'));
+ $endDate = new Carbon($request->get('end'));
+ $rules = $this->ruleGroupRepository->getActiveRules($ruleGroup);
// create new rule engine:
$newRuleEngine = app(RuleEngineInterface::class);
$newRuleEngine->setUser($user);
@@ -103,8 +96,6 @@ class ExecutionController extends Controller
/**
* Select transactions to apply the group on.
*
- * @param RuleGroup $ruleGroup
- *
* @return Factory|View
*/
public function selectTransactions(RuleGroup $ruleGroup)
diff --git a/app/Http/Controllers/SearchController.php b/app/Http/Controllers/SearchController.php
index 5963f8eb5e..b68d9de8a7 100644
--- a/app/Http/Controllers/SearchController.php
+++ b/app/Http/Controllers/SearchController.php
@@ -29,9 +29,7 @@ use FireflyIII\Support\Search\SearchInterface;
use Illuminate\Contracts\View\Factory;
use Illuminate\Http\JsonResponse;
use Illuminate\Http\Request;
-use Illuminate\Support\Facades\Log;
use Illuminate\View\View;
-use Throwable;
/**
* Class SearchController.
@@ -58,26 +56,23 @@ class SearchController extends Controller
/**
* Do the search.
*
- * @param Request $request
- * @param SearchInterface $searcher
- *
* @return Factory|View
*/
public function index(Request $request, SearchInterface $searcher)
{
// search params:
- $fullQuery = $request->get('search');
+ $fullQuery = $request->get('search');
if (is_array($request->get('search'))) {
$fullQuery = '';
}
- $fullQuery = (string)$fullQuery;
- $page = 0 === (int)$request->get('page') ? 1 : (int)$request->get('page');
- $ruleId = (int)$request->get('rule');
- $ruleChanged = false;
+ $fullQuery = (string)$fullQuery;
+ $page = 0 === (int)$request->get('page') ? 1 : (int)$request->get('page');
+ $ruleId = (int)$request->get('rule');
+ $ruleChanged = false;
// find rule, check if query is different, offer to update.
- $ruleRepository = app(RuleRepositoryInterface::class);
- $rule = $ruleRepository->find($ruleId);
+ $ruleRepository = app(RuleRepositoryInterface::class);
+ $rule = $ruleRepository->find($ruleId);
if (null !== $rule) {
$originalQuery = $ruleRepository->getSearchQuery($rule);
if ($originalQuery !== $fullQuery) {
@@ -99,20 +94,16 @@ class SearchController extends Controller
/**
* JSON request that does the work.
*
- * @param Request $request
- * @param SearchInterface $searcher
- *
- * @return JsonResponse
* @throws FireflyException
*/
public function search(Request $request, SearchInterface $searcher): JsonResponse
{
- $entry = $request->get('query');
+ $entry = $request->get('query');
if (!is_scalar($entry)) {
$entry = '';
}
- $fullQuery = (string)$entry;
- $page = 0 === (int)$request->get('page') ? 1 : (int)$request->get('page');
+ $fullQuery = (string)$entry;
+ $page = 0 === (int)$request->get('page') ? 1 : (int)$request->get('page');
$searcher->parseQuery($fullQuery);
@@ -121,15 +112,16 @@ class SearchController extends Controller
$hasPages = $groups->hasPages();
$searchTime = round($searcher->searchTime(), 3); // in seconds
$parameters = ['search' => $fullQuery];
- $url = route('search.index') . '?' . http_build_query($parameters);
+ $url = route('search.index').'?'.http_build_query($parameters);
$groups->setPath($url);
try {
$html = view('search.search', compact('groups', 'hasPages', 'searchTime'))->render();
- } catch (Throwable $e) {
- Log::error(sprintf('Cannot render search.search: %s', $e->getMessage()));
- Log::error($e->getTraceAsString());
+ } catch (\Throwable $e) {
+ app('log')->error(sprintf('Cannot render search.search: %s', $e->getMessage()));
+ app('log')->error($e->getTraceAsString());
$html = 'Could not render view.';
+
throw new FireflyException($html, 0, $e);
}
diff --git a/app/Http/Controllers/System/CronController.php b/app/Http/Controllers/System/CronController.php
index 1e9c80f9dd..2e4f731831 100644
--- a/app/Http/Controllers/System/CronController.php
+++ b/app/Http/Controllers/System/CronController.php
@@ -26,7 +26,6 @@ namespace FireflyIII\Http\Controllers\System;
use Illuminate\Contracts\Foundation\Application;
use Illuminate\Contracts\Routing\ResponseFactory;
use Illuminate\Http\Response;
-use Illuminate\Support\Facades\Log;
/**
* Class CronController
@@ -34,11 +33,11 @@ use Illuminate\Support\Facades\Log;
class CronController
{
/**
- * @return Application|ResponseFactory|Response
+ * @return Application|Response|ResponseFactory
*/
public function cron()
{
- Log::error('The cron endpoint has moved to GET /api/v1/cron/[token]');
+ app('log')->error('The cron endpoint has moved to GET /api/v1/cron/[token]');
return response('The cron endpoint has moved to GET /api/v1/cron/[token]', 500);
}
diff --git a/app/Http/Controllers/System/HealthcheckController.php b/app/Http/Controllers/System/HealthcheckController.php
index 2a17ca2f5f..8bec13fcd9 100644
--- a/app/Http/Controllers/System/HealthcheckController.php
+++ b/app/Http/Controllers/System/HealthcheckController.php
@@ -34,12 +34,11 @@ class HealthcheckController extends Controller
{
/**
* Sends 'OK' info when app is alive
- *
- * @return Response
*/
public function check(): Response
{
User::count(); // sanity check for database health. Will crash if not OK.
+
return response('OK', 200);
}
}
diff --git a/app/Http/Controllers/System/InstallController.php b/app/Http/Controllers/System/InstallController.php
index 42cd599107..5c00d52a3f 100644
--- a/app/Http/Controllers/System/InstallController.php
+++ b/app/Http/Controllers/System/InstallController.php
@@ -23,33 +23,28 @@ declare(strict_types=1);
namespace FireflyIII\Http\Controllers\System;
-use Artisan;
use Cache;
use Exception;
use FireflyIII\Exceptions\FireflyException;
use FireflyIII\Http\Controllers\Controller;
-use FireflyIII\Support\Facades\Preferences;
use FireflyIII\Support\Http\Controllers\GetConfigurationData;
use Illuminate\Contracts\View\Factory;
use Illuminate\Http\JsonResponse;
use Illuminate\Http\Request;
-use Illuminate\Support\Facades\Log;
use Illuminate\View\View;
use Laravel\Passport\Passport;
use phpseclib3\Crypt\RSA;
/**
* Class InstallController
- *
-
*/
class InstallController extends Controller
{
use GetConfigurationData;
- public const BASEDIR_ERROR = 'Firefly III cannot execute the upgrade commands. It is not allowed to because of an open_basedir restriction.';
- public const FORBIDDEN_ERROR = 'Internal PHP function "proc_close" is disabled for your installation. Auto-migration is not possible.';
- public const OTHER_ERROR = 'An unknown error prevented Firefly III from executing the upgrade commands. Sorry.';
+ public const string BASEDIR_ERROR = 'Firefly III cannot execute the upgrade commands. It is not allowed to because of an open_basedir restriction.';
+ public const string FORBIDDEN_ERROR = 'Internal PHP function "proc_close" is disabled for your installation. Auto-migration is not possible.';
+ public const string OTHER_ERROR = 'An unknown error prevented Firefly III from executing the upgrade commands. Sorry.';
private string $lastError;
private array $upgradeCommands;
@@ -58,6 +53,7 @@ class InstallController extends Controller
*/
public function __construct()
{
+ parent::__construct();
// empty on purpose.
$this->upgradeCommands = [
// there are 5 initial commands
@@ -71,7 +67,7 @@ class InstallController extends Controller
'firefly-iii:verify-security-alerts' => [],
];
- $this->lastError = '';
+ $this->lastError = '';
}
/**
@@ -91,11 +87,6 @@ class InstallController extends Controller
return view('install.index');
}
- /**
- * @param Request $request
- *
- * @return JsonResponse
- */
public function runCommand(Request $request): JsonResponse
{
$requestIndex = (int)$request->get('index');
@@ -107,18 +98,19 @@ class InstallController extends Controller
'errorMessage' => null,
];
- Log::debug(sprintf('Will now run commands. Request index is %d', $requestIndex));
- $indexes = array_values(array_keys($this->upgradeCommands));
+ app('log')->debug(sprintf('Will now run commands. Request index is %d', $requestIndex));
+ $indexes = array_values(array_keys($this->upgradeCommands));
if (array_key_exists($requestIndex, $indexes)) {
- $command = $indexes[$requestIndex];
- $parameters = $this->upgradeCommands[$command];
- Log::debug(sprintf('Will now execute command "%s" with parameters', $command), $parameters);
+ $command = $indexes[$requestIndex];
+ $parameters = $this->upgradeCommands[$command];
+ app('log')->debug(sprintf('Will now execute command "%s" with parameters', $command), $parameters);
+
try {
$result = $this->executeCommand($command, $parameters);
} catch (FireflyException $e) {
- Log::error($e->getMessage());
- Log::error($e->getTraceAsString());
- if (strpos($e->getMessage(), 'open_basedir restriction in effect')) {
+ app('log')->error($e->getMessage());
+ app('log')->error($e->getTraceAsString());
+ if (str_contains($e->getMessage(), 'open_basedir restriction in effect')) {
$this->lastError = self::BASEDIR_ERROR;
}
$result = false;
@@ -127,38 +119,37 @@ class InstallController extends Controller
if (false === $result) {
$response['errorMessage'] = $this->lastError;
$response['error'] = true;
+
return response()->json($response);
}
$response['hasNextCommand'] = array_key_exists($requestIndex + 1, $indexes);
$response['previous'] = $command;
}
+
return response()->json($response);
}
/**
- * @param string $command
- * @param array $args
- *
- * @return bool
* @throws FireflyException
*/
private function executeCommand(string $command, array $args): bool
{
- Log::debug(sprintf('Will now call command %s with args.', $command), $args);
+ app('log')->debug(sprintf('Will now call command %s with args.', $command), $args);
+
try {
if ('generate-keys' === $command) {
$this->keys();
}
if ('generate-keys' !== $command) {
- Artisan::call($command, $args);
- Log::debug(Artisan::output());
+ \Artisan::call($command, $args);
+ app('log')->debug(\Artisan::output());
}
- } catch (Exception $e) { // intentional generic exception
+ } catch (\Exception $e) { // intentional generic exception
throw new FireflyException($e->getMessage(), 0, $e);
}
// clear cache as well.
- Cache::clear();
- Preferences::mark();
+ \Cache::clear();
+ app('preferences')->mark();
return true;
}
@@ -168,11 +159,7 @@ class InstallController extends Controller
*/
public function keys(): void
{
- // switch on PHP version.
- $keys = [];
- // switch on class existence.
- Log::info('Will run PHP8 code.');
- $keys = RSA::createKey(4096);
+ $key = RSA::createKey(4096);
[$publicKey, $privateKey] = [
Passport::keyPath('oauth-public.key'),
@@ -183,7 +170,7 @@ class InstallController extends Controller
return;
}
- file_put_contents($publicKey, $keys['publickey']);
- file_put_contents($privateKey, $keys['privatekey']);
+ file_put_contents($publicKey, (string)$key->getPublicKey());
+ file_put_contents($privateKey, $key->toString('PKCS1'));
}
}
diff --git a/app/Http/Controllers/TagController.php b/app/Http/Controllers/TagController.php
index 1fd2592349..964282de65 100644
--- a/app/Http/Controllers/TagController.php
+++ b/app/Http/Controllers/TagController.php
@@ -36,8 +36,6 @@ use Illuminate\Http\RedirectResponse;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\Log;
use Illuminate\View\View;
-use Psr\Container\ContainerExceptionInterface;
-use Psr\Container\NotFoundExceptionInterface;
/**
* Class TagController.
@@ -81,8 +79,8 @@ class TagController extends Controller
$subTitleIcon = 'fa-tag';
// location info:
- $hasOldInput = null !== $request->old('_token');
- $locations = [
+ $hasOldInput = null !== $request->old('_token');
+ $locations = [
'location' => [
'latitude' => $hasOldInput ? old('location_latitude') : config('firefly.default_location.latitude'),
'longitude' => $hasOldInput ? old('location_longitude') : config('firefly.default_location.longitude'),
@@ -103,8 +101,6 @@ class TagController extends Controller
/**
* Delete a tag.
*
- * @param Tag $tag
- *
* @return Factory|View
*/
public function delete(Tag $tag)
@@ -120,8 +116,6 @@ class TagController extends Controller
/**
* Edit a tag.
*
- * @param Tag $tag
- *
* @return Factory|View
*/
public function edit(Tag $tag)
@@ -129,12 +123,12 @@ class TagController extends Controller
$subTitle = (string)trans('firefly.edit_tag', ['tag' => $tag->tag]);
$subTitleIcon = 'fa-tag';
- $location = $this->repository->getLocation($tag);
- $latitude = $location ? $location->latitude : config('firefly.default_location.latitude');
- $longitude = $location ? $location->longitude : config('firefly.default_location.longitude');
- $zoomLevel = $location ? $location->zoom_level : config('firefly.default_location.zoom_level');
- $hasLocation = null !== $location;
- $locations = [
+ $location = $this->repository->getLocation($tag);
+ $latitude = null !== $location ? $location->latitude : config('firefly.default_location.latitude');
+ $longitude = null !== $location ? $location->longitude : config('firefly.default_location.longitude');
+ $zoomLevel = null !== $location ? $location->zoom_level : config('firefly.default_location.zoom_level');
+ $hasLocation = null !== $location;
+ $locations = [
'location' => [
'latitude' => old('location_latitude') ?? $latitude,
'longitude' => old('location_longitude') ?? $longitude,
@@ -155,16 +149,14 @@ class TagController extends Controller
/**
* Edit a tag.
*
- * @param TagRepositoryInterface $repository
- *
* @return Factory|View
*/
public function index(TagRepositoryInterface $repository)
{
// start with oldest tag
- $first = session('first', today()) ?? today();
- $oldestTagDate = null === $repository->oldestTag() ? clone $first : $repository->oldestTag()->date;
- $newestTagDate = null === $repository->newestTag() ? today() : $repository->newestTag()->date;
+ $first = session('first', today()) ?? today();
+ $oldestTagDate = null === $repository->oldestTag() ? clone $first : $repository->oldestTag()->date;
+ $newestTagDate = null === $repository->newestTag() ? today() : $repository->newestTag()->date;
$oldestTagDate->startOfYear();
$newestTagDate->endOfYear();
$tags = [];
@@ -175,17 +167,14 @@ class TagController extends Controller
$tags[$year] = $repository->getTagsInYear($year);
$newestTagDate->subYear();
}
- $count = $repository->count();
+ $count = $repository->count();
return view('tags.index', compact('tags', 'count'));
}
- /**
- *
- */
- public function massDestroy(Request $request)
+ public function massDestroy(Request $request): RedirectResponse
{
- $tags = $request->get('tags');
+ $tags = $request->get('tags');
if (null === $tags || !is_array($tags)) {
session()->flash('info', (string)trans('firefly.select_tags_to_delete'));
@@ -197,20 +186,16 @@ class TagController extends Controller
$tag = $this->repository->find($tagId);
if (null !== $tag) {
$this->repository->destroy($tag);
- $count++;
+ ++$count;
}
}
- session()->flash('success', (string)trans_choice('firefly.deleted_x_tags', $count));
+ session()->flash('success', trans_choice('firefly.deleted_x_tags', $count));
return redirect(route('tags.index'));
}
/**
* Destroy a tag.
- *
- * @param Tag $tag
- *
- * @return RedirectResponse
*/
public function destroy(Tag $tag): RedirectResponse
{
@@ -226,15 +211,9 @@ class TagController extends Controller
/**
* Show a single tag.
*
- * @param Request $request
- * @param Tag $tag
- * @param Carbon|null $start
- * @param Carbon|null $end
- *
* @return Factory|View
+ *
* @throws FireflyException
- * @throws ContainerExceptionInterface
- * @throws NotFoundExceptionInterface
*/
public function show(Request $request, Tag $tag, Carbon $start = null, Carbon $end = null)
{
@@ -242,8 +221,8 @@ class TagController extends Controller
$subTitleIcon = 'fa-tag';
$page = (int)$request->get('page');
$pageSize = (int)app('preferences')->get('listPageSize', 50)->data;
- $start = $start ?? session('start');
- $end = $end ?? session('end');
+ $start ??= session('start');
+ $end ??= session('end');
$location = $this->repository->getLocation($tag);
$attachments = $this->repository->getAttachments($tag);
$subTitle = trans(
@@ -255,20 +234,21 @@ class TagController extends Controller
]
);
- $startPeriod = $this->repository->firstUseDate($tag);
- $startPeriod = $startPeriod ?? today(config('app.timezone'));
- $endPeriod = clone $end;
- $periods = $this->getTagPeriodOverview($tag, $startPeriod, $endPeriod);
- $path = route('tags.show', [$tag->id, $start->format('Y-m-d'), $end->format('Y-m-d')]);
+ $startPeriod = $this->repository->firstUseDate($tag);
+ $startPeriod ??= today(config('app.timezone'));
+ $endPeriod = clone $end;
+ $periods = $this->getTagPeriodOverview($tag, $startPeriod, $endPeriod);
+ $path = route('tags.show', [$tag->id, $start->format('Y-m-d'), $end->format('Y-m-d')]);
/** @var GroupCollectorInterface $collector */
- $collector = app(GroupCollectorInterface::class);
+ $collector = app(GroupCollectorInterface::class);
$collector->setRange($start, $end)->setLimit($pageSize)->setPage($page)->withAccountInformation()
- ->setTag($tag)->withBudgetInformation()->withCategoryInformation();
- $groups = $collector->getPaginatedGroups();
+ ->setTag($tag)->withBudgetInformation()->withCategoryInformation()
+ ;
+ $groups = $collector->getPaginatedGroups();
$groups->setPath($path);
- $sums = $this->repository->sumsOfTag($tag, $start, $end);
+ $sums = $this->repository->sumsOfTag($tag, $start, $end);
return view('tags.show', compact('tag', 'attachments', 'sums', 'periods', 'subTitle', 'subTitleIcon', 'groups', 'start', 'end', 'location'));
}
@@ -276,12 +256,7 @@ class TagController extends Controller
/**
* Show a single tag over all time.
*
- * @param Request $request
- * @param Tag $tag
- *
* @return Factory|View
- * @throws ContainerExceptionInterface
- * @throws NotFoundExceptionInterface
*/
public function showAll(Request $request, Tag $tag)
{
@@ -296,42 +271,41 @@ class TagController extends Controller
$attachments = $this->repository->getAttachments($tag);
$path = route('tags.show', [$tag->id, 'all']);
$location = $this->repository->getLocation($tag);
+
/** @var GroupCollectorInterface $collector */
- $collector = app(GroupCollectorInterface::class);
+ $collector = app(GroupCollectorInterface::class);
$collector->setRange($start, $end)->setLimit($pageSize)->setPage($page)->withAccountInformation()
- ->setTag($tag)->withBudgetInformation()->withCategoryInformation();
- $groups = $collector->getPaginatedGroups();
+ ->setTag($tag)->withBudgetInformation()->withCategoryInformation()
+ ;
+ $groups = $collector->getPaginatedGroups();
$groups->setPath($path);
- $sums = $this->repository->sumsOfTag($tag, $start, $end);
+ $sums = $this->repository->sumsOfTag($tag, $start, $end);
return view('tags.show', compact('tag', 'attachments', 'sums', 'periods', 'subTitle', 'subTitleIcon', 'groups', 'start', 'end', 'location'));
}
/**
* Store a tag.
- *
- * @param TagFormRequest $request
- *
- * @return RedirectResponse
*/
public function store(TagFormRequest $request): RedirectResponse
{
- $data = $request->collectTagData();
- Log::debug('Data from request', $data);
+ $data = $request->collectTagData();
+ app('log')->debug('Data from request', $data);
- $result = $this->repository->store($data);
- Log::debug('Data after storage', $result->toArray());
+ $result = $this->repository->store($data);
+ app('log')->debug('Data after storage', $result->toArray());
session()->flash('success', (string)trans('firefly.created_tag', ['tag' => $data['tag']]));
app('preferences')->mark();
// store attachment(s):
- /** @var array $files */
- $files = $request->hasFile('attachments') ? $request->file('attachments') : null;
+ /** @var null|array $files */
+ $files = $request->hasFile('attachments') ? $request->file('attachments') : null;
if (null !== $files && !auth()->user()->hasRole('demo')) {
$this->attachmentsHelper->saveAttachmentsForModel($result, $files);
}
if (null !== $files && auth()->user()->hasRole('demo')) {
+ Log::channel('audit')->warning(sprintf('The demo user is trying to upload attachments in %s.', __METHOD__));
session()->flash('info', (string)trans('firefly.no_att_demo_user'));
}
@@ -350,27 +324,23 @@ class TagController extends Controller
/**
* Update a tag.
- *
- * @param TagFormRequest $request
- * @param Tag $tag
- *
- * @return RedirectResponse
*/
public function update(TagFormRequest $request, Tag $tag): RedirectResponse
{
- $data = $request->collectTagData();
- $tag = $this->repository->update($tag, $data);
+ $data = $request->collectTagData();
+ $tag = $this->repository->update($tag, $data);
session()->flash('success', (string)trans('firefly.updated_tag', ['tag' => $data['tag']]));
app('preferences')->mark();
// store new attachment(s):
- /** @var array $files */
- $files = $request->hasFile('attachments') ? $request->file('attachments') : null;
+ /** @var null|array $files */
+ $files = $request->hasFile('attachments') ? $request->file('attachments') : null;
if (null !== $files && !auth()->user()->hasRole('demo')) {
$this->attachmentsHelper->saveAttachmentsForModel($tag, $files);
}
if (null !== $files && auth()->user()->hasRole('demo')) {
+ Log::channel('audit')->warning(sprintf('The demo user is trying to upload attachments in %s.', __METHOD__));
session()->flash('info', (string)trans('firefly.no_att_demo_user'));
}
diff --git a/app/Http/Controllers/Transaction/BulkController.php b/app/Http/Controllers/Transaction/BulkController.php
index 28f4831ea4..79d58cfda2 100644
--- a/app/Http/Controllers/Transaction/BulkController.php
+++ b/app/Http/Controllers/Transaction/BulkController.php
@@ -34,7 +34,6 @@ use Illuminate\Contracts\View\Factory;
use Illuminate\Http\RedirectResponse;
use Illuminate\Routing\Redirector;
use Illuminate\Support\Collection;
-use Illuminate\Support\Facades\Log;
use Illuminate\View\View;
/**
@@ -47,8 +46,6 @@ class BulkController extends Controller
/**
* BulkController constructor.
- *
-
*/
public function __construct()
{
@@ -70,13 +67,11 @@ class BulkController extends Controller
*
* TODO user wont be able to tell if the journal is part of a split.
*
- * @param array $journals
- *
* @return Factory|View
*/
public function edit(array $journals)
{
- $subTitle = (string)trans('firefly.mass_bulk_journals');
+ $subTitle = (string)trans('firefly.mass_bulk_journals');
$this->rememberPreviousUrl('transactions.bulk-edit.url');
@@ -93,9 +88,7 @@ class BulkController extends Controller
/**
* Update all journals.
*
- * @param BulkEditJournalRequest $request
- *
- * @return Application|RedirectResponse|Redirector
+ * @return Application|Redirector|RedirectResponse
*/
public function update(BulkEditJournalRequest $request)
{
@@ -115,7 +108,7 @@ class BulkController extends Controller
$resultB = $this->updateJournalTags($journal, $tagsAction, explode(',', $request->convertString('tags')));
$resultC = $this->updateJournalCategory($journal, $ignoreCategory, $request->convertString('category'));
if ($resultA || $resultB || $resultC) {
- $count++;
+ ++$count;
$collection->push($journal);
}
}
@@ -128,41 +121,27 @@ class BulkController extends Controller
}
app('preferences')->mark();
- $request->session()->flash('success', (string)trans_choice('firefly.mass_edited_transactions_success', $count));
+ $request->session()->flash('success', trans_choice('firefly.mass_edited_transactions_success', $count));
// redirect to previous URL:
return redirect($this->getPreviousUrl('transactions.bulk-edit.url'));
}
- /**
- * @param TransactionJournal $journal
- * @param bool $ignoreUpdate
- * @param int $budgetId
- *
- * @return bool
- */
private function updateJournalBudget(TransactionJournal $journal, bool $ignoreUpdate, int $budgetId): bool
{
if (true === $ignoreUpdate) {
return false;
}
- Log::debug(sprintf('Set budget to %d', $budgetId));
+ app('log')->debug(sprintf('Set budget to %d', $budgetId));
$this->repository->updateBudget($journal, $budgetId);
return true;
}
- /**
- * @param TransactionJournal $journal
- * @param string $action
- * @param array $tags
- *
- * @return bool
- */
private function updateJournalTags(TransactionJournal $journal, string $action, array $tags): bool
{
if ('do_replace' === $action) {
- Log::debug(sprintf('Set tags to %s', implode(',', $tags)));
+ app('log')->debug(sprintf('Set tags to %s', implode(',', $tags)));
$this->repository->updateTags($journal, $tags);
}
if ('do_append' === $action) {
@@ -174,19 +153,12 @@ class BulkController extends Controller
return true;
}
- /**
- * @param TransactionJournal $journal
- * @param bool $ignoreUpdate
- * @param string $category
- *
- * @return bool
- */
private function updateJournalCategory(TransactionJournal $journal, bool $ignoreUpdate, string $category): bool
{
if (true === $ignoreUpdate) {
return false;
}
- Log::debug(sprintf('Set budget to %s', $category));
+ app('log')->debug(sprintf('Set budget to %s', $category));
$this->repository->updateCategory($journal, $category);
return true;
diff --git a/app/Http/Controllers/Transaction/ConvertController.php b/app/Http/Controllers/Transaction/ConvertController.php
index ac5b9e6cab..7d4ceadece 100644
--- a/app/Http/Controllers/Transaction/ConvertController.php
+++ b/app/Http/Controllers/Transaction/ConvertController.php
@@ -33,7 +33,6 @@ use FireflyIII\Models\TransactionGroup;
use FireflyIII\Models\TransactionJournal;
use FireflyIII\Models\TransactionType;
use FireflyIII\Repositories\Account\AccountRepositoryInterface;
-use FireflyIII\Repositories\Journal\JournalRepositoryInterface;
use FireflyIII\Services\Internal\Update\JournalUpdateService;
use FireflyIII\Support\Http\Controllers\ModelInformation;
use FireflyIII\Transformers\TransactionGroupTransformer;
@@ -42,7 +41,6 @@ use Illuminate\Contracts\View\Factory;
use Illuminate\Http\RedirectResponse;
use Illuminate\Http\Request;
use Illuminate\Routing\Redirector;
-use Illuminate\Support\Facades\Log;
use Illuminate\View\View;
/**
@@ -55,12 +53,9 @@ class ConvertController extends Controller
use ModelInformation;
private AccountRepositoryInterface $accountRepository;
- private JournalRepositoryInterface $repository;
/**
* ConvertController constructor.
- *
-
*/
public function __construct()
{
@@ -69,7 +64,6 @@ class ConvertController extends Controller
// some useful repositories:
$this->middleware(
function ($request, $next) {
- $this->repository = app(JournalRepositoryInterface::class);
$this->accountRepository = app(AccountRepositoryInterface::class);
app('view')->share('title', (string)trans('firefly.transactions'));
app('view')->share('mainTitleIcon', 'fa-exchange');
@@ -82,12 +76,9 @@ class ConvertController extends Controller
/**
* Show overview of a to be converted transaction.
*
- * @param TransactionType $destinationType
- * @param TransactionGroup $group
- *
- * @return RedirectResponse|Redirector|Factory|View
- * @throws Exception
+ * @return Factory|Redirector|RedirectResponse|View
*
+ * @throws \Exception
*/
public function index(TransactionType $destinationType, TransactionGroup $group)
{
@@ -96,16 +87,16 @@ class ConvertController extends Controller
}
/** @var TransactionGroupTransformer $transformer */
- $transformer = app(TransactionGroupTransformer::class);
+ $transformer = app(TransactionGroupTransformer::class);
/** @var TransactionJournal $first */
- $first = $group->transactionJournals()->first();
- $sourceType = $first->transactionType;
+ $first = $group->transactionJournals()->first();
+ $sourceType = $first->transactionType;
- $groupTitle = $group->title ?? $first->description;
- $groupArray = $transformer->transformObject($group);
- $subTitle = (string)trans('firefly.convert_to_' . $destinationType->type, ['description' => $groupTitle]);
- $subTitleIcon = 'fa-exchange';
+ $groupTitle = $group->title ?? $first->description;
+ $groupArray = $transformer->transformObject($group);
+ $subTitle = (string)trans('firefly.convert_to_'.$destinationType->type, ['description' => $groupTitle]);
+ $subTitleIcon = 'fa-exchange';
// get a list of asset accounts and liabilities and stuff, in various combinations:
$validDepositSources = $this->getValidDepositSources();
@@ -114,13 +105,13 @@ class ConvertController extends Controller
$assets = $this->getAssetAccounts();
// old input variables:
- $preFilled = [
+ $preFilled = [
'source_name' => old('source_name'),
];
if ($sourceType->type === $destinationType->type) { // cannot convert to its own type.
- Log::debug('This is already a transaction of the expected type..');
- session()->flash('info', (string)trans('firefly.convert_is_already_type_' . $destinationType->type));
+ app('log')->debug('This is already a transaction of the expected type..');
+ session()->flash('info', (string)trans('firefly.convert_is_already_type_'.$destinationType->type));
return redirect(route('transactions.show', [$group->id]));
}
@@ -144,28 +135,27 @@ class ConvertController extends Controller
);
}
- /**
- * @return array
- */
private function getValidDepositSources(): array
{
// make repositories
$liabilityTypes = [AccountType::MORTGAGE, AccountType::DEBT, AccountType::CREDITCARD, AccountType::LOAN];
$accountList = $this->accountRepository
- ->getActiveAccountsByType([AccountType::REVENUE, AccountType::CASH, AccountType::LOAN, AccountType::DEBT, AccountType::MORTGAGE]);
+ ->getActiveAccountsByType([AccountType::REVENUE, AccountType::CASH, AccountType::LOAN, AccountType::DEBT, AccountType::MORTGAGE])
+ ;
$grouped = [];
+
// group accounts:
/** @var Account $account */
foreach ($accountList as $account) {
- $role = (string)$this->accountRepository->getMetaValue($account, 'account_role');
- $name = $account->name;
+ $role = (string)$this->accountRepository->getMetaValue($account, 'account_role');
+ $name = $account->name;
if ('' === $role) {
$role = 'no_account_type';
}
// maybe it's a liability thing:
if (in_array($account->accountType->type, $liabilityTypes, true)) {
- $role = 'l_' . $account->accountType->type;
+ $role = 'l_'.$account->accountType->type;
}
if (AccountType::CASH === $account->accountType->type) {
$role = 'cash_account';
@@ -175,16 +165,13 @@ class ConvertController extends Controller
$role = 'revenue_account';
}
- $key = (string)trans('firefly.opt_group_' . $role);
+ $key = (string)trans('firefly.opt_group_'.$role);
$grouped[$key][$account->id] = $name;
}
return $grouped;
}
- /**
- * @return array
- */
private function getValidWithdrawalDests(): array
{
// make repositories
@@ -193,18 +180,19 @@ class ConvertController extends Controller
[AccountType::EXPENSE, AccountType::CASH, AccountType::LOAN, AccountType::DEBT, AccountType::MORTGAGE]
);
$grouped = [];
+
// group accounts:
/** @var Account $account */
foreach ($accountList as $account) {
- $role = (string)$this->accountRepository->getMetaValue($account, 'account_role');
- $name = $account->name;
+ $role = (string)$this->accountRepository->getMetaValue($account, 'account_role');
+ $name = $account->name;
if ('' === $role) {
$role = 'no_account_type';
}
// maybe it's a liability thing:
if (in_array($account->accountType->type, $liabilityTypes, true)) {
- $role = 'l_' . $account->accountType->type;
+ $role = 'l_'.$account->accountType->type;
}
if (AccountType::CASH === $account->accountType->type) {
$role = 'cash_account';
@@ -214,7 +202,7 @@ class ConvertController extends Controller
$role = 'expense_account';
}
- $key = (string)trans('firefly.opt_group_' . $role);
+ $key = (string)trans('firefly.opt_group_'.$role);
$grouped[$key][$account->id] = $name;
}
@@ -222,8 +210,7 @@ class ConvertController extends Controller
}
/**
- * @return array
- * @throws Exception
+ * @throws \Exception
*/
private function getLiabilities(): array
{
@@ -231,22 +218,22 @@ class ConvertController extends Controller
$accountList = $this->accountRepository->getActiveAccountsByType([AccountType::LOAN, AccountType::DEBT, AccountType::MORTGAGE]);
$defaultCurrency = app('amount')->getDefaultCurrency();
$grouped = [];
+
// group accounts:
/** @var Account $account */
foreach ($accountList as $account) {
$balance = app('steam')->balance($account, today());
$currency = $this->accountRepository->getAccountCurrency($account) ?? $defaultCurrency;
- $role = 'l_' . $account->accountType->type;
- $key = (string)trans('firefly.opt_group_' . $role);
- $grouped[$key][$account->id] = $account->name . ' (' . app('amount')->formatAnything($currency, $balance, false) . ')';
+ $role = 'l_'.$account->accountType->type;
+ $key = (string)trans('firefly.opt_group_'.$role);
+ $grouped[$key][$account->id] = $account->name.' ('.app('amount')->formatAnything($currency, $balance, false).')';
}
return $grouped;
}
/**
- * @return array
- * @throws Exception
+ * @throws \Exception
*/
private function getAssetAccounts(): array
{
@@ -254,18 +241,19 @@ class ConvertController extends Controller
$accountList = $this->accountRepository->getActiveAccountsByType([AccountType::ASSET]);
$defaultCurrency = app('amount')->getDefaultCurrency();
$grouped = [];
+
// group accounts:
/** @var Account $account */
foreach ($accountList as $account) {
- $balance = app('steam')->balance($account, today());
- $currency = $this->accountRepository->getAccountCurrency($account) ?? $defaultCurrency;
- $role = (string)$this->accountRepository->getMetaValue($account, 'account_role');
+ $balance = app('steam')->balance($account, today());
+ $currency = $this->accountRepository->getAccountCurrency($account) ?? $defaultCurrency;
+ $role = (string)$this->accountRepository->getMetaValue($account, 'account_role');
if ('' === $role) {
$role = 'no_account_type';
}
- $key = (string)trans('firefly.opt_group_' . $role);
- $grouped[$key][$account->id] = $account->name . ' (' . app('amount')->formatAnything($currency, $balance, false) . ')';
+ $key = (string)trans('firefly.opt_group_'.$role);
+ $grouped[$key][$account->id] = $account->name.' ('.app('amount')->formatAnything($currency, $balance, false).')';
}
return $grouped;
@@ -274,12 +262,7 @@ class ConvertController extends Controller
/**
* Do the conversion.
*
- * @param Request $request
- * @param TransactionType $destinationType
- * @param TransactionGroup $group
- *
- * @return RedirectResponse|Redirector
- *
+ * @return Redirector|RedirectResponse
*/
public function postIndex(Request $request, TransactionType $destinationType, TransactionGroup $group)
{
@@ -302,39 +285,34 @@ class ConvertController extends Controller
// correct transfers:
$group->refresh();
- session()->flash('success', (string)trans('firefly.converted_to_' . $destinationType->type));
+ session()->flash('success', (string)trans('firefly.converted_to_'.$destinationType->type));
event(new UpdatedTransactionGroup($group, true, true));
return redirect(route('transactions.show', [$group->id]));
}
/**
- * @param TransactionJournal $journal
- * @param TransactionType $transactionType
- * @param array $data
- *
- * @return TransactionJournal
* @throws FireflyException
*/
private function convertJournal(TransactionJournal $journal, TransactionType $transactionType, array $data): TransactionJournal
{
/** @var AccountValidator $validator */
- $validator = app(AccountValidator::class);
+ $validator = app(AccountValidator::class);
$validator->setUser(auth()->user());
$validator->setTransactionType($transactionType->type);
- $sourceId = $data['source_id'][$journal->id] ?? null;
- $sourceName = $data['source_name'][$journal->id] ?? null;
- $destinationId = $data['destination_id'][$journal->id] ?? null;
- $destinationName = $data['destination_name'][$journal->id] ?? null;
+ $sourceId = $data['source_id'][$journal->id] ?? null;
+ $sourceName = $data['source_name'][$journal->id] ?? null;
+ $destinationId = $data['destination_id'][$journal->id] ?? null;
+ $destinationName = $data['destination_name'][$journal->id] ?? null;
// double check its not an empty string.
$sourceId = '' === $sourceId || null === $sourceId ? null : (int)$sourceId;
$sourceName = '' === $sourceName ? null : (string)$sourceName;
$destinationId = '' === $destinationId || null === $destinationId ? null : (int)$destinationId;
$destinationName = '' === $destinationName ? null : (string)$destinationName;
- $validSource = $validator->validateSource(['id' => $sourceId, 'name' => $sourceName,]);
- $validDestination = $validator->validateDestination(['id' => $destinationId, 'name' => $destinationName,]);
+ $validSource = $validator->validateSource(['id' => $sourceId, 'name' => $sourceName]);
+ $validDestination = $validator->validateDestination(['id' => $destinationId, 'name' => $destinationName]);
if (false === $validSource) {
throw new FireflyException(sprintf(trans('firefly.convert_invalid_source'), $journal->id));
@@ -345,15 +323,16 @@ class ConvertController extends Controller
// TODO typeOverrule: the account validator may have another opinion on the transaction type.
- $update = [
+ $update = [
'source_id' => $sourceId,
'source_name' => $sourceName,
'destination_id' => $destinationId,
'destination_name' => $destinationName,
'type' => $transactionType->type,
];
+
/** @var JournalUpdateService $service */
- $service = app(JournalUpdateService::class);
+ $service = app(JournalUpdateService::class);
$service->setTransactionJournal($journal);
$service->setData($update);
$service->update();
diff --git a/app/Http/Controllers/Transaction/CreateController.php b/app/Http/Controllers/Transaction/CreateController.php
index aa0b5ea285..efbeca2252 100644
--- a/app/Http/Controllers/Transaction/CreateController.php
+++ b/app/Http/Controllers/Transaction/CreateController.php
@@ -33,9 +33,6 @@ use Illuminate\Contracts\View\Factory;
use Illuminate\Contracts\View\View;
use Illuminate\Http\JsonResponse;
use Illuminate\Http\Request;
-use JsonException;
-use Psr\Container\ContainerExceptionInterface;
-use Psr\Container\NotFoundExceptionInterface;
/**
* Class CreateController
@@ -46,8 +43,6 @@ class CreateController extends Controller
/**
* CreateController constructor.
- *
-
*/
public function __construct()
{
@@ -64,11 +59,6 @@ class CreateController extends Controller
);
}
- /**
- * @param Request $request
- *
- * @return JsonResponse
- */
public function cloneGroup(Request $request): JsonResponse
{
$groupId = (int)$request->get('id');
@@ -84,11 +74,15 @@ class CreateController extends Controller
app('preferences')->mark();
- $title = $newGroup->title ?? $newGroup->transactionJournals->first()->description;
- $link = route('transactions.show', [$newGroup->id]);
+ $title = $newGroup->title ?? $newGroup->transactionJournals->first()->description;
+ $link = route('transactions.show', [$newGroup->id]);
session()->flash('success', trans('firefly.stored_journal', ['description' => $title]));
session()->flash('success_url', $link);
+ if ('edit' === $request->get('redirect')) {
+ return response()->json(['redirect' => route('transactions.edit', [$newGroup->id])]);
+ }
+
return response()->json(['redirect' => route('transactions.show', [$newGroup->id])]);
}
}
@@ -99,35 +93,51 @@ class CreateController extends Controller
/**
* Create a new transaction group.
*
- * @param string|null $objectType
- *
* @return Factory|View
+ *
* @throws FireflyException
- * @throws JsonException
- * @throws ContainerExceptionInterface
- * @throws NotFoundExceptionInterface
- */
+ * */
public function create(?string $objectType)
{
app('preferences')->mark();
- $sourceId = (int)request()->get('source');
- $destinationId = (int)request()->get('destination');
+ $sourceId = (int)request()->get('source');
+ $destinationId = (int)request()->get('destination');
/** @var AccountRepositoryInterface $accountRepository */
- $accountRepository = app(AccountRepositoryInterface::class);
- $cash = $accountRepository->getCashAccount();
- $preFilled = session()->has('preFilled') ? session('preFilled') : [];
- $subTitle = (string)trans(sprintf('breadcrumbs.create_%s', strtolower((string)$objectType)));
- $subTitleIcon = 'fa-plus';
- $optionalFields = app('preferences')->get('transaction_journal_optional_fields', [])->data;
- $allowedOpposingTypes = config('firefly.allowed_opposing_types');
- $accountToTypes = config('firefly.account_to_transaction');
- $defaultCurrency = app('amount')->getDefaultCurrency();
- $previousUrl = $this->rememberPreviousUrl('transactions.create.url');
- $parts = parse_url($previousUrl);
- $search = sprintf('?%s', $parts['query'] ?? '');
- $previousUrl = str_replace($search, '', $previousUrl);
+ $accountRepository = app(AccountRepositoryInterface::class);
+ $cash = $accountRepository->getCashAccount();
+ $preFilled = session()->has('preFilled') ? session('preFilled') : [];
+ $subTitle = (string)trans(sprintf('breadcrumbs.create_%s', strtolower((string)$objectType)));
+ $subTitleIcon = 'fa-plus';
+ $optionalFields = app('preferences')->get('transaction_journal_optional_fields', [])->data;
+ $allowedOpposingTypes = config('firefly.allowed_opposing_types');
+ $accountToTypes = config('firefly.account_to_transaction');
+ $defaultCurrency = app('amount')->getDefaultCurrency();
+ $previousUrl = $this->rememberPreviousUrl('transactions.create.url');
+ $parts = parse_url($previousUrl);
+ $search = sprintf('?%s', $parts['query'] ?? '');
+ $previousUrl = str_replace($search, '', $previousUrl);
+ if (!is_array($optionalFields)) {
+ $optionalFields = [];
+ }
+ // not really a fan of this, but meh.
+ $optionalDateFields = [
+ 'interest_date' => $optionalFields['interest_date'] ?? false,
+ 'book_date' => $optionalFields['book_date'] ?? false,
+ 'process_date' => $optionalFields['process_date'] ?? false,
+ 'due_date' => $optionalFields['due_date'] ?? false,
+ 'payment_date' => $optionalFields['payment_date'] ?? false,
+ 'invoice_date' => $optionalFields['invoice_date'] ?? false,
+ ];
+ $optionalFields['external_url'] ??= false;
+ $optionalFields['location'] ??= false;
+ $optionalFields['location'] = $optionalFields['location'] && true === config('firefly.enable_external_map');
+
+ // map info:
+ $longitude = config('firefly.default_location.longitude');
+ $latitude = config('firefly.default_location.latitude');
+ $zoomLevel = config('firefly.default_location.zoom_level');
session()->put('preFilled', $preFilled);
@@ -136,7 +146,11 @@ class CreateController extends Controller
compact(
'subTitleIcon',
'cash',
+ 'longitude',
+ 'latitude',
+ 'zoomLevel',
'objectType',
+ 'optionalDateFields',
'subTitle',
'defaultCurrency',
'previousUrl',
diff --git a/app/Http/Controllers/Transaction/DeleteController.php b/app/Http/Controllers/Transaction/DeleteController.php
index 8e2acc65bb..1519027067 100644
--- a/app/Http/Controllers/Transaction/DeleteController.php
+++ b/app/Http/Controllers/Transaction/DeleteController.php
@@ -34,7 +34,6 @@ use Illuminate\Contracts\View\Factory;
use Illuminate\Contracts\View\View;
use Illuminate\Http\RedirectResponse;
use Illuminate\Routing\Redirector;
-use Illuminate\Support\Facades\Log;
use Symfony\Component\HttpKernel\Exception\NotFoundHttpException;
/**
@@ -46,8 +45,6 @@ class DeleteController extends Controller
/**
* IndexController constructor.
- *
-
*/
public function __construct()
{
@@ -69,9 +66,7 @@ class DeleteController extends Controller
/**
* Shows the form that allows a user to delete a transaction journal.
*
- * @param TransactionGroup $group
- *
- * @return Factory|View|Redirector|RedirectResponse
+ * @return Factory|Redirector|RedirectResponse|View
*/
public function delete(TransactionGroup $group)
{
@@ -79,17 +74,17 @@ class DeleteController extends Controller
return $this->redirectGroupToAccount($group);
}
- Log::debug(sprintf('Start of delete view for group #%d', $group->id));
+ app('log')->debug(sprintf('Start of delete view for group #%d', $group->id));
- $journal = $group->transactionJournals->first();
+ $journal = $group->transactionJournals->first();
if (null === $journal) {
throw new NotFoundHttpException();
}
$objectType = strtolower($journal->transaction_type_type ?? $journal->transactionType->type);
- $subTitle = (string)trans('firefly.delete_' . $objectType, ['description' => $group->title ?? $journal->description]);
+ $subTitle = (string)trans('firefly.delete_'.$objectType, ['description' => $group->title ?? $journal->description]);
$previous = app('steam')->getSafePreviousUrl();
// put previous url in session
- Log::debug('Will try to remember previous URL');
+ app('log')->debug('Will try to remember previous URL');
$this->rememberPreviousUrl('transactions.delete.url');
return view('transactions.delete', compact('group', 'journal', 'subTitle', 'objectType', 'previous'));
@@ -97,31 +92,28 @@ class DeleteController extends Controller
/**
* Actually destroys the journal.
- *
- * @param TransactionGroup $group
- *
- * @return RedirectResponse
*/
- public function destroy(TransactionGroup $group): RedirectResponse
+ public function destroy(TransactionGroup $group): Redirector|RedirectResponse
{
- Log::debug(sprintf('Now in %s(#%d).', __METHOD__, $group->id));
+ app('log')->debug(sprintf('Now in %s(#%d).', __METHOD__, $group->id));
if (!$this->isEditableGroup($group)) {
return $this->redirectGroupToAccount($group);
}
- $journal = $group->transactionJournals->first();
+ $journal = $group->transactionJournals->first();
if (null === $journal) {
throw new NotFoundHttpException();
}
$objectType = strtolower($journal->transaction_type_type ?? $journal->transactionType->type);
- session()->flash('success', (string)trans('firefly.deleted_' . strtolower($objectType), ['description' => $group->title ?? $journal->description]));
+ session()->flash('success', (string)trans('firefly.deleted_'.strtolower($objectType), ['description' => $group->title ?? $journal->description]));
// grab asset account(s) from group:
- $accounts = [];
- /** @var TransactionJournal $journal */
- foreach ($group->transactionJournals as $journal) {
+ $accounts = [];
+
+ /** @var TransactionJournal $currentJournal */
+ foreach ($group->transactionJournals as $currentJournal) {
/** @var Transaction $transaction */
- foreach ($journal->transactions as $transaction) {
+ foreach ($currentJournal->transactions as $transaction) {
$type = $transaction->account->accountType->type;
// if is valid liability, trigger event!
if (in_array($type, config('firefly.valid_liabilities'), true)) {
@@ -134,12 +126,11 @@ class DeleteController extends Controller
/** @var Account $account */
foreach ($accounts as $account) {
- Log::debug(sprintf('Now going to trigger updated account event for account #%d', $account->id));
+ app('log')->debug(sprintf('Now going to trigger updated account event for account #%d', $account->id));
event(new UpdatedAccount($account));
}
app('preferences')->mark();
-
return redirect($this->getPreviousUrl('transactions.delete.url'));
}
}
diff --git a/app/Http/Controllers/Transaction/EditController.php b/app/Http/Controllers/Transaction/EditController.php
index 0a23eb77ce..e2fe8ba23d 100644
--- a/app/Http/Controllers/Transaction/EditController.php
+++ b/app/Http/Controllers/Transaction/EditController.php
@@ -25,8 +25,11 @@ namespace FireflyIII\Http\Controllers\Transaction;
use FireflyIII\Http\Controllers\Controller;
use FireflyIII\Models\TransactionGroup;
+use FireflyIII\Models\TransactionJournal;
use FireflyIII\Repositories\Account\AccountRepositoryInterface;
+use FireflyIII\Repositories\Journal\JournalRepositoryInterface;
use Illuminate\Contracts\View\Factory;
+use Illuminate\Http\JsonResponse;
use Illuminate\Http\RedirectResponse;
use Illuminate\Routing\Redirector;
use Illuminate\View\View;
@@ -36,30 +39,30 @@ use Illuminate\View\View;
*/
class EditController extends Controller
{
- /**
- * EditController constructor.
- *
+ private JournalRepositoryInterface $repository;
+ /**
+ * IndexController constructor.
*/
public function __construct()
{
parent::__construct();
- // some useful repositories:
+ // translations:
$this->middleware(
- static function ($request, $next) {
+ function ($request, $next) {
app('view')->share('title', (string)trans('firefly.transactions'));
app('view')->share('mainTitleIcon', 'fa-exchange');
+ $this->repository = app(JournalRepositoryInterface::class);
+
return $next($request);
}
);
}
/**
- * @param TransactionGroup $transactionGroup
- *
- * @return Factory|View|RedirectResponse|Redirector
+ * @return Factory|Redirector|RedirectResponse|View
*/
public function edit(TransactionGroup $transactionGroup)
{
@@ -70,19 +73,43 @@ class EditController extends Controller
}
/** @var AccountRepositoryInterface $repository */
- $repository = app(AccountRepositoryInterface::class);
- $allowedOpposingTypes = config('firefly.allowed_opposing_types');
- $accountToTypes = config('firefly.account_to_transaction');
- $expectedSourceTypes = config('firefly.expected_source_types');
- $allowedSourceDests = config('firefly.source_dests');
- //
+ $repository = app(AccountRepositoryInterface::class);
+ $allowedOpposingTypes = config('firefly.allowed_opposing_types');
+ $accountToTypes = config('firefly.account_to_transaction');
+ $expectedSourceTypes = config('firefly.expected_source_types');
+ $allowedSourceDests = config('firefly.source_dests');
+ $title = $transactionGroup->transactionJournals()->count() > 1 ? $transactionGroup->title : $transactionGroup->transactionJournals()->first()->description;
+ $subTitle = (string)trans('firefly.edit_transaction_title', ['description' => $title]);
+ $subTitleIcon = 'fa-plus';
+ $defaultCurrency = app('amount')->getDefaultCurrency();
+ $cash = $repository->getCashAccount();
+ $previousUrl = $this->rememberPreviousUrl('transactions.edit.url');
+ $parts = parse_url($previousUrl);
+ $search = sprintf('?%s', $parts['query'] ?? '');
+ $previousUrl = str_replace($search, '', $previousUrl);
- $defaultCurrency = app('amount')->getDefaultCurrency();
- $cash = $repository->getCashAccount();
- $previousUrl = $this->rememberPreviousUrl('transactions.edit.url');
- $parts = parse_url($previousUrl);
- $search = sprintf('?%s', $parts['query'] ?? '');
- $previousUrl = str_replace($search, '', $previousUrl);
+ // settings necessary for v2
+ $optionalFields = app('preferences')->get('transaction_journal_optional_fields', [])->data;
+ if (!is_array($optionalFields)) {
+ $optionalFields = [];
+ }
+ // not really a fan of this, but meh.
+ $optionalDateFields = [
+ 'interest_date' => $optionalFields['interest_date'] ?? false,
+ 'book_date' => $optionalFields['book_date'] ?? false,
+ 'process_date' => $optionalFields['process_date'] ?? false,
+ 'due_date' => $optionalFields['due_date'] ?? false,
+ 'payment_date' => $optionalFields['payment_date'] ?? false,
+ 'invoice_date' => $optionalFields['invoice_date'] ?? false,
+ ];
+ $optionalFields['external_url'] ??= false;
+ $optionalFields['location'] ??= false;
+ $optionalFields['location'] = $optionalFields['location'] && true === config('firefly.enable_external_map');
+
+ // map info voor v2:
+ $longitude = config('firefly.default_location.longitude');
+ $latitude = config('firefly.default_location.latitude');
+ $zoomLevel = config('firefly.default_location.zoom_level');
return view(
'transactions.edit',
@@ -90,6 +117,13 @@ class EditController extends Controller
'cash',
'allowedSourceDests',
'expectedSourceTypes',
+ 'optionalDateFields',
+ 'longitude',
+ 'latitude',
+ 'zoomLevel',
+ 'optionalFields',
+ 'subTitle',
+ 'subTitleIcon',
'transactionGroup',
'allowedOpposingTypes',
'accountToTypes',
@@ -98,4 +132,11 @@ class EditController extends Controller
)
);
}
+
+ public function unreconcile(TransactionJournal $journal): JsonResponse
+ {
+ $this->repository->unreconcileById($journal->id);
+
+ return response()->json([], 204);
+ }
}
diff --git a/app/Http/Controllers/Transaction/IndexController.php b/app/Http/Controllers/Transaction/IndexController.php
index 74636f6fb2..8013113c6d 100644
--- a/app/Http/Controllers/Transaction/IndexController.php
+++ b/app/Http/Controllers/Transaction/IndexController.php
@@ -32,8 +32,6 @@ use FireflyIII\Support\Http\Controllers\PeriodOverview;
use Illuminate\Contracts\View\Factory;
use Illuminate\Http\Request;
use Illuminate\View\View;
-use Psr\Container\ContainerExceptionInterface;
-use Psr\Container\NotFoundExceptionInterface;
/**
* Class IndexController
@@ -46,8 +44,6 @@ class IndexController extends Controller
/**
* IndexController constructor.
- *
-
*/
public function __construct()
{
@@ -69,15 +65,9 @@ class IndexController extends Controller
/**
* Index for a range of transactions.
*
- * @param Request $request
- * @param string $objectType
- * @param Carbon|null $start
- * @param Carbon|null $end
- *
* @return Factory|View
+ *
* @throws FireflyException
- * @throws ContainerExceptionInterface
- * @throws NotFoundExceptionInterface
*/
public function index(Request $request, string $objectType, Carbon $start = null, Carbon $end = null)
{
@@ -85,44 +75,52 @@ class IndexController extends Controller
$objectType = 'transfer';
}
- $subTitleIcon = config('firefly.transactionIconsByType.' . $objectType);
- $types = config('firefly.transactionTypesByType.' . $objectType);
+ // add a split for the (future) v2 release.
+ $periods = [];
+ $groups = [];
+ $subTitle = 'TODO page subtitle in v2';
+
+ $subTitleIcon = config('firefly.transactionIconsByType.'.$objectType);
+ $types = config('firefly.transactionTypesByType.'.$objectType);
$page = (int)$request->get('page');
$pageSize = (int)app('preferences')->get('listPageSize', 50)->data;
- if (null === $start) {
- $start = session('start');
- $end = session('end');
+
+ if ('v2' !== (string)config('firefly.layout')) {
+ if (null === $start) {
+ $start = session('start');
+ $end = session('end');
+ }
+ if (null === $end) {
+ // get last transaction ever?
+ $last = $this->repository->getLast();
+ $end = null !== $last ? $last->date : session('end');
+ }
+
+ [$start, $end] = $end < $start ? [$end, $start] : [$start, $end];
+ $startStr = $start->isoFormat($this->monthAndDayFormat);
+ $endStr = $end->isoFormat($this->monthAndDayFormat);
+ $subTitle = (string)trans(sprintf('firefly.title_%s_between', $objectType), ['start' => $startStr, 'end' => $endStr]);
+ $path = route('transactions.index', [$objectType, $start->format('Y-m-d'), $end->format('Y-m-d')]);
+ $firstJournal = $this->repository->firstNull();
+ $startPeriod = null === $firstJournal ? new Carbon() : $firstJournal->date;
+ $endPeriod = clone $end;
+ $periods = $this->getTransactionPeriodOverview($objectType, $startPeriod, $endPeriod);
+
+ /** @var GroupCollectorInterface $collector */
+ $collector = app(GroupCollectorInterface::class);
+
+ $collector->setRange($start, $end)
+ ->setTypes($types)
+ ->setLimit($pageSize)
+ ->setPage($page)
+ ->withBudgetInformation()
+ ->withCategoryInformation()
+ ->withAccountInformation()
+ ->withAttachmentInformation()
+ ;
+ $groups = $collector->getPaginatedGroups();
+ $groups->setPath($path);
}
- if (null === $end) {
- // get last transaction ever?
- $last = $this->repository->getLast();
- $end = $last ? $last->date : session('end');
- }
-
- [$start, $end] = $end < $start ? [$end, $start] : [$start, $end];
- $path = route('transactions.index', [$objectType, $start->format('Y-m-d'), $end->format('Y-m-d')]);
- $startStr = $start->isoFormat($this->monthAndDayFormat);
- $endStr = $end->isoFormat($this->monthAndDayFormat);
- $subTitle = (string)trans(sprintf('firefly.title_%s_between', $objectType), ['start' => $startStr, 'end' => $endStr]);
-
- $firstJournal = $this->repository->firstNull();
- $startPeriod = null === $firstJournal ? new Carbon() : $firstJournal->date;
- $endPeriod = clone $end;
- $periods = $this->getTransactionPeriodOverview($objectType, $startPeriod, $endPeriod);
-
- /** @var GroupCollectorInterface $collector */
- $collector = app(GroupCollectorInterface::class);
-
- $collector->setRange($start, $end)
- ->setTypes($types)
- ->setLimit($pageSize)
- ->setPage($page)
- ->withBudgetInformation()
- ->withCategoryInformation()
- ->withAccountInformation()
- ->withAttachmentInformation();
- $groups = $collector->getPaginatedGroups();
- $groups->setPath($path);
return view('transactions.index', compact('subTitle', 'objectType', 'subTitleIcon', 'groups', 'periods', 'start', 'end'));
}
@@ -130,38 +128,34 @@ class IndexController extends Controller
/**
* Index for ALL transactions.
*
- * @param Request $request
- * @param string $objectType
- *
* @return Factory|View
- * @throws ContainerExceptionInterface
- * @throws NotFoundExceptionInterface
*/
public function indexAll(Request $request, string $objectType)
{
- $subTitleIcon = config('firefly.transactionIconsByType.' . $objectType);
- $types = config('firefly.transactionTypesByType.' . $objectType);
+ $subTitleIcon = config('firefly.transactionIconsByType.'.$objectType);
+ $types = config('firefly.transactionTypesByType.'.$objectType);
$page = (int)$request->get('page');
$pageSize = (int)app('preferences')->get('listPageSize', 50)->data;
$path = route('transactions.index.all', [$objectType]);
$first = $this->repository->firstNull();
$start = null === $first ? new Carbon() : $first->date;
$last = $this->repository->getLast();
- $end = $last ? $last->date : today(config('app.timezone'));
- $subTitle = (string)trans('firefly.all_' . $objectType);
+ $end = null !== $last ? $last->date : today(config('app.timezone'));
+ $subTitle = (string)trans('firefly.all_'.$objectType);
/** @var GroupCollectorInterface $collector */
- $collector = app(GroupCollectorInterface::class);
+ $collector = app(GroupCollectorInterface::class);
$collector->setRange($start, $end)
- ->setTypes($types)
- ->setLimit($pageSize)
- ->setPage($page)
- ->withAccountInformation()
- ->withBudgetInformation()
- ->withCategoryInformation()
- ->withAttachmentInformation();
- $groups = $collector->getPaginatedGroups();
+ ->setTypes($types)
+ ->setLimit($pageSize)
+ ->setPage($page)
+ ->withAccountInformation()
+ ->withBudgetInformation()
+ ->withCategoryInformation()
+ ->withAttachmentInformation()
+ ;
+ $groups = $collector->getPaginatedGroups();
$groups->setPath($path);
return view('transactions.index', compact('subTitle', 'objectType', 'subTitleIcon', 'groups', 'start', 'end'));
diff --git a/app/Http/Controllers/Transaction/LinkController.php b/app/Http/Controllers/Transaction/LinkController.php
index f111b4460d..49a2e27dc8 100644
--- a/app/Http/Controllers/Transaction/LinkController.php
+++ b/app/Http/Controllers/Transaction/LinkController.php
@@ -33,7 +33,6 @@ use Illuminate\Contracts\View\Factory;
use Illuminate\Http\RedirectResponse;
use Illuminate\Http\Request;
use Illuminate\Routing\Redirector;
-use Illuminate\Support\Facades\Log;
use Illuminate\View\View;
/**
@@ -46,8 +45,6 @@ class LinkController extends Controller
/**
* LinkController constructor.
- *
-
*/
public function __construct()
{
@@ -69,8 +66,6 @@ class LinkController extends Controller
/**
* Delete a link.
*
- * @param TransactionJournalLink $link
- *
* @return Factory|View
*/
public function delete(TransactionJournalLink $link)
@@ -85,9 +80,7 @@ class LinkController extends Controller
/**
* Actually destroy it.
*
- * @param TransactionJournalLink $link
- *
- * @return RedirectResponse|Redirector
+ * @return Redirector|RedirectResponse
*/
public function destroy(TransactionJournalLink $link)
{
@@ -100,8 +93,6 @@ class LinkController extends Controller
}
/**
- * @param TransactionJournal $journal
- *
* @return Factory|View
*/
public function modal(TransactionJournal $journal)
@@ -114,17 +105,14 @@ class LinkController extends Controller
/**
* Store a new link.
*
- * @param JournalLinkRequest $request
- * @param TransactionJournal $journal
- *
- * @return RedirectResponse|Redirector
+ * @return Redirector|RedirectResponse
*/
public function store(JournalLinkRequest $request, TransactionJournal $journal)
{
- $linkInfo = $request->getLinkInfo();
+ $linkInfo = $request->getLinkInfo();
- Log::debug('We are here (store)');
- $other = $this->journalRepository->find($linkInfo['transaction_journal_id']);
+ app('log')->debug('We are here (store)');
+ $other = $this->journalRepository->find($linkInfo['transaction_journal_id']);
if (null === $other) {
session()->flash('error', (string)trans('firefly.invalid_link_selection'));
@@ -144,7 +132,7 @@ class LinkController extends Controller
return redirect(route('transactions.show', [$journal->transaction_group_id]));
}
- Log::debug(sprintf('Journal is %d, opposing is %d', $journal->id, $other->id));
+ app('log')->debug(sprintf('Journal is %d, opposing is %d', $journal->id, $other->id));
$this->repository->storeLink($linkInfo, $other, $journal);
session()->flash('success', (string)trans('firefly.journals_linked'));
@@ -154,9 +142,7 @@ class LinkController extends Controller
/**
* Switch link from A <> B to B <> A.
*
- * @param Request $request
- *
- * @return RedirectResponse|Redirector
+ * @return Redirector|RedirectResponse
*/
public function switchLink(Request $request)
{
diff --git a/app/Http/Controllers/Transaction/MassController.php b/app/Http/Controllers/Transaction/MassController.php
index c1837268a2..af7f14e87e 100644
--- a/app/Http/Controllers/Transaction/MassController.php
+++ b/app/Http/Controllers/Transaction/MassController.php
@@ -41,11 +41,9 @@ use Illuminate\Http\RedirectResponse;
use Illuminate\Routing\Redirector;
use Illuminate\Support\Facades\Log;
use Illuminate\View\View as IlluminateView;
-use InvalidArgumentException;
/**
* Class MassController.
- *
*/
class MassController extends Controller
{
@@ -53,8 +51,6 @@ class MassController extends Controller
/**
* MassController constructor.
- *
-
*/
public function __construct()
{
@@ -73,10 +69,6 @@ class MassController extends Controller
/**
* Mass delete transactions.
- *
- * @param array $journals
- *
- * @return IlluminateView
*/
public function delete(array $journals): IlluminateView
{
@@ -91,34 +83,34 @@ class MassController extends Controller
/**
* Do the mass delete.
*
- * @param MassDeleteJournalRequest $request
- *
* @return Application|Redirector|RedirectResponse
- *
*/
public function destroy(MassDeleteJournalRequest $request)
{
- Log::debug(sprintf('Now in %s', __METHOD__));
+ app('log')->debug(sprintf('Now in %s', __METHOD__));
$ids = $request->get('confirm_mass_delete');
$count = 0;
if (is_array($ids)) {
- Log::debug('Array of IDs', $ids);
+ app('log')->debug('Array of IDs', $ids);
+
/** @var string $journalId */
foreach ($ids as $journalId) {
- Log::debug(sprintf('Searching for ID #%d', $journalId));
- /** @var TransactionJournal $journal */
+ app('log')->debug(sprintf('Searching for ID #%d', $journalId));
+
+ /** @var null|TransactionJournal $journal */
$journal = $this->repository->find((int)$journalId);
- if (null !== $journal && (int)$journalId === (int)$journal->id) {
+ if (null !== $journal && (int)$journalId === $journal->id) {
$this->repository->destroyJournal($journal);
++$count;
- Log::debug(sprintf('Deleted transaction journal #%d', $journalId));
+ app('log')->debug(sprintf('Deleted transaction journal #%d', $journalId));
+
continue;
}
- Log::debug(sprintf('Could not find transaction journal #%d', $journalId));
+ app('log')->debug(sprintf('Could not find transaction journal #%d', $journalId));
}
}
app('preferences')->mark();
- session()->flash('success', (string)trans_choice('firefly.mass_deleted_transactions_success', $count));
+ session()->flash('success', trans_choice('firefly.mass_deleted_transactions_success', $count));
// redirect to previous URL:
return redirect($this->getPreviousUrl('transactions.mass-delete.url'));
@@ -126,29 +118,25 @@ class MassController extends Controller
/**
* Mass edit of journals.
- *
- * @param array $journals
- *
- * @return IlluminateView
*/
public function edit(array $journals): IlluminateView
{
- $subTitle = (string)trans('firefly.mass_edit_journals');
+ $subTitle = (string)trans('firefly.mass_edit_journals');
/** @var AccountRepositoryInterface $accountRepository */
- $accountRepository = app(AccountRepositoryInterface::class);
+ $accountRepository = app(AccountRepositoryInterface::class);
// valid withdrawal sources:
- $array = array_keys(config(sprintf('firefly.source_dests.%s', TransactionType::WITHDRAWAL)));
- $withdrawalSources = $accountRepository->getAccountsByType($array);
+ $array = array_keys(config(sprintf('firefly.source_dests.%s', TransactionType::WITHDRAWAL)));
+ $withdrawalSources = $accountRepository->getAccountsByType($array);
// valid deposit destinations:
$array = config(sprintf('firefly.source_dests.%s.%s', TransactionType::DEPOSIT, AccountType::REVENUE));
$depositDestinations = $accountRepository->getAccountsByType($array);
/** @var BudgetRepositoryInterface $budgetRepository */
- $budgetRepository = app(BudgetRepositoryInterface::class);
- $budgets = $budgetRepository->getBudgets();
+ $budgetRepository = app(BudgetRepositoryInterface::class);
+ $budgets = $budgetRepository->getBudgets();
// reverse amounts
foreach ($journals as $index => $journal) {
@@ -165,9 +153,8 @@ class MassController extends Controller
/**
* Mass update of journals.
*
- * @param MassEditJournalRequest $request
+ * @return Redirector|RedirectResponse
*
- * @return RedirectResponse|Redirector
* @throws FireflyException
*/
public function update(MassEditJournalRequest $request)
@@ -177,29 +164,28 @@ class MassController extends Controller
// TODO this is a weird error, should be caught.
throw new FireflyException('This is not an array.');
}
- $count = 0;
+ $count = 0;
+
/** @var string $journalId */
foreach ($journalIds as $journalId) {
$integer = (int)$journalId;
+
try {
$this->updateJournal($integer, $request);
- $count++;
+ ++$count;
} catch (FireflyException $e) {
// @ignoreException
}
}
app('preferences')->mark();
- session()->flash('success', (string)trans_choice('firefly.mass_edited_transactions_success', $count));
+ session()->flash('success', trans_choice('firefly.mass_edited_transactions_success', $count));
// redirect to previous URL:
return redirect($this->getPreviousUrl('transactions.mass-edit.url'));
}
/**
- * @param int $journalId
- * @param MassEditJournalRequest $request
- *
* @throws FireflyException
*/
private function updateJournal(int $journalId, MassEditJournalRequest $request): void
@@ -212,7 +198,7 @@ class MassController extends Controller
// for each field, call the update service.
$service->setTransactionJournal($journal);
- $data = [
+ $data = [
'date' => $this->getDateFromRequest($request, $journal->id, 'date'),
'description' => $this->getStringFromRequest($request, $journal->id, 'description'),
'source_id' => $this->getIntFromRequest($request, $journal->id, 'source_id'),
@@ -224,7 +210,7 @@ class MassController extends Controller
'amount' => $this->getStringFromRequest($request, $journal->id, 'amount'),
'foreign_amount' => $this->getStringFromRequest($request, $journal->id, 'foreign_amount'),
];
- Log::debug(sprintf('Will update journal #%d with data.', $journal->id), $data);
+ app('log')->debug(sprintf('Will update journal #%d with data.', $journal->id), $data);
// call service to update.
$service->setData($data);
@@ -233,13 +219,6 @@ class MassController extends Controller
event(new UpdatedTransactionGroup($journal->transactionGroup, true, true));
}
- /**
- * @param MassEditJournalRequest $request
- * @param int $journalId
- * @param string $key
- *
- * @return Carbon|null
- */
private function getDateFromRequest(MassEditJournalRequest $request, int $journalId, string $key): ?Carbon
{
$value = $request->get($key);
@@ -249,10 +228,12 @@ class MassController extends Controller
if (!array_key_exists($journalId, $value)) {
return null;
}
+
try {
$carbon = Carbon::parse($value[$journalId]);
- } catch (InvalidArgumentException $e) {
- $e->getMessage();
+ } catch (\InvalidArgumentException $e) {
+ Log::warning(sprintf('Could not parse "%s" but dont mind', $value[$journalId]));
+ Log::warning($e->getMessage());
return null;
}
@@ -260,13 +241,6 @@ class MassController extends Controller
return $carbon;
}
- /**
- * @param MassEditJournalRequest $request
- * @param int $journalId
- * @param string $string
- *
- * @return string|null
- */
private function getStringFromRequest(MassEditJournalRequest $request, int $journalId, string $string): ?string
{
$value = $request->get($string);
@@ -280,13 +254,6 @@ class MassController extends Controller
return (string)$value[$journalId];
}
- /**
- * @param MassEditJournalRequest $request
- * @param int $journalId
- * @param string $string
- *
- * @return int|null
- */
private function getIntFromRequest(MassEditJournalRequest $request, int $journalId, string $string): ?int
{
$value = $request->get($string);
diff --git a/app/Http/Controllers/Transaction/ShowController.php b/app/Http/Controllers/Transaction/ShowController.php
index 870d871347..b0f4f870ac 100644
--- a/app/Http/Controllers/Transaction/ShowController.php
+++ b/app/Http/Controllers/Transaction/ShowController.php
@@ -32,7 +32,6 @@ use FireflyIII\Repositories\TransactionGroup\TransactionGroupRepositoryInterface
use FireflyIII\Transformers\TransactionGroupTransformer;
use Illuminate\Contracts\View\Factory;
use Illuminate\Http\JsonResponse;
-use Illuminate\Http\Request;
use Illuminate\View\View;
use Symfony\Component\HttpFoundation\ParameterBag;
@@ -66,8 +65,6 @@ class ShowController extends Controller
}
/**
- * @param TransactionGroup $transactionGroup
- *
* @return JsonResponse
*/
public function debugShow(TransactionGroup $transactionGroup)
@@ -76,36 +73,34 @@ class ShowController extends Controller
}
/**
- * @param Request $request
- * @param TransactionGroup $transactionGroup
- *
* @return Factory|View
+ *
* @throws FireflyException
*/
- public function show(Request $request, TransactionGroup $transactionGroup)
+ public function show(TransactionGroup $transactionGroup)
{
- /** @var TransactionJournal $first */
- $first = $transactionGroup->transactionJournals()->first(['transaction_journals.*']);
- $splits = $transactionGroup->transactionJournals()->count();
+ /** @var null|TransactionJournal $first */
+ $first = $transactionGroup->transactionJournals()->first(['transaction_journals.*']);
+ $splits = $transactionGroup->transactionJournals()->count();
if (null === $first) {
throw new FireflyException('This transaction is broken :(.');
}
- $type = (string)trans(sprintf('firefly.%s', $first->transactionType->type));
- $title = 1 === $splits ? $first->description : $transactionGroup->title;
- $subTitle = sprintf('%s: "%s"', $type, $title);
+ $type = (string)trans(sprintf('firefly.%s', $first->transactionType->type));
+ $title = 1 === $splits ? $first->description : $transactionGroup->title;
+ $subTitle = sprintf('%s: "%s"', $type, $title);
/** @var TransactionGroupTransformer $transformer */
- $transformer = app(TransactionGroupTransformer::class);
+ $transformer = app(TransactionGroupTransformer::class);
$transformer->setParameters(new ParameterBag());
- $groupArray = $transformer->transformObject($transactionGroup);
+ $groupArray = $transformer->transformObject($transactionGroup);
// do some calculations:
- $amounts = $this->getAmounts($groupArray);
- $accounts = $this->getAccounts($groupArray);
+ $amounts = $this->getAmounts($groupArray);
+ $accounts = $this->getAccounts($groupArray);
- foreach ($groupArray['transactions'] as $index => $transaction) {
+ foreach (array_keys($groupArray['transactions']) as $index) {
$groupArray['transactions'][$index]['tags'] = $this->repository->getTagObjects(
$groupArray['transactions'][$index]['transaction_journal_id']
);
@@ -118,10 +113,9 @@ class ShowController extends Controller
$logEntries[$journal->id] = $this->aleRepository->getForObject($journal);
}
- $events = $this->repository->getPiggyEvents($transactionGroup);
- $attachments = $this->repository->getAttachments($transactionGroup);
- $links = $this->repository->getLinks($transactionGroup);
-
+ $events = $this->repository->getPiggyEvents($transactionGroup);
+ $attachments = $this->repository->getAttachments($transactionGroup);
+ $links = $this->repository->getLinks($transactionGroup);
return view(
'transactions.show',
@@ -143,16 +137,11 @@ class ShowController extends Controller
);
}
- /**
- * @param array $group
- *
- * @return array
- */
private function getAmounts(array $group): array
{
$amounts = [];
foreach ($group['transactions'] as $transaction) {
- $symbol = $transaction['currency_symbol'];
+ $symbol = $transaction['currency_symbol'];
if (!array_key_exists($symbol, $amounts)) {
$amounts[$symbol] = [
'amount' => '0',
@@ -162,12 +151,12 @@ class ShowController extends Controller
}
$amounts[$symbol]['amount'] = bcadd($amounts[$symbol]['amount'], $transaction['amount']);
if (null !== $transaction['foreign_amount'] && '' !== $transaction['foreign_amount']
- && bccomp(
+ && 0 !== bccomp(
'0',
$transaction['foreign_amount']
- ) !== 0) {
+ )) {
// same for foreign currency:
- $foreignSymbol = $transaction['foreign_currency_symbol'];
+ $foreignSymbol = $transaction['foreign_currency_symbol'];
if (!array_key_exists($foreignSymbol, $amounts)) {
$amounts[$foreignSymbol] = [
'amount' => '0',
@@ -185,14 +174,12 @@ class ShowController extends Controller
return $amounts;
}
- /**
- * @param array $group
- *
- * @return array
- */
private function getAccounts(array $group): array
{
- $accounts = [];
+ $accounts = [
+ 'source' => [],
+ 'destination' => [],
+ ];
foreach ($group['transactions'] as $transaction) {
$accounts['source'][] = [
diff --git a/app/Http/Controllers/TransactionCurrency/CreateController.php b/app/Http/Controllers/TransactionCurrency/CreateController.php
new file mode 100644
index 0000000000..75bb2f9cf3
--- /dev/null
+++ b/app/Http/Controllers/TransactionCurrency/CreateController.php
@@ -0,0 +1,137 @@
+.
+ */
+
+declare(strict_types=1);
+
+namespace FireflyIII\Http\Controllers\TransactionCurrency;
+
+use FireflyIII\Exceptions\FireflyException;
+use FireflyIII\Http\Controllers\Controller;
+use FireflyIII\Http\Requests\CurrencyFormRequest;
+use FireflyIII\Repositories\User\UserRepositoryInterface;
+use FireflyIII\Repositories\UserGroups\Currency\CurrencyRepositoryInterface;
+use FireflyIII\User;
+use Illuminate\Contracts\View\Factory;
+use Illuminate\Http\RedirectResponse;
+use Illuminate\Http\Request;
+use Illuminate\Routing\Redirector;
+use Illuminate\Support\Facades\Log;
+use Illuminate\View\View;
+
+/**
+ * Class CreateController
+ */
+class CreateController extends Controller
+{
+ protected CurrencyRepositoryInterface $repository;
+ protected UserRepositoryInterface $userRepository;
+
+ /**
+ * CurrencyController constructor.
+ */
+ public function __construct()
+ {
+ parent::__construct();
+
+ $this->middleware(
+ function ($request, $next) {
+ app('view')->share('title', (string)trans('firefly.currencies'));
+ app('view')->share('mainTitleIcon', 'fa-usd');
+ $this->repository = app(CurrencyRepositoryInterface::class);
+ $this->userRepository = app(UserRepositoryInterface::class);
+
+ return $next($request);
+ }
+ );
+ }
+
+ /**
+ * Create a currency.
+ *
+ * @return Factory|Redirector|RedirectResponse|View
+ */
+ public function create(Request $request)
+ {
+ /** @var User $user */
+ $user = auth()->user();
+ if (!$this->userRepository->hasRole($user, 'owner')) {
+ $request->session()->flash('error', (string)trans('firefly.ask_site_owner', ['owner' => e(config('firefly.site_owner'))]));
+
+ return redirect(route('currencies.index'));
+ }
+
+ $subTitleIcon = 'fa-plus';
+ $subTitle = (string)trans('firefly.create_currency');
+
+ // put previous url in session if not redirect from store (not "create another").
+ if (true !== session('currencies.create.fromStore')) {
+ $this->rememberPreviousUrl('currencies.create.url');
+ }
+ $request->session()->forget('currencies.create.fromStore');
+
+ Log::channel('audit')->info('Create new currency.');
+
+ return view('currencies.create', compact('subTitleIcon', 'subTitle'));
+ }
+
+ /**
+ * Store new currency.
+ *
+ * @return $this|Redirector|RedirectResponse
+ */
+ public function store(CurrencyFormRequest $request)
+ {
+ /** @var User $user */
+ $user = auth()->user();
+ $data = $request->getCurrencyData();
+ if (!$this->userRepository->hasRole($user, 'owner')) {
+ app('log')->error('User '.auth()->user()->id.' is not admin, but tried to store a currency.');
+ Log::channel('audit')->warning('Tried to create (POST) currency without admin rights.', $data);
+
+ return redirect($this->getPreviousUrl('currencies.create.url'))->withInput();
+ }
+
+ $data['enabled'] = true;
+
+ try {
+ $currency = $this->repository->store($data);
+ } catch (FireflyException $e) {
+ app('log')->error($e->getMessage());
+ Log::channel('audit')->warning('Could not store (POST) currency without admin rights.', $data);
+ $request->session()->flash('error', (string)trans('firefly.could_not_store_currency'));
+ $currency = null;
+ }
+ $redirect = redirect($this->getPreviousUrl('currencies.create.url'));
+
+ if (null !== $currency) {
+ $request->session()->flash('success', (string)trans('firefly.created_currency', ['name' => $currency->name]));
+ Log::channel('audit')->info('Created (POST) currency.', $data);
+ if (1 === (int)$request->get('create_another')) {
+ $request->session()->put('currencies.create.fromStore', true);
+
+ $redirect = redirect(route('currencies.create'))->withInput();
+ }
+ }
+
+ return $redirect;
+ }
+}
diff --git a/app/Http/Controllers/TransactionCurrency/DeleteController.php b/app/Http/Controllers/TransactionCurrency/DeleteController.php
new file mode 100644
index 0000000000..5ddecbff90
--- /dev/null
+++ b/app/Http/Controllers/TransactionCurrency/DeleteController.php
@@ -0,0 +1,136 @@
+.
+ */
+
+declare(strict_types=1);
+
+namespace FireflyIII\Http\Controllers\TransactionCurrency;
+
+use FireflyIII\Http\Controllers\Controller;
+use FireflyIII\Models\TransactionCurrency;
+use FireflyIII\Repositories\User\UserRepositoryInterface;
+use FireflyIII\Repositories\UserGroups\Currency\CurrencyRepositoryInterface;
+use FireflyIII\User;
+use Illuminate\Contracts\View\Factory;
+use Illuminate\Http\RedirectResponse;
+use Illuminate\Http\Request;
+use Illuminate\Routing\Redirector;
+use Illuminate\Support\Facades\Log;
+use Illuminate\View\View;
+
+/**
+ * Class DeleteController
+ */
+class DeleteController extends Controller
+{
+ protected CurrencyRepositoryInterface $repository;
+ protected UserRepositoryInterface $userRepository;
+
+ /**
+ * CurrencyController constructor.
+ */
+ public function __construct()
+ {
+ parent::__construct();
+
+ $this->middleware(
+ function ($request, $next) {
+ app('view')->share('title', (string)trans('firefly.currencies'));
+ app('view')->share('mainTitleIcon', 'fa-usd');
+ $this->repository = app(CurrencyRepositoryInterface::class);
+ $this->userRepository = app(UserRepositoryInterface::class);
+
+ return $next($request);
+ }
+ );
+ }
+
+ /**
+ * Deletes a currency.
+ *
+ * @return Factory|Redirector|RedirectResponse|View
+ */
+ public function delete(Request $request, TransactionCurrency $currency)
+ {
+ /** @var User $user */
+ $user = auth()->user();
+ if (!$this->userRepository->hasRole($user, 'owner')) {
+ $request->session()->flash('error', (string)trans('firefly.ask_site_owner', ['owner' => e(config('firefly.site_owner'))]));
+ Log::channel('audit')->warning(sprintf('Tried to visit page to delete currency %s but is not site owner.', $currency->code));
+
+ return redirect(route('currencies.index'));
+ }
+
+ if ($this->repository->currencyInUse($currency)) {
+ $location = $this->repository->currencyInUseAt($currency);
+ $message = (string)trans(sprintf('firefly.cannot_disable_currency_%s', $location), ['name' => e($currency->name)]);
+ $request->session()->flash('error', $message);
+ Log::channel('audit')->warning(sprintf('Tried to visit page to delete currency %s but currency is in use.', $currency->code));
+
+ return redirect(route('currencies.index'));
+ }
+
+ // put previous url in session
+ $this->rememberPreviousUrl('currencies.delete.url');
+ $subTitle = (string)trans('form.delete_currency', ['name' => $currency->name]);
+ Log::channel('audit')->info(sprintf('Visit page to delete currency %s.', $currency->code));
+
+ return view('currencies.delete', compact('currency', 'subTitle'));
+ }
+
+ /**
+ * Destroys a currency.
+ *
+ * @return Redirector|RedirectResponse
+ */
+ public function destroy(Request $request, TransactionCurrency $currency)
+ {
+ /** @var User $user */
+ $user = auth()->user();
+ if (!$this->userRepository->hasRole($user, 'owner')) {
+ $request->session()->flash('error', (string)trans('firefly.ask_site_owner', ['owner' => e(config('firefly.site_owner'))]));
+ Log::channel('audit')->warning(sprintf('Tried to delete currency %s but is not site owner.', $currency->code));
+
+ return redirect(route('currencies.index'));
+ }
+
+ if ($this->repository->currencyInUse($currency)) {
+ $request->session()->flash('error', (string)trans('firefly.cannot_delete_currency', ['name' => e($currency->name)]));
+ Log::channel('audit')->info(sprintf('Tried to delete currency %s but is in use.', $currency->code));
+
+ return redirect(route('currencies.index'));
+ }
+
+ if ($this->repository->isFallbackCurrency($currency)) {
+ $request->session()->flash('error', (string)trans('firefly.cannot_delete_fallback_currency', ['name' => e($currency->name)]));
+ Log::channel('audit')->info(sprintf('Tried to delete currency %s but is FALLBACK.', $currency->code));
+
+ return redirect(route('currencies.index'));
+ }
+
+ Log::channel('audit')->info(sprintf('Deleted currency %s.', $currency->code));
+ $this->repository->destroy($currency);
+
+ $request->session()->flash('success', (string)trans('firefly.deleted_currency', ['name' => $currency->name]));
+
+ return redirect($this->getPreviousUrl('currencies.delete.url'));
+ }
+}
diff --git a/app/Http/Controllers/TransactionCurrency/EditController.php b/app/Http/Controllers/TransactionCurrency/EditController.php
new file mode 100644
index 0000000000..75ceb9f539
--- /dev/null
+++ b/app/Http/Controllers/TransactionCurrency/EditController.php
@@ -0,0 +1,140 @@
+.
+ */
+
+declare(strict_types=1);
+
+namespace FireflyIII\Http\Controllers\TransactionCurrency;
+
+use FireflyIII\Http\Controllers\Controller;
+use FireflyIII\Http\Requests\CurrencyFormRequest;
+use FireflyIII\Models\TransactionCurrency;
+use FireflyIII\Repositories\User\UserRepositoryInterface;
+use FireflyIII\Repositories\UserGroups\Currency\CurrencyRepositoryInterface;
+use FireflyIII\User;
+use Illuminate\Contracts\View\Factory;
+use Illuminate\Http\RedirectResponse;
+use Illuminate\Http\Request;
+use Illuminate\Routing\Redirector;
+use Illuminate\Support\Facades\Log;
+use Illuminate\View\View;
+
+class EditController extends Controller
+{
+ protected CurrencyRepositoryInterface $repository;
+ protected UserRepositoryInterface $userRepository;
+
+ /**
+ * CurrencyController constructor.
+ */
+ public function __construct()
+ {
+ parent::__construct();
+
+ $this->middleware(
+ function ($request, $next) {
+ app('view')->share('title', (string)trans('firefly.currencies'));
+ app('view')->share('mainTitleIcon', 'fa-usd');
+ $this->repository = app(CurrencyRepositoryInterface::class);
+ $this->userRepository = app(UserRepositoryInterface::class);
+
+ return $next($request);
+ }
+ );
+ }
+
+ /**
+ * Edit a currency.
+ *
+ * @return Factory|Redirector|RedirectResponse|View
+ */
+ public function edit(Request $request, TransactionCurrency $currency)
+ {
+ /** @var User $user */
+ $user = auth()->user();
+ if (!$this->userRepository->hasRole($user, 'owner')) {
+ $request->session()->flash('error', (string)trans('firefly.ask_site_owner', ['owner' => e(config('firefly.site_owner'))]));
+ Log::channel('audit')->warning(sprintf('Tried to edit currency %s but is not owner.', $currency->code));
+
+ return redirect(route('currencies.index'));
+ }
+
+ $subTitleIcon = 'fa-pencil';
+ $subTitle = (string)trans('breadcrumbs.edit_currency', ['name' => $currency->name]);
+ $currency->symbol = htmlentities($currency->symbol);
+
+ // is currently enabled (for this user?)
+ $userCurrencies = $this->repository->get()->pluck('id')->toArray();
+ $enabled = in_array($currency->id, $userCurrencies, true);
+
+ // code to handle active-checkboxes
+ $hasOldInput = null !== $request->old('_token');
+ $preFilled = [
+ 'enabled' => $hasOldInput ? (bool)$request->old('enabled') : $enabled,
+ ];
+
+ $request->session()->flash('preFilled', $preFilled);
+ Log::channel('audit')->info('Edit currency.', $currency->toArray());
+
+ // put previous url in session if not redirect from store (not "return_to_edit").
+ if (true !== session('currencies.edit.fromUpdate')) {
+ $this->rememberPreviousUrl('currencies.edit.url');
+ }
+ $request->session()->forget('currencies.edit.fromUpdate');
+
+ return view('currencies.edit', compact('currency', 'subTitle', 'subTitleIcon'));
+ }
+
+ /**
+ * Updates a currency.
+ *
+ * @return Redirector|RedirectResponse
+ */
+ public function update(CurrencyFormRequest $request, TransactionCurrency $currency)
+ {
+ /** @var User $user */
+ $user = auth()->user();
+ $data = $request->getCurrencyData();
+
+ if (false === $data['enabled'] && $this->repository->currencyInUse($currency)) {
+ $data['enabled'] = true;
+ }
+
+ if (!$this->userRepository->hasRole($user, 'owner')) {
+ $request->session()->flash('error', (string)trans('firefly.ask_site_owner', ['owner' => e(config('firefly.site_owner'))]));
+ Log::channel('audit')->warning('Tried to update (POST) currency without admin rights.', $data);
+
+ return redirect(route('currencies.index'));
+ }
+ $currency = $this->repository->update($currency, $data);
+ Log::channel('audit')->info('Updated (POST) currency.', $data);
+ $request->session()->flash('success', (string)trans('firefly.updated_currency', ['name' => $currency->name]));
+ app('preferences')->mark();
+
+ if (1 === (int)$request->get('return_to_edit')) {
+ $request->session()->put('currencies.edit.fromUpdate', true);
+
+ return redirect(route('currencies.edit', [$currency->id]));
+ }
+
+ return redirect($this->getPreviousUrl('currencies.edit.url'));
+ }
+}
diff --git a/app/Http/Controllers/TransactionCurrency/IndexController.php b/app/Http/Controllers/TransactionCurrency/IndexController.php
new file mode 100644
index 0000000000..3dc9fb739f
--- /dev/null
+++ b/app/Http/Controllers/TransactionCurrency/IndexController.php
@@ -0,0 +1,96 @@
+.
+ */
+
+declare(strict_types=1);
+
+namespace FireflyIII\Http\Controllers\TransactionCurrency;
+
+use FireflyIII\Http\Controllers\Controller;
+use FireflyIII\Models\TransactionCurrency;
+use FireflyIII\Repositories\User\UserRepositoryInterface;
+use FireflyIII\Repositories\UserGroups\Currency\CurrencyRepositoryInterface;
+use FireflyIII\User;
+use Illuminate\Contracts\View\Factory;
+use Illuminate\Http\Request;
+use Illuminate\Pagination\LengthAwarePaginator;
+use Illuminate\View\View;
+
+class IndexController extends Controller
+{
+ protected CurrencyRepositoryInterface $repository;
+ protected UserRepositoryInterface $userRepository;
+
+ /**
+ * CurrencyController constructor.
+ */
+ public function __construct()
+ {
+ parent::__construct();
+
+ $this->middleware(
+ function ($request, $next) {
+ app('view')->share('title', (string)trans('firefly.currencies'));
+ app('view')->share('mainTitleIcon', 'fa-usd');
+ $this->repository = app(CurrencyRepositoryInterface::class);
+ $this->userRepository = app(UserRepositoryInterface::class);
+
+ return $next($request);
+ }
+ );
+ }
+
+ /**
+ * Show overview of currencies.
+ *
+ * @return Factory|View
+ */
+ public function index(Request $request)
+ {
+ /** @var User $user */
+ $user = auth()->user();
+ $page = 0 === (int)$request->get('page') ? 1 : (int)$request->get('page');
+ $pageSize = (int)app('preferences')->get('listPageSize', 50)->data;
+ $collection = $this->repository->getAll();
+ $total = $collection->count();
+ $collection = $collection->slice(($page - 1) * $pageSize, $pageSize);
+
+ // order so default is on top:
+ $collection = $collection->sortBy(
+ static function (TransactionCurrency $currency) {
+ $default = true === $currency->userGroupDefault ? 0 : 1;
+ $enabled = true === $currency->userGroupEnabled ? 0 : 1;
+
+ return sprintf('%s-%s-%s', $default, $enabled, $currency->code);
+ }
+ );
+
+ $currencies = new LengthAwarePaginator($collection, $total, $pageSize, $page);
+ $currencies->setPath(route('currencies.index'));
+ $isOwner = true;
+ if (!$this->userRepository->hasRole($user, 'owner')) {
+ $request->session()->flash('info', (string)trans('firefly.ask_site_owner', ['owner' => config('firefly.site_owner')]));
+ $isOwner = false;
+ }
+
+ return view('currencies.index', compact('currencies', 'isOwner'));
+ }
+}
diff --git a/app/Http/Controllers/Webhooks/CreateController.php b/app/Http/Controllers/Webhooks/CreateController.php
index 4bf123ef0b..b1d06ce1a1 100644
--- a/app/Http/Controllers/Webhooks/CreateController.php
+++ b/app/Http/Controllers/Webhooks/CreateController.php
@@ -26,23 +26,22 @@ namespace FireflyIII\Http\Controllers\Webhooks;
use FireflyIII\Http\Controllers\Controller;
use Illuminate\Contracts\View\Factory;
+use Illuminate\Support\Facades\Log;
use Illuminate\View\View;
+use Symfony\Component\HttpKernel\Exception\NotFoundHttpException;
/**
* Class CreateController
*/
class CreateController extends Controller
{
- /**
- *
- */
public function __construct()
{
parent::__construct();
// translations:
$this->middleware(
- function ($request, $next) {
+ static function ($request, $next) {
app('view')->share('mainTitleIcon', 'fa-bolt');
app('view')->share('subTitleIcon', 'fa-plus');
app('view')->share('title', (string)trans('firefly.webhooks'));
@@ -60,7 +59,14 @@ class CreateController extends Controller
*/
public function index()
{
+ if (false === config('firefly.allow_webhooks')) {
+ Log::channel('audit')->warning('User visits webhook create page, but webhooks are DISABLED.');
+
+ throw new NotFoundHttpException('Webhooks are not enabled.');
+ }
+ Log::channel('audit')->info('User visits webhook create page.');
$previousUrl = $this->rememberPreviousUrl('webhooks.create.url');
+
return view('webhooks.create', compact('previousUrl'));
}
}
diff --git a/app/Http/Controllers/Webhooks/DeleteController.php b/app/Http/Controllers/Webhooks/DeleteController.php
index 7d0cd15ae7..b1ecd4d78a 100644
--- a/app/Http/Controllers/Webhooks/DeleteController.php
+++ b/app/Http/Controllers/Webhooks/DeleteController.php
@@ -28,6 +28,8 @@ use FireflyIII\Models\Webhook;
use Illuminate\Contracts\Foundation\Application;
use Illuminate\Contracts\View\Factory;
use Illuminate\Contracts\View\View;
+use Illuminate\Support\Facades\Log;
+use Symfony\Component\HttpKernel\Exception\NotFoundHttpException;
/**
* Class DeleteController
@@ -36,8 +38,6 @@ class DeleteController extends Controller
{
/**
* DeleteController constructor.
- *
-
*/
public function __construct()
{
@@ -45,7 +45,7 @@ class DeleteController extends Controller
// translations:
$this->middleware(
- function ($request, $next) {
+ static function ($request, $next) {
app('view')->share('mainTitleIcon', 'fa-bolt');
app('view')->share('subTitleIcon', 'fa-trash');
app('view')->share('title', (string)trans('firefly.webhooks'));
@@ -59,12 +59,16 @@ class DeleteController extends Controller
/**
* Delete account screen.
*
- * @param Webhook $webhook
- *
- * @return Factory|Application|View
+ * @return Application|Factory|View
*/
public function index(Webhook $webhook)
{
+ if (false === config('firefly.allow_webhooks')) {
+ Log::channel('audit')->warning('User visits webhook delete page, but webhooks are DISABLED.');
+
+ throw new NotFoundHttpException('Webhooks are not enabled.');
+ }
+ Log::channel('audit')->info('User visits webhook delete page.');
$subTitle = (string)trans('firefly.delete_webhook', ['title' => $webhook->title]);
$this->rememberPreviousUrl('webhooks.delete.url');
diff --git a/app/Http/Controllers/Webhooks/EditController.php b/app/Http/Controllers/Webhooks/EditController.php
index 01a028334c..65f178a867 100644
--- a/app/Http/Controllers/Webhooks/EditController.php
+++ b/app/Http/Controllers/Webhooks/EditController.php
@@ -28,6 +28,8 @@ use FireflyIII\Models\Webhook;
use Illuminate\Contracts\Foundation\Application;
use Illuminate\Contracts\View\Factory;
use Illuminate\Contracts\View\View;
+use Illuminate\Support\Facades\Log;
+use Symfony\Component\HttpKernel\Exception\NotFoundHttpException;
/**
* Class EditController
@@ -36,8 +38,6 @@ class EditController extends Controller
{
/**
* DeleteController constructor.
- *
-
*/
public function __construct()
{
@@ -45,7 +45,7 @@ class EditController extends Controller
// translations:
$this->middleware(
- function ($request, $next) {
+ static function ($request, $next) {
app('view')->share('mainTitleIcon', 'fa-bolt');
app('view')->share('subTitleIcon', 'fa-pencil');
app('view')->share('title', (string)trans('firefly.webhooks'));
@@ -58,14 +58,18 @@ class EditController extends Controller
/**
* Delete account screen.
*
- * @param Webhook $webhook
- *
- * @return Factory|Application|View
+ * @return Application|Factory|View
*/
public function index(Webhook $webhook)
{
+ if (false === config('firefly.allow_webhooks')) {
+ Log::channel('audit')->warning('User visits webhook edit page, but webhooks are DISABLED.');
+
+ throw new NotFoundHttpException('Webhooks are not enabled.');
+ }
+ Log::channel('audit')->info('User visits webhook edit page.');
$subTitle = (string)trans('firefly.edit_webhook', ['title' => $webhook->title]);
- $this->rememberPreviousUrl('webhooks.delete.url');
+ $this->rememberPreviousUrl('webhooks.edit.url');
return view('webhooks.edit', compact('webhook', 'subTitle'));
}
diff --git a/app/Http/Controllers/Webhooks/IndexController.php b/app/Http/Controllers/Webhooks/IndexController.php
index fb5067aa21..c6ee272353 100644
--- a/app/Http/Controllers/Webhooks/IndexController.php
+++ b/app/Http/Controllers/Webhooks/IndexController.php
@@ -26,24 +26,22 @@ namespace FireflyIII\Http\Controllers\Webhooks;
use FireflyIII\Http\Controllers\Controller;
use Illuminate\Contracts\View\Factory;
-use Illuminate\Http\Request;
+use Illuminate\Support\Facades\Log;
use Illuminate\View\View;
+use Symfony\Component\HttpKernel\Exception\NotFoundHttpException;
/**
* Class IndexController
*/
class IndexController extends Controller
{
- /**
- *
- */
public function __construct()
{
parent::__construct();
// translations:
$this->middleware(
- function ($request, $next) {
+ static function ($request, $next) {
app('view')->share('mainTitleIcon', 'fa-bolt');
app('view')->share('title', (string)trans('firefly.webhooks'));
@@ -53,14 +51,17 @@ class IndexController extends Controller
}
/**
- * Show debug info.
- *
- * @param Request $request
- *
* @return Factory|View
*/
- public function index(Request $request)
+ public function index()
{
+ if (false === config('firefly.allow_webhooks')) {
+ Log::channel('audit')->warning('User visits webhook index page, but webhooks are DISABLED.');
+
+ throw new NotFoundHttpException('Webhooks are not enabled.');
+ }
+ Log::channel('audit')->info('User visits webhook index page.');
+
return view('webhooks.index');
}
}
diff --git a/app/Http/Controllers/Webhooks/ShowController.php b/app/Http/Controllers/Webhooks/ShowController.php
index 233523f96f..b0ba366162 100644
--- a/app/Http/Controllers/Webhooks/ShowController.php
+++ b/app/Http/Controllers/Webhooks/ShowController.php
@@ -28,6 +28,8 @@ use FireflyIII\Models\Webhook;
use Illuminate\Contracts\Foundation\Application;
use Illuminate\Contracts\View\Factory;
use Illuminate\Contracts\View\View;
+use Illuminate\Support\Facades\Log;
+use Symfony\Component\HttpKernel\Exception\NotFoundHttpException;
/**
* Class ShowController
@@ -36,8 +38,6 @@ class ShowController extends Controller
{
/**
* DeleteController constructor.
- *
-
*/
public function __construct()
{
@@ -45,7 +45,7 @@ class ShowController extends Controller
// translations:
$this->middleware(
- function ($request, $next) {
+ static function ($request, $next) {
app('view')->share('mainTitleIcon', 'fa-bolt');
app('view')->share('subTitleIcon', 'fa-bolt');
app('view')->share('title', (string)trans('firefly.webhooks'));
@@ -58,12 +58,16 @@ class ShowController extends Controller
/**
* Delete account screen.
*
- * @param Webhook $webhook
- *
- * @return Factory|Application|View
+ * @return Application|Factory|View
*/
public function index(Webhook $webhook)
{
+ if (false === config('firefly.allow_webhooks')) {
+ Log::channel('audit')->warning(sprintf('User visits webhook #%d page, but webhooks are DISABLED.', $webhook->id));
+
+ throw new NotFoundHttpException('Webhooks are not enabled.');
+ }
+ Log::channel('audit')->info(sprintf('User visits webhook #%d page.', $webhook->id));
$subTitle = (string)trans('firefly.show_webhook', ['title' => $webhook->title]);
return view('webhooks.show', compact('webhook', 'subTitle'));
diff --git a/app/Http/Kernel.php b/app/Http/Kernel.php
index 83e302cd3f..139547582c 100644
--- a/app/Http/Kernel.php
+++ b/app/Http/Kernel.php
@@ -54,16 +54,9 @@ use PragmaRX\Google2FALaravel\Middleware as MFAMiddleware;
/**
* Class Kernel
- *
-
*/
class Kernel extends HttpKernel
{
- /**
- * The application's global HTTP middleware stack.
- *
- * @var array
- */
protected $middleware
= [
SecureHeaders::class,
@@ -74,13 +67,6 @@ class Kernel extends HttpKernel
TrustProxies::class,
InstallationId::class,
];
- /**
- * The application's route middleware.
- *
- * These middleware may be assigned to groups or used individually.
- *
- * @var array
- */
protected $middlewareAliases
= [
'auth' => Authenticate::class,
@@ -90,11 +76,6 @@ class Kernel extends HttpKernel
'guest' => RedirectIfAuthenticated::class,
'throttle' => ThrottleRequests::class,
];
- /**
- * The application's route middleware groups.
- *
- * @var array
- */
protected $middlewareGroups
= [
// does not check login
@@ -141,7 +122,7 @@ class Kernel extends HttpKernel
VerifyCsrfToken::class,
Binder::class,
Authenticate::class,
- //RedirectIfTwoFactorAuthenticated::class,
+ // RedirectIfTwoFactorAuthenticated::class,
],
// MUST be logged in
@@ -186,7 +167,7 @@ class Kernel extends HttpKernel
ShareErrorsFromSession::class,
VerifyCsrfToken::class,
Authenticate::class,
- //AuthenticateTwoFactor::class,
+ // AuthenticateTwoFactor::class,
IsAdmin::class,
Range::class,
Binder::class,
@@ -206,13 +187,6 @@ class Kernel extends HttpKernel
'bindings',
],
];
- /**
- * The priority-sorted list of middleware.
- *
- * This forces non-global middleware to always be in the given order.
- *
- * @var array
- */
protected $middlewarePriority
= [
StartFireflySession::class,
diff --git a/app/Http/Middleware/AcceptHeaders.php b/app/Http/Middleware/AcceptHeaders.php
index cd3c7f64c2..8c525a4a52 100644
--- a/app/Http/Middleware/AcceptHeaders.php
+++ b/app/Http/Middleware/AcceptHeaders.php
@@ -29,18 +29,13 @@ use Illuminate\Http\Request;
use Illuminate\Http\Response;
use Symfony\Component\HttpKernel\Exception\BadRequestHttpException;
-/**
- *
- */
class AcceptHeaders
{
/**
* Handle the incoming requests.
*
- * @param Request $request
- * @param callable $next
- *
* @return Response
+ *
* @throws BadHttpHeaderException
*/
public function handle(Request $request, callable $next): mixed
@@ -50,7 +45,6 @@ class AcceptHeaders
$contentTypes = ['application/x-www-form-urlencoded', 'application/json', 'application/vnd.api+json', 'application/octet-stream'];
$submitted = (string)$request->header('Content-Type');
-
// if bad Accept header, send error.
if (!$request->accepts($accepts)) {
throw new BadHttpHeaderException(sprintf('Accept header "%s" is not something this server can provide.', $request->header('Accept')));
@@ -59,34 +53,31 @@ class AcceptHeaders
if (('POST' === $method || 'PUT' === $method) && !$request->hasHeader('Content-Type')) {
$error = new BadHttpHeaderException('Content-Type header cannot be empty.');
$error->statusCode = 415;
+
throw $error;
}
if (('POST' === $method || 'PUT' === $method) && !$this->acceptsHeader($submitted, $contentTypes)) {
$error = new BadHttpHeaderException(sprintf('Content-Type cannot be "%s"', $submitted));
$error->statusCode = 415;
+
throw $error;
}
// throw bad request if trace id is not a UUID
- $uuid = $request->header('X-Trace-Id');
- if (is_string($uuid) && '' !== trim($uuid) && (preg_match('/^[a-f\d]{8}(-[a-f\d]{4}){4}[a-f\d]{8}$/i', trim($uuid)) !== 1)) {
+ $uuid = $request->header('X-Trace-Id');
+ if (is_string($uuid) && '' !== trim($uuid) && (1 !== preg_match('/^[a-f\d]{8}(-[a-f\d]{4}){4}[a-f\d]{8}$/i', trim($uuid)))) {
throw new BadRequestHttpException('Bad X-Trace-Id header.');
}
return $next($request);
}
- /**
- * @param string $content
- * @param array $accepted
- *
- * @return bool
- */
private function acceptsHeader(string $content, array $accepted): bool
{
if (str_contains($content, ';')) {
$content = trim(explode(';', $content)[0]);
}
+
return in_array($content, $accepted, true);
}
}
diff --git a/app/Http/Middleware/Authenticate.php b/app/Http/Middleware/Authenticate.php
index 476ceabe80..400482d09d 100644
--- a/app/Http/Middleware/Authenticate.php
+++ b/app/Http/Middleware/Authenticate.php
@@ -24,13 +24,11 @@ declare(strict_types=1);
namespace FireflyIII\Http\Middleware;
-use Closure;
use FireflyIII\Exceptions\FireflyException;
use FireflyIII\User;
use Illuminate\Auth\AuthenticationException;
use Illuminate\Contracts\Auth\Factory as Auth;
use Illuminate\Http\Request;
-use Illuminate\Support\Facades\Log;
/**
* Class Authenticate
@@ -39,17 +37,11 @@ class Authenticate
{
/**
* The authentication factory instance.
- *
- * @var Auth
*/
protected Auth $auth;
/**
* Create a new middleware instance.
- *
- * @param Auth $auth
- *
- * @return void
*/
public function __construct(Auth $auth)
{
@@ -60,7 +52,6 @@ class Authenticate
* Handle an incoming request.
*
* @param Request $request
- * @param Closure $next
* @param string[] ...$guards
*
* @return mixed
@@ -68,7 +59,7 @@ class Authenticate
* @throws FireflyException
* @throws AuthenticationException
*/
- public function handle($request, Closure $next, ...$guards)
+ public function handle($request, \Closure $next, ...$guards)
{
$this->authenticate($request, $guards);
@@ -79,17 +70,19 @@ class Authenticate
* Determine if the user is logged in to any of the given guards.
*
* @param mixed $request
- * @param array $guards
*
* @return mixed
+ *
* @throws FireflyException
* @throws AuthenticationException
+ *
+ * @SuppressWarnings(PHPMD.UnusedFormalParameter)
*/
protected function authenticate($request, array $guards)
{
if (0 === count($guards)) {
// go for default guard:
- /** @noinspection PhpUndefinedMethodInspection */
+ // @noinspection PhpUndefinedMethodInspection
if ($this->auth->check()) {
// do an extra check on user object.
/** @noinspection PhpUndefinedMethodInspection */
@@ -98,7 +91,7 @@ class Authenticate
$this->validateBlockedUser($user, $guards);
}
- /** @noinspection PhpUndefinedMethodInspection */
+ // @noinspection PhpUndefinedMethodInspection
return $this->auth->authenticate();
}
@@ -110,6 +103,7 @@ class Authenticate
if ($result) {
$user = $this->auth->guard($guard)->user();
$this->validateBlockedUser($user, $guards);
+
// According to PHPstan the method returns void, but we'll see.
return $this->auth->shouldUse($guard); // @phpstan-ignore-line
}
@@ -119,27 +113,23 @@ class Authenticate
}
/**
- * @param User|null $user
- * @param array $guards
- *
- * @return void
* @throws AuthenticationException
*/
private function validateBlockedUser(?User $user, array $guards): void
{
if (null === $user) {
- Log::warning('User is null, throw exception?');
+ app('log')->warning('User is null, throw exception?');
}
if (null !== $user) {
- // Log::debug(get_class($user));
+ // app('log')->debug(get_class($user));
if (1 === (int)$user->blocked) {
$message = (string)trans('firefly.block_account_logout');
if ('email_changed' === $user->blocked_code) {
$message = (string)trans('firefly.email_changed_logout');
}
- Log::warning('User is blocked, cannot use authentication method.');
+ app('log')->warning('User is blocked, cannot use authentication method.');
app('session')->flash('logoutMessage', $message);
- /** @noinspection PhpUndefinedMethodInspection */
+ // @noinspection PhpUndefinedMethodInspection
$this->auth->logout(); // @phpstan-ignore-line (thinks function is undefined)
throw new AuthenticationException('Blocked account.', $guards);
diff --git a/app/Http/Middleware/Binder.php b/app/Http/Middleware/Binder.php
index 8c8c6e4bd5..9f4413a06d 100644
--- a/app/Http/Middleware/Binder.php
+++ b/app/Http/Middleware/Binder.php
@@ -23,7 +23,6 @@ declare(strict_types=1);
namespace FireflyIII\Http\Middleware;
-use Closure;
use FireflyIII\Support\Domain;
use Illuminate\Contracts\Auth\Factory as Auth;
use Illuminate\Http\Request;
@@ -40,6 +39,7 @@ class Binder
* @var Auth
*/
protected $auth;
+
/**
* The binders.
*
@@ -49,8 +49,6 @@ class Binder
/**
* Binder constructor.
- *
- * @param Auth $auth
*/
public function __construct(Auth $auth)
{
@@ -62,12 +60,10 @@ class Binder
* Handle an incoming request.
*
* @param Request $request
- * @param Closure $next
*
* @return mixed
- *
*/
- public function handle($request, Closure $next)
+ public function handle($request, \Closure $next)
{
foreach ($request->route()->parameters() as $key => $value) {
if (array_key_exists($key, $this->binders)) {
@@ -82,10 +78,6 @@ class Binder
/**
* Do the binding.
*
- * @param string $key
- * @param string $value
- * @param Route $route
- *
* @return mixed
*/
private function performBinding(string $key, string $value, Route $route)
diff --git a/app/Http/Middleware/EncryptCookies.php b/app/Http/Middleware/EncryptCookies.php
index def51a126c..4f7fb66aba 100644
--- a/app/Http/Middleware/EncryptCookies.php
+++ b/app/Http/Middleware/EncryptCookies.php
@@ -27,9 +27,5 @@ use Illuminate\Cookie\Middleware\EncryptCookies as Middleware;
/**
* Class EncryptCookies
- *
-
*/
-class EncryptCookies extends Middleware
-{
-}
+class EncryptCookies extends Middleware {}
diff --git a/app/Http/Middleware/InstallationId.php b/app/Http/Middleware/InstallationId.php
index 7a741e9ea6..297fe8ca6b 100644
--- a/app/Http/Middleware/InstallationId.php
+++ b/app/Http/Middleware/InstallationId.php
@@ -23,12 +23,10 @@ declare(strict_types=1);
namespace FireflyIII\Http\Middleware;
-use Closure;
use FireflyIII\Support\System\GeneratesInstallationId;
use Illuminate\Http\Request;
/**
- *
* Class InstallationId
*/
class InstallationId
@@ -39,13 +37,10 @@ class InstallationId
* Handle an incoming request.
*
* @param Request $request
- * @param Closure $next
*
* @return mixed
- *
- *
*/
- public function handle($request, Closure $next)
+ public function handle($request, \Closure $next)
{
$this->generateInstallationId();
diff --git a/app/Http/Middleware/Installer.php b/app/Http/Middleware/Installer.php
index feb97cad43..8fc6ee1c77 100644
--- a/app/Http/Middleware/Installer.php
+++ b/app/Http/Middleware/Installer.php
@@ -24,18 +24,14 @@ declare(strict_types=1);
namespace FireflyIII\Http\Middleware;
-use Closure;
use DB;
use FireflyIII\Exceptions\FireflyException;
use FireflyIII\Support\System\OAuthKeys;
use Illuminate\Database\QueryException;
use Illuminate\Http\Request;
-use Illuminate\Support\Facades\Log;
/**
* Class Installer
- *
- *
*/
class Installer
{
@@ -43,16 +39,14 @@ class Installer
* Handle an incoming request.
*
* @param Request $request
- * @param Closure $next
*
* @return mixed
*
* @throws FireflyException
- *
*/
- public function handle($request, Closure $next)
+ public function handle($request, \Closure $next)
{
- //Log::debug(sprintf('Installer middleware for URL %s', $request->url()));
+ // app('log')->debug(sprintf('Installer middleware for URL %s', $request->url()));
// ignore installer in test environment.
if ('testing' === config('app.env')) {
return $next($request);
@@ -61,7 +55,7 @@ class Installer
$url = $request->url();
$strpos = stripos($url, '/install');
if (false !== $strpos) {
- //Log::debug(sprintf('URL is %s, will NOT run installer middleware', $url));
+ // app('log')->debug(sprintf('URL is %s, will NOT run installer middleware', $url));
return $next($request);
}
@@ -73,6 +67,7 @@ class Installer
return response()->redirectTo(route('installer.index'));
}
OAuthKeys::verifyKeysRoutine();
+
// update scheme version
// update firefly version
return $next($request);
@@ -81,18 +76,17 @@ class Installer
/**
* Check if the tables are created and accounted for.
*
- * @return bool
* @throws FireflyException
*/
private function hasNoTables(): bool
{
- //Log::debug('Now in routine hasNoTables()');
+ // app('log')->debug('Now in routine hasNoTables()');
try {
- DB::table('users')->count();
+ \DB::table('users')->count();
} catch (QueryException $e) {
$message = $e->getMessage();
- Log::error(sprintf('Error message trying to access users-table: %s', $message));
+ app('log')->error(sprintf('Error message trying to access users-table: %s', $message));
if ($this->isAccessDenied($message)) {
throw new FireflyException(
'It seems your database configuration is not correct. Please verify the username and password in your .env file.',
@@ -106,20 +100,17 @@ class Installer
return true;
}
+
throw new FireflyException(sprintf('Could not access the database: %s', $message), 0, $e);
}
- //Log::debug('Everything seems OK with the tables.');
+ // app('log')->debug('Everything seems OK with the tables.');
return false;
}
/**
* Is access denied error.
- *
- * @param string $message
- *
- * @return bool
*/
protected function isAccessDenied(string $message): bool
{
@@ -128,10 +119,6 @@ class Installer
/**
* Is no tables exist error.
- *
- * @param string $message
- *
- * @return bool
*/
protected function noTablesExist(string $message): bool
{
@@ -140,8 +127,6 @@ class Installer
/**
* Check if the "db_version" variable is correct.
- *
- * @return bool
*/
private function oldDBVersion(): bool
{
@@ -160,15 +145,13 @@ class Installer
return true;
}
- //Log::info(sprintf('Configured DB version (%d) equals expected DB version (%d)', $dbVersion, $configVersion));
+ // app('log')->info(sprintf('Configured DB version (%d) equals expected DB version (%d)', $dbVersion, $configVersion));
return false;
}
/**
* Check if the "firefly_version" variable is correct.
- *
- * @return bool
*/
private function oldVersion(): bool
{
@@ -187,7 +170,7 @@ class Installer
return true;
}
- //Log::info(sprintf('Installed Firefly III version (%s) equals expected Firefly III version (%s)', $dbVersion, $configVersion));
+ // app('log')->info(sprintf('Installed Firefly III version (%s) equals expected Firefly III version (%s)', $dbVersion, $configVersion));
return false;
}
diff --git a/app/Http/Middleware/InterestingMessage.php b/app/Http/Middleware/InterestingMessage.php
index b609de52ab..1d8a284aa0 100644
--- a/app/Http/Middleware/InterestingMessage.php
+++ b/app/Http/Middleware/InterestingMessage.php
@@ -23,14 +23,13 @@ declare(strict_types=1);
namespace FireflyIII\Http\Middleware;
-use Closure;
use FireflyIII\Models\Account;
use FireflyIII\Models\Bill;
+use FireflyIII\Models\TransactionCurrency;
use FireflyIII\Models\TransactionGroup;
use FireflyIII\Models\TransactionJournal;
use FireflyIII\Models\Webhook;
use Illuminate\Http\Request;
-use Preferences;
/**
* Class InterestingMessage
@@ -40,52 +39,44 @@ class InterestingMessage
/**
* Flashes the user an interesting message if the URL parameters warrant it.
*
- * @param Request $request
- * @param Closure $next
- *
* @return mixed
- *
*/
- public function handle(Request $request, Closure $next)
+ public function handle(Request $request, \Closure $next)
{
if ($this->testing()) {
return $next($request);
}
if ($this->groupMessage($request)) {
- Preferences::mark();
+ app('preferences')->mark();
$this->handleGroupMessage($request);
}
if ($this->accountMessage($request)) {
- Preferences::mark();
+ app('preferences')->mark();
$this->handleAccountMessage($request);
}
if ($this->billMessage($request)) {
- Preferences::mark();
+ app('preferences')->mark();
$this->handleBillMessage($request);
}
if ($this->webhookMessage($request)) {
- Preferences::mark();
+ app('preferences')->mark();
$this->handleWebhookMessage($request);
}
+ if ($this->currencyMessage($request)) {
+ app('preferences')->mark();
+ $this->handleCurrencyMessage($request);
+ }
return $next($request);
}
- /**
- * @return bool
- */
private function testing(): bool
{
// ignore middleware in test environment.
return 'testing' === config('app.env') || !auth()->check();
}
- /**
- * @param Request $request
- *
- * @return bool
- */
private function groupMessage(Request $request): bool
{
// get parameters from request.
@@ -95,9 +86,6 @@ class InterestingMessage
return null !== $transactionGroupId && null !== $message;
}
- /**
- * @param Request $request
- */
private function handleGroupMessage(Request $request): void
{
// get parameters from request.
@@ -105,21 +93,21 @@ class InterestingMessage
$message = $request->get('message');
// send message about newly created transaction group.
- /** @var TransactionGroup $group */
- $group = auth()->user()->transactionGroups()->with(['transactionJournals', 'transactionJournals.transactionType'])->find((int)$transactionGroupId);
+ /** @var null|TransactionGroup $group */
+ $group = auth()->user()->transactionGroups()->with(['transactionJournals', 'transactionJournals.transactionType'])->find((int)$transactionGroupId);
if (null === $group) {
return;
}
- $count = $group->transactionJournals->count();
+ $count = $group->transactionJournals->count();
- /** @var TransactionJournal $journal */
- $journal = $group->transactionJournals->first();
+ /** @var null|TransactionJournal $journal */
+ $journal = $group->transactionJournals->first();
if (null === $journal) {
return;
}
- $title = $count > 1 ? $group->title : $journal->description;
+ $title = $count > 1 ? $group->title : $journal->description;
if ('created' === $message) {
session()->flash('success_url', route('transactions.show', [$transactionGroupId]));
session()->flash('success', (string)trans('firefly.stored_journal', ['description' => $title]));
@@ -136,11 +124,6 @@ class InterestingMessage
}
}
- /**
- * @param Request $request
- *
- * @return bool
- */
private function accountMessage(Request $request): bool
{
// get parameters from request.
@@ -150,17 +133,14 @@ class InterestingMessage
return null !== $accountId && null !== $message;
}
- /**
- * @param Request $request
- */
private function handleAccountMessage(Request $request): void
{
// get parameters from request.
$accountId = $request->get('account_id');
$message = $request->get('message');
- /** @var Account $account */
- $account = auth()->user()->accounts()->withTrashed()->find($accountId);
+ /** @var null|Account $account */
+ $account = auth()->user()->accounts()->withTrashed()->find($accountId);
if (null === $account) {
return;
@@ -176,11 +156,6 @@ class InterestingMessage
}
}
- /**
- * @param Request $request
- *
- * @return bool
- */
private function billMessage(Request $request): bool
{
// get parameters from request.
@@ -190,17 +165,14 @@ class InterestingMessage
return null !== $billId && null !== $message;
}
- /**
- * @param Request $request
- */
private function handleBillMessage(Request $request): void
{
// get parameters from request.
$billId = $request->get('bill_id');
$message = $request->get('message');
- /** @var Bill $bill */
- $bill = auth()->user()->bills()->withTrashed()->find($billId);
+ /** @var null|Bill $bill */
+ $bill = auth()->user()->bills()->withTrashed()->find($billId);
if (null === $bill) {
return;
@@ -213,31 +185,23 @@ class InterestingMessage
}
}
- /**
- * @param Request $request
- *
- * @return bool
- */
private function webhookMessage(Request $request): bool
{
// get parameters from request.
- $billId = $request->get('webhook_id');
- $message = $request->get('message');
+ $webhookId = $request->get('webhook_id');
+ $message = $request->get('message');
- return null !== $billId && null !== $message;
+ return null !== $webhookId && null !== $message;
}
- /**
- * @param Request $request
- */
private function handleWebhookMessage(Request $request): void
{
// get parameters from request.
$webhookId = $request->get('webhook_id');
$message = $request->get('message');
- /** @var Webhook $webhook */
- $webhook = auth()->user()->webhooks()->withTrashed()->find($webhookId);
+ /** @var null|Webhook $webhook */
+ $webhook = auth()->user()->webhooks()->withTrashed()->find($webhookId);
if (null === $webhook) {
return;
@@ -252,4 +216,46 @@ class InterestingMessage
session()->flash('success', (string)trans('firefly.stored_new_webhook', ['title' => $webhook->title]));
}
}
+
+ private function currencyMessage(Request $request): bool
+ {
+ // get parameters from request.
+ $code = $request->get('code');
+ $message = $request->get('message');
+
+ return null !== $code && null !== $message;
+ }
+
+ private function handleCurrencyMessage(Request $request): void
+ {
+ // params:
+ // get parameters from request.
+ $code = $request->get('code');
+ $message = $request->get('message');
+
+ /** @var null|TransactionCurrency $currency */
+ $currency = TransactionCurrency::whereCode($code)->first();
+
+ if (null === $currency) {
+ return;
+ }
+ if ('enabled' === $message) {
+ session()->flash('success', (string)trans('firefly.currency_is_now_enabled', ['name' => $currency->name]));
+ }
+ if ('enable_failed' === $message) {
+ session()->flash('error', (string)trans('firefly.could_not_enable_currency', ['name' => $currency->name]));
+ }
+ if ('disabled' === $message) {
+ session()->flash('success', (string)trans('firefly.currency_is_now_disabled', ['name' => $currency->name]));
+ }
+ if ('disable_failed' === $message) {
+ session()->flash('error', (string)trans('firefly.could_not_disable_currency', ['name' => $currency->name]));
+ }
+ if ('default' === $message) {
+ session()->flash('success', (string)trans('firefly.new_default_currency', ['name' => $currency->name]));
+ }
+ if ('default_failed' === $message) {
+ session()->flash('error', (string)trans('firefly.default_currency_failed', ['name' => $currency->name]));
+ }
+ }
}
diff --git a/app/Http/Middleware/IsAdmin.php b/app/Http/Middleware/IsAdmin.php
index 0bde6c57d4..c992713911 100644
--- a/app/Http/Middleware/IsAdmin.php
+++ b/app/Http/Middleware/IsAdmin.php
@@ -23,7 +23,6 @@ declare(strict_types=1);
namespace FireflyIII\Http\Middleware;
-use Closure;
use FireflyIII\Repositories\User\UserRepositoryInterface;
use FireflyIII\User;
use Illuminate\Http\Request;
@@ -37,13 +36,11 @@ class IsAdmin
/**
* Handle an incoming request. Must be admin.
*
- * @param Request $request
- * @param Closure $next
- * @param string|null $guard
+ * @param null|string $guard
*
* @return mixed
*/
- public function handle(Request $request, Closure $next, $guard = null)
+ public function handle(Request $request, \Closure $next, $guard = null)
{
if (Auth::guard($guard)->guest()) {
if ($request->ajax()) {
@@ -52,8 +49,10 @@ class IsAdmin
return response()->redirectTo(route('login'));
}
+
/** @var User $user */
- $user = auth()->user();
+ $user = auth()->user();
+
/** @var UserRepositoryInterface $repository */
$repository = app(UserRepositoryInterface::class);
if (!$repository->hasRole($user, 'owner')) {
diff --git a/app/Http/Middleware/IsDemoUser.php b/app/Http/Middleware/IsDemoUser.php
index e174c8d95e..0cc04ddc18 100644
--- a/app/Http/Middleware/IsDemoUser.php
+++ b/app/Http/Middleware/IsDemoUser.php
@@ -23,11 +23,9 @@ declare(strict_types=1);
namespace FireflyIII\Http\Middleware;
-use Closure;
use FireflyIII\Repositories\User\UserRepositoryInterface;
use FireflyIII\User;
use Illuminate\Http\Request;
-use Illuminate\Support\Facades\Log;
/**
* Class IsDemoUser.
@@ -37,15 +35,12 @@ class IsDemoUser
/**
* Handle an incoming request.
*
- * @param Request $request
- * @param Closure $next
- *
* @return mixed
*/
- public function handle(Request $request, Closure $next)
+ public function handle(Request $request, \Closure $next)
{
- /** @var User $user */
- $user = $request->user();
+ /** @var null|User $user */
+ $user = $request->user();
if (null === $user) {
return $next($request);
}
@@ -53,7 +48,7 @@ class IsDemoUser
/** @var UserRepositoryInterface $repository */
$repository = app(UserRepositoryInterface::class);
if ($repository->hasRole($user, 'demo')) {
- Log::info('User is a demo user.');
+ app('log')->info('User is a demo user.');
$request->session()->flash('info', (string)trans('firefly.not_available_demo_user'));
$current = $request->url();
$previous = $request->session()->previousUrl();
diff --git a/app/Http/Middleware/Range.php b/app/Http/Middleware/Range.php
index 997dcd218a..2a46678f6a 100644
--- a/app/Http/Middleware/Range.php
+++ b/app/Http/Middleware/Range.php
@@ -23,13 +23,10 @@ declare(strict_types=1);
namespace FireflyIII\Http\Middleware;
-use App;
use Carbon\Carbon;
-use Closure;
use FireflyIII\Repositories\Journal\JournalRepositoryInterface;
use FireflyIII\Support\Http\Controllers\RequestInformation;
use Illuminate\Http\Request;
-use Illuminate\Support\Facades\Log;
/**
* Class SessionFilter.
@@ -41,14 +38,11 @@ class Range
/**
* Handle an incoming request.
*
- * @param Request $request
- * @param Closure $next
- *
* @return mixed
*/
- public function handle(Request $request, Closure $next)
+ public function handle(Request $request, \Closure $next)
{
- if ($request->user()) {
+ if (null !== $request->user()) {
// set start, end and finish:
$this->setRange();
@@ -70,9 +64,13 @@ class Range
// ignore preference. set the range to be the current month:
if (!app('session')->has('start') && !app('session')->has('end')) {
$viewRange = app('preferences')->get('viewRange', '1M')->data;
+ if (is_array($viewRange)) {
+ $viewRange = '1M';
+ }
+
$today = today(config('app.timezone'));
- $start = app('navigation')->updateStartDate($viewRange, $today);
- $end = app('navigation')->updateEndDate($viewRange, $start);
+ $start = app('navigation')->updateStartDate((string)$viewRange, $today);
+ $end = app('navigation')->updateEndDate((string)$viewRange, $start);
app('session')->put('start', $start);
app('session')->put('end', $end);
@@ -96,19 +94,19 @@ class Range
private function configureView(): void
{
// get locale preference:
- $language = app('steam')->getLanguage();
- $locale = app('steam')->getLocale();
- App::setLocale($language);
+ $language = app('steam')->getLanguage();
+ $locale = app('steam')->getLocale();
+ \App::setLocale($language);
Carbon::setLocale(substr($locale, 0, 2));
- $localeArray = app('steam')->getLocaleArray($locale);
+ $localeArray = app('steam')->getLocaleArray($locale);
setlocale(LC_TIME, $localeArray);
- $moneyResult = setlocale(LC_MONETARY, $localeArray);
+ $moneyResult = setlocale(LC_MONETARY, $localeArray);
// send error to view, if could not set money format
if (false === $moneyResult) {
- Log::error('Could not set locale. The following array doesnt work: ', $localeArray);
+ app('log')->error('Could not set locale. The following array doesnt work: ', $localeArray);
app('view')->share('invalidMonetaryLocale', true);
}
@@ -118,7 +116,7 @@ class Range
$defaultCurrency = app('amount')->getDefaultCurrency();
// also format for moment JS:
- $madMomentJS = (string)trans('config.month_and_day_moment_js', [], $locale);
+ $madMomentJS = (string)trans('config.month_and_day_moment_js', [], $locale);
app('view')->share('madMomentJS', $madMomentJS);
app('view')->share('monthAndDayFormat', $monthAndDayFormat);
diff --git a/app/Http/Middleware/RedirectIfAuthenticated.php b/app/Http/Middleware/RedirectIfAuthenticated.php
index b5bc8281ef..5bffbb7146 100644
--- a/app/Http/Middleware/RedirectIfAuthenticated.php
+++ b/app/Http/Middleware/RedirectIfAuthenticated.php
@@ -23,14 +23,11 @@ declare(strict_types=1);
namespace FireflyIII\Http\Middleware;
-use Closure;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\Auth;
/**
* Class RedirectIfAuthenticated
- *
-
*/
class RedirectIfAuthenticated
{
@@ -38,12 +35,11 @@ class RedirectIfAuthenticated
* Handle an incoming request.
*
* @param Request $request
- * @param Closure $next
- * @param string|null $guard
+ * @param null|string $guard
*
* @return mixed
*/
- public function handle($request, Closure $next, $guard = null)
+ public function handle($request, \Closure $next, $guard = null)
{
if (Auth::guard($guard)->check()) {
return response()->redirectTo(route('index'));
diff --git a/app/Http/Middleware/SecureHeaders.php b/app/Http/Middleware/SecureHeaders.php
index cf8021ba71..d5d29d02c6 100644
--- a/app/Http/Middleware/SecureHeaders.php
+++ b/app/Http/Middleware/SecureHeaders.php
@@ -23,13 +23,10 @@ declare(strict_types=1);
namespace FireflyIII\Http\Middleware;
-use Closure;
-use Exception;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\Vite;
/**
- *
* Class SecureHeaders
*/
class SecureHeaders
@@ -37,22 +34,20 @@ class SecureHeaders
/**
* Handle an incoming request.
*
- * @param Request $request
- * @param Closure $next
- *
* @return mixed
- * @throws Exception
+ *
+ * @throws \Exception
*/
- public function handle(Request $request, Closure $next)
+ public function handle(Request $request, \Closure $next)
{
// generate and share nonce.
- $nonce = base64_encode(random_bytes(16));
+ $nonce = base64_encode(random_bytes(16));
Vite::useCspNonce($nonce);
app('view')->share('JS_NONCE', $nonce);
- $response = $next($request);
- $trackingScriptSrc = $this->getTrackingScriptSource();
- $csp = [
+ $response = $next($request);
+ $trackingScriptSrc = $this->getTrackingScriptSource();
+ $csp = [
"default-src 'none'",
"object-src 'none'",
sprintf("script-src 'unsafe-eval' 'strict-dynamic' 'self' 'unsafe-inline' 'nonce-%1s' %2s", $nonce, $trackingScriptSrc),
@@ -64,10 +59,10 @@ class SecureHeaders
"manifest-src 'self'",
];
- $route = $request->route();
- $customUrl = '';
- $authGuard = (string)config('firefly.authentication_guard');
- $logoutUrl = (string)config('firefly.custom_logout_url');
+ $route = $request->route();
+ $customUrl = '';
+ $authGuard = (string)config('firefly.authentication_guard');
+ $logoutUrl = (string)config('firefly.custom_logout_url');
if ('remote_user_guard' === $authGuard && '' !== $logoutUrl) {
$customUrl = $logoutUrl;
}
@@ -76,18 +71,18 @@ class SecureHeaders
$csp[] = sprintf("form-action 'self' %s", $customUrl);
}
- $featurePolicies = [
+ $featurePolicies = [
"geolocation 'none'",
"midi 'none'",
- //"notifications 'none'",
- //"push 'self'",
+ // "notifications 'none'",
+ // "push 'self'",
"sync-xhr 'self'",
"microphone 'none'",
"camera 'none'",
"magnetometer 'none'",
"gyroscope 'none'",
- //"speaker 'none'",
- //"vibrate 'none'",
+ // "speaker 'none'",
+ // "vibrate 'none'",
"fullscreen 'self'",
"payment 'none'",
];
@@ -112,8 +107,6 @@ class SecureHeaders
/**
* Return part of a CSP header allowing scripts from Matomo.
- *
- * @return string
*/
private function getTrackingScriptSource(): string
{
diff --git a/app/Http/Middleware/StartFireflySession.php b/app/Http/Middleware/StartFireflySession.php
index 753965a3d4..dad24baa3c 100644
--- a/app/Http/Middleware/StartFireflySession.php
+++ b/app/Http/Middleware/StartFireflySession.php
@@ -29,15 +29,12 @@ use Illuminate\Session\Middleware\StartSession;
/**
* Class StartFireflySession.
- *
-
*/
class StartFireflySession extends StartSession
{
/**
* Store the current URL for the request if necessary.
*
- * @param Request $request
* @param Session $session
*/
protected function storeCurrentUrl(Request $request, $session): void
diff --git a/app/Http/Middleware/TrimStrings.php b/app/Http/Middleware/TrimStrings.php
index 049725b850..d0362148b9 100644
--- a/app/Http/Middleware/TrimStrings.php
+++ b/app/Http/Middleware/TrimStrings.php
@@ -27,16 +27,9 @@ use Illuminate\Foundation\Http\Middleware\TrimStrings as Middleware;
/**
* Class TrimStrings
- *
-
*/
class TrimStrings extends Middleware
{
- /**
- * The names of the attributes that should not be trimmed.
- *
- * @var array
- */
protected $except
= [
'password',
diff --git a/frontend/src/stores/teststore.js b/app/Http/Middleware/TrustHosts.php
similarity index 56%
rename from frontend/src/stores/teststore.js
rename to app/Http/Middleware/TrustHosts.php
index 4dc39e04ef..4045a4aba8 100644
--- a/frontend/src/stores/teststore.js
+++ b/app/Http/Middleware/TrustHosts.php
@@ -1,6 +1,7 @@
+.
+ * along with this program. If not, see https://www.gnu.org/licenses/.
*/
-import {defineStore} from 'pinia';
+declare(strict_types=1);
-export const useCounterStore = defineStore('counter', {
- state: () => ({
- counter: 0
- }),
+namespace FireflyIII\Http\Middleware;
- getters: {
- doubleCount(state) {
- return state.counter * 2
+use Illuminate\Http\Middleware\TrustHosts as Middleware;
+
+class TrustHosts extends Middleware
+{
+ /**
+ * Get the host patterns that should be trusted.
+ *
+ * @return array
+ */
+ public function hosts(): array
+ {
+ return [
+ $this->allSubdomainsOfApplicationUrl(),
+ ];
}
- },
-
- actions: {
- increment() {
- this.counter++
- }
- }
-})
+}
diff --git a/app/Http/Middleware/TrustProxies.php b/app/Http/Middleware/TrustProxies.php
index 51094a3040..1b957bcc5e 100644
--- a/app/Http/Middleware/TrustProxies.php
+++ b/app/Http/Middleware/TrustProxies.php
@@ -28,8 +28,6 @@ use Symfony\Component\HttpFoundation\Request;
/**
* Class TrustProxies
- *
-
*/
class TrustProxies extends Middleware
{
diff --git a/app/Http/Middleware/VerifyCsrfToken.php b/app/Http/Middleware/VerifyCsrfToken.php
index 2e981f1aae..03d670e78b 100644
--- a/app/Http/Middleware/VerifyCsrfToken.php
+++ b/app/Http/Middleware/VerifyCsrfToken.php
@@ -27,9 +27,5 @@ use Illuminate\Foundation\Http\Middleware\VerifyCsrfToken as Middleware;
/**
* Class VerifyCsrfToken.
- *
-
*/
-class VerifyCsrfToken extends Middleware
-{
-}
+class VerifyCsrfToken extends Middleware {}
diff --git a/app/Http/Requests/AccountFormRequest.php b/app/Http/Requests/AccountFormRequest.php
index e201825218..e9b4f06206 100644
--- a/app/Http/Requests/AccountFormRequest.php
+++ b/app/Http/Requests/AccountFormRequest.php
@@ -26,26 +26,28 @@ namespace FireflyIII\Http\Requests;
use FireflyIII\Enums\UserRoleEnum;
use FireflyIII\Models\Account;
use FireflyIII\Models\Location;
+use FireflyIII\Rules\IsValidAmount;
use FireflyIII\Rules\UniqueIban;
use FireflyIII\Support\Request\AppendsLocationData;
use FireflyIII\Support\Request\ChecksLogin;
use FireflyIII\Support\Request\ConvertsDataTypes;
use Illuminate\Foundation\Http\FormRequest;
+use Illuminate\Support\Facades\Log;
+use Illuminate\Validation\Validator;
/**
* Class AccountFormRequest.
*/
class AccountFormRequest extends FormRequest
{
- use ConvertsDataTypes;
use AppendsLocationData;
use ChecksLogin;
+ use ConvertsDataTypes;
+
protected array $acceptedRoles = [UserRoleEnum::MANAGE_TRANSACTIONS];
/**
* Get all data.
- *
- * @return array
*/
public function getAccountData(): array
{
@@ -94,8 +96,6 @@ class AccountFormRequest extends FormRequest
/**
* Rules for this request.
- *
- * @return array
*/
public function rules(): array
{
@@ -104,32 +104,40 @@ class AccountFormRequest extends FormRequest
$ccPaymentTypes = implode(',', array_keys(config('firefly.ccTypes')));
$rules = [
'name' => 'required|max:1024|min:1|uniqueAccountForUser',
- 'opening_balance' => 'numeric|nullable|max:1000000000',
+ 'opening_balance' => ['nullable', new IsValidAmount()],
'opening_balance_date' => 'date|required_with:opening_balance|nullable',
'iban' => ['iban', 'nullable', new UniqueIban(null, $this->convertString('objectType'))],
'BIC' => 'bic|nullable',
- 'virtual_balance' => 'numeric|nullable|max:1000000000',
+ 'virtual_balance' => ['nullable', new IsValidAmount()],
'currency_id' => 'exists:transaction_currencies,id',
- 'account_number' => 'between:1,255|uniqueAccountNumberForUser|nullable',
- 'account_role' => 'in:' . $accountRoles,
+ 'account_number' => 'min:1|max:255|uniqueAccountNumberForUser|nullable',
+ 'account_role' => 'in:'.$accountRoles,
'active' => 'boolean',
- 'cc_type' => 'in:' . $ccPaymentTypes,
+ 'cc_type' => 'in:'.$ccPaymentTypes,
'amount_currency_id_opening_balance' => 'exists:transaction_currencies,id',
'amount_currency_id_virtual_balance' => 'exists:transaction_currencies,id',
- 'what' => 'in:' . $types,
+ 'what' => 'in:'.$types,
'interest_period' => 'in:daily,monthly,yearly',
+ 'notes' => 'min:1|max:32768|nullable',
];
$rules = Location::requestRules($rules);
- /** @var Account $account */
- $account = $this->route()->parameter('account');
+ /** @var null|Account $account */
+ $account = $this->route()->parameter('account');
if (null !== $account) {
// add rules:
$rules['id'] = 'belongsToUser:accounts';
- $rules['name'] = 'required|max:1024|min:1|uniqueAccountForUser:' . $account->id;
+ $rules['name'] = 'required|max:1024|min:1|uniqueAccountForUser:'.$account->id;
$rules['iban'] = ['iban', 'nullable', new UniqueIban($account, $account->accountType->type)];
}
return $rules;
}
+
+ public function withValidator(Validator $validator): void
+ {
+ if ($validator->fails()) {
+ Log::channel('audit')->error(sprintf('Validation errors in %s', __CLASS__), $validator->errors()->toArray());
+ }
+ }
}
diff --git a/app/Http/Requests/AttachmentFormRequest.php b/app/Http/Requests/AttachmentFormRequest.php
index c09915b069..0845dea163 100644
--- a/app/Http/Requests/AttachmentFormRequest.php
+++ b/app/Http/Requests/AttachmentFormRequest.php
@@ -26,21 +26,19 @@ namespace FireflyIII\Http\Requests;
use FireflyIII\Support\Request\ChecksLogin;
use FireflyIII\Support\Request\ConvertsDataTypes;
use Illuminate\Foundation\Http\FormRequest;
+use Illuminate\Support\Facades\Log;
+use Illuminate\Validation\Validator;
/**
* Class AttachmentFormRequest.
- *
-
*/
class AttachmentFormRequest extends FormRequest
{
- use ConvertsDataTypes;
use ChecksLogin;
+ use ConvertsDataTypes;
/**
* Returns the data required by the controller.
- *
- * @return array
*/
public function getAttachmentData(): array
{
@@ -52,15 +50,20 @@ class AttachmentFormRequest extends FormRequest
/**
* Rules for this request.
- *
- * @return array
*/
public function rules(): array
{
// fixed
return [
- 'title' => 'between:1,255|nullable',
- 'notes' => 'between:1,65536|nullable',
+ 'title' => 'min:1|max:255|nullable',
+ 'notes' => 'min:1|max:32768|nullable',
];
}
+
+ public function withValidator(Validator $validator): void
+ {
+ if ($validator->fails()) {
+ Log::channel('audit')->error(sprintf('Validation errors in %s', __CLASS__), $validator->errors()->toArray());
+ }
+ }
}
diff --git a/app/Http/Requests/BillStoreRequest.php b/app/Http/Requests/BillStoreRequest.php
index 8b2ef19b54..ceb6f3d0e0 100644
--- a/app/Http/Requests/BillStoreRequest.php
+++ b/app/Http/Requests/BillStoreRequest.php
@@ -23,22 +23,23 @@ declare(strict_types=1);
namespace FireflyIII\Http\Requests;
+use FireflyIII\Rules\IsValidPositiveAmount;
use FireflyIII\Support\Request\ChecksLogin;
use FireflyIII\Support\Request\ConvertsDataTypes;
use Illuminate\Foundation\Http\FormRequest;
+use Illuminate\Support\Facades\Log;
+use Illuminate\Validation\Validator;
/**
* Class BillStoreRequest.
*/
class BillStoreRequest extends FormRequest
{
- use ConvertsDataTypes;
use ChecksLogin;
+ use ConvertsDataTypes;
/**
* Returns the data required by the controller.
- *
- * @return array
*/
public function getBillData(): array
{
@@ -61,22 +62,28 @@ class BillStoreRequest extends FormRequest
/**
* Rules for this request.
- *
- * @return array
*/
public function rules(): array
{
return [
- 'name' => 'required|between:1,255|uniqueObjectForUser:bills,name',
- 'amount_min' => 'required|numeric|gt:0|max:1000000000',
- 'amount_max' => 'required|numeric|gt:0|max:1000000000',
+ 'name' => 'required|min:1|max:255|uniqueObjectForUser:bills,name',
+ 'amount_min' => ['required', new IsValidPositiveAmount()],
+ 'amount_max' => ['required', new IsValidPositiveAmount()],
'transaction_currency_id' => 'required|exists:transaction_currencies,id',
'date' => 'required|date',
+ 'notes' => 'min:1|max:32768|nullable',
'bill_end_date' => 'nullable|date',
'extension_date' => 'nullable|date',
- 'repeat_freq' => sprintf('required|in:%s', join(',', config('firefly.bill_periods'))),
+ 'repeat_freq' => sprintf('required|in:%s', implode(',', config('firefly.bill_periods'))),
'skip' => 'required|integer|gte:0|lte:31',
'active' => 'boolean',
];
}
+
+ public function withValidator(Validator $validator): void
+ {
+ if ($validator->fails()) {
+ Log::channel('audit')->error(sprintf('Validation errors in %s', __CLASS__), $validator->errors()->toArray());
+ }
+ }
}
diff --git a/app/Http/Requests/BillUpdateRequest.php b/app/Http/Requests/BillUpdateRequest.php
index 89ffa5b0a7..8494b80294 100644
--- a/app/Http/Requests/BillUpdateRequest.php
+++ b/app/Http/Requests/BillUpdateRequest.php
@@ -24,22 +24,23 @@ declare(strict_types=1);
namespace FireflyIII\Http\Requests;
use FireflyIII\Models\Bill;
+use FireflyIII\Rules\IsValidPositiveAmount;
use FireflyIII\Support\Request\ChecksLogin;
use FireflyIII\Support\Request\ConvertsDataTypes;
use Illuminate\Foundation\Http\FormRequest;
+use Illuminate\Support\Facades\Log;
+use Illuminate\Validation\Validator;
/**
* Class BillUpdateRequest.
*/
class BillUpdateRequest extends FormRequest
{
- use ConvertsDataTypes;
use ChecksLogin;
+ use ConvertsDataTypes;
/**
* Returns the data required by the controller.
- *
- * @return array
*/
public function getBillData(): array
{
@@ -62,8 +63,6 @@ class BillUpdateRequest extends FormRequest
/**
* Rules for this request.
- *
- * @return array
*/
public function rules(): array
{
@@ -71,17 +70,24 @@ class BillUpdateRequest extends FormRequest
$bill = $this->route()->parameter('bill');
return [
- 'name' => sprintf('required|between:1,255|uniqueObjectForUser:bills,name,%d', $bill->id),
- 'amount_min' => 'required|numeric|gt:0|max:1000000000',
- 'amount_max' => 'required|numeric|gt:0|max:1000000000',
+ 'name' => sprintf('required|min:1|max:255|uniqueObjectForUser:bills,name,%d', $bill->id),
+ 'amount_min' => ['required', new IsValidPositiveAmount()],
+ 'amount_max' => ['required', new IsValidPositiveAmount()],
'transaction_currency_id' => 'required|exists:transaction_currencies,id',
'date' => 'required|date',
'bill_end_date' => 'nullable|date',
'extension_date' => 'nullable|date',
- 'repeat_freq' => sprintf('required|in:%s', join(',', config('firefly.bill_periods'))),
+ 'repeat_freq' => sprintf('required|in:%s', implode(',', config('firefly.bill_periods'))),
'skip' => 'required|integer|gte:0|lte:31',
'active' => 'boolean',
- 'notes' => 'between:1,65536|nullable',
+ 'notes' => 'min:1|max:32768|nullable',
];
}
+
+ public function withValidator(Validator $validator): void
+ {
+ if ($validator->fails()) {
+ Log::channel('audit')->error(sprintf('Validation errors in %s', __CLASS__), $validator->errors()->toArray());
+ }
+ }
}
diff --git a/app/Http/Requests/BudgetFormStoreRequest.php b/app/Http/Requests/BudgetFormStoreRequest.php
index 3165ee7e78..f43a4c0624 100644
--- a/app/Http/Requests/BudgetFormStoreRequest.php
+++ b/app/Http/Requests/BudgetFormStoreRequest.php
@@ -23,10 +23,12 @@ declare(strict_types=1);
namespace FireflyIII\Http\Requests;
+use FireflyIII\Rules\IsValidPositiveAmount;
use FireflyIII\Support\Request\ChecksLogin;
use FireflyIII\Support\Request\ConvertsDataTypes;
use FireflyIII\Validation\AutoBudget\ValidatesAutoBudgetRequest;
use Illuminate\Foundation\Http\FormRequest;
+use Illuminate\Support\Facades\Log;
use Illuminate\Validation\Validator;
/**
@@ -34,14 +36,12 @@ use Illuminate\Validation\Validator;
*/
class BudgetFormStoreRequest extends FormRequest
{
+ use ChecksLogin;
use ConvertsDataTypes;
use ValidatesAutoBudgetRequest;
- use ChecksLogin;
/**
* Returns the data required by the controller.
- *
- * @return array
*/
public function getBudgetData(): array
{
@@ -57,35 +57,34 @@ class BudgetFormStoreRequest extends FormRequest
/**
* Rules for this request.
- *
- * @return array
*/
public function rules(): array
{
return [
- 'name' => 'required|between:1,100|uniqueObjectForUser:budgets,name',
- 'active' => 'numeric|between:0,1',
+ 'name' => 'required|min:1|max:255|uniqueObjectForUser:budgets,name',
+ 'active' => 'numeric|min:0|max:1',
'auto_budget_type' => 'numeric|integer|gte:0|lte:3',
'auto_budget_currency_id' => 'exists:transaction_currencies,id',
- 'auto_budget_amount' => 'min:0|max:1000000000|required_if:auto_budget_type,1|required_if:auto_budget_type,2',
+ 'auto_budget_amount' => ['required_if:auto_budget_type,1', 'required_if:auto_budget_type,2', new IsValidPositiveAmount()],
'auto_budget_period' => 'in:daily,weekly,monthly,quarterly,half_year,yearly',
+ 'notes' => 'min:1|max:32768|nullable',
];
}
/**
* Configure the validator instance with special rules for after the basic validation rules.
- *
- * @param Validator $validator
- *
- * @return void
*/
public function withValidator(Validator $validator): void
{
$validator->after(
- function (Validator $validator) {
+ function (Validator $validator): void {
// validate all account info
$this->validateAutoBudgetAmount($validator);
}
);
+
+ if ($validator->fails()) {
+ Log::channel('audit')->error(sprintf('Validation errors in %s', __CLASS__), $validator->errors()->toArray());
+ }
}
}
diff --git a/app/Http/Requests/BudgetFormUpdateRequest.php b/app/Http/Requests/BudgetFormUpdateRequest.php
index ab61f774f5..81396f1748 100644
--- a/app/Http/Requests/BudgetFormUpdateRequest.php
+++ b/app/Http/Requests/BudgetFormUpdateRequest.php
@@ -24,10 +24,12 @@ declare(strict_types=1);
namespace FireflyIII\Http\Requests;
use FireflyIII\Models\Budget;
+use FireflyIII\Rules\IsValidPositiveAmount;
use FireflyIII\Support\Request\ChecksLogin;
use FireflyIII\Support\Request\ConvertsDataTypes;
use FireflyIII\Validation\AutoBudget\ValidatesAutoBudgetRequest;
use Illuminate\Foundation\Http\FormRequest;
+use Illuminate\Support\Facades\Log;
use Illuminate\Validation\Validator;
/**
@@ -35,14 +37,12 @@ use Illuminate\Validation\Validator;
*/
class BudgetFormUpdateRequest extends FormRequest
{
+ use ChecksLogin;
use ConvertsDataTypes;
use ValidatesAutoBudgetRequest;
- use ChecksLogin;
/**
* Returns the data required by the controller.
- *
- * @return array
*/
public function getBudgetData(): array
{
@@ -58,44 +58,42 @@ class BudgetFormUpdateRequest extends FormRequest
/**
* Rules for this request.
- *
- * @return array
*/
public function rules(): array
{
- $nameRule = 'required|between:1,100|uniqueObjectForUser:budgets,name';
+ $nameRule = 'required|min:1|max:255|uniqueObjectForUser:budgets,name';
- /** @var Budget $budget */
- $budget = $this->route()->parameter('budget');
+ /** @var null|Budget $budget */
+ $budget = $this->route()->parameter('budget');
if (null !== $budget) {
- $nameRule = 'required|between:1,100|uniqueObjectForUser:budgets,name,' . $budget->id;
+ $nameRule = 'required|min:1|max:255|uniqueObjectForUser:budgets,name,'.$budget->id;
}
return [
'name' => $nameRule,
- 'active' => 'numeric|between:0,1',
+ 'active' => 'numeric|min:0|max:1',
'auto_budget_type' => 'numeric|integer|gte:0|lte:31',
'auto_budget_currency_id' => 'exists:transaction_currencies,id',
- 'auto_budget_amount' => 'min:0|max:1000000000|required_if:auto_budget_type,1|required_if:auto_budget_type,2|numeric',
+ 'auto_budget_amount' => ['required_if:auto_budget_type,1', 'required_if:auto_budget_type,2|numeric', new IsValidPositiveAmount()],
'auto_budget_period' => 'in:daily,weekly,monthly,quarterly,half_year,yearly',
+ 'notes' => 'min:1|max:32768|nullable',
];
}
/**
* Configure the validator instance with special rules for after the basic validation rules.
- *
- * @param Validator $validator
- *
- * @return void
*/
public function withValidator(Validator $validator): void
{
$validator->after(
- function (Validator $validator) {
+ function (Validator $validator): void {
// validate all account info
$this->validateAutoBudgetAmount($validator);
}
);
+ if ($validator->fails()) {
+ Log::channel('audit')->error(sprintf('Validation errors in %s', __CLASS__), $validator->errors()->toArray());
+ }
}
}
diff --git a/app/Http/Requests/BudgetIncomeRequest.php b/app/Http/Requests/BudgetIncomeRequest.php
index 43ed98c284..0ba22c3f06 100644
--- a/app/Http/Requests/BudgetIncomeRequest.php
+++ b/app/Http/Requests/BudgetIncomeRequest.php
@@ -23,13 +23,14 @@ declare(strict_types=1);
namespace FireflyIII\Http\Requests;
+use FireflyIII\Rules\IsValidPositiveAmount;
use FireflyIII\Support\Request\ChecksLogin;
use Illuminate\Foundation\Http\FormRequest;
+use Illuminate\Support\Facades\Log;
+use Illuminate\Validation\Validator;
/**
* Class BudgetIncomeRequest.
- *
-
*/
class BudgetIncomeRequest extends FormRequest
{
@@ -37,16 +38,21 @@ class BudgetIncomeRequest extends FormRequest
/**
* Rules for this request.
- *
- * @return array
*/
public function rules(): array
{
// fixed
return [
- 'amount' => 'numeric|required|min:0|max:1000000000',
+ 'amount' => ['required', new IsValidPositiveAmount()],
'start' => 'required|date|before:end',
'end' => 'required|date|after:start',
];
}
+
+ public function withValidator(Validator $validator): void
+ {
+ if ($validator->fails()) {
+ Log::channel('audit')->error(sprintf('Validation errors in %s', __CLASS__), $validator->errors()->toArray());
+ }
+ }
}
diff --git a/app/Http/Requests/BulkEditJournalRequest.php b/app/Http/Requests/BulkEditJournalRequest.php
index 1f8c04074e..40b0e794fa 100644
--- a/app/Http/Requests/BulkEditJournalRequest.php
+++ b/app/Http/Requests/BulkEditJournalRequest.php
@@ -26,19 +26,19 @@ namespace FireflyIII\Http\Requests;
use FireflyIII\Support\Request\ChecksLogin;
use FireflyIII\Support\Request\ConvertsDataTypes;
use Illuminate\Foundation\Http\FormRequest;
+use Illuminate\Support\Facades\Log;
+use Illuminate\Validation\Validator;
/**
* Class MassEditBulkJournalRequest.
*/
class BulkEditJournalRequest extends FormRequest
{
- use ConvertsDataTypes;
use ChecksLogin;
+ use ConvertsDataTypes;
/**
* Rules for this request.
- *
- * @return array
*/
public function rules(): array
{
@@ -48,4 +48,11 @@ class BulkEditJournalRequest extends FormRequest
'tags_action' => 'in:no_nothing,do_replace,do_append',
];
}
+
+ public function withValidator(Validator $validator): void
+ {
+ if ($validator->fails()) {
+ Log::channel('audit')->error(sprintf('Validation errors in %s', __CLASS__), $validator->errors()->toArray());
+ }
+ }
}
diff --git a/app/Http/Requests/CategoryFormRequest.php b/app/Http/Requests/CategoryFormRequest.php
index 0e3c309d36..367dede1a8 100644
--- a/app/Http/Requests/CategoryFormRequest.php
+++ b/app/Http/Requests/CategoryFormRequest.php
@@ -27,19 +27,19 @@ use FireflyIII\Models\Category;
use FireflyIII\Support\Request\ChecksLogin;
use FireflyIII\Support\Request\ConvertsDataTypes;
use Illuminate\Foundation\Http\FormRequest;
+use Illuminate\Support\Facades\Log;
+use Illuminate\Validation\Validator;
/**
* Class CategoryFormRequest.
*/
class CategoryFormRequest extends FormRequest
{
- use ConvertsDataTypes;
use ChecksLogin;
+ use ConvertsDataTypes;
/**
* Get information for the controller.
- *
- * @return array
*/
public function getCategoryData(): array
{
@@ -51,22 +51,29 @@ class CategoryFormRequest extends FormRequest
/**
* Rules for this request.
- *
- * @return array
*/
public function rules(): array
{
- $nameRule = 'required|between:1,100|uniqueObjectForUser:categories,name';
- /** @var Category $category */
+ $nameRule = 'required|min:1|max:255|uniqueObjectForUser:categories,name';
+
+ /** @var null|Category $category */
$category = $this->route()->parameter('category');
if (null !== $category) {
- $nameRule = 'required|between:1,100|uniqueObjectForUser:categories,name,' . $category->id;
+ $nameRule = 'required|min:1|max:255|uniqueObjectForUser:categories,name,'.$category->id;
}
// fixed
return [
- 'name' => $nameRule,
+ 'name' => $nameRule,
+ 'notes' => 'min:1|max:32768|nullable',
];
}
+
+ public function withValidator(Validator $validator): void
+ {
+ if ($validator->fails()) {
+ Log::channel('audit')->error(sprintf('Validation errors in %s', __CLASS__), $validator->errors()->toArray());
+ }
+ }
}
diff --git a/app/Http/Requests/ConfigurationRequest.php b/app/Http/Requests/ConfigurationRequest.php
index 7517fbf878..ff7eb9b743 100644
--- a/app/Http/Requests/ConfigurationRequest.php
+++ b/app/Http/Requests/ConfigurationRequest.php
@@ -25,11 +25,11 @@ namespace FireflyIII\Http\Requests;
use FireflyIII\Support\Request\ChecksLogin;
use Illuminate\Foundation\Http\FormRequest;
+use Illuminate\Support\Facades\Log;
+use Illuminate\Validation\Validator;
/**
* Class ConfigurationRequest.
- *
-
*/
class ConfigurationRequest extends FormRequest
{
@@ -37,8 +37,6 @@ class ConfigurationRequest extends FormRequest
/**
* Returns the data required by the controller.
- *
- * @return array
*/
public function getConfigurationData(): array
{
@@ -50,15 +48,20 @@ class ConfigurationRequest extends FormRequest
/**
* Rules for this request.
- *
- * @return array
*/
public function rules(): array
{
// fixed
return [
- 'single_user_mode' => 'between:0,1|numeric',
- 'is_demo_site' => 'between:0,1|numeric',
+ 'single_user_mode' => 'min:0|max:1|numeric',
+ 'is_demo_site' => 'min:0|max:1|numeric',
];
}
+
+ public function withValidator(Validator $validator): void
+ {
+ if ($validator->fails()) {
+ Log::channel('audit')->error(sprintf('Validation errors in %s', __CLASS__), $validator->errors()->toArray());
+ }
+ }
}
diff --git a/app/Http/Requests/CurrencyFormRequest.php b/app/Http/Requests/CurrencyFormRequest.php
index b0048f8496..02587f9b22 100644
--- a/app/Http/Requests/CurrencyFormRequest.php
+++ b/app/Http/Requests/CurrencyFormRequest.php
@@ -27,19 +27,19 @@ use FireflyIII\Models\TransactionCurrency;
use FireflyIII\Support\Request\ChecksLogin;
use FireflyIII\Support\Request\ConvertsDataTypes;
use Illuminate\Foundation\Http\FormRequest;
+use Illuminate\Support\Facades\Log;
+use Illuminate\Validation\Validator;
/**
* Class CurrencyFormRequest.
*/
class CurrencyFormRequest extends FormRequest
{
- use ConvertsDataTypes;
use ChecksLogin;
+ use ConvertsDataTypes;
/**
* Returns the data required by the controller.
- *
- * @return array
*/
public function getCurrencyData(): array
{
@@ -54,13 +54,11 @@ class CurrencyFormRequest extends FormRequest
/**
* Rules for this request.
- *
- * @return array
*/
public function rules(): array
{
// fixed
- $rules = [
+ $rules = [
'name' => 'required|max:48|min:1|uniqueCurrencyName',
'code' => 'required|min:3|max:51|uniqueCurrencyCode',
'symbol' => 'required|min:1|max:51|uniqueCurrencySymbol',
@@ -68,7 +66,7 @@ class CurrencyFormRequest extends FormRequest
'enabled' => 'in:0,1',
];
- /** @var TransactionCurrency $currency */
+ /** @var null|TransactionCurrency $currency */
$currency = $this->route()->parameter('currency');
if (null !== $currency) {
@@ -83,4 +81,11 @@ class CurrencyFormRequest extends FormRequest
return $rules;
}
+
+ public function withValidator(Validator $validator): void
+ {
+ if ($validator->fails()) {
+ Log::channel('audit')->error(sprintf('Validation errors in %s', __CLASS__), $validator->errors()->toArray());
+ }
+ }
}
diff --git a/app/Http/Requests/DeleteAccountFormRequest.php b/app/Http/Requests/DeleteAccountFormRequest.php
index 51d65450ec..5d5296a99a 100644
--- a/app/Http/Requests/DeleteAccountFormRequest.php
+++ b/app/Http/Requests/DeleteAccountFormRequest.php
@@ -25,11 +25,11 @@ namespace FireflyIII\Http\Requests;
use FireflyIII\Support\Request\ChecksLogin;
use Illuminate\Foundation\Http\FormRequest;
+use Illuminate\Support\Facades\Log;
+use Illuminate\Validation\Validator;
/**
* Class DeleteAccountFormRequest.
- *
-
*/
class DeleteAccountFormRequest extends FormRequest
{
@@ -37,8 +37,6 @@ class DeleteAccountFormRequest extends FormRequest
/**
* Rules for this request.
- *
- * @return array
*/
public function rules(): array
{
@@ -47,4 +45,11 @@ class DeleteAccountFormRequest extends FormRequest
'password' => 'required',
];
}
+
+ public function withValidator(Validator $validator): void
+ {
+ if ($validator->fails()) {
+ Log::channel('audit')->error(sprintf('Validation errors in %s', __CLASS__), $validator->errors()->toArray());
+ }
+ }
}
diff --git a/app/Http/Requests/EmailFormRequest.php b/app/Http/Requests/EmailFormRequest.php
index 1c7429e84f..0cb58eb4ed 100644
--- a/app/Http/Requests/EmailFormRequest.php
+++ b/app/Http/Requests/EmailFormRequest.php
@@ -26,11 +26,11 @@ namespace FireflyIII\Http\Requests;
use FireflyIII\Support\Request\ChecksLogin;
use FireflyIII\Support\Request\ConvertsDataTypes;
use Illuminate\Foundation\Http\FormRequest;
+use Illuminate\Support\Facades\Log;
+use Illuminate\Validation\Validator;
/**
* Class EmailFormRequest.
- *
-
*/
class EmailFormRequest extends FormRequest
{
@@ -39,8 +39,6 @@ class EmailFormRequest extends FormRequest
/**
* Rules for this request.
- *
- * @return array
*/
public function rules(): array
{
@@ -49,4 +47,11 @@ class EmailFormRequest extends FormRequest
'email' => 'required|email',
];
}
+
+ public function withValidator(Validator $validator): void
+ {
+ if ($validator->fails()) {
+ Log::channel('audit')->error(sprintf('Validation errors in %s', __CLASS__), $validator->errors()->toArray());
+ }
+ }
}
diff --git a/app/Http/Requests/InviteUserFormRequest.php b/app/Http/Requests/InviteUserFormRequest.php
index d751e26f54..9e2cde1ede 100644
--- a/app/Http/Requests/InviteUserFormRequest.php
+++ b/app/Http/Requests/InviteUserFormRequest.php
@@ -27,19 +27,19 @@ namespace FireflyIII\Http\Requests;
use FireflyIII\Support\Request\ChecksLogin;
use FireflyIII\Support\Request\ConvertsDataTypes;
use Illuminate\Foundation\Http\FormRequest;
+use Illuminate\Support\Facades\Log;
+use Illuminate\Validation\Validator;
/**
* Class InviteUserFormRequest
*/
class InviteUserFormRequest extends FormRequest
{
- use ConvertsDataTypes;
use ChecksLogin;
+ use ConvertsDataTypes;
/**
* Rules for this request.
- *
- * @return array
*/
public function rules(): array
{
@@ -47,4 +47,11 @@ class InviteUserFormRequest extends FormRequest
'invited_user' => 'required|email|unique:invited_users,email',
];
}
+
+ public function withValidator(Validator $validator): void
+ {
+ if ($validator->fails()) {
+ Log::channel('audit')->error(sprintf('Validation errors in %s', __CLASS__), $validator->errors()->toArray());
+ }
+ }
}
diff --git a/app/Http/Requests/JournalLinkRequest.php b/app/Http/Requests/JournalLinkRequest.php
index 7eb14cbee6..6e2e083f11 100644
--- a/app/Http/Requests/JournalLinkRequest.php
+++ b/app/Http/Requests/JournalLinkRequest.php
@@ -27,19 +27,19 @@ use FireflyIII\Models\LinkType;
use FireflyIII\Support\Request\ChecksLogin;
use FireflyIII\Support\Request\ConvertsDataTypes;
use Illuminate\Foundation\Http\FormRequest;
+use Illuminate\Support\Facades\Log;
+use Illuminate\Validation\Validator;
/**
* Class JournalLink.
*/
class JournalLinkRequest extends FormRequest
{
- use ConvertsDataTypes;
use ChecksLogin;
+ use ConvertsDataTypes;
/**
* Returns the data required by the controller.
- *
- * @return array
*/
public function getLinkInfo(): array
{
@@ -56,20 +56,19 @@ class JournalLinkRequest extends FormRequest
/**
* Rules for this request.
- *
- * @return array
*/
public function rules(): array
{
// all possible combinations of link types and inward / outward:
$combinations = [];
$linkTypes = LinkType::get(['id']);
+
/** @var LinkType $type */
foreach ($linkTypes as $type) {
$combinations[] = sprintf('%d_inward', $type->id);
$combinations[] = sprintf('%d_outward', $type->id);
}
- $string = implode(',', $combinations);
+ $string = implode(',', $combinations);
// fixed
return [
@@ -77,4 +76,11 @@ class JournalLinkRequest extends FormRequest
'opposing' => 'belongsToUser:transaction_journals',
];
}
+
+ public function withValidator(Validator $validator): void
+ {
+ if ($validator->fails()) {
+ Log::channel('audit')->error(sprintf('Validation errors in %s', __CLASS__), $validator->errors()->toArray());
+ }
+ }
}
diff --git a/app/Http/Requests/LinkTypeFormRequest.php b/app/Http/Requests/LinkTypeFormRequest.php
index 2705775ba7..5b9b4470f7 100644
--- a/app/Http/Requests/LinkTypeFormRequest.php
+++ b/app/Http/Requests/LinkTypeFormRequest.php
@@ -26,6 +26,8 @@ namespace FireflyIII\Http\Requests;
use FireflyIII\Support\Request\ChecksLogin;
use FireflyIII\Support\Request\ConvertsDataTypes;
use Illuminate\Foundation\Http\FormRequest;
+use Illuminate\Support\Facades\Log;
+use Illuminate\Validation\Validator;
/**
* Class LinkTypeFormRequest.
@@ -37,8 +39,6 @@ class LinkTypeFormRequest extends FormRequest
/**
* Rules for this request.
- *
- * @return array
*/
public function rules(): array
{
@@ -47,7 +47,7 @@ class LinkTypeFormRequest extends FormRequest
$idRule = '';
// get parameter link:
- $link = $this->route()->parameter('linkType');
+ $link = $this->route()->parameter('linkType');
if (null !== $link) {
$idRule = 'exists:link_types,id';
@@ -61,4 +61,11 @@ class LinkTypeFormRequest extends FormRequest
'outward' => 'required|max:255|min:1|different:inward',
];
}
+
+ public function withValidator(Validator $validator): void
+ {
+ if ($validator->fails()) {
+ Log::channel('audit')->error(sprintf('Validation errors in %s', __CLASS__), $validator->errors()->toArray());
+ }
+ }
}
diff --git a/app/Http/Requests/MassDeleteJournalRequest.php b/app/Http/Requests/MassDeleteJournalRequest.php
index ca81fda9ff..f6da58b661 100644
--- a/app/Http/Requests/MassDeleteJournalRequest.php
+++ b/app/Http/Requests/MassDeleteJournalRequest.php
@@ -25,11 +25,11 @@ namespace FireflyIII\Http\Requests;
use FireflyIII\Support\Request\ChecksLogin;
use Illuminate\Foundation\Http\FormRequest;
+use Illuminate\Support\Facades\Log;
+use Illuminate\Validation\Validator;
/**
* Class MassDeleteJournalRequest.
- *
-
*/
class MassDeleteJournalRequest extends FormRequest
{
@@ -37,8 +37,6 @@ class MassDeleteJournalRequest extends FormRequest
/**
* Rules for this request.
- *
- * @return array
*/
public function rules(): array
{
@@ -47,4 +45,11 @@ class MassDeleteJournalRequest extends FormRequest
'confirm_mass_delete.*' => 'required|belongsToUser:transaction_journals,id',
];
}
+
+ public function withValidator(Validator $validator): void
+ {
+ if ($validator->fails()) {
+ Log::channel('audit')->error(sprintf('Validation errors in %s', __CLASS__), $validator->errors()->toArray());
+ }
+ }
}
diff --git a/app/Http/Requests/MassEditJournalRequest.php b/app/Http/Requests/MassEditJournalRequest.php
index 0ac30468b3..cb48c0b736 100644
--- a/app/Http/Requests/MassEditJournalRequest.php
+++ b/app/Http/Requests/MassEditJournalRequest.php
@@ -25,11 +25,11 @@ namespace FireflyIII\Http\Requests;
use FireflyIII\Support\Request\ChecksLogin;
use Illuminate\Foundation\Http\FormRequest;
+use Illuminate\Support\Facades\Log;
+use Illuminate\Validation\Validator;
/**
* Class MassEditJournalRequest.
- *
-
*/
class MassEditJournalRequest extends FormRequest
{
@@ -37,15 +37,13 @@ class MassEditJournalRequest extends FormRequest
/**
* Rules for this request.
- *
- * @return array
*/
public function rules(): array
{
// fixed
return [
- 'description.*' => 'required|min:1|max:255',
+ 'description.*' => 'required|min:1|max:1024',
'source_id.*' => 'numeric|belongsToUser:accounts,id',
'destination_id.*' => 'numeric|belongsToUser:accounts,id',
'journals.*' => 'numeric|belongsToUser:transaction_journals,id',
@@ -53,4 +51,11 @@ class MassEditJournalRequest extends FormRequest
'expense_account' => 'max:255',
];
}
+
+ public function withValidator(Validator $validator): void
+ {
+ if ($validator->fails()) {
+ Log::channel('audit')->error(sprintf('Validation errors in %s', __CLASS__), $validator->errors()->toArray());
+ }
+ }
}
diff --git a/app/Http/Requests/NewUserFormRequest.php b/app/Http/Requests/NewUserFormRequest.php
index a09ba41480..2e16f47c48 100644
--- a/app/Http/Requests/NewUserFormRequest.php
+++ b/app/Http/Requests/NewUserFormRequest.php
@@ -23,36 +23,42 @@ declare(strict_types=1);
namespace FireflyIII\Http\Requests;
+use FireflyIII\Rules\IsValidAmount;
use FireflyIII\Support\Request\ChecksLogin;
use FireflyIII\Support\Request\ConvertsDataTypes;
use Illuminate\Foundation\Http\FormRequest;
+use Illuminate\Support\Facades\Log;
+use Illuminate\Validation\Validator;
/**
* Class NewUserFormRequest.
- *
-
*/
class NewUserFormRequest extends FormRequest
{
- use ConvertsDataTypes;
use ChecksLogin;
+ use ConvertsDataTypes;
/**
* Rules for this request.
- *
- * @return array
*/
public function rules(): array
{
// fixed
return [
- 'bank_name' => 'required|between:1,200',
- 'bank_balance' => 'required|numeric|max:1000000000',
- 'savings_balance' => 'numeric|max:1000000000',
- 'credit_card_limit' => 'numeric|max:1000000000',
+ 'bank_name' => 'required|min:1|max:255',
+ 'bank_balance' => ['required', new IsValidAmount()],
+ 'savings_balance' => ['nullable', new IsValidAmount()],
+ 'credit_card_limit' => ['nullable', new IsValidAmount()],
'amount_currency_id_bank_balance' => 'exists:transaction_currencies,id',
'amount_currency_id_savings_balance' => 'exists:transaction_currencies,id',
'amount_currency_id_credit_card_limit' => 'exists:transaction_currencies,id',
];
}
+
+ public function withValidator(Validator $validator): void
+ {
+ if ($validator->fails()) {
+ Log::channel('audit')->error(sprintf('Validation errors in %s', __CLASS__), $validator->errors()->toArray());
+ }
+ }
}
diff --git a/app/Http/Requests/ObjectGroupFormRequest.php b/app/Http/Requests/ObjectGroupFormRequest.php
index cabec0d41d..03948c4486 100644
--- a/app/Http/Requests/ObjectGroupFormRequest.php
+++ b/app/Http/Requests/ObjectGroupFormRequest.php
@@ -27,19 +27,19 @@ use FireflyIII\Models\ObjectGroup;
use FireflyIII\Support\Request\ChecksLogin;
use FireflyIII\Support\Request\ConvertsDataTypes;
use Illuminate\Foundation\Http\FormRequest;
+use Illuminate\Support\Facades\Log;
+use Illuminate\Validation\Validator;
/**
* Class ObjectGroupFormRequest.
*/
class ObjectGroupFormRequest extends FormRequest
{
- use ConvertsDataTypes;
use ChecksLogin;
+ use ConvertsDataTypes;
/**
* Returns the data required by the controller.
- *
- * @return array
*/
public function getObjectGroupData(): array
{
@@ -50,21 +50,26 @@ class ObjectGroupFormRequest extends FormRequest
/**
* Rules for this request.
- *
- * @return array
*/
public function rules(): array
{
- /** @var ObjectGroup $objectGroup */
+ /** @var null|ObjectGroup $objectGroup */
$objectGroup = $this->route()->parameter('objectGroup');
- $titleRule = 'required|between:1,255|uniqueObjectGroup';
+ $titleRule = 'required|min:1|max:255|uniqueObjectGroup';
if (null !== $objectGroup) {
- $titleRule = sprintf('required|between:1,255|uniqueObjectGroup:%d', $objectGroup->id);
+ $titleRule = sprintf('required|min:1|max:255|uniqueObjectGroup:%d', $objectGroup->id);
}
return [
'title' => $titleRule,
];
}
+
+ public function withValidator(Validator $validator): void
+ {
+ if ($validator->fails()) {
+ Log::channel('audit')->error(sprintf('Validation errors in %s', __CLASS__), $validator->errors()->toArray());
+ }
+ }
}
diff --git a/app/Http/Requests/PiggyBankStoreRequest.php b/app/Http/Requests/PiggyBankStoreRequest.php
index b4baa67c46..94087fedb8 100644
--- a/app/Http/Requests/PiggyBankStoreRequest.php
+++ b/app/Http/Requests/PiggyBankStoreRequest.php
@@ -23,22 +23,23 @@ declare(strict_types=1);
namespace FireflyIII\Http\Requests;
+use FireflyIII\Rules\IsValidPositiveAmount;
use FireflyIII\Support\Request\ChecksLogin;
use FireflyIII\Support\Request\ConvertsDataTypes;
use Illuminate\Foundation\Http\FormRequest;
+use Illuminate\Support\Facades\Log;
+use Illuminate\Validation\Validator;
/**
* Class PiggyBankStoreRequest.
*/
class PiggyBankStoreRequest extends FormRequest
{
- use ConvertsDataTypes;
use ChecksLogin;
+ use ConvertsDataTypes;
/**
* Returns the data required by the controller.
- *
- * @return array
*/
public function getPiggyBankData(): array
{
@@ -55,19 +56,25 @@ class PiggyBankStoreRequest extends FormRequest
/**
* Rules for this request.
- *
- * @return array
*/
public function rules(): array
{
return [
- 'name' => 'required|between:1,255|uniquePiggyBankForUser',
+ 'name' => 'required|min:1|max:255|uniquePiggyBankForUser',
'account_id' => 'required|belongsToUser:accounts',
- 'targetamount' => 'nullable|numeric|max:1000000000',
+ 'targetamount' => ['nullable', new IsValidPositiveAmount()],
'startdate' => 'date',
'targetdate' => 'date|nullable',
'order' => 'integer|min:1',
'object_group' => 'min:0|max:255',
+ 'notes' => 'min:1|max:32768|nullable',
];
}
+
+ public function withValidator(Validator $validator): void
+ {
+ if ($validator->fails()) {
+ Log::channel('audit')->error(sprintf('Validation errors in %s', __CLASS__), $validator->errors()->toArray());
+ }
+ }
}
diff --git a/app/Http/Requests/PiggyBankUpdateRequest.php b/app/Http/Requests/PiggyBankUpdateRequest.php
index 4f7558689c..7f10011678 100644
--- a/app/Http/Requests/PiggyBankUpdateRequest.php
+++ b/app/Http/Requests/PiggyBankUpdateRequest.php
@@ -24,22 +24,23 @@ declare(strict_types=1);
namespace FireflyIII\Http\Requests;
use FireflyIII\Models\PiggyBank;
+use FireflyIII\Rules\IsValidPositiveAmount;
use FireflyIII\Support\Request\ChecksLogin;
use FireflyIII\Support\Request\ConvertsDataTypes;
use Illuminate\Foundation\Http\FormRequest;
+use Illuminate\Support\Facades\Log;
+use Illuminate\Validation\Validator;
/**
* Class PiggyBankFormRequest.
*/
class PiggyBankUpdateRequest extends FormRequest
{
- use ConvertsDataTypes;
use ChecksLogin;
+ use ConvertsDataTypes;
/**
* Returns the data required by the controller.
- *
- * @return array
*/
public function getPiggyBankData(): array
{
@@ -56,8 +57,6 @@ class PiggyBankUpdateRequest extends FormRequest
/**
* Rules for this request.
- *
- * @return array
*/
public function rules(): array
{
@@ -65,13 +64,21 @@ class PiggyBankUpdateRequest extends FormRequest
$piggy = $this->route()->parameter('piggyBank');
return [
- 'name' => sprintf('required|between:1,255|uniquePiggyBankForUser:%d', $piggy->id),
+ 'name' => sprintf('required|min:1|max:255|uniquePiggyBankForUser:%d', $piggy->id),
'account_id' => 'required|belongsToUser:accounts',
- 'targetamount' => 'nullable|numeric|max:1000000000',
+ 'targetamount' => ['nullable', new IsValidPositiveAmount()],
'startdate' => 'date',
'targetdate' => 'date|nullable',
- 'order' => 'integer|max:65536|min:1',
+ 'order' => 'integer|max:32768|min:1',
'object_group' => 'min:0|max:255',
+ 'notes' => 'min:1|max:32768|nullable',
];
}
+
+ public function withValidator(Validator $validator): void
+ {
+ if ($validator->fails()) {
+ Log::channel('audit')->error(sprintf('Validation errors in %s', __CLASS__), $validator->errors()->toArray());
+ }
+ }
}
diff --git a/app/Http/Requests/ProfileFormRequest.php b/app/Http/Requests/ProfileFormRequest.php
index f643abb3b3..690697681e 100644
--- a/app/Http/Requests/ProfileFormRequest.php
+++ b/app/Http/Requests/ProfileFormRequest.php
@@ -25,11 +25,11 @@ namespace FireflyIII\Http\Requests;
use FireflyIII\Support\Request\ChecksLogin;
use Illuminate\Foundation\Http\FormRequest;
+use Illuminate\Support\Facades\Log;
+use Illuminate\Validation\Validator;
/**
* Class ProfileFormRequest.
- *
-
*/
class ProfileFormRequest extends FormRequest
{
@@ -37,8 +37,6 @@ class ProfileFormRequest extends FormRequest
/**
* Rules for this request.
- *
- * @return array
*/
public function rules(): array
{
@@ -49,4 +47,11 @@ class ProfileFormRequest extends FormRequest
'new_password_confirmation' => 'required',
];
}
+
+ public function withValidator(Validator $validator): void
+ {
+ if ($validator->fails()) {
+ Log::channel('audit')->error(sprintf('Validation errors in %s', __CLASS__), $validator->errors()->toArray());
+ }
+ }
}
diff --git a/app/Http/Requests/ReconciliationStoreRequest.php b/app/Http/Requests/ReconciliationStoreRequest.php
index c9a1613f20..2524ce4fb3 100644
--- a/app/Http/Requests/ReconciliationStoreRequest.php
+++ b/app/Http/Requests/ReconciliationStoreRequest.php
@@ -23,24 +23,24 @@ declare(strict_types=1);
namespace FireflyIII\Http\Requests;
+use FireflyIII\Rules\IsValidAmount;
use FireflyIII\Rules\ValidJournals;
use FireflyIII\Support\Request\ChecksLogin;
use FireflyIII\Support\Request\ConvertsDataTypes;
use Illuminate\Foundation\Http\FormRequest;
use Illuminate\Support\Facades\Log;
+use Illuminate\Validation\Validator;
/**
* Class ReconciliationStoreRequest
*/
class ReconciliationStoreRequest extends FormRequest
{
- use ConvertsDataTypes;
use ChecksLogin;
+ use ConvertsDataTypes;
/**
* Returns the data required by the controller.
- *
- * @return array
*/
public function getAll(): array
{
@@ -48,7 +48,7 @@ class ReconciliationStoreRequest extends FormRequest
if (!is_array($transactions)) {
$transactions = [];
}
- $data = [
+ $data = [
'start' => $this->getCarbonDate('start'),
'end' => $this->getCarbonDate('end'),
'start_balance' => $this->convertString('startBalance'),
@@ -57,26 +57,31 @@ class ReconciliationStoreRequest extends FormRequest
'journals' => $transactions,
'reconcile' => $this->convertString('reconcile'),
];
- Log::debug('In ReconciliationStoreRequest::getAll(). Will now return data.');
+ app('log')->debug('In ReconciliationStoreRequest::getAll(). Will now return data.');
return $data;
}
/**
* Rules for this request.
- *
- * @return array
*/
public function rules(): array
{
return [
'start' => 'required|date',
'end' => 'required|date',
- 'startBalance' => 'numeric|max:1000000000',
- 'endBalance' => 'numeric|max:1000000000',
- 'difference' => 'required|numeric|max:1000000000',
+ 'startBalance' => ['nullable', new IsValidAmount()],
+ 'endBalance' => ['nullable', new IsValidAmount()],
+ 'difference' => ['required', new IsValidAmount()],
'journals' => [new ValidJournals()],
'reconcile' => 'required|in:create,nothing',
];
}
+
+ public function withValidator(Validator $validator): void
+ {
+ if ($validator->fails()) {
+ Log::channel('audit')->error(sprintf('Validation errors in %s', __CLASS__), $validator->errors()->toArray());
+ }
+ }
}
diff --git a/app/Http/Requests/RecurrenceFormRequest.php b/app/Http/Requests/RecurrenceFormRequest.php
index dce42861b4..0bdaef8ef1 100644
--- a/app/Http/Requests/RecurrenceFormRequest.php
+++ b/app/Http/Requests/RecurrenceFormRequest.php
@@ -27,6 +27,7 @@ use FireflyIII\Exceptions\FireflyException;
use FireflyIII\Factory\CategoryFactory;
use FireflyIII\Models\Recurrence;
use FireflyIII\Models\TransactionType;
+use FireflyIII\Rules\IsValidPositiveAmount;
use FireflyIII\Rules\ValidRecurrenceRepetitionType;
use FireflyIII\Rules\ValidRecurrenceRepetitionValue;
use FireflyIII\Support\Request\ChecksLogin;
@@ -41,20 +42,20 @@ use Illuminate\Validation\Validator;
*/
class RecurrenceFormRequest extends FormRequest
{
- use ConvertsDataTypes;
use ChecksLogin;
+ use ConvertsDataTypes;
/**
* Get the data required by the controller.
*
- * @return array
* @throws FireflyException
*
+ * @SuppressWarnings(PHPMD.ExcessiveMethodLength)
*/
public function getAll(): array
{
- $repetitionData = $this->parseRepetitionData();
- $return = [
+ $repetitionData = $this->parseRepetitionData();
+ $return = [
'recurrence' => [
'type' => $this->convertString('transaction_type'),
'title' => $this->convertString('title'),
@@ -95,7 +96,6 @@ class RecurrenceFormRequest extends FormRequest
'weekend' => $this->convertInteger('weekend'),
],
],
-
];
// fill in foreign currency data
@@ -130,8 +130,9 @@ class RecurrenceFormRequest extends FormRequest
}
// replace category name with a new category:
- $factory = app(CategoryFactory::class);
+ $factory = app(CategoryFactory::class);
$factory->setUser(auth()->user());
+
/**
* @var int $index
* @var array $transaction
@@ -151,8 +152,6 @@ class RecurrenceFormRequest extends FormRequest
/**
* Parses repetition data.
- *
- * @return array
*/
private function parseRepetitionData(): array
{
@@ -165,8 +164,8 @@ class RecurrenceFormRequest extends FormRequest
if ('daily' === $value) {
$return['type'] = $value;
}
- //monthly,17
- //ndom,3,7
+ // monthly,17
+ // ndom,3,7
if (in_array(substr($value, 0, 6), ['yearly', 'weekly'], true)) {
$return['type'] = substr($value, 0, 6);
$return['moment'] = substr($value, 7);
@@ -185,45 +184,43 @@ class RecurrenceFormRequest extends FormRequest
/**
* The rules for this request.
- *
- * @return array
- *
*/
public function rules(): array
{
- $today = today(config('app.timezone'));
- $tomorrow = today(config('app.timezone'))->addDay();
- $rules = [
+ $today = today(config('app.timezone'));
+ $tomorrow = today(config('app.timezone'))->addDay();
+ $before = today(config('app.timezone'))->addYears(25);
+ $rules = [
// mandatory info for recurrence.
- 'title' => 'required|between:1,255|uniqueObjectForUser:recurrences,title',
- 'first_date' => 'required|date|after:' . $today->format('Y-m-d'),
- 'repetition_type' => ['required', new ValidRecurrenceRepetitionValue(), new ValidRecurrenceRepetitionType(), 'between:1,20'],
+ 'title' => 'required|min:1|max:255|uniqueObjectForUser:recurrences,title',
+ 'first_date' => sprintf('required|date|before:%s|after:%s', $before->format('Y-m-d'), $today->format('Y-m-d')),
+ 'repetition_type' => ['required', new ValidRecurrenceRepetitionValue(), new ValidRecurrenceRepetitionType(), 'min:1', 'max:32'],
'skip' => 'required|numeric|integer|gte:0|lte:31',
-
+ 'notes' => 'min:1|max:32768|nullable',
// optional for recurrence:
- 'recurring_description' => 'between:0,65000',
- 'active' => 'numeric|between:0,1',
- 'apply_rules' => 'numeric|between:0,1',
+ 'recurring_description' => 'min:0|max:32768',
+ 'active' => 'numeric|min:0|max:1',
+ 'apply_rules' => 'numeric|min:0|max:1',
// mandatory for transaction:
- 'transaction_description' => 'required|between:1,255',
+ 'transaction_description' => 'required|min:1|max:255',
'transaction_type' => 'required|in:withdrawal,deposit,transfer',
'transaction_currency_id' => 'required|exists:transaction_currencies,id',
- 'amount' => 'numeric|required|gt:0|max:1000000000',
+ 'amount' => ['required', new IsValidPositiveAmount()],
// mandatory account info:
'source_id' => 'numeric|belongsToUser:accounts,id|nullable',
- 'source_name' => 'between:1,255|nullable',
+ 'source_name' => 'min:1|max:255|nullable',
'destination_id' => 'numeric|belongsToUser:accounts,id|nullable',
- 'destination_name' => 'between:1,255|nullable',
+ 'destination_name' => 'min:1|max:255|nullable',
// foreign amount data:
- 'foreign_amount' => 'nullable|gt:0|max:1000000000',
+ 'foreign_amount' => ['nullable', new IsValidPositiveAmount()],
// optional fields:
'budget_id' => 'mustExist:budgets,id|belongsToUser:budgets,id|nullable',
'bill_id' => 'mustExist:bills,id|belongsToUser:bills,id|nullable',
- 'category' => 'between:1,255|nullable',
- 'tags' => 'between:1,255|nullable',
+ 'category' => 'min:1|max:255|nullable',
+ 'tags' => 'min:1|max:255|nullable',
];
if ($this->convertInteger('foreign_currency_id') > 0) {
$rules['foreign_currency_id'] = 'exists:transaction_currencies,id';
@@ -231,7 +228,7 @@ class RecurrenceFormRequest extends FormRequest
// if ends after X repetitions, set another rule
if ('times' === $this->convertString('repetition_end')) {
- $rules['repetitions'] = 'required|numeric|between:0,254';
+ $rules['repetitions'] = 'required|numeric|min:0|max:255';
}
// if foreign amount, currency must be different.
if (null !== $this->convertFloat('foreign_amount')) { // intentional float, used because it defaults to null.
@@ -240,17 +237,17 @@ class RecurrenceFormRequest extends FormRequest
// if ends at date X, set another rule.
if ('until_date' === $this->convertString('repetition_end')) {
- $rules['repeat_until'] = 'required|date|after:' . $tomorrow->format('Y-m-d');
+ $rules['repeat_until'] = 'required|date|after:'.$tomorrow->format('Y-m-d');
}
// switch on type to expand rules for source and destination accounts:
- $type = strtolower($this->convertString('transaction_type'));
+ $type = strtolower($this->convertString('transaction_type'));
if (strtolower(TransactionType::WITHDRAWAL) === $type) {
$rules['source_id'] = 'required|exists:accounts,id|belongsToUser:accounts';
- $rules['destination_name'] = 'between:1,255|nullable';
+ $rules['destination_name'] = 'min:1|max:255|nullable';
}
if (strtolower(TransactionType::DEPOSIT) === $type) {
- $rules['source_name'] = 'between:1,255|nullable';
+ $rules['source_name'] = 'min:1|max:255|nullable';
$rules['destination_id'] = 'required|exists:accounts,id|belongsToUser:accounts';
}
if (strtolower(TransactionType::TRANSFER) === $type) {
@@ -260,11 +257,11 @@ class RecurrenceFormRequest extends FormRequest
}
// update some rules in case the user is editing a post:
- /** @var Recurrence $recurrence */
+ /** @var null|Recurrence $recurrence */
$recurrence = $this->route()->parameter('recurrence');
if ($recurrence instanceof Recurrence) {
$rules['id'] = 'required|numeric|exists:recurrences,id';
- $rules['title'] = 'required|between:1,255|uniqueObjectForUser:recurrences,title,' . $recurrence->id;
+ $rules['title'] = 'required|min:1|max:255|uniqueObjectForUser:recurrences,title,'.$recurrence->id;
$rules['first_date'] = 'required|date';
}
@@ -273,31 +270,29 @@ class RecurrenceFormRequest extends FormRequest
/**
* Configure the validator instance with special rules for after the basic validation rules.
- *
- * @param Validator $validator
- *
- * @return void
*/
public function withValidator(Validator $validator): void
{
$validator->after(
- function (Validator $validator) {
+ function (Validator $validator): void {
// validate all account info
$this->validateAccountInformation($validator);
}
);
+ if ($validator->fails()) {
+ Log::channel('audit')->error(sprintf('Validation errors in %s', __CLASS__), $validator->errors()->toArray());
+ }
}
/**
* Validates the given account information. Switches on given transaction type.
*
- * @param Validator $validator
- *
* @throws FireflyException
*/
public function validateAccountInformation(Validator $validator): void
{
- Log::debug('Now in validateAccountInformation (RecurrenceFormRequest)()');
+ app('log')->debug('Now in validateAccountInformation (RecurrenceFormRequest)()');
+
/** @var AccountValidator $accountValidator */
$accountValidator = app(AccountValidator::class);
$data = $validator->getData();
@@ -306,13 +301,13 @@ class RecurrenceFormRequest extends FormRequest
$accountValidator->setTransactionType($transactionType);
// default values:
- $sourceId = null;
- $destinationId = null;
+ $sourceId = null;
+ $destinationId = null;
// TODO typeOverrule: the account validator may have another opinion the transaction type.
// TODO either use 'withdrawal' or the strtolower() variant, not both.
- $type = $this->convertString('transaction_type');
- $throwError = true;
+ $type = $this->convertString('transaction_type');
+ $throwError = true;
if ('withdrawal' === $type) {
$throwError = false;
$sourceId = (int)$data['source_id'];
@@ -321,19 +316,19 @@ class RecurrenceFormRequest extends FormRequest
if ('deposit' === $type) {
$throwError = false;
$sourceId = (int)$data['deposit_source_id'];
- $destinationId = (int)$data['destination_id'];
+ $destinationId = (int)($data['destination_id'] ?? 0);
}
if ('transfer' === $type) {
$throwError = false;
$sourceId = (int)$data['source_id'];
- $destinationId = (int)$data['destination_id'];
+ $destinationId = (int)($data['destination_id'] ?? 0);
}
if (true === $throwError) {
throw new FireflyException(sprintf('Cannot handle transaction type "%s"', $this->convertString('transaction_type')));
}
// validate source account.
- $validSource = $accountValidator->validateSource(['id' => $sourceId,]);
+ $validSource = $accountValidator->validateSource(['id' => $sourceId]);
// do something with result:
if (false === $validSource) {
@@ -345,7 +340,7 @@ class RecurrenceFormRequest extends FormRequest
}
// validate destination account
- $validDestination = $accountValidator->validateDestination(['id' => $destinationId,]);
+ $validDestination = $accountValidator->validateDestination(['id' => $destinationId]);
// do something with result:
if (false === $validDestination) {
$message = (string)trans('validation.generic_invalid_destination');
diff --git a/app/Http/Requests/ReportFormRequest.php b/app/Http/Requests/ReportFormRequest.php
index 94e6f83f64..3a0977bbe7 100644
--- a/app/Http/Requests/ReportFormRequest.php
+++ b/app/Http/Requests/ReportFormRequest.php
@@ -34,6 +34,7 @@ use FireflyIII\Support\Request\ChecksLogin;
use Illuminate\Foundation\Http\FormRequest;
use Illuminate\Support\Collection;
use Illuminate\Support\Facades\Log;
+use Illuminate\Validation\Validator;
/**
* Class CategoryFormRequest.
@@ -44,8 +45,6 @@ class ReportFormRequest extends FormRequest
/**
* Validate list of accounts.
- *
- * @return Collection
*/
public function getAccountList(): Collection
{
@@ -68,8 +67,6 @@ class ReportFormRequest extends FormRequest
/**
* Validate list of budgets.
- *
- * @return Collection
*/
public function getBudgetList(): Collection
{
@@ -91,8 +88,6 @@ class ReportFormRequest extends FormRequest
/**
* Validate list of categories.
- *
- * @return Collection
*/
public function getCategoryList(): Collection
{
@@ -114,8 +109,6 @@ class ReportFormRequest extends FormRequest
/**
* Validate list of accounts which exist twice in system.
- *
- * @return Collection
*/
public function getDoubleList(): Collection
{
@@ -138,8 +131,6 @@ class ReportFormRequest extends FormRequest
/**
* Validate end date.
*
- * @return Carbon
- *
* @throws FireflyException
*/
public function getEndDate(): Carbon
@@ -148,33 +139,36 @@ class ReportFormRequest extends FormRequest
$range = $this->get('daterange');
$parts = explode(' - ', (string)$range);
if (2 === count($parts)) {
- $string = $parts[1];
+ $string = $parts[1];
// validate as date
// if regex for YYYY-MM-DD:
$pattern = '/^(19|20)\d\d-(0[1-9]|1[012])-(0[1-9]|[12][\d]|3[01])$/';
- if (preg_match($pattern, $string)) {
+ $result = preg_match($pattern, $string);
+ if (false !== $result && 0 !== $result) {
try {
$date = new Carbon($parts[1]);
- } catch (Exception $e) { // intentional generic exception
+ } catch (\Exception $e) { // intentional generic exception
$error = sprintf('"%s" is not a valid date range: %s', $range, $e->getMessage());
- Log::error($error);
- Log::error($e->getTraceAsString());
+ app('log')->error($error);
+ app('log')->error($e->getTraceAsString());
+
throw new FireflyException($error, 0, $e);
}
+
return $date;
}
- $error = sprintf('"%s" is not a valid date range: %s', $range, 'invalid format :(');
- Log::error($error);
+ $error = sprintf('"%s" is not a valid date range: %s', $range, 'invalid format :(');
+ app('log')->error($error);
+
throw new FireflyException($error, 0);
}
+
return $date;
}
/**
* Validate start date.
*
- * @return Carbon
- *
* @throws FireflyException
*/
public function getStartDate(): Carbon
@@ -183,23 +177,27 @@ class ReportFormRequest extends FormRequest
$range = $this->get('daterange');
$parts = explode(' - ', (string)$range);
if (2 === count($parts)) {
- $string = $parts[0];
+ $string = $parts[0];
// validate as date
// if regex for YYYY-MM-DD:
$pattern = '/^(19|20)\d\d-(0[1-9]|1[012])-(0[1-9]|[12][\d]|3[01])$/';
- if (preg_match($pattern, $string)) {
+ $result = preg_match($pattern, $string);
+ if (false !== $result && 0 !== $result) {
try {
$date = new Carbon($parts[0]);
- } catch (Exception $e) { // intentional generic exception
+ } catch (\Exception $e) { // intentional generic exception
$error = sprintf('"%s" is not a valid date range: %s', $range, $e->getMessage());
- Log::error($error);
- Log::error($e->getTraceAsString());
+ app('log')->error($error);
+ app('log')->error($e->getTraceAsString());
+
throw new FireflyException($error, 0, $e);
}
+
return $date;
}
- $error = sprintf('"%s" is not a valid date range: %s', $range, 'invalid format :(');
- Log::error($error);
+ $error = sprintf('"%s" is not a valid date range: %s', $range, 'invalid format :(');
+ app('log')->error($error);
+
throw new FireflyException($error, 0);
}
@@ -208,8 +206,6 @@ class ReportFormRequest extends FormRequest
/**
* Validate list of tags.
- *
- * @return Collection
*/
public function getTagList(): Collection
{
@@ -218,17 +214,19 @@ class ReportFormRequest extends FormRequest
$set = $this->get('tag');
$collection = new Collection();
if (is_array($set)) {
- Log::debug('Set is:', $set);
+ app('log')->debug('Set is:', $set);
}
if (!is_array($set)) {
- Log::error(sprintf('Set is not an array! "%s"', $set));
+ app('log')->debug(sprintf('Set is not an array! "%s"', $set));
+
return $collection;
}
foreach ($set as $tagTag) {
- Log::debug(sprintf('Now searching for "%s"', $tagTag));
+ app('log')->debug(sprintf('Now searching for "%s"', $tagTag));
$tag = $repository->findByTag($tagTag);
if (null !== $tag) {
$collection->push($tag);
+
continue;
}
$tag = $repository->find((int)$tagTag);
@@ -242,8 +240,6 @@ class ReportFormRequest extends FormRequest
/**
* Rules for this request.
- *
- * @return array
*/
public function rules(): array
{
@@ -251,4 +247,11 @@ class ReportFormRequest extends FormRequest
'report_type' => 'in:audit,default,category,budget,tag,double',
];
}
+
+ public function withValidator(Validator $validator): void
+ {
+ if ($validator->fails()) {
+ Log::channel('audit')->error(sprintf('Validation errors in %s', __CLASS__), $validator->errors()->toArray());
+ }
+ }
}
diff --git a/app/Http/Requests/RuleFormRequest.php b/app/Http/Requests/RuleFormRequest.php
index d27371e4d7..6d6f831815 100644
--- a/app/Http/Requests/RuleFormRequest.php
+++ b/app/Http/Requests/RuleFormRequest.php
@@ -28,21 +28,20 @@ use FireflyIII\Support\Request\ChecksLogin;
use FireflyIII\Support\Request\ConvertsDataTypes;
use FireflyIII\Support\Request\GetRuleConfiguration;
use Illuminate\Foundation\Http\FormRequest;
+use Illuminate\Support\Facades\Log;
+use Illuminate\Validation\Validator;
/**
* Class RuleFormRequest.
*/
class RuleFormRequest extends FormRequest
{
+ use ChecksLogin;
use ConvertsDataTypes;
use GetRuleConfiguration;
- use ChecksLogin;
/**
* Get all data for controller.
- *
- * @return array
- *
*/
public function getRuleData(): array
{
@@ -59,9 +58,6 @@ class RuleFormRequest extends FormRequest
];
}
- /**
- * @return array
- */
private function getRuleTriggerData(): array
{
$return = [];
@@ -84,11 +80,6 @@ class RuleFormRequest extends FormRequest
return $return;
}
- /**
- * @param array $array
- *
- * @return array
- */
public static function replaceAmountTrigger(array $array): array
{
// do some sneaky search and replace.
@@ -110,12 +101,10 @@ class RuleFormRequest extends FormRequest
if (in_array($array['type'], $amountFields, true) && '0' === $array['value']) {
$array['value'] = '0.00';
}
+
return $array;
}
- /**
- * @return array
- */
private function getRuleActionData(): array
{
$return = [];
@@ -136,41 +125,46 @@ class RuleFormRequest extends FormRequest
/**
* Rules for this request.
- *
- * @return array
*/
public function rules(): array
{
- $validTriggers = $this->getTriggers();
- $validActions = array_keys(config('firefly.rule-actions'));
+ $validTriggers = $this->getTriggers();
+ $validActions = array_keys(config('firefly.rule-actions'));
// some actions require text (aka context):
- $contextActions = implode(',', config('firefly.context-rule-actions'));
+ $contextActions = implode(',', config('firefly.context-rule-actions'));
// some triggers require text (aka context):
$contextTriggers = implode(',', $this->getTriggersWithContext());
// initial set of rules:
- $rules = [
- 'title' => 'required|between:1,100|uniqueObjectForUser:rules,title',
- 'description' => 'between:1,5000|nullable',
+ $rules = [
+ 'title' => 'required|min:1|max:255|uniqueObjectForUser:rules,title',
+ 'description' => 'min:1|max:32768|nullable',
'stop_processing' => 'boolean',
'rule_group_id' => 'required|belongsToUser:rule_groups',
'trigger' => 'required|in:store-journal,update-journal',
- 'triggers.*.type' => 'required|in:' . implode(',', $validTriggers),
+ 'triggers.*.type' => 'required|in:'.implode(',', $validTriggers),
'triggers.*.value' => sprintf('required_if:triggers.*.type,%s|max:1024|min:1|ruleTriggerValue', $contextTriggers),
- 'actions.*.type' => 'required|in:' . implode(',', $validActions),
+ 'actions.*.type' => 'required|in:'.implode(',', $validActions),
'actions.*.value' => sprintf('required_if:actions.*.type,%s|min:0|max:1024|ruleActionValue', $contextActions),
'strict' => 'in:0,1',
];
- /** @var Rule $rule */
- $rule = $this->route()->parameter('rule');
+ /** @var null|Rule $rule */
+ $rule = $this->route()->parameter('rule');
if (null !== $rule) {
- $rules['title'] = 'required|between:1,100|uniqueObjectForUser:rules,title,' . $rule->id;
+ $rules['title'] = 'required|min:1|max:255|uniqueObjectForUser:rules,title,'.$rule->id;
}
return $rules;
}
+
+ public function withValidator(Validator $validator): void
+ {
+ if ($validator->fails()) {
+ Log::channel('audit')->error(sprintf('Validation errors in %s', __CLASS__), $validator->errors()->toArray());
+ }
+ }
}
diff --git a/app/Http/Requests/RuleGroupFormRequest.php b/app/Http/Requests/RuleGroupFormRequest.php
index 91da192e06..ac0a4fc891 100644
--- a/app/Http/Requests/RuleGroupFormRequest.php
+++ b/app/Http/Requests/RuleGroupFormRequest.php
@@ -28,19 +28,19 @@ use FireflyIII\Rules\IsBoolean;
use FireflyIII\Support\Request\ChecksLogin;
use FireflyIII\Support\Request\ConvertsDataTypes;
use Illuminate\Foundation\Http\FormRequest;
+use Illuminate\Support\Facades\Log;
+use Illuminate\Validation\Validator;
/**
* Class RuleGroupFormRequest.
*/
class RuleGroupFormRequest extends FormRequest
{
- use ConvertsDataTypes;
use ChecksLogin;
+ use ConvertsDataTypes;
/**
* Get all data for controller.
- *
- * @return array
*/
public function getRuleGroupData(): array
{
@@ -58,24 +58,29 @@ class RuleGroupFormRequest extends FormRequest
/**
* Rules for this request.
- *
- * @return array
*/
public function rules(): array
{
- $titleRule = 'required|between:1,100|uniqueObjectForUser:rule_groups,title';
+ $titleRule = 'required|min:1|max:255|uniqueObjectForUser:rule_groups,title';
- /** @var RuleGroup $ruleGroup */
+ /** @var null|RuleGroup $ruleGroup */
$ruleGroup = $this->route()->parameter('ruleGroup');
if (null !== $ruleGroup) {
- $titleRule = 'required|between:1,100|uniqueObjectForUser:rule_groups,title,' . $ruleGroup->id;
+ $titleRule = 'required|min:1|max:255|uniqueObjectForUser:rule_groups,title,'.$ruleGroup->id;
}
return [
'title' => $titleRule,
- 'description' => 'between:1,5000|nullable',
+ 'description' => 'min:1|max:32768|nullable',
'active' => [new IsBoolean()],
];
}
+
+ public function withValidator(Validator $validator): void
+ {
+ if ($validator->fails()) {
+ Log::channel('audit')->error(sprintf('Validation errors in %s', __CLASS__), $validator->errors()->toArray());
+ }
+ }
}
diff --git a/app/Http/Requests/SelectTransactionsRequest.php b/app/Http/Requests/SelectTransactionsRequest.php
index 17f5284ca1..13a5f7729a 100644
--- a/app/Http/Requests/SelectTransactionsRequest.php
+++ b/app/Http/Requests/SelectTransactionsRequest.php
@@ -26,11 +26,11 @@ namespace FireflyIII\Http\Requests;
use Carbon\Carbon;
use FireflyIII\Support\Request\ChecksLogin;
use Illuminate\Foundation\Http\FormRequest;
+use Illuminate\Support\Facades\Log;
+use Illuminate\Validation\Validator;
/**
* Class SelectTransactionsRequest.
- *
-
*/
class SelectTransactionsRequest extends FormRequest
{
@@ -38,8 +38,6 @@ class SelectTransactionsRequest extends FormRequest
/**
* Rules for this request.
- *
- * @return array
*/
public function rules(): array
{
@@ -50,10 +48,17 @@ class SelectTransactionsRequest extends FormRequest
$today = today(config('app.timezone'))->addDay()->format('Y-m-d');
return [
- 'start' => 'required|date|after:' . $first,
- 'end' => 'required|date|before:' . $today,
+ 'start' => 'required|date|after:'.$first,
+ 'end' => 'required|date|before:'.$today,
'accounts' => 'required',
'accounts.*' => 'required|exists:accounts,id|belongsToUser:accounts',
];
}
+
+ public function withValidator(Validator $validator): void
+ {
+ if ($validator->fails()) {
+ Log::channel('audit')->error(sprintf('Validation errors in %s', __CLASS__), $validator->errors()->toArray());
+ }
+ }
}
diff --git a/app/Http/Requests/TagFormRequest.php b/app/Http/Requests/TagFormRequest.php
index c006faaef7..2a30cd6344 100644
--- a/app/Http/Requests/TagFormRequest.php
+++ b/app/Http/Requests/TagFormRequest.php
@@ -29,20 +29,20 @@ use FireflyIII\Support\Request\AppendsLocationData;
use FireflyIII\Support\Request\ChecksLogin;
use FireflyIII\Support\Request\ConvertsDataTypes;
use Illuminate\Foundation\Http\FormRequest;
+use Illuminate\Support\Facades\Log;
+use Illuminate\Validation\Validator;
/**
* Class TagFormRequest.
*/
class TagFormRequest extends FormRequest
{
- use ConvertsDataTypes;
use AppendsLocationData;
use ChecksLogin;
+ use ConvertsDataTypes;
/**
* Get all data for controller.
- *
- * @return array
*/
public function collectTagData(): array
{
@@ -57,29 +57,33 @@ class TagFormRequest extends FormRequest
/**
* Rules for this request.
- *
- * @return array
*/
public function rules(): array
{
- $idRule = '';
+ $idRule = '';
- /** @var Tag $tag */
+ /** @var null|Tag $tag */
$tag = $this->route()->parameter('tag');
$tagRule = 'required|max:1024|min:1|uniqueObjectForUser:tags,tag';
if (null !== $tag) {
$idRule = 'belongsToUser:tags';
- $tagRule = 'required|max:1024|min:1|uniqueObjectForUser:tags,tag,' . $tag->id;
+ $tagRule = 'required|max:1024|min:1|uniqueObjectForUser:tags,tag,'.$tag->id;
}
- $rules = [
+ $rules = [
'tag' => $tagRule,
'id' => $idRule,
- 'description' => 'max:65536|min:1|nullable',
+ 'description' => 'max:32768|min:1|nullable',
'date' => 'date|nullable',
-
];
return Location::requestRules($rules);
}
+
+ public function withValidator(Validator $validator): void
+ {
+ if ($validator->fails()) {
+ Log::channel('audit')->error(sprintf('Validation errors in %s', __CLASS__), $validator->errors()->toArray());
+ }
+ }
}
diff --git a/app/Http/Requests/TestRuleFormRequest.php b/app/Http/Requests/TestRuleFormRequest.php
index 39b7cc62d3..40511100b2 100644
--- a/app/Http/Requests/TestRuleFormRequest.php
+++ b/app/Http/Requests/TestRuleFormRequest.php
@@ -26,22 +26,20 @@ namespace FireflyIII\Http\Requests;
use FireflyIII\Support\Request\ChecksLogin;
use FireflyIII\Support\Request\GetRuleConfiguration;
use Illuminate\Foundation\Http\FormRequest;
+use Illuminate\Support\Facades\Log;
+use Illuminate\Validation\Validator;
/**
* Class TestRuleFormRequest.
- *
-
*/
class TestRuleFormRequest extends FormRequest
{
- use GetRuleConfiguration;
use ChecksLogin;
+ use GetRuleConfiguration;
/**
* Rules for this request.
* TODO these rules are not valid anymore.
- *
- * @return array
*/
public function rules(): array
{
@@ -49,8 +47,15 @@ class TestRuleFormRequest extends FormRequest
$validTriggers = $this->getTriggers();
return [
- 'rule-trigger.*' => 'required|max:1024|min:1|in:' . implode(',', $validTriggers),
+ 'rule-trigger.*' => 'required|max:1024|min:1|in:'.implode(',', $validTriggers),
'rule-trigger-value.*' => 'required|max:1024|min:1|ruleTriggerValue',
];
}
+
+ public function withValidator(Validator $validator): void
+ {
+ if ($validator->fails()) {
+ Log::channel('audit')->error(sprintf('Validation errors in %s', __CLASS__), $validator->errors()->toArray());
+ }
+ }
}
diff --git a/app/Http/Requests/TokenFormRequest.php b/app/Http/Requests/TokenFormRequest.php
index eedf49a616..ab7d883225 100644
--- a/app/Http/Requests/TokenFormRequest.php
+++ b/app/Http/Requests/TokenFormRequest.php
@@ -25,11 +25,11 @@ namespace FireflyIII\Http\Requests;
use FireflyIII\Support\Request\ChecksLogin;
use Illuminate\Foundation\Http\FormRequest;
+use Illuminate\Support\Facades\Log;
+use Illuminate\Validation\Validator;
/**
* Class TokenFormRequest.
- *
-
*/
class TokenFormRequest extends FormRequest
{
@@ -37,8 +37,6 @@ class TokenFormRequest extends FormRequest
/**
* Rules for this request.
- *
- * @return array
*/
public function rules(): array
{
@@ -47,4 +45,11 @@ class TokenFormRequest extends FormRequest
'code' => 'required|2faCode',
];
}
+
+ public function withValidator(Validator $validator): void
+ {
+ if ($validator->fails()) {
+ Log::channel('audit')->error(sprintf('Validation errors in %s', __CLASS__), $validator->errors()->toArray());
+ }
+ }
}
diff --git a/app/Http/Requests/TriggerRecurrenceRequest.php b/app/Http/Requests/TriggerRecurrenceRequest.php
index 205141f368..a1ad139b6e 100644
--- a/app/Http/Requests/TriggerRecurrenceRequest.php
+++ b/app/Http/Requests/TriggerRecurrenceRequest.php
@@ -1,6 +1,5 @@
'required|date',
];
}
+
+ public function withValidator(Validator $validator): void
+ {
+ if ($validator->fails()) {
+ Log::channel('audit')->error(sprintf('Validation errors in %s', __CLASS__), $validator->errors()->toArray());
+ }
+ }
}
diff --git a/app/Http/Requests/UserFormRequest.php b/app/Http/Requests/UserFormRequest.php
index 1305bda1fc..fa9d62cb8e 100644
--- a/app/Http/Requests/UserFormRequest.php
+++ b/app/Http/Requests/UserFormRequest.php
@@ -26,21 +26,19 @@ namespace FireflyIII\Http\Requests;
use FireflyIII\Support\Request\ChecksLogin;
use FireflyIII\Support\Request\ConvertsDataTypes;
use Illuminate\Foundation\Http\FormRequest;
+use Illuminate\Support\Facades\Log;
+use Illuminate\Validation\Validator;
/**
* Class UserFormRequest.
- *
-
*/
class UserFormRequest extends FormRequest
{
- use ConvertsDataTypes;
use ChecksLogin;
+ use ConvertsDataTypes;
/**
* Get data for controller.
- *
- * @return array
*/
public function getUserData(): array
{
@@ -55,8 +53,6 @@ class UserFormRequest extends FormRequest
/**
* Rules for this request.
- *
- * @return array
*/
public function rules(): array
{
@@ -64,9 +60,16 @@ class UserFormRequest extends FormRequest
'id' => 'required|exists:users,id',
'email' => 'email|required',
'password' => 'confirmed|secure_password',
- 'blocked_code' => 'between:0,30|nullable',
- 'blocked' => 'between:0,1|numeric',
- 'is_owner' => 'between:0,1|numeric',
+ 'blocked_code' => 'min:0|max:32|nullable',
+ 'blocked' => 'min:0|max:1|numeric',
+ 'is_owner' => 'min:0|max:1|numeric',
];
}
+
+ public function withValidator(Validator $validator): void
+ {
+ if ($validator->fails()) {
+ Log::channel('audit')->error(sprintf('Validation errors in %s', __CLASS__), $validator->errors()->toArray());
+ }
+ }
}
diff --git a/app/Http/Requests/UserRegistrationRequest.php b/app/Http/Requests/UserRegistrationRequest.php
index c8c68c35a7..026fd05a9d 100644
--- a/app/Http/Requests/UserRegistrationRequest.php
+++ b/app/Http/Requests/UserRegistrationRequest.php
@@ -25,11 +25,11 @@ namespace FireflyIII\Http\Requests;
use FireflyIII\Support\Request\ChecksLogin;
use Illuminate\Foundation\Http\FormRequest;
+use Illuminate\Support\Facades\Log;
+use Illuminate\Validation\Validator;
/**
* Class UserRegistrationRequest.
- *
-
*/
class UserRegistrationRequest extends FormRequest
{
@@ -37,8 +37,6 @@ class UserRegistrationRequest extends FormRequest
/**
* Verify the request.
- *
- * @return bool
*/
public function authorize(): bool
{
@@ -48,8 +46,6 @@ class UserRegistrationRequest extends FormRequest
/**
* Rules for this request.
- *
- * @return array
*/
public function rules(): array
{
@@ -59,4 +55,11 @@ class UserRegistrationRequest extends FormRequest
'password' => 'confirmed|secure_password',
];
}
+
+ public function withValidator(Validator $validator): void
+ {
+ if ($validator->fails()) {
+ Log::channel('audit')->error(sprintf('Validation errors in %s', __CLASS__), $validator->errors()->toArray());
+ }
+ }
}
diff --git a/app/Jobs/CreateAutoBudgetLimits.php b/app/Jobs/CreateAutoBudgetLimits.php
index 9c86241ea2..ce0c15e173 100644
--- a/app/Jobs/CreateAutoBudgetLimits.php
+++ b/app/Jobs/CreateAutoBudgetLimits.php
@@ -36,7 +36,6 @@ use Illuminate\Foundation\Bus\Dispatchable;
use Illuminate\Queue\InteractsWithQueue;
use Illuminate\Queue\SerializesModels;
use Illuminate\Support\Collection;
-use Illuminate\Support\Facades\Log;
/**
* Class CreateAutoBudgetLimits
@@ -52,17 +51,14 @@ class CreateAutoBudgetLimits implements ShouldQueue
/**
* Create a new job instance.
- *
- *
- * @param Carbon|null $date
*/
public function __construct(?Carbon $date)
{
if (null !== $date) {
- $newDate = clone $date;
+ $newDate = clone $date;
$newDate->startOfDay();
$this->date = $newDate;
- Log::debug(sprintf('Created new CreateAutoBudgetLimits("%s")', $this->date->format('Y-m-d')));
+ app('log')->debug(sprintf('Created new CreateAutoBudgetLimits("%s")', $this->date->format('Y-m-d')));
}
}
@@ -73,34 +69,32 @@ class CreateAutoBudgetLimits implements ShouldQueue
*/
public function handle(): void
{
- Log::debug(sprintf('Now at start of CreateAutoBudgetLimits() job for %s.', $this->date->format('D d M Y')));
+ app('log')->debug(sprintf('Now at start of CreateAutoBudgetLimits() job for %s.', $this->date->format('D d M Y')));
$autoBudgets = AutoBudget::get();
- Log::debug(sprintf('Found %d auto budgets.', $autoBudgets->count()));
+ app('log')->debug(sprintf('Found %d auto budgets.', $autoBudgets->count()));
foreach ($autoBudgets as $autoBudget) {
$this->handleAutoBudget($autoBudget);
}
}
/**
- * @param AutoBudget $autoBudget
- *
* @throws FireflyException
*/
private function handleAutoBudget(AutoBudget $autoBudget): void
{
if (null === $autoBudget->budget) {
- Log::info(sprintf('Auto budget #%d is associated with a deleted budget.', $autoBudget->id));
+ app('log')->info(sprintf('Auto budget #%d is associated with a deleted budget.', $autoBudget->id));
$autoBudget->delete();
return;
}
if (false === $autoBudget->budget->active) {
- Log::info(sprintf('Auto budget #%d is associated with an inactive budget.', $autoBudget->id));
+ app('log')->info(sprintf('Auto budget #%d is associated with an inactive budget.', $autoBudget->id));
return;
}
if (!$this->isMagicDay($autoBudget)) {
- Log::info(
+ app('log')->info(
sprintf(
'Today (%s) is not a magic day for %s auto-budget #%d (part of budget #%d "%s")',
$this->date->format('Y-m-d'),
@@ -110,11 +104,11 @@ class CreateAutoBudgetLimits implements ShouldQueue
$autoBudget->budget->name
)
);
- Log::debug(sprintf('Done with auto budget #%d', $autoBudget->id));
+ app('log')->debug(sprintf('Done with auto budget #%d', $autoBudget->id));
return;
}
- Log::info(
+ app('log')->info(
sprintf(
'Today (%s) is a magic day for %s auto-budget #%d (part of budget #%d "%s")',
$this->date->format('Y-m-d'),
@@ -126,8 +120,8 @@ class CreateAutoBudgetLimits implements ShouldQueue
);
// get date range for budget limit, based on range in auto-budget
- $start = app('navigation')->startOfPeriod($this->date, $autoBudget->period);
- $end = app('navigation')->endOfPeriod($start, $autoBudget->period);
+ $start = app('navigation')->startOfPeriod($this->date, $autoBudget->period);
+ $end = app('navigation')->endOfPeriod($start, $autoBudget->period);
// find budget limit:
$budgetLimit = $this->findBudgetLimit($autoBudget->budget, $start, $end);
@@ -136,7 +130,7 @@ class CreateAutoBudgetLimits implements ShouldQueue
// that's easy: create one.
// do nothing else.
$this->createBudgetLimit($autoBudget, $start, $end);
- Log::debug(sprintf('Done with auto budget #%d', $autoBudget->id));
+ app('log')->debug(sprintf('Done with auto budget #%d', $autoBudget->id));
return;
}
@@ -144,24 +138,21 @@ class CreateAutoBudgetLimits implements ShouldQueue
if (null === $budgetLimit && AutoBudget::AUTO_BUDGET_ROLLOVER === (int)$autoBudget->auto_budget_type) {
// budget limit exists already,
$this->createRollover($autoBudget);
- Log::debug(sprintf('Done with auto budget #%d', $autoBudget->id));
+ app('log')->debug(sprintf('Done with auto budget #%d', $autoBudget->id));
return;
}
if (null === $budgetLimit && AutoBudget::AUTO_BUDGET_ADJUSTED === (int)$autoBudget->auto_budget_type) {
// budget limit exists already,
$this->createAdjustedLimit($autoBudget);
- Log::debug(sprintf('Done with auto budget #%d', $autoBudget->id));
+ app('log')->debug(sprintf('Done with auto budget #%d', $autoBudget->id));
return;
}
- Log::debug(sprintf('Done with auto budget #%d', $autoBudget->id));
+ app('log')->debug(sprintf('Done with auto budget #%d', $autoBudget->id));
}
/**
- * @param AutoBudget $autoBudget
- *
- * @return bool
* @throws FireflyException
*/
private function isMagicDay(AutoBudget $autoBudget): bool
@@ -195,19 +186,13 @@ class CreateAutoBudgetLimits implements ShouldQueue
return '01-01' === $value;
}
+
throw new FireflyException(sprintf('isMagicDay() can\'t handle period "%s"', $autoBudget->period));
}
- /**
- * @param Budget $budget
- * @param Carbon $start
- * @param Carbon $end
- *
- * @return BudgetLimit|null
- */
private function findBudgetLimit(Budget $budget, Carbon $start, Carbon $end): ?BudgetLimit
{
- Log::debug(
+ app('log')->debug(
sprintf(
'Going to find a budget limit for budget #%d ("%s") between %s and %s',
$budget->id,
@@ -218,52 +203,45 @@ class CreateAutoBudgetLimits implements ShouldQueue
);
return $budget->budgetlimits()
- ->where('start_date', $start->format('Y-m-d'))
- ->where('end_date', $end->format('Y-m-d'))->first();
+ ->where('start_date', $start->format('Y-m-d'))
+ ->where('end_date', $end->format('Y-m-d'))->first()
+ ;
}
- /**
- * @param AutoBudget $autoBudget
- * @param Carbon $start
- * @param Carbon $end
- * @param string|null $amount
- */
- private function createBudgetLimit(AutoBudget $autoBudget, Carbon $start, Carbon $end, ?string $amount = null)
+ private function createBudgetLimit(AutoBudget $autoBudget, Carbon $start, Carbon $end, ?string $amount = null): void
{
- Log::debug(sprintf('No budget limit exist. Must create one for auto-budget #%d', $autoBudget->id));
+ app('log')->debug(sprintf('No budget limit exist. Must create one for auto-budget #%d', $autoBudget->id));
if (null !== $amount) {
- Log::debug(sprintf('Amount is overruled and will be set to %s', $amount));
+ app('log')->debug(sprintf('Amount is overruled and will be set to %s', $amount));
}
- $budgetLimit = new BudgetLimit();
+ $budgetLimit = new BudgetLimit();
$budgetLimit->budget()->associate($autoBudget->budget);
$budgetLimit->transactionCurrency()->associate($autoBudget->transactionCurrency);
$budgetLimit->start_date = $start;
$budgetLimit->end_date = $end;
$budgetLimit->amount = $amount ?? $autoBudget->amount;
$budgetLimit->period = $autoBudget->period;
- $budgetLimit->generated = true;
+ $budgetLimit->generated = 1;
$budgetLimit->save();
- Log::debug(sprintf('Created budget limit #%d.', $budgetLimit->id));
+ app('log')->debug(sprintf('Created budget limit #%d.', $budgetLimit->id));
}
/**
- * @param AutoBudget $autoBudget
- *
* @throws FireflyException
*/
private function createRollover(AutoBudget $autoBudget): void
{
- Log::debug(sprintf('Will now manage rollover for auto budget #%d', $autoBudget->id));
+ app('log')->debug(sprintf('Will now manage rollover for auto budget #%d', $autoBudget->id));
// current period:
- $start = app('navigation')->startOfPeriod($this->date, $autoBudget->period);
- $end = app('navigation')->endOfPeriod($start, $autoBudget->period);
+ $start = app('navigation')->startOfPeriod($this->date, $autoBudget->period);
+ $end = app('navigation')->endOfPeriod($start, $autoBudget->period);
// which means previous period:
$previousStart = app('navigation')->subtractPeriod($start, $autoBudget->period);
$previousEnd = app('navigation')->endOfPeriod($previousStart, $autoBudget->period);
- Log::debug(
+ app('log')->debug(
sprintf(
'Current period is %s-%s, so previous period is %s-%s',
$start->format('Y-m-d'),
@@ -274,61 +252,56 @@ class CreateAutoBudgetLimits implements ShouldQueue
);
// has budget limit in previous period?
- $budgetLimit = $this->findBudgetLimit($autoBudget->budget, $previousStart, $previousEnd);
+ $budgetLimit = $this->findBudgetLimit($autoBudget->budget, $previousStart, $previousEnd);
if (null === $budgetLimit) {
- Log::debug('No budget limit exists in previous period, so create one.');
+ app('log')->debug('No budget limit exists in previous period, so create one.');
// if not, create it and we're done.
$this->createBudgetLimit($autoBudget, $start, $end);
- Log::debug(sprintf('Done with auto budget #%d', $autoBudget->id));
+ app('log')->debug(sprintf('Done with auto budget #%d', $autoBudget->id));
return;
}
- Log::debug('Budget limit exists for previous period.');
+ app('log')->debug('Budget limit exists for previous period.');
// if has one, calculate expenses and use that as a base.
- $repository = app(OperationsRepositoryInterface::class);
+ $repository = app(OperationsRepositoryInterface::class);
$repository->setUser($autoBudget->budget->user);
- $spent = $repository->sumExpenses($previousStart, $previousEnd, null, new Collection([$autoBudget->budget]), $autoBudget->transactionCurrency);
- $currencyId = (int)$autoBudget->transaction_currency_id;
- $spentAmount = $spent[$currencyId]['sum'] ?? '0';
- Log::debug(sprintf('Spent in previous budget period (%s-%s) is %s', $previousStart->format('Y-m-d'), $previousEnd->format('Y-m-d'), $spentAmount));
+ $spent = $repository->sumExpenses($previousStart, $previousEnd, null, new Collection([$autoBudget->budget]), $autoBudget->transactionCurrency);
+ $currencyId = $autoBudget->transaction_currency_id;
+ $spentAmount = $spent[$currencyId]['sum'] ?? '0';
+ app('log')->debug(sprintf('Spent in previous budget period (%s-%s) is %s', $previousStart->format('Y-m-d'), $previousEnd->format('Y-m-d'), $spentAmount));
// if you spent more in previous budget period, than whatever you had previous budget period, the amount resets
// previous budget limit + spent
- $budgetLeft = bcadd($budgetLimit->amount, $spentAmount);
- $totalAmount = $autoBudget->amount;
- Log::debug(sprintf('Total amount left for previous budget period is %s', $budgetLeft));
+ $budgetLeft = bcadd($budgetLimit->amount, $spentAmount);
+ $totalAmount = $autoBudget->amount;
+ app('log')->debug(sprintf('Total amount left for previous budget period is %s', $budgetLeft));
if (-1 !== bccomp('0', $budgetLeft)) {
- Log::info(sprintf('The amount left is negative, so it will be reset to %s.', $totalAmount));
+ app('log')->info(sprintf('The amount left is negative, so it will be reset to %s.', $totalAmount));
}
if (1 !== bccomp('0', $budgetLeft)) {
$totalAmount = bcadd($budgetLeft, $totalAmount);
- Log::info(sprintf('The amount left is positive, so the new amount will be %s.', $totalAmount));
+ app('log')->info(sprintf('The amount left is positive, so the new amount will be %s.', $totalAmount));
}
// create budget limit:
$this->createBudgetLimit($autoBudget, $start, $end, $totalAmount);
- Log::debug(sprintf('Done with auto budget #%d', $autoBudget->id));
+ app('log')->debug(sprintf('Done with auto budget #%d', $autoBudget->id));
}
- /**
- * @param AutoBudget $autoBudget
- *
- * @return void
- */
private function createAdjustedLimit(AutoBudget $autoBudget): void
{
- Log::debug(sprintf('Will now manage rollover for auto budget #%d', $autoBudget->id));
+ app('log')->debug(sprintf('Will now manage rollover for auto budget #%d', $autoBudget->id));
// current period:
- $start = app('navigation')->startOfPeriod($this->date, $autoBudget->period);
- $end = app('navigation')->endOfPeriod($start, $autoBudget->period);
+ $start = app('navigation')->startOfPeriod($this->date, $autoBudget->period);
+ $end = app('navigation')->endOfPeriod($start, $autoBudget->period);
// which means previous period:
- $previousStart = app('navigation')->subtractPeriod($start, $autoBudget->period);
- $previousEnd = app('navigation')->endOfPeriod($previousStart, $autoBudget->period);
+ $previousStart = app('navigation')->subtractPeriod($start, $autoBudget->period);
+ $previousEnd = app('navigation')->endOfPeriod($previousStart, $autoBudget->period);
- Log::debug(
+ app('log')->debug(
sprintf(
'Current period is %s-%s, so previous period is %s-%s',
$start->format('Y-m-d'),
@@ -339,56 +312,53 @@ class CreateAutoBudgetLimits implements ShouldQueue
);
// has budget limit in previous period?
- $budgetLimit = $this->findBudgetLimit($autoBudget->budget, $previousStart, $previousEnd);
+ $budgetLimit = $this->findBudgetLimit($autoBudget->budget, $previousStart, $previousEnd);
if (null === $budgetLimit) {
- Log::debug('No budget limit exists in previous period, so create one.');
+ app('log')->debug('No budget limit exists in previous period, so create one.');
// if not, create standard amount, and we're done.
$this->createBudgetLimit($autoBudget, $start, $end);
+
return;
}
- Log::debug('Budget limit exists for previous period.');
+ app('log')->debug('Budget limit exists for previous period.');
// if has one, calculate expenses and use that as a base.
- $repository = app(OperationsRepositoryInterface::class);
+ $repository = app(OperationsRepositoryInterface::class);
$repository->setUser($autoBudget->budget->user);
- $spent = $repository->sumExpenses($previousStart, $previousEnd, null, new Collection([$autoBudget->budget]), $autoBudget->transactionCurrency);
- $currencyId = (int)$autoBudget->transaction_currency_id;
- $spentAmount = $spent[$currencyId]['sum'] ?? '0';
- Log::debug(sprintf('Spent in previous budget period (%s-%s) is %s', $previousStart->format('Y-m-d'), $previousEnd->format('Y-m-d'), $spentAmount));
+ $spent = $repository->sumExpenses($previousStart, $previousEnd, null, new Collection([$autoBudget->budget]), $autoBudget->transactionCurrency);
+ $currencyId = $autoBudget->transaction_currency_id;
+ $spentAmount = $spent[$currencyId]['sum'] ?? '0';
+ app('log')->debug(sprintf('Spent in previous budget period (%s-%s) is %s', $previousStart->format('Y-m-d'), $previousEnd->format('Y-m-d'), $spentAmount));
// what you spent in previous period PLUS the amount for the current period,
// if that is more than zero, that's the amount that will be set.
$budgetAvailable = bcadd(bcadd($budgetLimit->amount, $autoBudget->amount), $spentAmount);
$totalAmount = $autoBudget->amount;
- Log::debug(sprintf('Total amount available for current budget period is %s', $budgetAvailable));
-
+ app('log')->debug(sprintf('Total amount available for current budget period is %s', $budgetAvailable));
if (-1 !== bccomp($budgetAvailable, $totalAmount)) {
- Log::info(sprintf('There is no overspending, no need to adjust. Budget limit amount will be %s.', $budgetAvailable));
+ app('log')->info(sprintf('There is no overspending, no need to adjust. Budget limit amount will be %s.', $budgetAvailable));
// create budget limit:
$this->createBudgetLimit($autoBudget, $start, $end, $budgetAvailable);
}
if (1 !== bccomp($budgetAvailable, $totalAmount) && 1 === bccomp($budgetAvailable, '0')) {
- Log::info(sprintf('There was overspending, so the new amount will be %s.', $budgetAvailable));
+ app('log')->info(sprintf('There was overspending, so the new amount will be %s.', $budgetAvailable));
// create budget limit:
$this->createBudgetLimit($autoBudget, $start, $end, $budgetAvailable);
}
if (1 !== bccomp($budgetAvailable, $totalAmount) && -1 === bccomp($budgetAvailable, '0')) {
- Log::info('There was overspending, but so much even this period cant fix that. Reset it to 1.');
+ app('log')->info('There was overspending, but so much even this period cant fix that. Reset it to 1.');
// create budget limit:
$this->createBudgetLimit($autoBudget, $start, $end, '1');
}
- Log::debug(sprintf('Done with auto budget #%d', $autoBudget->id));
+ app('log')->debug(sprintf('Done with auto budget #%d', $autoBudget->id));
}
- /**
- * @param Carbon $date
- */
public function setDate(Carbon $date): void
{
- $newDate = clone $date;
+ $newDate = clone $date;
$newDate->startOfDay();
$this->date = $newDate;
}
diff --git a/app/Jobs/CreateRecurringTransactions.php b/app/Jobs/CreateRecurringTransactions.php
index ec00f99e90..4aa0520d94 100644
--- a/app/Jobs/CreateRecurringTransactions.php
+++ b/app/Jobs/CreateRecurringTransactions.php
@@ -42,11 +42,9 @@ use Illuminate\Foundation\Bus\Dispatchable;
use Illuminate\Queue\InteractsWithQueue;
use Illuminate\Queue\SerializesModels;
use Illuminate\Support\Collection;
-use Illuminate\Support\Facades\Log;
/**
* Class CreateRecurringTransactions.
- *
*/
class CreateRecurringTransactions implements ShouldQueue
{
@@ -68,18 +66,15 @@ class CreateRecurringTransactions implements ShouldQueue
/**
* Create a new job instance.
- *
- *
- * @param Carbon|null $date
*/
public function __construct(?Carbon $date)
{
- $newDate = new Carbon();
+ $newDate = new Carbon();
$newDate->startOfDay();
- $this->date = $newDate;
+ $this->date = $newDate;
if (null !== $date) {
- $newDate = clone $date;
+ $newDate = clone $date;
$newDate->startOfDay();
$this->date = $newDate;
}
@@ -93,12 +88,9 @@ class CreateRecurringTransactions implements ShouldQueue
$this->recurrences = new Collection();
$this->groups = new Collection();
- Log::debug(sprintf('Created new CreateRecurringTransactions("%s")', $this->date->format('Y-m-d')));
+ app('log')->debug(sprintf('Created new CreateRecurringTransactions("%s")', $this->date->format('Y-m-d')));
}
- /**
- * @return Collection
- */
public function getGroups(): Collection
{
return $this->groups;
@@ -109,25 +101,26 @@ class CreateRecurringTransactions implements ShouldQueue
*/
public function handle(): void
{
- Log::debug(sprintf('Now at start of CreateRecurringTransactions() job for %s.', $this->date->format('D d M Y')));
+ app('log')->debug(sprintf('Now at start of CreateRecurringTransactions() job for %s.', $this->date->format('D d M Y')));
// only use recurrences from database if there is no collection submitted.
if (0 !== count($this->recurrences)) {
- Log::debug('Using predetermined set of recurrences.');
+ app('log')->debug('Using predetermined set of recurrences.');
}
if (0 === count($this->recurrences)) {
- Log::debug('Grab all recurrences from the database.');
+ app('log')->debug('Grab all recurrences from the database.');
$this->recurrences = $this->repository->getAll();
}
$result = [];
$count = $this->recurrences->count();
$this->submitted = $count;
- Log::debug(sprintf('Count of collection is %d', $count));
+ app('log')->debug(sprintf('Count of collection is %d', $count));
// filter recurrences:
- $filtered = $this->filterRecurrences($this->recurrences);
- Log::debug(sprintf('Left after filtering is %d', $filtered->count()));
+ $filtered = $this->filterRecurrences($this->recurrences);
+ app('log')->debug(sprintf('Left after filtering is %d', $filtered->count()));
+
/** @var Recurrence $recurrence */
foreach ($filtered as $recurrence) {
if (!array_key_exists($recurrence->user_id, $result)) {
@@ -140,30 +133,25 @@ class CreateRecurringTransactions implements ShouldQueue
// clear cache for user
app('preferences')->setForUser($recurrence->user, 'lastActivity', microtime());
- Log::debug(sprintf('Now at recurrence #%d of user #%d', $recurrence->id, $recurrence->user_id));
- $createdReps = $this->handleRepetitions($recurrence);
- Log::debug(sprintf('Done with recurrence #%d', $recurrence->id));
+ app('log')->debug(sprintf('Now at recurrence #%d of user #%d', $recurrence->id, $recurrence->user_id));
+ $createdReps = $this->handleRepetitions($recurrence);
+ app('log')->debug(sprintf('Done with recurrence #%d', $recurrence->id));
$result[$recurrence->user_id] = $result[$recurrence->user_id]->merge($createdReps);
- $this->executed++;
+ ++$this->executed;
}
- Log::debug('Now running report thing.');
+ app('log')->debug('Now running report thing.');
// will now send email to users.
foreach ($result as $userId => $journals) {
event(new RequestedReportOnJournals($userId, $journals));
}
- Log::debug('Done with handle()');
+ app('log')->debug('Done with handle()');
// clear cache:
app('preferences')->mark();
}
- /**
- * @param Collection $recurrences
- *
- * @return Collection
- */
private function filterRecurrences(Collection $recurrences): Collection
{
return $recurrences->filter(
@@ -175,18 +163,13 @@ class CreateRecurringTransactions implements ShouldQueue
/**
* Is the info in the recurrence valid?
- *
- * @param Recurrence $recurrence
- *
- * @return bool
- *
*/
private function validRecurrence(Recurrence $recurrence): bool
{
- Log::debug(sprintf('Now filtering recurrence #%d, owned by user #%d', $recurrence->id, $recurrence->user_id));
+ app('log')->debug(sprintf('Now filtering recurrence #%d, owned by user #%d', $recurrence->id, $recurrence->user_id));
// is not active.
if (!$this->active($recurrence)) {
- Log::info(sprintf('Recurrence #%d is not active. Skipped.', $recurrence->id));
+ app('log')->info(sprintf('Recurrence #%d is not active. Skipped.', $recurrence->id));
return false;
}
@@ -194,14 +177,14 @@ class CreateRecurringTransactions implements ShouldQueue
// has repeated X times.
$journalCount = $this->repository->getJournalCount($recurrence);
if (0 !== $recurrence->repetitions && $journalCount >= $recurrence->repetitions && false === $this->force) {
- Log::info(sprintf('Recurrence #%d has run %d times, so will run no longer.', $recurrence->id, $recurrence->repetitions));
+ app('log')->info(sprintf('Recurrence #%d has run %d times, so will run no longer.', $recurrence->id, $recurrence->repetitions));
return false;
}
// is no longer running
if ($this->repeatUntilHasPassed($recurrence)) {
- Log::info(
+ app('log')->info(
sprintf(
'Recurrence #%d was set to run until %s, and today\'s date is %s. Skipped.',
$recurrence->id,
@@ -215,7 +198,7 @@ class CreateRecurringTransactions implements ShouldQueue
// first_date is in the future
if ($this->hasNotStartedYet($recurrence)) {
- Log::info(
+ app('log')->info(
sprintf(
'Recurrence #%d is set to run on %s, and today\'s date is %s. Skipped.',
$recurrence->id,
@@ -229,21 +212,17 @@ class CreateRecurringTransactions implements ShouldQueue
// already fired today (with success):
if (false === $this->force && $this->hasFiredToday($recurrence)) {
- Log::info(sprintf('Recurrence #%d has already fired today. Skipped.', $recurrence->id));
+ app('log')->info(sprintf('Recurrence #%d has already fired today. Skipped.', $recurrence->id));
return false;
}
- Log::debug('Will be included.');
+ app('log')->debug('Will be included.');
return true;
}
/**
* Return recurring transaction is active.
- *
- * @param Recurrence $recurrence
- *
- * @return bool
*/
private function active(Recurrence $recurrence): bool
{
@@ -252,10 +231,6 @@ class CreateRecurringTransactions implements ShouldQueue
/**
* Return true if the $repeat_until date is in the past.
- *
- * @param Recurrence $recurrence
- *
- * @return bool
*/
private function repeatUntilHasPassed(Recurrence $recurrence): bool
{
@@ -265,25 +240,17 @@ class CreateRecurringTransactions implements ShouldQueue
/**
* Has the recurrence started yet?
- *
- * @param Recurrence $recurrence
- *
- * @return bool
*/
private function hasNotStartedYet(Recurrence $recurrence): bool
{
$startDate = $this->getStartDate($recurrence);
- Log::debug(sprintf('Start date is %s', $startDate->format('Y-m-d')));
+ app('log')->debug(sprintf('Start date is %s', $startDate->format('Y-m-d')));
return $startDate->gt($this->date);
}
/**
* Get the start date of a recurrence.
- *
- * @param Recurrence $recurrence
- *
- * @return Carbon
*/
private function getStartDate(Recurrence $recurrence): Carbon
{
@@ -297,10 +264,6 @@ class CreateRecurringTransactions implements ShouldQueue
/**
* Has the recurrence fired today.
- *
- * @param Recurrence $recurrence
- *
- * @return bool
*/
private function hasFiredToday(Recurrence $recurrence): bool
{
@@ -311,18 +274,16 @@ class CreateRecurringTransactions implements ShouldQueue
* Separate method that will loop all repetitions and do something with it. Will return
* all created transaction journals.
*
- * @param Recurrence $recurrence
- *
- * @return Collection
* @throws DuplicateTransactionException
* @throws FireflyException
*/
private function handleRepetitions(Recurrence $recurrence): Collection
{
$collection = new Collection();
+
/** @var RecurrenceRepetition $repetition */
foreach ($recurrence->recurrenceRepetitions as $repetition) {
- Log::debug(
+ app('log')->debug(
sprintf(
'Now repeating %s with value "%s", skips every %d time(s)',
$repetition->repetition_type,
@@ -335,31 +296,27 @@ class CreateRecurringTransactions implements ShouldQueue
// add two days to $this->date, so we always include the weekend.
$includeWeekend = clone $this->date;
$includeWeekend->addDays(2);
- $occurrences = $this->repository->getOccurrencesInRange($repetition, $recurrence->first_date, $includeWeekend);
+ $occurrences = $this->repository->getOccurrencesInRange($repetition, $recurrence->first_date, $includeWeekend);
unset($includeWeekend);
- $result = $this->handleOccurrences($recurrence, $repetition, $occurrences);
- $collection = $collection->merge($result);
+ $result = $this->handleOccurrences($recurrence, $repetition, $occurrences);
+ $collection = $collection->merge($result);
}
return $collection;
}
/**
- * Check if the occurences should be executed.
+ * Check if the occurrences should be executed.
*
- * @param Recurrence $recurrence
- * @param RecurrenceRepetition $repetition
- * @param array $occurrences
- *
- * @return Collection
* @throws DuplicateTransactionException
* @throws FireflyException
*/
private function handleOccurrences(Recurrence $recurrence, RecurrenceRepetition $repetition, array $occurrences): Collection
{
$collection = new Collection();
+
/** @var Carbon $date */
foreach ($occurrences as $date) {
$result = $this->handleOccurrence($recurrence, $repetition, $date);
@@ -372,11 +329,6 @@ class CreateRecurringTransactions implements ShouldQueue
}
/**
- * @param Recurrence $recurrence
- * @param RecurrenceRepetition $repetition
- * @param Carbon $date
- *
- * @return TransactionGroup|null
* @throws DuplicateTransactionException
* @throws FireflyException
*/
@@ -386,52 +338,50 @@ class CreateRecurringTransactions implements ShouldQueue
if ($date->ne($this->date)) {
return null;
}
- Log::debug(sprintf('%s IS today (%s)', $date->format('Y-m-d'), $this->date->format('Y-m-d')));
+ app('log')->debug(sprintf('%s IS today (%s)', $date->format('Y-m-d'), $this->date->format('Y-m-d')));
// count created journals on THIS day.
- $journalCount = $this->repository->getJournalCount($recurrence, $date, $date);
+ $journalCount = $this->repository->getJournalCount($recurrence, $date, $date);
if ($journalCount > 0 && false === $this->force) {
- Log::info(sprintf('Already created %d journal(s) for date %s', $journalCount, $date->format('Y-m-d')));
+ app('log')->info(sprintf('Already created %d journal(s) for date %s', $journalCount, $date->format('Y-m-d')));
return null;
}
if ($this->repository->createdPreviously($recurrence, $date) && false === $this->force) {
- Log::info('There is a transaction already made for this date, so will not be created now');
+ app('log')->info('There is a transaction already made for this date, so will not be created now');
return null;
}
-
if ($journalCount > 0 && true === $this->force) {
app('log')->warning(sprintf('Already created %d groups for date %s but FORCED to continue.', $journalCount, $date->format('Y-m-d')));
}
// create transaction array and send to factory.
- $groupTitle = null;
- $count = $recurrence->recurrenceTransactions->count();
+ $groupTitle = null;
+ $count = $recurrence->recurrenceTransactions->count();
if ($count > 1) {
/** @var RecurrenceTransaction $first */
-
$first = $recurrence->recurrenceTransactions()->first();
$groupTitle = $first->description;
}
if (0 === $count) {
- Log::error('No transactions to be created in this recurrence. Cannot continue.');
+ app('log')->error('No transactions to be created in this recurrence. Cannot continue.');
return null;
}
- $array = [
+ $array = [
'user' => $recurrence->user_id,
'group_title' => $groupTitle,
'transactions' => $this->getTransactionData($recurrence, $repetition, $date),
];
/** @var TransactionGroup $group */
- $group = $this->groupRepository->store($array);
- $this->created++;
- Log::info(sprintf('Created new transaction group #%d', $group->id));
+ $group = $this->groupRepository->store($array);
+ ++$this->created;
+ app('log')->info(sprintf('Created new transaction group #%d', $group->id));
// trigger event:
event(new StoredTransactionGroup($group, $recurrence->apply_rules, true));
@@ -446,13 +396,6 @@ class CreateRecurringTransactions implements ShouldQueue
/**
* Get transaction information from a recurring transaction.
- *
- * @param Recurrence $recurrence
- * @param RecurrenceRepetition $repetition
- * @param Carbon $date
- *
- * @return array
- *
*/
private function getTransactionData(Recurrence $recurrence, RecurrenceRepetition $repetition, Carbon $date): array
{
@@ -460,16 +403,18 @@ class CreateRecurringTransactions implements ShouldQueue
$total = $this->repository->totalTransactions($recurrence, $repetition);
$count = $this->repository->getJournalCount($recurrence) + 1;
$transactions = $recurrence->recurrenceTransactions()->get();
+
/** @var RecurrenceTransaction $first */
- $first = $transactions->first();
- $return = [];
+ $first = $transactions->first();
+ $return = [];
+
/** @var RecurrenceTransaction $transaction */
foreach ($transactions as $index => $transaction) {
$single = [
'type' => null === $first->transactionType ? strtolower($recurrence->transactionType->type) : strtolower($first->transactionType->type),
'date' => $date,
'user' => $recurrence->user_id,
- 'currency_id' => (int)$transaction->transaction_currency_id,
+ 'currency_id' => $transaction->transaction_currency_id,
'currency_code' => null,
'description' => $first->description,
'amount' => $transaction->amount,
@@ -486,7 +431,7 @@ class CreateRecurringTransactions implements ShouldQueue
'foreign_amount' => $transaction->foreign_amount,
'reconciled' => false,
'identifier' => $index,
- 'recurrence_id' => (int)$recurrence->id,
+ 'recurrence_id' => $recurrence->id,
'order' => $index,
'notes' => (string)trans('firefly.created_from_recurrence', ['id' => $recurrence->id, 'title' => $recurrence->title]),
'tags' => $this->repository->getTags($transaction),
@@ -504,27 +449,18 @@ class CreateRecurringTransactions implements ShouldQueue
return $return;
}
- /**
- * @param Carbon $date
- */
public function setDate(Carbon $date): void
{
- $newDate = clone $date;
+ $newDate = clone $date;
$newDate->startOfDay();
$this->date = $newDate;
}
- /**
- * @param bool $force
- */
public function setForce(bool $force): void
{
$this->force = $force;
}
- /**
- * @param Collection $recurrences
- */
public function setRecurrences(Collection $recurrences): void
{
$this->recurrences = $recurrences;
diff --git a/app/Jobs/DownloadExchangeRates.php b/app/Jobs/DownloadExchangeRates.php
index 79c944537b..723d85b8a4 100644
--- a/app/Jobs/DownloadExchangeRates.php
+++ b/app/Jobs/DownloadExchangeRates.php
@@ -37,7 +37,6 @@ use Illuminate\Foundation\Bus\Dispatchable;
use Illuminate\Queue\InteractsWithQueue;
use Illuminate\Queue\SerializesModels;
use Illuminate\Support\Collection;
-use Illuminate\Support\Facades\Log;
/**
* Class DownloadExchangeRates
@@ -56,9 +55,6 @@ class DownloadExchangeRates implements ShouldQueue
/**
* Create a new job instance.
- *
- *
- * @param Carbon|null $date
*/
public function __construct(?Carbon $date)
{
@@ -67,14 +63,14 @@ class DownloadExchangeRates implements ShouldQueue
// get all users:
/** @var UserRepositoryInterface $userRepository */
- $userRepository = app(UserRepositoryInterface::class);
- $this->users = $userRepository->all();
+ $userRepository = app(UserRepositoryInterface::class);
+ $this->users = $userRepository->all();
if (null !== $date) {
- $newDate = clone $date;
+ $newDate = clone $date;
$newDate->startOfDay();
$this->date = $newDate;
- Log::debug(sprintf('Created new DownloadExchangeRates("%s")', $this->date->format('Y-m-d')));
+ app('log')->debug(sprintf('Created new DownloadExchangeRates("%s")', $this->date->format('Y-m-d')));
}
}
@@ -83,8 +79,8 @@ class DownloadExchangeRates implements ShouldQueue
*/
public function handle(): void
{
- Log::debug('Now in handle()');
- $currencies = $this->repository->get();
+ app('log')->debug('Now in handle()');
+ $currencies = $this->repository->getCompleteSet();
/** @var TransactionCurrency $currency */
foreach ($currencies as $currency) {
@@ -93,114 +89,99 @@ class DownloadExchangeRates implements ShouldQueue
}
/**
- * @param TransactionCurrency $currency
- *
- * @return void
* @throws GuzzleException
*/
private function downloadRates(TransactionCurrency $currency): void
{
- Log::debug(sprintf('Now downloading new exchange rates for currency %s.', $currency->code));
- $base = sprintf('%s/%s/%s', (string)config('cer.url'), $this->date->year, $this->date->isoWeek);
- $client = new Client();
- $url = sprintf('%s/%s.json', $base, $currency->code);
+ app('log')->debug(sprintf('Now downloading new exchange rates for currency %s.', $currency->code));
+ $base = sprintf('%s/%s/%s', (string)config('cer.url'), $this->date->year, $this->date->isoWeek);
+ $client = new Client();
+ $url = sprintf('%s/%s.json', $base, $currency->code);
+
try {
$res = $client->get($url);
} catch (RequestException $e) {
app('log')->warning(sprintf('Trying to grab "%s" resulted in error "%d".', $url, $e->getMessage()));
+
return;
}
$statusCode = $res->getStatusCode();
if (200 !== $statusCode) {
app('log')->warning(sprintf('Trying to grab "%s" resulted in status code %d.', $url, $statusCode));
+
return;
}
- $body = (string)$res->getBody();
- $json = json_decode($body, true);
+ $body = (string)$res->getBody();
+ $json = json_decode($body, true);
if (false === $json || null === $json) {
app('log')->warning(sprintf('Trying to grab "%s" resulted in bad JSON.', $url));
+
+ return;
+ }
+ $date = Carbon::createFromFormat('Y-m-d', $json['date'], config('app.timezone'));
+ if (false === $date) {
return;
}
- $date = Carbon::createFromFormat('Y-m-d', $json['date'], config('app.timezone'));
$this->saveRates($currency, $date, $json['rates']);
}
- /**
- * @param TransactionCurrency $currency
- * @param Carbon $date
- * @param array $rates
- *
- * @return void
- */
private function saveRates(TransactionCurrency $currency, Carbon $date, array $rates): void
{
foreach ($rates as $code => $rate) {
$to = $this->getCurrency($code);
if (null === $to) {
- Log::debug(sprintf('Currency %s is not in use, do not save rate.', $code));
+ app('log')->debug(sprintf('Currency %s is not in use, do not save rate.', $code));
+
continue;
}
- Log::debug(sprintf('Currency %s is in use.', $code));
+ app('log')->debug(sprintf('Currency %s is in use.', $code));
$this->saveRate($currency, $to, $date, $rate);
}
}
- /**
- * @param string $code
- *
- * @return TransactionCurrency|null
- */
private function getCurrency(string $code): ?TransactionCurrency
{
// if we have it already, don't bother searching for it again.
if (array_key_exists($code, $this->active)) {
- Log::debug(sprintf('Already know what the result is of searching for %s', $code));
+ app('log')->debug(sprintf('Already know what the result is of searching for %s', $code));
+
return $this->active[$code];
}
// find it in the database.
- $currency = $this->repository->findByCode($code);
+ $currency = $this->repository->findByCode($code);
if (null === $currency) {
- Log::debug(sprintf('Did not find currency %s.', $code));
+ app('log')->debug(sprintf('Did not find currency %s.', $code));
$this->active[$code] = null;
+
return null;
}
if (false === $currency->enabled) {
- Log::debug(sprintf('Currency %s is not enabled.', $code));
+ app('log')->debug(sprintf('Currency %s is not enabled.', $code));
$this->active[$code] = null;
+
return null;
}
- Log::debug(sprintf('Currency %s is enabled.', $code));
+ app('log')->debug(sprintf('Currency %s is enabled.', $code));
$this->active[$code] = $currency;
return $currency;
}
- /**
- * @param TransactionCurrency $from
- * @param TransactionCurrency $to
- * @param Carbon $date
- * @param float $rate
- *
- * @return void
- */
private function saveRate(TransactionCurrency $from, TransactionCurrency $to, Carbon $date, float $rate): void
{
foreach ($this->users as $user) {
$this->repository->setUser($user);
$existing = $this->repository->getExchangeRate($from, $to, $date);
if (null === $existing) {
- Log::debug(sprintf('Saved rate from %s to %s for user #%d.', $from->code, $to->code, $user->id));
+ app('log')->debug(sprintf('Saved rate from %s to %s for user #%d.', $from->code, $to->code, $user->id));
$this->repository->setExchangeRate($from, $to, $date, $rate);
}
}
}
- /**
- * @param Carbon $date
- */
public function setDate(Carbon $date): void
{
- $newDate = clone $date;
+ $newDate = clone $date;
$newDate->startOfDay();
$this->date = $newDate;
}
diff --git a/app/Jobs/MailError.php b/app/Jobs/MailError.php
index bb4b916b7d..c06a617d03 100644
--- a/app/Jobs/MailError.php
+++ b/app/Jobs/MailError.php
@@ -23,20 +23,14 @@ declare(strict_types=1);
namespace FireflyIII\Jobs;
-use Exception;
-use FireflyIII\Exceptions\FireflyException;
use Illuminate\Contracts\Queue\ShouldQueue;
use Illuminate\Mail\Message;
use Illuminate\Queue\InteractsWithQueue;
use Illuminate\Queue\SerializesModels;
-use Illuminate\Support\Facades\Log;
-use Mail;
use Symfony\Component\Mailer\Exception\TransportException;
/**
* Class MailError.
- *
-
*/
class MailError extends Job implements ShouldQueue
{
@@ -50,11 +44,6 @@ class MailError extends Job implements ShouldQueue
/**
* MailError constructor.
- *
- * @param array $userData
- * @param string $destination
- * @param string $ipAddress
- * @param array $exceptionData
*/
public function __construct(array $userData, string $destination, string $ipAddress, array $exceptionData)
{
@@ -63,17 +52,15 @@ class MailError extends Job implements ShouldQueue
$this->ipAddress = $ipAddress;
$this->exception = $exceptionData;
$debug = $exceptionData;
- unset($debug['stackTrace']);
- unset($debug['headers']);
- Log::error(sprintf('Exception is: %s', json_encode($debug)));
+ unset($debug['stackTrace'], $debug['headers']);
+
+ app('log')->error(sprintf('Exception is: %s', json_encode($debug)));
}
/**
* Execute the job.
- *
- * @throws FireflyException
*/
- public function handle()
+ public function handle(): void
{
$email = (string)config('firefly.site_owner');
$args = $this->exception;
@@ -81,29 +68,31 @@ class MailError extends Job implements ShouldQueue
$args['user'] = $this->userData;
$args['ip'] = $this->ipAddress;
$args['token'] = config('firefly.ipinfo_token');
- if ($this->attempts() < 3 && strlen($email) > 0) {
+ if ($this->attempts() < 3 && '' !== $email) {
try {
- Mail::send(
+ \Mail::send(
['emails.error-html', 'emails.error-text'],
$args,
- function (Message $message) use ($email) {
+ static function (Message $message) use ($email): void {
if ('mail@example.com' !== $email) {
$message->to($email, $email)->subject((string)trans('email.error_subject'));
}
}
);
- } catch (Exception | TransportException $e) { // intentional generic exception
+ } catch (\Exception|TransportException $e) { // @phpstan-ignore-line
$message = $e->getMessage();
if (str_contains($message, 'Bcc')) {
- Log::warning('[Bcc] Could not email or log the error. Please validate your email settings, use the .env.example file as a guide.');
+ app('log')->warning('[Bcc] Could not email or log the error. Please validate your email settings, use the .env.example file as a guide.');
+
return;
}
if (str_contains($message, 'RFC 2822')) {
- Log::warning('[RFC] Could not email or log the error. Please validate your email settings, use the .env.example file as a guide.');
+ app('log')->warning('[RFC] Could not email or log the error. Please validate your email settings, use the .env.example file as a guide.');
+
return;
}
- Log::error($e->getMessage());
- Log::error($e->getTraceAsString());
+ app('log')->error($e->getMessage());
+ app('log')->error($e->getTraceAsString());
}
}
}
diff --git a/app/Jobs/SendWebhookMessage.php b/app/Jobs/SendWebhookMessage.php
index 42dfdf5d46..b656b58df3 100644
--- a/app/Jobs/SendWebhookMessage.php
+++ b/app/Jobs/SendWebhookMessage.php
@@ -31,7 +31,6 @@ use Illuminate\Contracts\Queue\ShouldQueue;
use Illuminate\Foundation\Bus\Dispatchable;
use Illuminate\Queue\InteractsWithQueue;
use Illuminate\Queue\SerializesModels;
-use Illuminate\Support\Facades\Log;
/**
* Class SendWebhookMessage
@@ -47,8 +46,6 @@ class SendWebhookMessage implements ShouldQueue
/**
* Create a new job instance.
- *
- * @param WebhookMessage $message
*/
public function __construct(WebhookMessage $message)
{
@@ -57,12 +54,10 @@ class SendWebhookMessage implements ShouldQueue
/**
* Execute the job.
- *
- * @return void
*/
public function handle(): void
{
- Log::debug(sprintf('Now handling webhook message #%d', $this->message->id));
+ app('log')->debug(sprintf('Now handling webhook message #%d', $this->message->id));
// send job!
$sender = app(WebhookSenderInterface::class);
$sender->setMessage($this->message);
diff --git a/app/Jobs/WarnAboutBills.php b/app/Jobs/WarnAboutBills.php
index 7438d9f760..e7f1915dfd 100644
--- a/app/Jobs/WarnAboutBills.php
+++ b/app/Jobs/WarnAboutBills.php
@@ -32,7 +32,6 @@ use Illuminate\Contracts\Queue\ShouldQueue;
use Illuminate\Foundation\Bus\Dispatchable;
use Illuminate\Queue\InteractsWithQueue;
use Illuminate\Queue\SerializesModels;
-use Illuminate\Support\Facades\Log;
/**
* Class WarnAboutBills
@@ -49,25 +48,22 @@ class WarnAboutBills implements ShouldQueue
/**
* Create a new job instance.
- *
- *
- * @param Carbon|null $date
*/
public function __construct(?Carbon $date)
{
- $newDate = new Carbon();
+ $newDate = new Carbon();
$newDate->startOfDay();
- $this->date = $newDate;
+ $this->date = $newDate;
if (null !== $date) {
- $newDate = clone $date;
+ $newDate = clone $date;
$newDate->startOfDay();
$this->date = $newDate;
}
$this->force = false;
- Log::debug(sprintf('Created new WarnAboutBills("%s")', $this->date->format('Y-m-d')));
+ app('log')->debug(sprintf('Created new WarnAboutBills("%s")', $this->date->format('Y-m-d')));
}
/**
@@ -75,11 +71,12 @@ class WarnAboutBills implements ShouldQueue
*/
public function handle(): void
{
- Log::debug(sprintf('Now at start of WarnAboutBills() job for %s.', $this->date->format('D d M Y')));
+ app('log')->debug(sprintf('Now at start of WarnAboutBills() job for %s.', $this->date->format('D d M Y')));
$bills = Bill::all();
+
/** @var Bill $bill */
foreach ($bills as $bill) {
- Log::debug(sprintf('Now checking bill #%d ("%s")', $bill->id, $bill->name));
+ app('log')->debug(sprintf('Now checking bill #%d ("%s")', $bill->id, $bill->name));
if ($this->hasDateFields($bill)) {
if ($this->needsWarning($bill, 'end_date')) {
$this->sendWarning($bill, 'end_date');
@@ -89,89 +86,65 @@ class WarnAboutBills implements ShouldQueue
}
}
}
- Log::debug('Done with handle()');
+ app('log')->debug('Done with handle()');
// clear cache:
app('preferences')->mark();
}
- /**
- * @param Bill $bill
- *
- * @return bool
- */
private function hasDateFields(Bill $bill): bool
{
if (false === $bill->active) {
- Log::debug('Bill is not active.');
+ app('log')->debug('Bill is not active.');
+
return false;
}
if (null === $bill->end_date && null === $bill->extension_date) {
- Log::debug('Bill has no date fields.');
+ app('log')->debug('Bill has no date fields.');
+
return false;
}
+
return true;
}
- /**
- * @param Bill $bill
- * @param string $field
- *
- * @return bool
- */
private function needsWarning(Bill $bill, string $field): bool
{
- if (null === $bill->$field) {
+ if (null === $bill->{$field}) {
return false;
}
$diff = $this->getDiff($bill, $field);
$list = config('firefly.bill_reminder_periods');
- Log::debug(sprintf('Difference in days for field "%s" ("%s") is %d day(s)', $field, $bill->$field->format('Y-m-d'), $diff));
+ app('log')->debug(sprintf('Difference in days for field "%s" ("%s") is %d day(s)', $field, $bill->{$field}->format('Y-m-d'), $diff));
if (in_array($diff, $list, true)) {
return true;
}
+
return false;
}
- /**
- * @param Bill $bill
- * @param string $field
- *
- * @return int
- */
private function getDiff(Bill $bill, string $field): int
{
$today = clone $this->date;
- $carbon = clone $bill->$field;
+ $carbon = clone $bill->{$field};
+
return $today->diffInDays($carbon, false);
}
- /**
- * @param Bill $bill
- * @param string $field
- *
- * @return void
- */
private function sendWarning(Bill $bill, string $field): void
{
$diff = $this->getDiff($bill, $field);
- Log::debug('Will now send warning!');
+ app('log')->debug('Will now send warning!');
event(new WarnUserAboutBill($bill, $field, $diff));
}
- /**
- * @param Carbon $date
- */
public function setDate(Carbon $date): void
{
- $newDate = clone $date;
+ $newDate = clone $date;
$newDate->startOfDay();
$this->date = $newDate;
}
- /**
- * @param bool $force
- */
public function setForce(bool $force): void
{
$this->force = $force;
diff --git a/app/Mail/AccessTokenCreatedMail.php b/app/Mail/AccessTokenCreatedMail.php
index 185300fa13..e908864838 100644
--- a/app/Mail/AccessTokenCreatedMail.php
+++ b/app/Mail/AccessTokenCreatedMail.php
@@ -29,8 +29,6 @@ use Illuminate\Queue\SerializesModels;
/**
* Class AccessTokenCreatedMail
- *
-
*/
class AccessTokenCreatedMail extends Mailable
{
@@ -40,9 +38,7 @@ class AccessTokenCreatedMail extends Mailable
/**
* AccessTokenCreatedMail constructor.
*/
- public function __construct()
- {
- }
+ public function __construct() {}
/**
* Build the message.
@@ -53,6 +49,7 @@ class AccessTokenCreatedMail extends Mailable
{
return $this
->markdown('emails.token-created')
- ->subject((string)trans('email.access_token_created_subject'));
+ ->subject((string)trans('email.access_token_created_subject'))
+ ;
}
}
diff --git a/app/Mail/AdminTestMail.php b/app/Mail/AdminTestMail.php
index 502f015361..1971dce7dc 100644
--- a/app/Mail/AdminTestMail.php
+++ b/app/Mail/AdminTestMail.php
@@ -31,8 +31,6 @@ use Illuminate\Queue\SerializesModels;
* Class AdminTestMail.
*
* Sends a test mail to administrators.
- *
-
*/
class AdminTestMail extends Mailable
{
@@ -44,9 +42,7 @@ class AdminTestMail extends Mailable
/**
* AdminTestMail constructor.
*/
- public function __construct()
- {
- }
+ public function __construct() {}
/**
* Build the message.
@@ -57,6 +53,7 @@ class AdminTestMail extends Mailable
{
return $this
->markdown('emails.admin-test')
- ->subject((string)trans('email.admin_test_subject'));
+ ->subject((string)trans('email.admin_test_subject'))
+ ;
}
}
diff --git a/app/Mail/BillWarningMail.php b/app/Mail/BillWarningMail.php
index e1811e9ebc..588772148f 100644
--- a/app/Mail/BillWarningMail.php
+++ b/app/Mail/BillWarningMail.php
@@ -43,10 +43,6 @@ class BillWarningMail extends Mailable
/**
* ConfirmEmailChangeMail constructor.
- *
- * @param Bill $bill
- * @param string $field
- * @param int $diff
*/
public function __construct(Bill $bill, string $field, int $diff)
{
@@ -69,6 +65,7 @@ class BillWarningMail extends Mailable
return $this
->markdown('emails.bill-warning')
- ->subject($subject);
+ ->subject($subject)
+ ;
}
}
diff --git a/app/Mail/ConfirmEmailChangeMail.php b/app/Mail/ConfirmEmailChangeMail.php
index 452ce6e4e7..d4346eff6c 100644
--- a/app/Mail/ConfirmEmailChangeMail.php
+++ b/app/Mail/ConfirmEmailChangeMail.php
@@ -31,8 +31,6 @@ use Illuminate\Queue\SerializesModels;
* Class ConfirmEmailChangeMail
*
* Sends message to new address to confirm change.
- *
-
*/
class ConfirmEmailChangeMail extends Mailable
{
@@ -45,10 +43,6 @@ class ConfirmEmailChangeMail extends Mailable
/**
* ConfirmEmailChangeMail constructor.
- *
- * @param string $newEmail
- * @param string $oldEmail
- * @param string $url
*/
public function __construct(string $newEmail, string $oldEmail, string $url)
{
@@ -65,9 +59,10 @@ class ConfirmEmailChangeMail extends Mailable
public function build(): self
{
return $this
- //->view('emails.confirm-email-change-html')
- //->text('emails.confirm-email-change-text')
+ // ->view('emails.confirm-email-change-html')
+ // ->text('emails.confirm-email-change-text')
->markdown('emails.confirm-email-change')
- ->subject((string)trans('email.email_change_subject'));
+ ->subject((string)trans('email.email_change_subject'))
+ ;
}
}
diff --git a/app/Mail/InvitationMail.php b/app/Mail/InvitationMail.php
index faa1fa8582..151e7d423a 100644
--- a/app/Mail/InvitationMail.php
+++ b/app/Mail/InvitationMail.php
@@ -43,17 +43,13 @@ class InvitationMail extends Mailable
/**
* OAuthTokenCreatedMail constructor.
- *
- * @param string $invitee
- * @param string $admin
- * @param string $url
*/
public function __construct(string $invitee, string $admin, string $url)
{
$this->invitee = $invitee;
$this->admin = $admin;
$this->url = $url;
- $this->host = parse_url($url, PHP_URL_HOST);
+ $this->host = (string)parse_url($url, PHP_URL_HOST);
}
/**
@@ -65,6 +61,7 @@ class InvitationMail extends Mailable
{
return $this
->markdown('emails.invitation')
- ->subject((string)trans('email.invite_user_subject'));
+ ->subject((string)trans('email.invite_user_subject'))
+ ;
}
}
diff --git a/app/Mail/NewIPAddressWarningMail.php b/app/Mail/NewIPAddressWarningMail.php
index bddb54d960..e8fdf5ea86 100644
--- a/app/Mail/NewIPAddressWarningMail.php
+++ b/app/Mail/NewIPAddressWarningMail.php
@@ -28,7 +28,6 @@ use FireflyIII\Exceptions\FireflyException;
use Illuminate\Bus\Queueable;
use Illuminate\Mail\Mailable;
use Illuminate\Queue\SerializesModels;
-use Illuminate\Support\Facades\Log;
/**
* Class NewIPAddressWarningMail
@@ -44,8 +43,6 @@ class NewIPAddressWarningMail extends Mailable
/**
* OAuthTokenCreatedMail constructor.
- *
- * @param string $ipAddress
*/
public function __construct(string $ipAddress)
{
@@ -61,10 +58,11 @@ class NewIPAddressWarningMail extends Mailable
{
$this->time = now(config('app.timezone'))->isoFormat((string)trans('config.date_time_js'));
$this->host = '';
+
try {
$hostName = app('steam')->getHostName($this->ipAddress);
} catch (FireflyException $e) {
- Log::error($e->getMessage());
+ app('log')->error($e->getMessage());
$hostName = $this->ipAddress;
}
if ($hostName !== $this->ipAddress) {
@@ -73,6 +71,7 @@ class NewIPAddressWarningMail extends Mailable
return $this
->markdown('emails.new-ip')
- ->subject((string)trans('email.login_from_new_ip'));
+ ->subject((string)trans('email.login_from_new_ip'))
+ ;
}
}
diff --git a/app/Mail/OAuthTokenCreatedMail.php b/app/Mail/OAuthTokenCreatedMail.php
index 2c75fa3d36..9ccb95942d 100644
--- a/app/Mail/OAuthTokenCreatedMail.php
+++ b/app/Mail/OAuthTokenCreatedMail.php
@@ -30,8 +30,6 @@ use Laravel\Passport\Client;
/**
* Class OAuthTokenCreatedMail
- *
-
*/
class OAuthTokenCreatedMail extends Mailable
{
@@ -42,8 +40,6 @@ class OAuthTokenCreatedMail extends Mailable
/**
* OAuthTokenCreatedMail constructor.
- *
- * @param Client $client
*/
public function __construct(Client $client)
{
@@ -59,6 +55,7 @@ class OAuthTokenCreatedMail extends Mailable
{
return $this
->markdown('emails.oauth-client-created')
- ->subject((string)trans('email.oauth_created_subject'));
+ ->subject((string)trans('email.oauth_created_subject'))
+ ;
}
}
diff --git a/app/Mail/RegisteredUser.php b/app/Mail/RegisteredUser.php
index d460047eed..8659c8e3f9 100644
--- a/app/Mail/RegisteredUser.php
+++ b/app/Mail/RegisteredUser.php
@@ -31,8 +31,6 @@ use Illuminate\Queue\SerializesModels;
* Sends newly registered user an email message.
*
* Class RegisteredUser
- *
-
*/
class RegisteredUser extends Mailable
{
@@ -43,8 +41,6 @@ class RegisteredUser extends Mailable
/**
* Create a new message instance.
- *
- * @param string $address
*/
public function __construct(string $address)
{
@@ -60,6 +56,7 @@ class RegisteredUser extends Mailable
{
return $this
->markdown('emails.registered')
- ->subject((string)trans('email.registered_subject'));
+ ->subject((string)trans('email.registered_subject'))
+ ;
}
}
diff --git a/app/Mail/ReportNewJournalsMail.php b/app/Mail/ReportNewJournalsMail.php
index 62e6a12cd4..ff7515ff68 100644
--- a/app/Mail/ReportNewJournalsMail.php
+++ b/app/Mail/ReportNewJournalsMail.php
@@ -35,8 +35,6 @@ use Illuminate\Support\Collection;
* Class ReportNewJournalsMail.
*
* Sends a list of newly created journals to the user.
- *
-
*/
class ReportNewJournalsMail extends Mailable
{
@@ -48,8 +46,6 @@ class ReportNewJournalsMail extends Mailable
/**
* ConfirmEmailChangeMail constructor.
- *
- * @param Collection $groups
*/
public function __construct(Collection $groups)
{
@@ -67,11 +63,11 @@ class ReportNewJournalsMail extends Mailable
return $this
->markdown('emails.report-new-journals')
- ->subject((string)trans_choice('email.new_journals_subject', $this->groups->count()));
+ ->subject(trans_choice('email.new_journals_subject', $this->groups->count()))
+ ;
}
/**
- * @return void
* @throws FireflyException
*/
private function transform(): void
diff --git a/app/Mail/RequestedNewPassword.php b/app/Mail/RequestedNewPassword.php
index f91c84ceef..0be46c5251 100644
--- a/app/Mail/RequestedNewPassword.php
+++ b/app/Mail/RequestedNewPassword.php
@@ -30,8 +30,6 @@ use Illuminate\Queue\SerializesModels;
/**
* Sends user link for new password.
* Class RequestedNewPassword
- *
-
*/
class RequestedNewPassword extends Mailable
{
@@ -42,8 +40,6 @@ class RequestedNewPassword extends Mailable
/**
* RequestedNewPassword constructor.
- *
- * @param string $url
*/
public function __construct(string $url)
{
@@ -59,6 +55,7 @@ class RequestedNewPassword extends Mailable
{
return $this
->markdown('emails.password')
- ->subject((string)trans('email.reset_pw_subject'));
+ ->subject((string)trans('email.reset_pw_subject'))
+ ;
}
}
diff --git a/app/Mail/UndoEmailChangeMail.php b/app/Mail/UndoEmailChangeMail.php
index 6f6a202997..70d243685a 100644
--- a/app/Mail/UndoEmailChangeMail.php
+++ b/app/Mail/UndoEmailChangeMail.php
@@ -29,8 +29,6 @@ use Illuminate\Queue\SerializesModels;
/**
* Class UndoEmailChangeMail
- *
-
*/
class UndoEmailChangeMail extends Mailable
{
@@ -43,10 +41,6 @@ class UndoEmailChangeMail extends Mailable
/**
* UndoEmailChangeMail constructor.
- *
- * @param string $newEmail
- * @param string $oldEmail
- * @param string $url
*/
public function __construct(string $newEmail, string $oldEmail, string $url)
{
@@ -64,6 +58,7 @@ class UndoEmailChangeMail extends Mailable
{
return $this
->markdown('emails.undo-email-change')
- ->subject((string)trans('email.email_change_subject'));
+ ->subject((string)trans('email.email_change_subject'))
+ ;
}
}
diff --git a/app/Models/Account.php b/app/Models/Account.php
index c44881ef38..9736462044 100644
--- a/app/Models/Account.php
+++ b/app/Models/Account.php
@@ -25,6 +25,8 @@ namespace FireflyIII\Models;
use Carbon\Carbon;
use Eloquent;
+use FireflyIII\Support\Models\ReturnsIntegerIdTrait;
+use FireflyIII\Support\Models\ReturnsIntegerUserIdTrait;
use FireflyIII\User;
use Illuminate\Database\Eloquent\Builder as EloquentBuilder;
use Illuminate\Database\Eloquent\Casts\Attribute;
@@ -42,40 +44,41 @@ use Symfony\Component\HttpKernel\Exception\NotFoundHttpException;
/**
* Class Account
*
- * @property int $id
- * @property \Illuminate\Support\Carbon|null $created_at
- * @property \Illuminate\Support\Carbon|null $updated_at
- * @property \Illuminate\Support\Carbon|null $deleted_at
- * @property int $user_id
- * @property int $account_type_id
- * @property string $name
- * @property string|null $virtual_balance
- * @property string|null $iban
- * @property bool $active
- * @property bool $encrypted
- * @property int $order
- * @property-read Collection|AccountMeta[] $accountMeta
- * @property-read int|null $account_meta_count
- * @property AccountType $accountType
- * @property-read Collection|Attachment[] $attachments
- * @property-read int|null $attachments_count
- * @property-read string $account_number
- * @property-read string $edit_name
- * @property-read Collection|Location[] $locations
- * @property-read int|null $locations_count
- * @property-read Collection|Note[] $notes
- * @property-read int|null $notes_count
- * @property-read Collection|ObjectGroup[] $objectGroups
- * @property-read int|null $object_groups_count
- * @property-read Collection|PiggyBank[] $piggyBanks
- * @property-read int|null $piggy_banks_count
- * @property-read Collection|Transaction[] $transactions
- * @property-read int|null $transactions_count
- * @property-read User $user
+ * @property int $id
+ * @property null|Carbon $created_at
+ * @property null|Carbon $updated_at
+ * @property null|Carbon $deleted_at
+ * @property int $user_id
+ * @property int $account_type_id
+ * @property string $name
+ * @property string $virtual_balance
+ * @property null|string $iban
+ * @property bool $active
+ * @property bool $encrypted
+ * @property int $order
+ * @property AccountMeta[]|Collection $accountMeta
+ * @property null|int $account_meta_count
+ * @property AccountType $accountType
+ * @property Attachment[]|Collection $attachments
+ * @property null|int $attachments_count
+ * @property string $account_number
+ * @property string $edit_name
+ * @property Collection|Location[] $locations
+ * @property null|int $locations_count
+ * @property Collection|Note[] $notes
+ * @property null|int $notes_count
+ * @property Collection|ObjectGroup[] $objectGroups
+ * @property null|int $object_groups_count
+ * @property Collection|PiggyBank[] $piggyBanks
+ * @property null|int $piggy_banks_count
+ * @property Collection|Transaction[] $transactions
+ * @property null|int $transactions_count
+ * @property User $user
+ *
* @method static EloquentBuilder|Account accountTypeIn($types)
* @method static EloquentBuilder|Account newModelQuery()
* @method static EloquentBuilder|Account newQuery()
- * @method static Builder|Account onlyTrashed()
+ * @method static Builder|Account onlyTrashed()
* @method static EloquentBuilder|Account query()
* @method static EloquentBuilder|Account whereAccountTypeId($value)
* @method static EloquentBuilder|Account whereActive($value)
@@ -89,89 +92,82 @@ use Symfony\Component\HttpKernel\Exception\NotFoundHttpException;
* @method static EloquentBuilder|Account whereUpdatedAt($value)
* @method static EloquentBuilder|Account whereUserId($value)
* @method static EloquentBuilder|Account whereVirtualBalance($value)
- * @method static Builder|Account withTrashed()
- * @method static Builder|Account withoutTrashed()
- * @property Carbon $lastActivityDate
- * @property string $startBalance
- * @property string $endBalance
- * @property string $difference
- * @property string $interest
- * @property string $interestPeriod
- * @property string $accountTypeString
- * @property Location $location
- * @property string $liability_direction
- * @property string $current_debt
- * @property int|null $user_group_id
+ * @method static Builder|Account withTrashed()
+ * @method static Builder|Account withoutTrashed()
+ *
+ * @property Carbon $lastActivityDate
+ * @property string $startBalance
+ * @property string $endBalance
+ * @property string $difference
+ * @property string $interest
+ * @property string $interestPeriod
+ * @property string $accountTypeString
+ * @property Location $location
+ * @property string $liability_direction
+ * @property string $current_debt
+ * @property int $user_group_id
+ *
* @method static EloquentBuilder|Account whereUserGroupId($value)
+ *
+ * @property null|UserGroup $userGroup
+ *
* @mixin Eloquent
*/
class Account extends Model
{
- use SoftDeletes;
use HasFactory;
+ use ReturnsIntegerIdTrait;
+ use ReturnsIntegerUserIdTrait;
+ use SoftDeletes;
- /**
- * The attributes that should be casted to native types.
- *
- * @var array
- */
protected $casts
- = [
- 'created_at' => 'datetime',
- 'updated_at' => 'datetime',
- 'user_id' => 'integer',
- 'deleted_at' => 'datetime',
- 'active' => 'boolean',
- 'encrypted' => 'boolean',
- ];
- /** @var array Fields that can be filled */
- protected $fillable = ['user_id', 'user_group_id', 'account_type_id', 'name', 'active', 'virtual_balance', 'iban'];
- /** @var array Hidden from view */
- protected $hidden = ['encrypted'];
+ = [
+ 'created_at' => 'datetime',
+ 'updated_at' => 'datetime',
+ 'user_id' => 'integer',
+ 'deleted_at' => 'datetime',
+ 'active' => 'boolean',
+ 'encrypted' => 'boolean',
+ ];
+
+ protected $fillable = ['user_id', 'user_group_id', 'account_type_id', 'name', 'active', 'virtual_balance', 'iban'];
+
+ protected $hidden = ['encrypted'];
private bool $joinedAccountTypes = false;
/**
* Route binder. Converts the key in the URL to the specified object (or throw 404).
*
- * @param string $value
- *
- * @return Account
* @throws NotFoundHttpException
*/
- public static function routeBinder(string $value): Account
+ public static function routeBinder(string $value): self
{
if (auth()->check()) {
$accountId = (int)$value;
+
/** @var User $user */
- $user = auth()->user();
- /** @var Account $account */
- $account = $user->accounts()->with(['accountType'])->find($accountId);
+ $user = auth()->user();
+
+ /** @var null|Account $account */
+ $account = $user->accounts()->with(['accountType'])->find($accountId);
if (null !== $account) {
return $account;
}
}
+
throw new NotFoundHttpException();
}
- /**
- * @return BelongsTo
- */
public function user(): BelongsTo
{
return $this->belongsTo(User::class);
}
- /**
- * @return BelongsTo
- */
public function accountType(): BelongsTo
{
return $this->belongsTo(AccountType::class);
}
- /**
- * @return MorphMany
- */
public function attachments(): MorphMany
{
return $this->morphMany(Attachment::class, 'attachable');
@@ -179,30 +175,23 @@ class Account extends Model
/**
* Get the account number.
- *
- * @return string
*/
public function getAccountNumberAttribute(): string
{
- /** @var AccountMeta $metaValue */
+ /** @var null|AccountMeta $metaValue */
$metaValue = $this->accountMeta()
- ->where('name', 'account_number')
- ->first();
+ ->where('name', 'account_number')
+ ->first()
+ ;
- return $metaValue ? $metaValue->data : '';
+ return null !== $metaValue ? $metaValue->data : '';
}
- /**
- * @return HasMany
- */
public function accountMeta(): HasMany
{
return $this->hasMany(AccountMeta::class);
}
- /**
- * @return string
- */
public function getEditNameAttribute(): string
{
$name = $this->name;
@@ -214,9 +203,6 @@ class Account extends Model
return $name;
}
- /**
- * @return MorphMany
- */
public function locations(): MorphMany
{
return $this->morphMany(Location::class, 'locatable');
@@ -238,19 +224,11 @@ class Account extends Model
return $this->morphToMany(ObjectGroup::class, 'object_groupable');
}
- /**
- * @return HasMany
- */
public function piggyBanks(): HasMany
{
return $this->hasMany(PiggyBank::class);
}
- /**
- *
- * @param EloquentBuilder $query
- * @param array $types
- */
public function scopeAccountTypeIn(EloquentBuilder $query, array $types): void
{
if (false === $this->joinedAccountTypes) {
@@ -260,38 +238,56 @@ class Account extends Model
$query->whereIn('account_types.type', $types);
}
- /**
- *
- * @param mixed $value
- *
-
- */
public function setVirtualBalanceAttribute(mixed $value): void
{
- $value = (string)$value;
+ $value = (string)$value;
if ('' === $value) {
$value = null;
}
$this->attributes['virtual_balance'] = $value;
}
- /**
- * @return HasMany
- */
public function transactions(): HasMany
{
return $this->hasMany(Transaction::class);
}
+ public function userGroup(): BelongsTo
+ {
+ return $this->belongsTo(UserGroup::class);
+ }
+
+ protected function accountId(): Attribute
+ {
+ return Attribute::make(
+ get: static fn ($value) => (int)$value,
+ );
+ }
+
+ /**
+ * Get the user ID
+ */
+ protected function accountTypeId(): Attribute
+ {
+ return Attribute::make(
+ get: static fn ($value) => (int)$value,
+ );
+ }
+
+ protected function order(): Attribute
+ {
+ return Attribute::make(
+ get: static fn ($value) => (int)$value,
+ );
+ }
+
/**
* Get the virtual balance
- *
- * @return Attribute
*/
protected function virtualBalance(): Attribute
{
return Attribute::make(
- get: fn ($value) => (string)$value,
+ get: static fn ($value) => (string)$value,
);
}
}
diff --git a/app/Models/AccountMeta.php b/app/Models/AccountMeta.php
index 6d7a31aaa2..799543776c 100644
--- a/app/Models/AccountMeta.php
+++ b/app/Models/AccountMeta.php
@@ -23,22 +23,24 @@ declare(strict_types=1);
namespace FireflyIII\Models;
+use Carbon\Carbon;
use Eloquent;
+use FireflyIII\Support\Models\ReturnsIntegerIdTrait;
use Illuminate\Database\Eloquent\Builder;
use Illuminate\Database\Eloquent\Model;
use Illuminate\Database\Eloquent\Relations\BelongsTo;
-use Illuminate\Support\Carbon;
/**
* Class AccountMeta
*
- * @property int $id
- * @property Carbon|null $created_at
- * @property Carbon|null $updated_at
- * @property int $account_id
- * @property string $name
- * @property mixed $data
- * @property-read Account $account
+ * @property int $id
+ * @property null|Carbon $created_at
+ * @property null|Carbon $updated_at
+ * @property int $account_id
+ * @property string $name
+ * @property mixed $data
+ * @property Account $account
+ *
* @method static Builder|AccountMeta newModelQuery()
* @method static Builder|AccountMeta newQuery()
* @method static Builder|AccountMeta query()
@@ -48,49 +50,35 @@ use Illuminate\Support\Carbon;
* @method static Builder|AccountMeta whereId($value)
* @method static Builder|AccountMeta whereName($value)
* @method static Builder|AccountMeta whereUpdatedAt($value)
+ *
* @mixin Eloquent
*/
class AccountMeta extends Model
{
- /**
- * The attributes that should be casted to native types.
- *
- * @var array
- */
- protected $casts
- = [
- 'created_at' => 'datetime',
- 'updated_at' => 'datetime',
- ];
- /** @var array Fields that can be filled */
- protected $fillable = ['account_id', 'name', 'data'];
- /** @var string The table to store the data in */
- protected $table = 'account_meta';
+ use ReturnsIntegerIdTrait;
+
+ protected $casts
+ = [
+ 'created_at' => 'datetime',
+ 'updated_at' => 'datetime',
+ ];
+
+ protected $fillable = ['account_id', 'name', 'data'];
+
+ /** @var string The table to store the data in */
+ protected $table = 'account_meta';
- /**
- * @return BelongsTo
- */
public function account(): BelongsTo
{
return $this->belongsTo(Account::class);
}
- /**
- * @param mixed $value
- *
- * @return mixed
- */
- public function getDataAttribute($value): string
+ public function getDataAttribute(mixed $value): string
{
return (string)json_decode($value, true);
}
- /**
- * @param mixed $value
- *
-
- */
- public function setDataAttribute($value): void
+ public function setDataAttribute(mixed $value): void
{
$this->attributes['data'] = json_encode($value);
}
diff --git a/app/Models/AccountType.php b/app/Models/AccountType.php
index b166052150..54036c23ab 100644
--- a/app/Models/AccountType.php
+++ b/app/Models/AccountType.php
@@ -23,22 +23,24 @@ declare(strict_types=1);
namespace FireflyIII\Models;
+use Carbon\Carbon;
use Eloquent;
+use FireflyIII\Support\Models\ReturnsIntegerIdTrait;
use Illuminate\Database\Eloquent\Builder;
use Illuminate\Database\Eloquent\Collection;
use Illuminate\Database\Eloquent\Model;
use Illuminate\Database\Eloquent\Relations\HasMany;
-use Illuminate\Support\Carbon;
/**
* FireflyIII\Models\AccountType
*
- * @property int $id
- * @property Carbon|null $created_at
- * @property Carbon|null $updated_at
- * @property string $type
- * @property-read Collection|Account[] $accounts
- * @property-read int|null $accounts_count
+ * @property int $id
+ * @property null|Carbon $created_at
+ * @property null|Carbon $updated_at
+ * @property string $type
+ * @property Account[]|Collection $accounts
+ * @property null|int $accounts_count
+ *
* @method static Builder|AccountType newModelQuery()
* @method static Builder|AccountType newQuery()
* @method static Builder|AccountType query()
@@ -46,42 +48,36 @@ use Illuminate\Support\Carbon;
* @method static Builder|AccountType whereId($value)
* @method static Builder|AccountType whereType($value)
* @method static Builder|AccountType whereUpdatedAt($value)
+ *
* @mixin Eloquent
*/
class AccountType extends Model
{
- public const ASSET = 'Asset account';
- public const BENEFICIARY = 'Beneficiary account';
- public const CASH = 'Cash account';
- public const CREDITCARD = 'Credit card';
- public const DEBT = 'Debt';
- public const DEFAULT = 'Default account';
- public const EXPENSE = 'Expense account';
- public const IMPORT = 'Import account';
- public const INITIAL_BALANCE = 'Initial balance account';
- public const LIABILITY_CREDIT = 'Liability credit account';
- public const LOAN = 'Loan';
- public const MORTGAGE = 'Mortgage';
- public const RECONCILIATION = 'Reconciliation account';
- public const REVENUE = 'Revenue account';
+ use ReturnsIntegerIdTrait;
+ public const string ASSET = 'Asset account';
+ public const string BENEFICIARY = 'Beneficiary account';
+ public const string CASH = 'Cash account';
+ public const string CREDITCARD = 'Credit card';
+ public const string DEBT = 'Debt';
+ public const string DEFAULT = 'Default account';
+ public const string EXPENSE = 'Expense account';
+ public const string IMPORT = 'Import account';
+ public const string INITIAL_BALANCE = 'Initial balance account';
+ public const string LIABILITY_CREDIT = 'Liability credit account';
+ public const string LOAN = 'Loan';
+ public const string MORTGAGE = 'Mortgage';
+ public const string RECONCILIATION = 'Reconciliation account';
+ public const string REVENUE = 'Revenue account';
- /**
- * The attributes that should be casted to native types.
- *
- * @var array
- */
protected $casts
- = [
- 'created_at' => 'datetime',
- 'updated_at' => 'datetime',
- ];
- /** @var array Fields that can be filled */
- protected $fillable = ['type'];
+ = [
+ 'created_at' => 'datetime',
+ 'updated_at' => 'datetime',
+ ];
+
+ protected $fillable = ['type'];
- /**
- * @return HasMany
- */
public function accounts(): HasMany
{
return $this->hasMany(Account::class);
diff --git a/app/Models/Attachment.php b/app/Models/Attachment.php
index 235a8c1663..c0dedb7db3 100644
--- a/app/Models/Attachment.php
+++ b/app/Models/Attachment.php
@@ -23,8 +23,12 @@ declare(strict_types=1);
namespace FireflyIII\Models;
+use Carbon\Carbon;
use Eloquent;
+use FireflyIII\Support\Models\ReturnsIntegerIdTrait;
+use FireflyIII\Support\Models\ReturnsIntegerUserIdTrait;
use FireflyIII\User;
+use Illuminate\Database\Eloquent\Casts\Attribute;
use Illuminate\Database\Eloquent\Collection;
use Illuminate\Database\Eloquent\Model;
use Illuminate\Database\Eloquent\Relations\BelongsTo;
@@ -32,35 +36,35 @@ use Illuminate\Database\Eloquent\Relations\MorphMany;
use Illuminate\Database\Eloquent\Relations\MorphTo;
use Illuminate\Database\Eloquent\SoftDeletes;
use Illuminate\Database\Query\Builder;
-use Illuminate\Support\Carbon;
use Symfony\Component\HttpKernel\Exception\NotFoundHttpException;
/**
* FireflyIII\Models\Attachment
*
- * @property int $id
- * @property Carbon|null $created_at
- * @property Carbon|null $updated_at
- * @property Carbon|null $deleted_at
- * @property int $user_id
- * @property int $attachable_id
- * @property string $attachable_type
- * @property bool $file_exists
- * @property string $md5
- * @property string $filename
- * @property string|null $title
- * @property string|null $description
- * @property string $mime
- * @property int $size
- * @property bool $uploaded
- * @property string $notes_text
- * @property-read Model|Eloquent $attachable
- * @property Collection|Note[] $notes
- * @property-read int|null $notes_count
- * @property-read User $user
+ * @property int $id
+ * @property null|Carbon $created_at
+ * @property null|Carbon $updated_at
+ * @property null|Carbon $deleted_at
+ * @property int $user_id
+ * @property int $attachable_id
+ * @property string $attachable_type
+ * @property bool $file_exists
+ * @property string $md5
+ * @property string $filename
+ * @property null|string $title
+ * @property null|string $description
+ * @property string $mime
+ * @property int|string $size
+ * @property bool $uploaded
+ * @property string $notes_text
+ * @property \Eloquent|Model $attachable
+ * @property Collection|Note[] $notes
+ * @property null|int $notes_count
+ * @property User $user
+ *
* @method static \Illuminate\Database\Eloquent\Builder|Attachment newModelQuery()
* @method static \Illuminate\Database\Eloquent\Builder|Attachment newQuery()
- * @method static Builder|Attachment onlyTrashed()
+ * @method static Builder|Attachment onlyTrashed()
* @method static \Illuminate\Database\Eloquent\Builder|Attachment query()
* @method static \Illuminate\Database\Eloquent\Builder|Attachment whereAttachableId($value)
* @method static \Illuminate\Database\Eloquent\Builder|Attachment whereAttachableType($value)
@@ -76,57 +80,54 @@ use Symfony\Component\HttpKernel\Exception\NotFoundHttpException;
* @method static \Illuminate\Database\Eloquent\Builder|Attachment whereUpdatedAt($value)
* @method static \Illuminate\Database\Eloquent\Builder|Attachment whereUploaded($value)
* @method static \Illuminate\Database\Eloquent\Builder|Attachment whereUserId($value)
- * @method static Builder|Attachment withTrashed()
- * @method static Builder|Attachment withoutTrashed()
- * @property int|null $user_group_id
+ * @method static Builder|Attachment withTrashed()
+ * @method static Builder|Attachment withoutTrashed()
+ *
+ * @property int $user_group_id
+ *
* @method static \Illuminate\Database\Eloquent\Builder|Attachment whereUserGroupId($value)
+ *
* @mixin Eloquent
*/
class Attachment extends Model
{
+ use ReturnsIntegerIdTrait;
+ use ReturnsIntegerUserIdTrait;
use SoftDeletes;
- /**
- * The attributes that should be casted to native types.
- *
- * @var array
- */
protected $casts
- = [
- 'created_at' => 'datetime',
- 'updated_at' => 'datetime',
- 'deleted_at' => 'datetime',
- 'uploaded' => 'boolean',
- ];
- /** @var array Fields that can be filled */
+ = [
+ 'created_at' => 'datetime',
+ 'updated_at' => 'datetime',
+ 'deleted_at' => 'datetime',
+ 'uploaded' => 'boolean',
+ ];
+
protected $fillable = ['attachable_id', 'attachable_type', 'user_id', 'md5', 'filename', 'mime', 'title', 'description', 'size', 'uploaded'];
/**
* Route binder. Converts the key in the URL to the specified object (or throw 404).
*
- * @param string $value
- *
- * @return Attachment
* @throws NotFoundHttpException
*/
- public static function routeBinder(string $value): Attachment
+ public static function routeBinder(string $value): self
{
if (auth()->check()) {
$attachmentId = (int)$value;
+
/** @var User $user */
- $user = auth()->user();
- /** @var Attachment $attachment */
- $attachment = $user->attachments()->find($attachmentId);
+ $user = auth()->user();
+
+ /** @var null|Attachment $attachment */
+ $attachment = $user->attachments()->find($attachmentId);
if (null !== $attachment) {
return $attachment;
}
}
+
throw new NotFoundHttpException();
}
- /**
- * @return BelongsTo
- */
public function user(): BelongsTo
{
return $this->belongsTo(User::class);
@@ -134,9 +135,6 @@ class Attachment extends Model
/**
* Get all of the owning attachable models.
- *
- *
- * @return MorphTo
*/
public function attachable(): MorphTo
{
@@ -145,8 +143,6 @@ class Attachment extends Model
/**
* Returns the expected filename for this attachment.
- *
- * @return string
*/
public function fileName(): string
{
@@ -160,4 +156,11 @@ class Attachment extends Model
{
return $this->morphMany(Note::class, 'noteable');
}
+
+ protected function attachableId(): Attribute
+ {
+ return Attribute::make(
+ get: static fn ($value) => (int)$value,
+ );
+ }
}
diff --git a/app/Models/AuditLogEntry.php b/app/Models/AuditLogEntry.php
index fac7d1a7ef..cc2a93b2e4 100644
--- a/app/Models/AuditLogEntry.php
+++ b/app/Models/AuditLogEntry.php
@@ -24,35 +24,40 @@ declare(strict_types=1);
namespace FireflyIII\Models;
+use Carbon\Carbon;
use Eloquent;
+use FireflyIII\Support\Models\ReturnsIntegerIdTrait;
use Illuminate\Database\Eloquent\Builder;
+use Illuminate\Database\Eloquent\Casts\Attribute;
use Illuminate\Database\Eloquent\Model;
use Illuminate\Database\Eloquent\Relations\MorphTo;
use Illuminate\Database\Eloquent\SoftDeletes;
-use Illuminate\Support\Carbon;
/**
* Class AuditLogEntry
*
- * @property-read Model|Eloquent $auditable
- * @property-read Model|Eloquent $changer
- * @method static Builder|AuditLogEntry newModelQuery()
- * @method static Builder|AuditLogEntry newQuery()
+ * @property \Eloquent|Model $auditable
+ * @property \Eloquent|Model $changer
+ *
+ * @method static Builder|AuditLogEntry newModelQuery()
+ * @method static Builder|AuditLogEntry newQuery()
* @method static \Illuminate\Database\Query\Builder|AuditLogEntry onlyTrashed()
- * @method static Builder|AuditLogEntry query()
+ * @method static Builder|AuditLogEntry query()
* @method static \Illuminate\Database\Query\Builder|AuditLogEntry withTrashed()
* @method static \Illuminate\Database\Query\Builder|AuditLogEntry withoutTrashed()
- * @property int $id
- * @property Carbon|null $created_at
- * @property Carbon|null $updated_at
- * @property Carbon|null $deleted_at
- * @property int $auditable_id
- * @property string $auditable_type
- * @property int $changer_id
- * @property string $changer_type
- * @property string $action
- * @property array|null $before
- * @property array|null $after
+ *
+ * @property int $id
+ * @property null|Carbon $created_at
+ * @property null|Carbon $updated_at
+ * @property null|Carbon $deleted_at
+ * @property int $auditable_id
+ * @property string $auditable_type
+ * @property int $changer_id
+ * @property string $changer_type
+ * @property string $action
+ * @property null|array $before
+ * @property null|array $after
+ *
* @method static Builder|AuditLogEntry whereAction($value)
* @method static Builder|AuditLogEntry whereAfter($value)
* @method static Builder|AuditLogEntry whereAuditableId($value)
@@ -64,10 +69,12 @@ use Illuminate\Support\Carbon;
* @method static Builder|AuditLogEntry whereDeletedAt($value)
* @method static Builder|AuditLogEntry whereId($value)
* @method static Builder|AuditLogEntry whereUpdatedAt($value)
+ *
* @mixin Eloquent
*/
class AuditLogEntry extends Model
{
+ use ReturnsIntegerIdTrait;
use SoftDeletes;
protected $casts
@@ -79,17 +86,27 @@ class AuditLogEntry extends Model
'deleted_at' => 'datetime',
];
- /**
- */
public function auditable(): MorphTo
{
return $this->morphTo();
}
- /**
- */
public function changer(): MorphTo
{
return $this->morphTo();
}
+
+ protected function auditableId(): Attribute
+ {
+ return Attribute::make(
+ get: static fn ($value) => (int)$value,
+ );
+ }
+
+ protected function changerId(): Attribute
+ {
+ return Attribute::make(
+ get: static fn ($value) => (int)$value,
+ );
+ }
}
diff --git a/app/Models/AutoBudget.php b/app/Models/AutoBudget.php
index 41f446da71..ba274a2f32 100644
--- a/app/Models/AutoBudget.php
+++ b/app/Models/AutoBudget.php
@@ -24,31 +24,33 @@ declare(strict_types=1);
namespace FireflyIII\Models;
+use Carbon\Carbon;
use Eloquent;
+use FireflyIII\Support\Models\ReturnsIntegerIdTrait;
use Illuminate\Database\Eloquent\Casts\Attribute;
use Illuminate\Database\Eloquent\Model;
use Illuminate\Database\Eloquent\Relations\BelongsTo;
use Illuminate\Database\Eloquent\SoftDeletes;
use Illuminate\Database\Query\Builder;
-use Illuminate\Support\Carbon;
/**
* FireflyIII\Models\AutoBudget
*
- * @property int $id
- * @property Carbon|null $created_at
- * @property Carbon|null $updated_at
- * @property Carbon|null $deleted_at
- * @property int $budget_id
- * @property int $transaction_currency_id
- * @property int $auto_budget_type
- * @property string $amount
- * @property string $period
- * @property-read Budget $budget
- * @property-read TransactionCurrency $transactionCurrency
+ * @property int $id
+ * @property null|Carbon $created_at
+ * @property null|Carbon $updated_at
+ * @property null|Carbon $deleted_at
+ * @property int $budget_id
+ * @property int $transaction_currency_id
+ * @property int|string $auto_budget_type
+ * @property string $amount
+ * @property string $period
+ * @property Budget $budget
+ * @property TransactionCurrency $transactionCurrency
+ *
* @method static \Illuminate\Database\Eloquent\Builder|AutoBudget newModelQuery()
* @method static \Illuminate\Database\Eloquent\Builder|AutoBudget newQuery()
- * @method static Builder|AutoBudget onlyTrashed()
+ * @method static Builder|AutoBudget onlyTrashed()
* @method static \Illuminate\Database\Eloquent\Builder|AutoBudget query()
* @method static \Illuminate\Database\Eloquent\Builder|AutoBudget whereAmount($value)
* @method static \Illuminate\Database\Eloquent\Builder|AutoBudget whereAutoBudgetType($value)
@@ -59,42 +61,49 @@ use Illuminate\Support\Carbon;
* @method static \Illuminate\Database\Eloquent\Builder|AutoBudget wherePeriod($value)
* @method static \Illuminate\Database\Eloquent\Builder|AutoBudget whereTransactionCurrencyId($value)
* @method static \Illuminate\Database\Eloquent\Builder|AutoBudget whereUpdatedAt($value)
- * @method static Builder|AutoBudget withTrashed()
- * @method static Builder|AutoBudget withoutTrashed()
+ * @method static Builder|AutoBudget withTrashed()
+ * @method static Builder|AutoBudget withoutTrashed()
+ *
* @mixin Eloquent
*/
class AutoBudget extends Model
{
+ use ReturnsIntegerIdTrait;
use SoftDeletes;
- public const AUTO_BUDGET_ADJUSTED = 3;
- public const AUTO_BUDGET_RESET = 1;
- public const AUTO_BUDGET_ROLLOVER = 2;
- protected $fillable = ['budget_id', 'amount', 'period'];
+ public const int AUTO_BUDGET_ADJUSTED = 3;
+ public const int AUTO_BUDGET_RESET = 1;
+ public const int AUTO_BUDGET_ROLLOVER = 2;
+ protected $fillable = ['budget_id', 'amount', 'period'];
- /**
- * @return BelongsTo
- */
public function budget(): BelongsTo
{
return $this->belongsTo(Budget::class);
}
- /**
- * @return BelongsTo
- */
public function transactionCurrency(): BelongsTo
{
return $this->belongsTo(TransactionCurrency::class);
}
- /**
- * @return Attribute
- */
protected function amount(): Attribute
{
return Attribute::make(
- get: fn ($value) => (string)$value,
+ get: static fn ($value) => (string)$value,
+ );
+ }
+
+ protected function budgetId(): Attribute
+ {
+ return Attribute::make(
+ get: static fn ($value) => (int)$value,
+ );
+ }
+
+ protected function transactionCurrencyId(): Attribute
+ {
+ return Attribute::make(
+ get: static fn ($value) => (int)$value,
);
}
}
diff --git a/app/Models/AvailableBudget.php b/app/Models/AvailableBudget.php
index eac01d5043..95bdaa6120 100644
--- a/app/Models/AvailableBudget.php
+++ b/app/Models/AvailableBudget.php
@@ -23,33 +23,36 @@ declare(strict_types=1);
namespace FireflyIII\Models;
+use Carbon\Carbon;
use Eloquent;
+use FireflyIII\Support\Models\ReturnsIntegerIdTrait;
+use FireflyIII\Support\Models\ReturnsIntegerUserIdTrait;
use FireflyIII\User;
use Illuminate\Database\Eloquent\Casts\Attribute;
use Illuminate\Database\Eloquent\Model;
use Illuminate\Database\Eloquent\Relations\BelongsTo;
use Illuminate\Database\Eloquent\SoftDeletes;
use Illuminate\Database\Query\Builder;
-use Illuminate\Support\Carbon;
use Symfony\Component\HttpKernel\Exception\NotFoundHttpException;
/**
* FireflyIII\Models\AvailableBudget
*
- * @property int $id
- * @property Carbon|null $created_at
- * @property Carbon|null $updated_at
- * @property Carbon|null $deleted_at
- * @property int $user_id
- * @property int $transaction_currency_id
- * @property string $amount
- * @property Carbon $start_date
- * @property Carbon $end_date
- * @property-read TransactionCurrency $transactionCurrency
- * @property-read User $user
+ * @property int $id
+ * @property null|Carbon $created_at
+ * @property null|Carbon $updated_at
+ * @property null|Carbon $deleted_at
+ * @property int $user_id
+ * @property int $transaction_currency_id
+ * @property string $amount
+ * @property Carbon $start_date
+ * @property Carbon $end_date
+ * @property TransactionCurrency $transactionCurrency
+ * @property User $user
+ *
* @method static \Illuminate\Database\Eloquent\Builder|AvailableBudget newModelQuery()
* @method static \Illuminate\Database\Eloquent\Builder|AvailableBudget newQuery()
- * @method static Builder|AvailableBudget onlyTrashed()
+ * @method static Builder|AvailableBudget onlyTrashed()
* @method static \Illuminate\Database\Eloquent\Builder|AvailableBudget query()
* @method static \Illuminate\Database\Eloquent\Builder|AvailableBudget whereAmount($value)
* @method static \Illuminate\Database\Eloquent\Builder|AvailableBudget whereCreatedAt($value)
@@ -60,79 +63,77 @@ use Symfony\Component\HttpKernel\Exception\NotFoundHttpException;
* @method static \Illuminate\Database\Eloquent\Builder|AvailableBudget whereTransactionCurrencyId($value)
* @method static \Illuminate\Database\Eloquent\Builder|AvailableBudget whereUpdatedAt($value)
* @method static \Illuminate\Database\Eloquent\Builder|AvailableBudget whereUserId($value)
- * @method static Builder|AvailableBudget withTrashed()
- * @method static Builder|AvailableBudget withoutTrashed()
- * @property int|null $user_group_id
+ * @method static Builder|AvailableBudget withTrashed()
+ * @method static Builder|AvailableBudget withoutTrashed()
+ *
+ * @property int $user_group_id
+ *
* @method static \Illuminate\Database\Eloquent\Builder|AvailableBudget whereUserGroupId($value)
+ *
* @mixin Eloquent
*/
class AvailableBudget extends Model
{
+ use ReturnsIntegerIdTrait;
+ use ReturnsIntegerUserIdTrait;
use SoftDeletes;
- /**
- * The attributes that should be casted to native types.
- *
- * @var array
- */
protected $casts
- = [
- 'created_at' => 'datetime',
- 'updated_at' => 'datetime',
- 'deleted_at' => 'datetime',
- 'start_date' => 'date',
- 'end_date' => 'date',
- 'transaction_currency_id' => 'int',
- ];
- /** @var array Fields that can be filled */
+ = [
+ 'created_at' => 'datetime',
+ 'updated_at' => 'datetime',
+ 'deleted_at' => 'datetime',
+ 'start_date' => 'date',
+ 'end_date' => 'date',
+ 'transaction_currency_id' => 'int',
+ ];
+
protected $fillable = ['user_id', 'user_group_id', 'transaction_currency_id', 'amount', 'start_date', 'end_date'];
/**
* Route binder. Converts the key in the URL to the specified object (or throw 404).
*
- * @param string $value
- *
- * @return AvailableBudget
* @throws NotFoundHttpException
*/
- public static function routeBinder(string $value): AvailableBudget
+ public static function routeBinder(string $value): self
{
if (auth()->check()) {
$availableBudgetId = (int)$value;
+
/** @var User $user */
- $user = auth()->user();
- /** @var AvailableBudget $availableBudget */
- $availableBudget = $user->availableBudgets()->find($availableBudgetId);
+ $user = auth()->user();
+
+ /** @var null|AvailableBudget $availableBudget */
+ $availableBudget = $user->availableBudgets()->find($availableBudgetId);
if (null !== $availableBudget) {
return $availableBudget;
}
}
+
throw new NotFoundHttpException();
}
- /**
- * @return BelongsTo
- */
public function user(): BelongsTo
{
return $this->belongsTo(User::class);
}
- /**
- * @return BelongsTo
- */
public function transactionCurrency(): BelongsTo
{
return $this->belongsTo(TransactionCurrency::class);
}
- /**
- * @return Attribute
- */
protected function amount(): Attribute
{
return Attribute::make(
- get: fn ($value) => (string)$value,
+ get: static fn ($value) => (string)$value,
+ );
+ }
+
+ protected function transactionCurrencyId(): Attribute
+ {
+ return Attribute::make(
+ get: static fn ($value) => (int)$value,
);
}
}
diff --git a/app/Models/Bill.php b/app/Models/Bill.php
index f9f2510fc2..ff50cc7aa6 100644
--- a/app/Models/Bill.php
+++ b/app/Models/Bill.php
@@ -23,7 +23,10 @@ declare(strict_types=1);
namespace FireflyIII\Models;
+use Carbon\Carbon;
use Eloquent;
+use FireflyIII\Support\Models\ReturnsIntegerIdTrait;
+use FireflyIII\Support\Models\ReturnsIntegerUserIdTrait;
use FireflyIII\User;
use Illuminate\Database\Eloquent\Casts\Attribute;
use Illuminate\Database\Eloquent\Collection;
@@ -31,47 +34,48 @@ use Illuminate\Database\Eloquent\Model;
use Illuminate\Database\Eloquent\Relations\BelongsTo;
use Illuminate\Database\Eloquent\Relations\HasMany;
use Illuminate\Database\Eloquent\Relations\MorphMany;
+use Illuminate\Database\Eloquent\Relations\MorphToMany;
use Illuminate\Database\Eloquent\SoftDeletes;
use Illuminate\Database\Query\Builder;
-use Illuminate\Support\Carbon;
use Symfony\Component\HttpKernel\Exception\NotFoundHttpException;
/**
* FireflyIII\Models\Bill
*
- * @property int $id
- * @property Carbon|null $created_at
- * @property Carbon|null $updated_at
- * @property Carbon|null $deleted_at
- * @property int $user_id
- * @property int|null $transaction_currency_id
- * @property string $name
- * @property string $match
- * @property string $amount_min
- * @property string $amount_max
- * @property Carbon $date
- * @property Carbon|null $end_date
- * @property Carbon|null $extension_date
- * @property string $repeat_freq
- * @property int $skip
- * @property bool $automatch
- * @property bool $active
- * @property bool $name_encrypted
- * @property bool $match_encrypted
- * @property int $order
- * @property-read Collection|Attachment[] $attachments
- * @property-read int|null $attachments_count
- * @property-read Collection|Note[] $notes
- * @property-read int|null $notes_count
- * @property-read Collection|ObjectGroup[] $objectGroups
- * @property-read int|null $object_groups_count
- * @property-read TransactionCurrency|null $transactionCurrency
- * @property-read Collection|TransactionJournal[] $transactionJournals
- * @property-read int|null $transaction_journals_count
- * @property-read User $user
+ * @property int $id
+ * @property null|Carbon $created_at
+ * @property null|Carbon $updated_at
+ * @property null|Carbon $deleted_at
+ * @property int $user_id
+ * @property int $transaction_currency_id
+ * @property string $name
+ * @property string $match
+ * @property string $amount_min
+ * @property string $amount_max
+ * @property Carbon $date
+ * @property null|Carbon $end_date
+ * @property null|Carbon $extension_date
+ * @property string $repeat_freq
+ * @property int $skip
+ * @property bool $automatch
+ * @property bool $active
+ * @property bool $name_encrypted
+ * @property bool $match_encrypted
+ * @property int $order
+ * @property Attachment[]|Collection $attachments
+ * @property null|int $attachments_count
+ * @property Collection|Note[] $notes
+ * @property null|int $notes_count
+ * @property Collection|ObjectGroup[] $objectGroups
+ * @property null|int $object_groups_count
+ * @property null|TransactionCurrency $transactionCurrency
+ * @property Collection|TransactionJournal[] $transactionJournals
+ * @property null|int $transaction_journals_count
+ * @property User $user
+ *
* @method static \Illuminate\Database\Eloquent\Builder|Bill newModelQuery()
* @method static \Illuminate\Database\Eloquent\Builder|Bill newQuery()
- * @method static Builder|Bill onlyTrashed()
+ * @method static Builder|Bill onlyTrashed()
* @method static \Illuminate\Database\Eloquent\Builder|Bill query()
* @method static \Illuminate\Database\Eloquent\Builder|Bill whereActive($value)
* @method static \Illuminate\Database\Eloquent\Builder|Bill whereAmountMax($value)
@@ -93,91 +97,84 @@ use Symfony\Component\HttpKernel\Exception\NotFoundHttpException;
* @method static \Illuminate\Database\Eloquent\Builder|Bill whereTransactionCurrencyId($value)
* @method static \Illuminate\Database\Eloquent\Builder|Bill whereUpdatedAt($value)
* @method static \Illuminate\Database\Eloquent\Builder|Bill whereUserId($value)
- * @method static Builder|Bill withTrashed()
- * @method static Builder|Bill withoutTrashed()
- * @property int|null $user_group_id
+ * @method static Builder|Bill withTrashed()
+ * @method static Builder|Bill withoutTrashed()
+ *
+ * @property int $user_group_id
+ *
* @method static \Illuminate\Database\Eloquent\Builder|Bill whereUserGroupId($value)
+ *
* @mixin Eloquent
*/
class Bill extends Model
{
+ use ReturnsIntegerIdTrait;
+ use ReturnsIntegerUserIdTrait;
use SoftDeletes;
- /**
- * The attributes that should be casted to native types.
- *
- * @var array
- */
protected $casts
- = [
- 'created_at' => 'datetime',
- 'updated_at' => 'datetime',
- 'deleted_at' => 'datetime',
- 'date' => 'date',
- 'end_date' => 'date',
- 'extension_date' => 'date',
- 'skip' => 'int',
- 'automatch' => 'boolean',
- 'active' => 'boolean',
- 'name_encrypted' => 'boolean',
- 'match_encrypted' => 'boolean',
- ];
+ = [
+ 'created_at' => 'datetime',
+ 'updated_at' => 'datetime',
+ 'deleted_at' => 'datetime',
+ 'date' => 'date',
+ 'end_date' => 'date',
+ 'extension_date' => 'date',
+ 'skip' => 'int',
+ 'automatch' => 'boolean',
+ 'active' => 'boolean',
+ 'name_encrypted' => 'boolean',
+ 'match_encrypted' => 'boolean',
+ ];
- /** @var array Fields that can be filled */
protected $fillable
- = [
- 'name',
- 'match',
- 'amount_min',
- 'user_id',
- 'user_group_id',
- 'amount_max',
- 'date',
- 'repeat_freq',
- 'skip',
- 'automatch',
- 'active',
- 'transaction_currency_id',
- 'end_date',
- 'extension_date',
- ];
- /** @var array Hidden from view */
+ = [
+ 'name',
+ 'match',
+ 'amount_min',
+ 'user_id',
+ 'user_group_id',
+ 'amount_max',
+ 'date',
+ 'repeat_freq',
+ 'skip',
+ 'automatch',
+ 'active',
+ 'transaction_currency_id',
+ 'end_date',
+ 'extension_date',
+ ];
+
protected $hidden = ['amount_min_encrypted', 'amount_max_encrypted', 'name_encrypted', 'match_encrypted'];
/**
* Route binder. Converts the key in the URL to the specified object (or throw 404).
*
- * @param string $value
- *
- * @return Bill
* @throws NotFoundHttpException
*/
- public static function routeBinder(string $value): Bill
+ public static function routeBinder(string $value): self
{
if (auth()->check()) {
$billId = (int)$value;
+
/** @var User $user */
- $user = auth()->user();
- /** @var Bill $bill */
- $bill = $user->bills()->find($billId);
+ $user = auth()->user();
+
+ /** @var null|Bill $bill */
+ $bill = $user->bills()->find($billId);
if (null !== $bill) {
return $bill;
}
}
+
throw new NotFoundHttpException();
}
- /**
- * @return BelongsTo
- */
public function user(): BelongsTo
{
return $this->belongsTo(User::class);
}
- /**
- * @return MorphMany
- */
public function attachments(): MorphMany
{
return $this->morphMany(Attachment::class, 'attachable');
@@ -192,15 +189,14 @@ class Bill extends Model
}
/**
- * Get all of the tags for the post.
+ * Get all the tags for the post.
*/
- public function objectGroups()
+ public function objectGroups(): MorphToMany
{
return $this->morphToMany(ObjectGroup::class, 'object_groupable');
}
/**
- *
* @param mixed $value
*/
public function setAmountMaxAttribute($value): void
@@ -210,25 +206,17 @@ class Bill extends Model
/**
* @param mixed $value
- *
-
*/
public function setAmountMinAttribute($value): void
{
$this->attributes['amount_min'] = (string)$value;
}
- /**
- * @return BelongsTo
- */
public function transactionCurrency(): BelongsTo
{
return $this->belongsTo(TransactionCurrency::class);
}
- /**
- * @return HasMany
- */
public function transactionJournals(): HasMany
{
return $this->hasMany(TransactionJournal::class);
@@ -236,25 +224,45 @@ class Bill extends Model
/**
* Get the max amount
- *
- * @return Attribute
*/
protected function amountMax(): Attribute
{
return Attribute::make(
- get: fn ($value) => (string)$value,
+ get: static fn ($value) => (string)$value,
);
}
/**
* Get the min amount
- *
- * @return Attribute
*/
protected function amountMin(): Attribute
{
return Attribute::make(
- get: fn ($value) => (string)$value,
+ get: static fn ($value) => (string)$value,
+ );
+ }
+
+ protected function order(): Attribute
+ {
+ return Attribute::make(
+ get: static fn ($value) => (int)$value,
+ );
+ }
+
+ /**
+ * Get the skip
+ */
+ protected function skip(): Attribute
+ {
+ return Attribute::make(
+ get: static fn ($value) => (int)$value,
+ );
+ }
+
+ protected function transactionCurrencyId(): Attribute
+ {
+ return Attribute::make(
+ get: static fn ($value) => (int)$value,
);
}
}
diff --git a/app/Models/Budget.php b/app/Models/Budget.php
index 88e6a30138..dd7f9a5a6b 100644
--- a/app/Models/Budget.php
+++ b/app/Models/Budget.php
@@ -23,8 +23,12 @@ declare(strict_types=1);
namespace FireflyIII\Models;
+use Carbon\Carbon;
use Eloquent;
+use FireflyIII\Support\Models\ReturnsIntegerIdTrait;
+use FireflyIII\Support\Models\ReturnsIntegerUserIdTrait;
use FireflyIII\User;
+use Illuminate\Database\Eloquent\Casts\Attribute;
use Illuminate\Database\Eloquent\Collection;
use Illuminate\Database\Eloquent\Model;
use Illuminate\Database\Eloquent\Relations\BelongsTo;
@@ -33,35 +37,35 @@ use Illuminate\Database\Eloquent\Relations\HasMany;
use Illuminate\Database\Eloquent\Relations\MorphMany;
use Illuminate\Database\Eloquent\SoftDeletes;
use Illuminate\Database\Query\Builder;
-use Illuminate\Support\Carbon;
use Symfony\Component\HttpKernel\Exception\NotFoundHttpException;
/**
* FireflyIII\Models\Budget
*
- * @property int $id
- * @property Carbon|null $created_at
- * @property Carbon|null $updated_at
- * @property Carbon|null $deleted_at
- * @property int $user_id
- * @property string $name
- * @property bool $active
- * @property bool $encrypted
- * @property int $order
- * @property-read Collection|Attachment[] $attachments
- * @property-read int|null $attachments_count
- * @property-read Collection|AutoBudget[] $autoBudgets
- * @property-read int|null $auto_budgets_count
- * @property-read Collection|BudgetLimit[] $budgetlimits
- * @property-read int|null $budgetlimits_count
- * @property-read Collection|TransactionJournal[] $transactionJournals
- * @property-read int|null $transaction_journals_count
- * @property-read Collection|Transaction[] $transactions
- * @property-read int|null $transactions_count
- * @property-read User $user
+ * @property int $id
+ * @property null|Carbon $created_at
+ * @property null|Carbon $updated_at
+ * @property null|Carbon $deleted_at
+ * @property int $user_id
+ * @property string $name
+ * @property bool $active
+ * @property bool $encrypted
+ * @property int $order
+ * @property Attachment[]|Collection $attachments
+ * @property null|int $attachments_count
+ * @property AutoBudget[]|Collection $autoBudgets
+ * @property null|int $auto_budgets_count
+ * @property BudgetLimit[]|Collection $budgetlimits
+ * @property null|int $budgetlimits_count
+ * @property Collection|TransactionJournal[] $transactionJournals
+ * @property null|int $transaction_journals_count
+ * @property Collection|Transaction[] $transactions
+ * @property null|int $transactions_count
+ * @property User $user
+ *
* @method static \Illuminate\Database\Eloquent\Builder|Budget newModelQuery()
* @method static \Illuminate\Database\Eloquent\Builder|Budget newQuery()
- * @method static Builder|Budget onlyTrashed()
+ * @method static Builder|Budget onlyTrashed()
* @method static \Illuminate\Database\Eloquent\Builder|Budget query()
* @method static \Illuminate\Database\Eloquent\Builder|Budget whereActive($value)
* @method static \Illuminate\Database\Eloquent\Builder|Budget whereCreatedAt($value)
@@ -72,87 +76,76 @@ use Symfony\Component\HttpKernel\Exception\NotFoundHttpException;
* @method static \Illuminate\Database\Eloquent\Builder|Budget whereOrder($value)
* @method static \Illuminate\Database\Eloquent\Builder|Budget whereUpdatedAt($value)
* @method static \Illuminate\Database\Eloquent\Builder|Budget whereUserId($value)
- * @method static Builder|Budget withTrashed()
- * @method static Builder|Budget withoutTrashed()
- * @property string $email
- * @property int|null $user_group_id
+ * @method static Builder|Budget withTrashed()
+ * @method static Builder|Budget withoutTrashed()
+ *
+ * @property string $email
+ * @property int $user_group_id
+ *
* @method static \Illuminate\Database\Eloquent\Builder|Budget whereUserGroupId($value)
- * @property-read Collection|Note[] $notes
- * @property-read int|null $notes_count
+ *
+ * @property Collection|Note[] $notes
+ * @property null|int $notes_count
+ *
* @mixin Eloquent
*/
class Budget extends Model
{
+ use ReturnsIntegerIdTrait;
+ use ReturnsIntegerUserIdTrait;
use SoftDeletes;
- /**
- * The attributes that should be casted to native types.
- *
- * @var array
- */
protected $casts
- = [
- 'created_at' => 'datetime',
- 'updated_at' => 'datetime',
- 'deleted_at' => 'datetime',
- 'active' => 'boolean',
- 'encrypted' => 'boolean',
- ];
- /** @var array Fields that can be filled */
+ = [
+ 'created_at' => 'datetime',
+ 'updated_at' => 'datetime',
+ 'deleted_at' => 'datetime',
+ 'active' => 'boolean',
+ 'encrypted' => 'boolean',
+ ];
+
protected $fillable = ['user_id', 'name', 'active', 'order', 'user_group_id'];
- /** @var array Hidden from view */
- protected $hidden = ['encrypted'];
+
+ protected $hidden = ['encrypted'];
/**
* Route binder. Converts the key in the URL to the specified object (or throw 404).
*
- * @param string $value
- *
- * @return Budget
* @throws NotFoundHttpException
*/
- public static function routeBinder(string $value): Budget
+ public static function routeBinder(string $value): self
{
if (auth()->check()) {
$budgetId = (int)$value;
+
/** @var User $user */
- $user = auth()->user();
- /** @var Budget $budget */
- $budget = $user->budgets()->find($budgetId);
+ $user = auth()->user();
+
+ /** @var null|Budget $budget */
+ $budget = $user->budgets()->find($budgetId);
if (null !== $budget) {
return $budget;
}
}
+
throw new NotFoundHttpException();
}
- /**
- * @return BelongsTo
- */
public function user(): BelongsTo
{
return $this->belongsTo(User::class);
}
- /**
- * @return MorphMany
- */
public function attachments(): MorphMany
{
return $this->morphMany(Attachment::class, 'attachable');
}
- /**
- * @return HasMany
- */
public function autoBudgets(): HasMany
{
return $this->hasMany(AutoBudget::class);
}
- /**
- * @return HasMany
- */
public function budgetlimits(): HasMany
{
return $this->hasMany(BudgetLimit::class);
@@ -166,19 +159,20 @@ class Budget extends Model
return $this->morphMany(Note::class, 'noteable');
}
- /**
- * @return BelongsToMany
- */
public function transactionJournals(): BelongsToMany
{
return $this->belongsToMany(TransactionJournal::class, 'budget_transaction_journal', 'budget_id');
}
- /**
- * @return BelongsToMany
- */
public function transactions(): BelongsToMany
{
return $this->belongsToMany(Transaction::class, 'budget_transaction', 'budget_id');
}
+
+ protected function order(): Attribute
+ {
+ return Attribute::make(
+ get: static fn ($value) => (int)$value,
+ );
+ }
}
diff --git a/app/Models/BudgetLimit.php b/app/Models/BudgetLimit.php
index 59cec2c1f1..e8528e5e40 100644
--- a/app/Models/BudgetLimit.php
+++ b/app/Models/BudgetLimit.php
@@ -23,33 +23,35 @@ declare(strict_types=1);
namespace FireflyIII\Models;
+use Carbon\Carbon;
use Eloquent;
use FireflyIII\Events\Model\BudgetLimit\Created;
use FireflyIII\Events\Model\BudgetLimit\Deleted;
use FireflyIII\Events\Model\BudgetLimit\Updated;
+use FireflyIII\Support\Models\ReturnsIntegerIdTrait;
use Illuminate\Database\Eloquent\Builder;
use Illuminate\Database\Eloquent\Casts\Attribute;
use Illuminate\Database\Eloquent\Model;
use Illuminate\Database\Eloquent\Relations\BelongsTo;
-use Illuminate\Support\Carbon;
use Symfony\Component\HttpKernel\Exception\NotFoundHttpException;
/**
* FireflyIII\Models\BudgetLimit
*
- * @property int $id
- * @property Carbon|null $created_at
- * @property Carbon|null $updated_at
- * @property int $budget_id
- * @property int|null $transaction_currency_id
- * @property Carbon $start_date
- * @property Carbon|null $end_date
- * @property string $amount
- * @property string $spent
- * @property string|null $period
- * @property int $generated
- * @property-read Budget $budget
- * @property-read TransactionCurrency|null $transactionCurrency
+ * @property int $id
+ * @property null|Carbon $created_at
+ * @property null|Carbon $updated_at
+ * @property int $budget_id
+ * @property int $transaction_currency_id
+ * @property Carbon $start_date
+ * @property null|Carbon $end_date
+ * @property string $amount
+ * @property string $spent
+ * @property null|string $period
+ * @property int|string $generated
+ * @property Budget $budget
+ * @property null|TransactionCurrency $transactionCurrency
+ *
* @method static Builder|BudgetLimit newModelQuery()
* @method static Builder|BudgetLimit newQuery()
* @method static Builder|BudgetLimit query()
@@ -63,66 +65,57 @@ use Symfony\Component\HttpKernel\Exception\NotFoundHttpException;
* @method static Builder|BudgetLimit whereStartDate($value)
* @method static Builder|BudgetLimit whereTransactionCurrencyId($value)
* @method static Builder|BudgetLimit whereUpdatedAt($value)
+ *
* @mixin Eloquent
*/
class BudgetLimit extends Model
{
- /**
- * The attributes that should be casted to native types.
- *
- * @var array
- */
+ use ReturnsIntegerIdTrait;
+
protected $casts
- = [
- 'created_at' => 'datetime',
- 'updated_at' => 'datetime',
- 'start_date' => 'date',
- 'end_date' => 'date',
- 'auto_budget' => 'boolean',
- ];
+ = [
+ 'created_at' => 'datetime',
+ 'updated_at' => 'datetime',
+ 'start_date' => 'date',
+ 'end_date' => 'date',
+ 'auto_budget' => 'boolean',
+ ];
protected $dispatchesEvents
- = [
- 'created' => Created::class,
- 'updated' => Updated::class,
- 'deleted' => Deleted::class,
- ];
- /** @var array Fields that can be filled */
+ = [
+ 'created' => Created::class,
+ 'updated' => Updated::class,
+ 'deleted' => Deleted::class,
+ ];
+
protected $fillable = ['budget_id', 'start_date', 'end_date', 'amount', 'transaction_currency_id'];
/**
* Route binder. Converts the key in the URL to the specified object (or throw 404).
*
- * @param string $value
- *
- * @return BudgetLimit
* @throws NotFoundHttpException
*/
- public static function routeBinder(string $value): BudgetLimit
+ public static function routeBinder(string $value): self
{
if (auth()->check()) {
$budgetLimitId = (int)$value;
$budgetLimit = self::where('budget_limits.id', $budgetLimitId)
- ->leftJoin('budgets', 'budgets.id', '=', 'budget_limits.budget_id')
- ->where('budgets.user_id', auth()->user()->id)
- ->first(['budget_limits.*']);
+ ->leftJoin('budgets', 'budgets.id', '=', 'budget_limits.budget_id')
+ ->where('budgets.user_id', auth()->user()->id)
+ ->first(['budget_limits.*'])
+ ;
if (null !== $budgetLimit) {
return $budgetLimit;
}
}
+
throw new NotFoundHttpException();
}
- /**
- * @return BelongsTo
- */
public function budget(): BelongsTo
{
return $this->belongsTo(Budget::class);
}
- /**
- * @return BelongsTo
- */
public function transactionCurrency(): BelongsTo
{
return $this->belongsTo(TransactionCurrency::class);
@@ -130,13 +123,25 @@ class BudgetLimit extends Model
/**
* Get the amount
- *
- * @return Attribute
*/
protected function amount(): Attribute
{
return Attribute::make(
- get: fn ($value) => (string)$value,
+ get: static fn ($value) => (string)$value,
+ );
+ }
+
+ protected function budgetId(): Attribute
+ {
+ return Attribute::make(
+ get: static fn ($value) => (int)$value,
+ );
+ }
+
+ protected function transactionCurrencyId(): Attribute
+ {
+ return Attribute::make(
+ get: static fn ($value) => (int)$value,
);
}
}
diff --git a/app/Models/Category.php b/app/Models/Category.php
index dc52f22bbb..5901af1e7c 100644
--- a/app/Models/Category.php
+++ b/app/Models/Category.php
@@ -25,6 +25,8 @@ namespace FireflyIII\Models;
use Carbon\Carbon;
use Eloquent;
+use FireflyIII\Support\Models\ReturnsIntegerIdTrait;
+use FireflyIII\Support\Models\ReturnsIntegerUserIdTrait;
use FireflyIII\User;
use Illuminate\Database\Eloquent\Collection;
use Illuminate\Database\Eloquent\Model;
@@ -38,26 +40,27 @@ use Symfony\Component\HttpKernel\Exception\NotFoundHttpException;
/**
* FireflyIII\Models\Category
*
- * @property int $id
- * @property \Illuminate\Support\Carbon|null $created_at
- * @property \Illuminate\Support\Carbon|null $updated_at
- * @property \Illuminate\Support\Carbon|null $deleted_at
- * @property int $user_id
- * @property string $name
- * @property Carbon $lastActivity
- * @property bool $encrypted
- * @property-read Collection|Attachment[] $attachments
- * @property-read int|null $attachments_count
- * @property-read Collection|Note[] $notes
- * @property-read int|null $notes_count
- * @property-read Collection|TransactionJournal[] $transactionJournals
- * @property-read int|null $transaction_journals_count
- * @property-read Collection|Transaction[] $transactions
- * @property-read int|null $transactions_count
- * @property-read User $user
+ * @property int $id
+ * @property null|Carbon $created_at
+ * @property null|Carbon $updated_at
+ * @property null|Carbon $deleted_at
+ * @property int $user_id
+ * @property string $name
+ * @property Carbon $lastActivity
+ * @property bool $encrypted
+ * @property Attachment[]|Collection $attachments
+ * @property null|int $attachments_count
+ * @property Collection|Note[] $notes
+ * @property null|int $notes_count
+ * @property Collection|TransactionJournal[] $transactionJournals
+ * @property null|int $transaction_journals_count
+ * @property Collection|Transaction[] $transactions
+ * @property null|int $transactions_count
+ * @property User $user
+ *
* @method static \Illuminate\Database\Eloquent\Builder|Category newModelQuery()
* @method static \Illuminate\Database\Eloquent\Builder|Category newQuery()
- * @method static Builder|Category onlyTrashed()
+ * @method static Builder|Category onlyTrashed()
* @method static \Illuminate\Database\Eloquent\Builder|Category query()
* @method static \Illuminate\Database\Eloquent\Builder|Category whereCreatedAt($value)
* @method static \Illuminate\Database\Eloquent\Builder|Category whereDeletedAt($value)
@@ -66,67 +69,61 @@ use Symfony\Component\HttpKernel\Exception\NotFoundHttpException;
* @method static \Illuminate\Database\Eloquent\Builder|Category whereName($value)
* @method static \Illuminate\Database\Eloquent\Builder|Category whereUpdatedAt($value)
* @method static \Illuminate\Database\Eloquent\Builder|Category whereUserId($value)
- * @method static Builder|Category withTrashed()
- * @method static Builder|Category withoutTrashed()
- * @property int|null $user_group_id
+ * @method static Builder|Category withTrashed()
+ * @method static Builder|Category withoutTrashed()
+ *
+ * @property int $user_group_id
+ *
* @method static \Illuminate\Database\Eloquent\Builder|Category whereUserGroupId($value)
+ *
* @mixin Eloquent
*/
class Category extends Model
{
+ use ReturnsIntegerIdTrait;
+ use ReturnsIntegerUserIdTrait;
use SoftDeletes;
- /**
- * The attributes that should be casted to native types.
- *
- * @var array
- */
protected $casts
- = [
- 'created_at' => 'datetime',
- 'updated_at' => 'datetime',
- 'deleted_at' => 'datetime',
- 'encrypted' => 'boolean',
- ];
- /** @var array Fields that can be filled */
+ = [
+ 'created_at' => 'datetime',
+ 'updated_at' => 'datetime',
+ 'deleted_at' => 'datetime',
+ 'encrypted' => 'boolean',
+ ];
+
protected $fillable = ['user_id', 'user_group_id', 'name'];
- /** @var array Hidden from view */
- protected $hidden = ['encrypted'];
+
+ protected $hidden = ['encrypted'];
/**
* Route binder. Converts the key in the URL to the specified object (or throw 404).
*
- * @param string $value
- *
- * @return Category
* @throws NotFoundHttpException
*/
- public static function routeBinder(string $value): Category
+ public static function routeBinder(string $value): self
{
if (auth()->check()) {
$categoryId = (int)$value;
+
/** @var User $user */
- $user = auth()->user();
- /** @var Category $category */
- $category = $user->categories()->find($categoryId);
+ $user = auth()->user();
+
+ /** @var null|Category $category */
+ $category = $user->categories()->find($categoryId);
if (null !== $category) {
return $category;
}
}
+
throw new NotFoundHttpException();
}
- /**
- * @return BelongsTo
- */
public function user(): BelongsTo
{
return $this->belongsTo(User::class);
}
- /**
- * @return MorphMany
- */
public function attachments(): MorphMany
{
return $this->morphMany(Attachment::class, 'attachable');
@@ -140,17 +137,11 @@ class Category extends Model
return $this->morphMany(Note::class, 'noteable');
}
- /**
- * @return BelongsToMany
- */
public function transactionJournals(): BelongsToMany
{
return $this->belongsToMany(TransactionJournal::class, 'category_transaction_journal', 'category_id');
}
- /**
- * @return BelongsToMany
- */
public function transactions(): BelongsToMany
{
return $this->belongsToMany(Transaction::class, 'category_transaction', 'category_id');
diff --git a/app/Models/Configuration.php b/app/Models/Configuration.php
index 8abf4eb569..815e3aaa63 100644
--- a/app/Models/Configuration.php
+++ b/app/Models/Configuration.php
@@ -23,24 +23,26 @@ declare(strict_types=1);
namespace FireflyIII\Models;
+use Carbon\Carbon;
use Eloquent;
+use FireflyIII\Support\Models\ReturnsIntegerIdTrait;
use Illuminate\Database\Eloquent\Model;
use Illuminate\Database\Eloquent\SoftDeletes;
use Illuminate\Database\Query\Builder;
-use Illuminate\Support\Carbon;
/**
* FireflyIII\Models\Configuration
*
* @property int $id
- * @property Carbon|null $created_at
- * @property Carbon|null $updated_at
- * @property Carbon|null $deleted_at
+ * @property null|Carbon $created_at
+ * @property null|Carbon $updated_at
+ * @property null|Carbon $deleted_at
* @property string $name
* @property mixed $data
+ *
* @method static \Illuminate\Database\Eloquent\Builder|Configuration newModelQuery()
* @method static \Illuminate\Database\Eloquent\Builder|Configuration newQuery()
- * @method static Builder|Configuration onlyTrashed()
+ * @method static Builder|Configuration onlyTrashed()
* @method static \Illuminate\Database\Eloquent\Builder|Configuration query()
* @method static \Illuminate\Database\Eloquent\Builder|Configuration whereCreatedAt($value)
* @method static \Illuminate\Database\Eloquent\Builder|Configuration whereData($value)
@@ -48,32 +50,29 @@ use Illuminate\Support\Carbon;
* @method static \Illuminate\Database\Eloquent\Builder|Configuration whereId($value)
* @method static \Illuminate\Database\Eloquent\Builder|Configuration whereName($value)
* @method static \Illuminate\Database\Eloquent\Builder|Configuration whereUpdatedAt($value)
- * @method static Builder|Configuration withTrashed()
- * @method static Builder|Configuration withoutTrashed()
+ * @method static Builder|Configuration withTrashed()
+ * @method static Builder|Configuration withoutTrashed()
+ *
* @mixin Eloquent
*/
class Configuration extends Model
{
+ use ReturnsIntegerIdTrait;
use SoftDeletes;
- /**
- * The attributes that should be casted to native types.
- *
- * @var array
- */
protected $casts
- = [
- 'created_at' => 'datetime',
- 'updated_at' => 'datetime',
- 'deleted_at' => 'datetime',
- ];
+ = [
+ 'created_at' => 'datetime',
+ 'updated_at' => 'datetime',
+ 'deleted_at' => 'datetime',
+ ];
+
/** @var string The table to store the data in */
protected $table = 'configuration';
/**
* TODO can be replaced with native laravel code.
*
- *
* @param mixed $value
*
* @return mixed
@@ -84,7 +83,6 @@ class Configuration extends Model
}
/**
- *
* @param mixed $value
*/
public function setDataAttribute($value): void
diff --git a/app/Models/CurrencyExchangeRate.php b/app/Models/CurrencyExchangeRate.php
index 31a95e8348..c4cf0a4d49 100644
--- a/app/Models/CurrencyExchangeRate.php
+++ b/app/Models/CurrencyExchangeRate.php
@@ -23,31 +23,34 @@ declare(strict_types=1);
namespace FireflyIII\Models;
+use Carbon\Carbon;
use Eloquent;
+use FireflyIII\Support\Models\ReturnsIntegerIdTrait;
+use FireflyIII\Support\Models\ReturnsIntegerUserIdTrait;
use FireflyIII\User;
use Illuminate\Database\Eloquent\Builder;
use Illuminate\Database\Eloquent\Casts\Attribute;
use Illuminate\Database\Eloquent\Model;
use Illuminate\Database\Eloquent\Relations\BelongsTo;
use Illuminate\Database\Eloquent\SoftDeletes;
-use Illuminate\Support\Carbon;
/**
* Class CurrencyExchangeRate
*
- * @property int $id
- * @property Carbon|null $created_at
- * @property Carbon|null $updated_at
- * @property string|null $deleted_at
- * @property int $user_id
- * @property int $from_currency_id
- * @property int $to_currency_id
- * @property Carbon $date
- * @property string $rate
- * @property string|null $user_rate
- * @property-read TransactionCurrency $fromCurrency
- * @property-read TransactionCurrency $toCurrency
- * @property-read User $user
+ * @property int $id
+ * @property null|Carbon $created_at
+ * @property null|Carbon $updated_at
+ * @property null|string $deleted_at
+ * @property int $user_id
+ * @property int $from_currency_id
+ * @property int $to_currency_id
+ * @property Carbon $date
+ * @property string $rate
+ * @property string $user_rate
+ * @property TransactionCurrency $fromCurrency
+ * @property TransactionCurrency $toCurrency
+ * @property User $user
+ *
* @method static Builder|CurrencyExchangeRate newModelQuery()
* @method static Builder|CurrencyExchangeRate newQuery()
* @method static Builder|CurrencyExchangeRate query()
@@ -61,70 +64,73 @@ use Illuminate\Support\Carbon;
* @method static Builder|CurrencyExchangeRate whereUpdatedAt($value)
* @method static Builder|CurrencyExchangeRate whereUserId($value)
* @method static Builder|CurrencyExchangeRate whereUserRate($value)
- * @property int|null $user_group_id
+ *
+ * @property int $user_group_id
+ *
* @method static Builder|CurrencyExchangeRate whereUserGroupId($value)
* @method static Builder|CurrencyExchangeRate onlyTrashed()
* @method static Builder|CurrencyExchangeRate withTrashed()
* @method static Builder|CurrencyExchangeRate withoutTrashed()
+ *
* @mixin Eloquent
*/
class CurrencyExchangeRate extends Model
{
+ use ReturnsIntegerIdTrait;
+ use ReturnsIntegerUserIdTrait;
use SoftDeletes;
- /** @var array Convert these fields to other data types */
protected $casts
= [
- 'created_at' => 'datetime',
- 'updated_at' => 'datetime',
- 'user_id' => 'int',
- 'from_currency_id' => 'int',
- 'to_currency_id' => 'int',
- 'date' => 'datetime',
- ];
+ 'created_at' => 'datetime',
+ 'updated_at' => 'datetime',
+ 'user_id' => 'int',
+ 'from_currency_id' => 'int',
+ 'to_currency_id' => 'int',
+ 'date' => 'datetime',
+ ];
protected $fillable = ['user_id', 'from_currency_id', 'to_currency_id', 'date', 'rate'];
- /**
- * @return BelongsTo
- */
public function fromCurrency(): BelongsTo
{
return $this->belongsTo(TransactionCurrency::class, 'from_currency_id');
}
- /**
- * @return BelongsTo
- */
public function toCurrency(): BelongsTo
{
return $this->belongsTo(TransactionCurrency::class, 'to_currency_id');
}
- /**
- * @return BelongsTo
- */
public function user(): BelongsTo
{
return $this->belongsTo(User::class);
}
- /**
- * @return Attribute
- */
- protected function rate(): Attribute
+ protected function fromCurrencyId(): Attribute
{
return Attribute::make(
- get: fn ($value) => (string)$value,
+ get: static fn ($value) => (int)$value,
+ );
+ }
+
+ protected function rate(): Attribute
+ {
+ return Attribute::make(
+ get: static fn ($value) => (string)$value,
+ );
+ }
+
+ protected function toCurrencyId(): Attribute
+ {
+ return Attribute::make(
+ get: static fn ($value) => (int)$value,
);
}
- /**
- * @return Attribute
- */
protected function userRate(): Attribute
{
return Attribute::make(
- get: fn ($value) => (string)$value,
+ get: static fn ($value) => (string)$value,
);
}
}
diff --git a/app/Models/GroupMembership.php b/app/Models/GroupMembership.php
index 1af5447862..add3a01472 100644
--- a/app/Models/GroupMembership.php
+++ b/app/Models/GroupMembership.php
@@ -24,26 +24,30 @@ declare(strict_types=1);
namespace FireflyIII\Models;
+use Carbon\Carbon;
use Eloquent;
+use FireflyIII\Support\Models\ReturnsIntegerIdTrait;
+use FireflyIII\Support\Models\ReturnsIntegerUserIdTrait;
use FireflyIII\User;
use Illuminate\Database\Eloquent\Builder;
+use Illuminate\Database\Eloquent\Casts\Attribute;
use Illuminate\Database\Eloquent\Model;
use Illuminate\Database\Eloquent\Relations\BelongsTo;
-use Illuminate\Support\Carbon;
/**
* Class GroupMembership
*
- * @property int $id
- * @property Carbon|null $created_at
- * @property Carbon|null $updated_at
- * @property string|null $deleted_at
- * @property int $user_id
- * @property int $user_group_id
- * @property int $user_role_id
- * @property-read User $user
- * @property-read UserGroup $userGroup
- * @property-read UserRole $userRole
+ * @property int $id
+ * @property null|Carbon $created_at
+ * @property null|Carbon $updated_at
+ * @property null|string $deleted_at
+ * @property int $user_id
+ * @property int $user_group_id
+ * @property int $user_role_id
+ * @property User $user
+ * @property UserGroup $userGroup
+ * @property UserRole $userRole
+ *
* @method static Builder|GroupMembership newModelQuery()
* @method static Builder|GroupMembership newQuery()
* @method static Builder|GroupMembership query()
@@ -54,33 +58,35 @@ use Illuminate\Support\Carbon;
* @method static Builder|GroupMembership whereUserGroupId($value)
* @method static Builder|GroupMembership whereUserId($value)
* @method static Builder|GroupMembership whereUserRoleId($value)
+ *
* @mixin Eloquent
*/
class GroupMembership extends Model
{
+ use ReturnsIntegerIdTrait;
+ use ReturnsIntegerUserIdTrait;
+
protected $fillable = ['user_id', 'user_group_id', 'user_role_id'];
- /**
- * @return BelongsTo
- */
public function user(): BelongsTo
{
return $this->belongsTo(User::class);
}
- /**
- * @return BelongsTo
- */
public function userGroup(): BelongsTo
{
return $this->belongsTo(UserGroup::class);
}
- /**
- * @return BelongsTo
- */
public function userRole(): BelongsTo
{
return $this->belongsTo(UserRole::class);
}
+
+ protected function userRoleId(): Attribute
+ {
+ return Attribute::make(
+ get: static fn ($value) => (int)$value,
+ );
+ }
}
diff --git a/app/Models/InvitedUser.php b/app/Models/InvitedUser.php
index b0203f49f3..2ef0a11f7b 100644
--- a/app/Models/InvitedUser.php
+++ b/app/Models/InvitedUser.php
@@ -26,6 +26,8 @@ namespace FireflyIII\Models;
use Carbon\Carbon;
use Eloquent;
+use FireflyIII\Support\Models\ReturnsIntegerIdTrait;
+use FireflyIII\Support\Models\ReturnsIntegerUserIdTrait;
use FireflyIII\User;
use Illuminate\Database\Eloquent\Builder;
use Illuminate\Database\Eloquent\Model;
@@ -35,18 +37,21 @@ use Symfony\Component\HttpKernel\Exception\NotFoundHttpException;
/**
* Class InvitedUser
*
- * @property-read User $user
+ * @property User $user
+ *
* @method static Builder|InvitedUser newModelQuery()
* @method static Builder|InvitedUser newQuery()
* @method static Builder|InvitedUser query()
+ *
* @property int $id
- * @property Carbon|null $created_at
- * @property Carbon|null $updated_at
+ * @property null|Carbon $created_at
+ * @property null|Carbon $updated_at
* @property int $user_id
* @property string $email
* @property string $invite_code
* @property Carbon $expires
* @property bool $redeemed
+ *
* @method static Builder|InvitedUser whereCreatedAt($value)
* @method static Builder|InvitedUser whereEmail($value)
* @method static Builder|InvitedUser whereExpires($value)
@@ -55,40 +60,39 @@ use Symfony\Component\HttpKernel\Exception\NotFoundHttpException;
* @method static Builder|InvitedUser whereRedeemed($value)
* @method static Builder|InvitedUser whereUpdatedAt($value)
* @method static Builder|InvitedUser whereUserId($value)
+ *
* @mixin Eloquent
*/
class InvitedUser extends Model
{
+ use ReturnsIntegerIdTrait;
+ use ReturnsIntegerUserIdTrait;
+
protected $casts
= [
- 'expires' => 'datetime',
- 'redeemed' => 'boolean',
- ];
+ 'expires' => 'datetime',
+ 'redeemed' => 'boolean',
+ ];
protected $fillable = ['user_id', 'email', 'invite_code', 'expires', 'redeemed'];
/**
* Route binder. Converts the key in the URL to the specified object (or throw 404).
- *
- * @param string $value
- *
- * @return InvitedUser
*/
- public static function routeBinder(string $value): InvitedUser
+ public static function routeBinder(string $value): self
{
if (auth()->check()) {
$attemptId = (int)$value;
- /** @var InvitedUser $attempt */
- $attempt = self::find($attemptId);
+
+ /** @var null|InvitedUser $attempt */
+ $attempt = self::find($attemptId);
if (null !== $attempt) {
return $attempt;
}
}
+
throw new NotFoundHttpException();
}
- /**
- * @return BelongsTo
- */
public function user(): BelongsTo
{
return $this->belongsTo(User::class);
diff --git a/app/Models/LinkType.php b/app/Models/LinkType.php
index 1703672153..f08edd46c8 100644
--- a/app/Models/LinkType.php
+++ b/app/Models/LinkType.php
@@ -23,32 +23,34 @@ declare(strict_types=1);
namespace FireflyIII\Models;
+use Carbon\Carbon;
use Eloquent;
+use FireflyIII\Support\Models\ReturnsIntegerIdTrait;
use Illuminate\Database\Eloquent\Collection;
use Illuminate\Database\Eloquent\Model;
use Illuminate\Database\Eloquent\Relations\HasMany;
use Illuminate\Database\Eloquent\SoftDeletes;
use Illuminate\Database\Query\Builder;
-use Illuminate\Support\Carbon;
use Symfony\Component\HttpKernel\Exception\NotFoundHttpException;
/**
* FireflyIII\Models\LinkType
*
- * @property int $id
- * @property Carbon|null $created_at
- * @property Carbon|null $updated_at
- * @property Carbon|null $deleted_at
- * @property string $name
- * @property string $outward
- * @property string $inward
- * @property int $journalCount
- * @property bool $editable
- * @property-read Collection|TransactionJournalLink[] $transactionJournalLinks
- * @property-read int|null $transaction_journal_links_count
+ * @property int $id
+ * @property null|Carbon $created_at
+ * @property null|Carbon $updated_at
+ * @property null|Carbon $deleted_at
+ * @property string $name
+ * @property string $outward
+ * @property string $inward
+ * @property int $journalCount
+ * @property bool $editable
+ * @property Collection|TransactionJournalLink[] $transactionJournalLinks
+ * @property null|int $transaction_journal_links_count
+ *
* @method static \Illuminate\Database\Eloquent\Builder|LinkType newModelQuery()
* @method static \Illuminate\Database\Eloquent\Builder|LinkType newQuery()
- * @method static Builder|LinkType onlyTrashed()
+ * @method static Builder|LinkType onlyTrashed()
* @method static \Illuminate\Database\Eloquent\Builder|LinkType query()
* @method static \Illuminate\Database\Eloquent\Builder|LinkType whereCreatedAt($value)
* @method static \Illuminate\Database\Eloquent\Builder|LinkType whereDeletedAt($value)
@@ -58,40 +60,32 @@ use Symfony\Component\HttpKernel\Exception\NotFoundHttpException;
* @method static \Illuminate\Database\Eloquent\Builder|LinkType whereName($value)
* @method static \Illuminate\Database\Eloquent\Builder|LinkType whereOutward($value)
* @method static \Illuminate\Database\Eloquent\Builder|LinkType whereUpdatedAt($value)
- * @method static Builder|LinkType withTrashed()
- * @method static Builder|LinkType withoutTrashed()
+ * @method static Builder|LinkType withTrashed()
+ * @method static Builder|LinkType withoutTrashed()
+ *
* @mixin Eloquent
*/
class LinkType extends Model
{
+ use ReturnsIntegerIdTrait;
use SoftDeletes;
- /**
- * The attributes that should be casted to native types.
- *
- * @var array
- */
protected $casts
- = [
- 'created_at' => 'datetime',
- 'updated_at' => 'datetime',
- 'deleted_at' => 'datetime',
- 'editable' => 'boolean',
- ];
+ = [
+ 'created_at' => 'datetime',
+ 'updated_at' => 'datetime',
+ 'deleted_at' => 'datetime',
+ 'editable' => 'boolean',
+ ];
- /** @var array Fields that can be filled */
protected $fillable = ['name', 'inward', 'outward', 'editable'];
/**
* Route binder. Converts the key in the URL to the specified object (or throw 404).
*
- * @param string $value
- *
- * @return LinkType
- *
* @throws NotFoundHttpException
*/
- public static function routeBinder(string $value): LinkType
+ public static function routeBinder(string $value): self
{
if (auth()->check()) {
$linkTypeId = (int)$value;
@@ -100,12 +94,10 @@ class LinkType extends Model
return $linkType;
}
}
+
throw new NotFoundHttpException();
}
- /**
- * @return HasMany
- */
public function transactionJournalLinks(): HasMany
{
return $this->hasMany(TransactionJournalLink::class);
diff --git a/app/Models/Location.php b/app/Models/Location.php
index 76ea452351..4b0d913db2 100644
--- a/app/Models/Location.php
+++ b/app/Models/Location.php
@@ -24,29 +24,32 @@ declare(strict_types=1);
namespace FireflyIII\Models;
+use Carbon\Carbon;
use Eloquent;
+use FireflyIII\Support\Models\ReturnsIntegerIdTrait;
use Illuminate\Database\Eloquent\Builder;
+use Illuminate\Database\Eloquent\Casts\Attribute;
use Illuminate\Database\Eloquent\Collection;
use Illuminate\Database\Eloquent\Model;
use Illuminate\Database\Eloquent\Relations\MorphMany;
use Illuminate\Database\Eloquent\Relations\MorphTo;
-use Illuminate\Support\Carbon;
/**
* FireflyIII\Models\Location
*
- * @property int $id
- * @property Carbon|null $created_at
- * @property Carbon|null $updated_at
- * @property Carbon|null $deleted_at
- * @property int $locatable_id
- * @property string $locatable_type
- * @property float|null $latitude
- * @property float|null $longitude
- * @property int|null $zoom_level
- * @property-read Collection|Account[] $accounts
- * @property-read int|null $accounts_count
- * @property-read Model|Eloquent $locatable
+ * @property int $id
+ * @property null|Carbon $created_at
+ * @property null|Carbon $updated_at
+ * @property null|Carbon $deleted_at
+ * @property int $locatable_id
+ * @property string $locatable_type
+ * @property null|float $latitude
+ * @property null|float $longitude
+ * @property null|int $zoom_level
+ * @property Account[]|Collection $accounts
+ * @property null|int $accounts_count
+ * @property \Eloquent|Model $locatable
+ *
* @method static Builder|Location newModelQuery()
* @method static Builder|Location newQuery()
* @method static Builder|Location query()
@@ -59,33 +62,30 @@ use Illuminate\Support\Carbon;
* @method static Builder|Location whereLongitude($value)
* @method static Builder|Location whereUpdatedAt($value)
* @method static Builder|Location whereZoomLevel($value)
+ *
+ * @property Collection $transactionJournals
+ * @property null|int $transaction_journals_count
+ *
* @mixin Eloquent
*/
class Location extends Model
{
- /**
- * The attributes that should be casted to native types.
- *
- * @var array
- */
+ use ReturnsIntegerIdTrait;
+
protected $casts
- = [
- 'created_at' => 'datetime',
- 'updated_at' => 'datetime',
- 'deleted_at' => 'datetime',
- 'zoomLevel' => 'int',
- 'latitude' => 'float',
- 'longitude' => 'float',
- ];
- /** @var array Fields that can be filled */
+ = [
+ 'created_at' => 'datetime',
+ 'updated_at' => 'datetime',
+ 'deleted_at' => 'datetime',
+ 'zoomLevel' => 'int',
+ 'latitude' => 'float',
+ 'longitude' => 'float',
+ ];
+
protected $fillable = ['locatable_id', 'locatable_type', 'latitude', 'longitude', 'zoom_level'];
/**
* Add rules for locations.
- *
- * @param array $rules
- *
- * @return array
*/
public static function requestRules(array $rules): array
{
@@ -96,22 +96,28 @@ class Location extends Model
return $rules;
}
- /**
- * Get all the accounts.
- */
public function accounts(): MorphMany
{
- return $this->morphMany(Account::class, 'noteable');
+ return $this->morphMany(Account::class, 'locatable');
}
/**
* Get all the owning attachable models.
- *
- *
- * @return MorphTo
*/
public function locatable(): MorphTo
{
return $this->morphTo();
}
+
+ public function transactionJournals(): MorphMany
+ {
+ return $this->morphMany(TransactionJournal::class, 'locatable');
+ }
+
+ protected function locatableId(): Attribute
+ {
+ return Attribute::make(
+ get: static fn ($value) => (int)$value,
+ );
+ }
}
diff --git a/app/Models/Note.php b/app/Models/Note.php
index 1a8a2cab11..d3238150da 100644
--- a/app/Models/Note.php
+++ b/app/Models/Note.php
@@ -23,28 +23,31 @@ declare(strict_types=1);
namespace FireflyIII\Models;
+use Carbon\Carbon;
use Eloquent;
+use FireflyIII\Support\Models\ReturnsIntegerIdTrait;
+use Illuminate\Database\Eloquent\Casts\Attribute;
use Illuminate\Database\Eloquent\Model;
use Illuminate\Database\Eloquent\Relations\MorphTo;
use Illuminate\Database\Eloquent\SoftDeletes;
use Illuminate\Database\Query\Builder;
-use Illuminate\Support\Carbon;
/**
* FireflyIII\Models\Note
*
- * @property int $id
- * @property Carbon|null $created_at
- * @property Carbon|null $updated_at
- * @property Carbon|null $deleted_at
- * @property int $noteable_id
- * @property string $noteable_type
- * @property string|null $title
- * @property string|null $text
- * @property-read Model|Eloquent $noteable
+ * @property int $id
+ * @property null|Carbon $created_at
+ * @property null|Carbon $updated_at
+ * @property null|Carbon $deleted_at
+ * @property int $noteable_id
+ * @property string $noteable_type
+ * @property null|string $title
+ * @property null|string $text
+ * @property \Eloquent|Model $noteable
+ *
* @method static \Illuminate\Database\Eloquent\Builder|Note newModelQuery()
* @method static \Illuminate\Database\Eloquent\Builder|Note newQuery()
- * @method static Builder|Note onlyTrashed()
+ * @method static Builder|Note onlyTrashed()
* @method static \Illuminate\Database\Eloquent\Builder|Note query()
* @method static \Illuminate\Database\Eloquent\Builder|Note whereCreatedAt($value)
* @method static \Illuminate\Database\Eloquent\Builder|Note whereDeletedAt($value)
@@ -54,34 +57,37 @@ use Illuminate\Support\Carbon;
* @method static \Illuminate\Database\Eloquent\Builder|Note whereText($value)
* @method static \Illuminate\Database\Eloquent\Builder|Note whereTitle($value)
* @method static \Illuminate\Database\Eloquent\Builder|Note whereUpdatedAt($value)
- * @method static Builder|Note withTrashed()
- * @method static Builder|Note withoutTrashed()
+ * @method static Builder|Note withTrashed()
+ * @method static Builder|Note withoutTrashed()
+ *
* @mixin Eloquent
*/
class Note extends Model
{
+ use ReturnsIntegerIdTrait;
use SoftDeletes;
- /**
- * The attributes that should be casted to native types.
- *
- * @var array
- */
protected $casts
- = [
- 'created_at' => 'datetime',
- 'updated_at' => 'datetime',
- 'deleted_at' => 'datetime',
- ];
- /** @var array Fields that can be filled */
+ = [
+ 'created_at' => 'datetime',
+ 'updated_at' => 'datetime',
+ 'deleted_at' => 'datetime',
+ ];
+
protected $fillable = ['title', 'text', 'noteable_id', 'noteable_type'];
/**
- *
* Get all the owning noteable models.
*/
public function noteable(): MorphTo
{
return $this->morphTo();
}
+
+ protected function noteableId(): Attribute
+ {
+ return Attribute::make(
+ get: static fn ($value) => (int)$value,
+ );
+ }
}
diff --git a/app/Models/ObjectGroup.php b/app/Models/ObjectGroup.php
index af3b8e813b..bd5d2ba832 100644
--- a/app/Models/ObjectGroup.php
+++ b/app/Models/ObjectGroup.php
@@ -24,33 +24,37 @@ declare(strict_types=1);
namespace FireflyIII\Models;
+use Carbon\Carbon;
use Eloquent;
+use FireflyIII\Support\Models\ReturnsIntegerIdTrait;
+use FireflyIII\Support\Models\ReturnsIntegerUserIdTrait;
use FireflyIII\User;
use Illuminate\Database\Eloquent\Builder;
+use Illuminate\Database\Eloquent\Casts\Attribute;
use Illuminate\Database\Eloquent\Collection;
use Illuminate\Database\Eloquent\Model;
use Illuminate\Database\Eloquent\Relations\BelongsTo;
use Illuminate\Database\Eloquent\Relations\MorphToMany;
-use Illuminate\Support\Carbon;
use Symfony\Component\HttpKernel\Exception\NotFoundHttpException;
/**
* FireflyIII\Models\ObjectGroup
*
- * @property int $id
- * @property int $user_id
- * @property Carbon|null $created_at
- * @property Carbon|null $updated_at
- * @property Carbon|null $deleted_at
- * @property string $title
- * @property int $order
- * @property-read Collection|Account[] $accounts
- * @property-read int|null $accounts_count
- * @property-read Collection|Bill[] $bills
- * @property-read int|null $bills_count
- * @property-read Collection|PiggyBank[] $piggyBanks
- * @property-read int|null $piggy_banks_count
- * @property-read User $user
+ * @property int $id
+ * @property int $user_id
+ * @property null|Carbon $created_at
+ * @property null|Carbon $updated_at
+ * @property null|Carbon $deleted_at
+ * @property string $title
+ * @property int $order
+ * @property Account[]|Collection $accounts
+ * @property null|int $accounts_count
+ * @property Bill[]|Collection $bills
+ * @property null|int $bills_count
+ * @property Collection|PiggyBank[] $piggyBanks
+ * @property null|int $piggy_banks_count
+ * @property User $user
+ *
* @method static Builder|ObjectGroup newModelQuery()
* @method static Builder|ObjectGroup newQuery()
* @method static Builder|ObjectGroup query()
@@ -61,51 +65,49 @@ use Symfony\Component\HttpKernel\Exception\NotFoundHttpException;
* @method static Builder|ObjectGroup whereTitle($value)
* @method static Builder|ObjectGroup whereUpdatedAt($value)
* @method static Builder|ObjectGroup whereUserId($value)
- * @property int|null $user_group_id
+ *
+ * @property int $user_group_id
+ *
* @method static Builder|ObjectGroup whereUserGroupId($value)
+ *
* @mixin Eloquent
*/
class ObjectGroup extends Model
{
- /**
- * The attributes that should be casted to native types.
- *
- * @var array
- */
+ use ReturnsIntegerIdTrait;
+ use ReturnsIntegerUserIdTrait;
+
protected $casts
= [
- 'created_at' => 'datetime',
- 'updated_at' => 'datetime',
- 'user_id' => 'integer',
- 'deleted_at' => 'datetime',
- ];
+ 'created_at' => 'datetime',
+ 'updated_at' => 'datetime',
+ 'user_id' => 'integer',
+ 'deleted_at' => 'datetime',
+ ];
protected $fillable = ['title', 'order', 'user_id', 'user_group_id'];
/**
* Route binder. Converts the key in the URL to the specified object (or throw 404).
*
- * @param string $value
- *
- * @return ObjectGroup
* @throws NotFoundHttpException
*/
- public static function routeBinder(string $value): ObjectGroup
+ public static function routeBinder(string $value): self
{
if (auth()->check()) {
$objectGroupId = (int)$value;
- /** @var ObjectGroup $objectGroup */
- $objectGroup = self::where('object_groups.id', $objectGroupId)
- ->where('object_groups.user_id', auth()->user()->id)->first();
+
+ /** @var null|ObjectGroup $objectGroup */
+ $objectGroup = self::where('object_groups.id', $objectGroupId)
+ ->where('object_groups.user_id', auth()->user()->id)->first()
+ ;
if (null !== $objectGroup) {
return $objectGroup;
}
}
+
throw new NotFoundHttpException();
}
- /**
- * @return BelongsTo
- */
public function user(): BelongsTo
{
return $this->belongsTo(User::class);
@@ -134,4 +136,11 @@ class ObjectGroup extends Model
{
return $this->morphedByMany(PiggyBank::class, 'object_groupable');
}
+
+ protected function order(): Attribute
+ {
+ return Attribute::make(
+ get: static fn ($value) => (int)$value,
+ );
+ }
}
diff --git a/app/Models/PiggyBank.php b/app/Models/PiggyBank.php
index 47c5aa6de0..912748415f 100644
--- a/app/Models/PiggyBank.php
+++ b/app/Models/PiggyBank.php
@@ -23,47 +23,50 @@ declare(strict_types=1);
namespace FireflyIII\Models;
+use Carbon\Carbon;
use Eloquent;
+use FireflyIII\Support\Models\ReturnsIntegerIdTrait;
use Illuminate\Database\Eloquent\Casts\Attribute;
use Illuminate\Database\Eloquent\Collection;
use Illuminate\Database\Eloquent\Model;
use Illuminate\Database\Eloquent\Relations\BelongsTo;
use Illuminate\Database\Eloquent\Relations\HasMany;
use Illuminate\Database\Eloquent\Relations\MorphMany;
+use Illuminate\Database\Eloquent\Relations\MorphToMany;
use Illuminate\Database\Eloquent\SoftDeletes;
use Illuminate\Database\Query\Builder;
-use Illuminate\Support\Carbon;
use Symfony\Component\HttpKernel\Exception\NotFoundHttpException;
/**
* FireflyIII\Models\PiggyBank
*
- * @property int $id
- * @property Carbon|null $created_at
- * @property Carbon|null $updated_at
- * @property Carbon|null $deleted_at
- * @property int $account_id
- * @property string $name
- * @property string $targetamount
- * @property Carbon|null $startdate
- * @property Carbon|null $targetdate
- * @property int $order
- * @property bool $active
- * @property bool $encrypted
- * @property-read Account $account
- * @property-read Collection|Attachment[] $attachments
- * @property-read int|null $attachments_count
- * @property-read Collection|Note[] $notes
- * @property-read int|null $notes_count
- * @property-read Collection|ObjectGroup[] $objectGroups
- * @property-read int|null $object_groups_count
- * @property-read Collection|PiggyBankEvent[] $piggyBankEvents
- * @property-read int|null $piggy_bank_events_count
- * @property-read Collection|PiggyBankRepetition[] $piggyBankRepetitions
- * @property-read int|null $piggy_bank_repetitions_count
+ * @property int $id
+ * @property null|Carbon $created_at
+ * @property null|Carbon $updated_at
+ * @property null|Carbon $deleted_at
+ * @property int $account_id
+ * @property string $name
+ * @property string $targetamount
+ * @property null|Carbon $startdate
+ * @property null|Carbon $targetdate
+ * @property int $order
+ * @property bool $active
+ * @property bool $encrypted
+ * @property Account $account
+ * @property Attachment[]|Collection $attachments
+ * @property null|int $attachments_count
+ * @property Collection|Note[] $notes
+ * @property null|int $notes_count
+ * @property Collection|ObjectGroup[] $objectGroups
+ * @property null|int $object_groups_count
+ * @property Collection|PiggyBankEvent[] $piggyBankEvents
+ * @property null|int $piggy_bank_events_count
+ * @property Collection|PiggyBankRepetition[] $piggyBankRepetitions
+ * @property null|int $piggy_bank_repetitions_count
+ *
* @method static \Illuminate\Database\Eloquent\Builder|PiggyBank newModelQuery()
* @method static \Illuminate\Database\Eloquent\Builder|PiggyBank newQuery()
- * @method static Builder|PiggyBank onlyTrashed()
+ * @method static Builder|PiggyBank onlyTrashed()
* @method static \Illuminate\Database\Eloquent\Builder|PiggyBank query()
* @method static \Illuminate\Database\Eloquent\Builder|PiggyBank whereAccountId($value)
* @method static \Illuminate\Database\Eloquent\Builder|PiggyBank whereActive($value)
@@ -77,75 +80,65 @@ use Symfony\Component\HttpKernel\Exception\NotFoundHttpException;
* @method static \Illuminate\Database\Eloquent\Builder|PiggyBank whereTargetamount($value)
* @method static \Illuminate\Database\Eloquent\Builder|PiggyBank whereTargetdate($value)
* @method static \Illuminate\Database\Eloquent\Builder|PiggyBank whereUpdatedAt($value)
- * @method static Builder|PiggyBank withTrashed()
- * @method static Builder|PiggyBank withoutTrashed()
+ * @method static Builder|PiggyBank withTrashed()
+ * @method static Builder|PiggyBank withoutTrashed()
+ *
* @mixin Eloquent
*/
class PiggyBank extends Model
{
+ use ReturnsIntegerIdTrait;
use SoftDeletes;
- /**
- * The attributes that should be cast to native types.
- *
- * @var array
- */
protected $casts
- = [
- 'created_at' => 'datetime',
- 'updated_at' => 'datetime',
- 'deleted_at' => 'datetime',
- 'startdate' => 'date',
- 'targetdate' => 'date',
- 'order' => 'int',
- 'active' => 'boolean',
- 'encrypted' => 'boolean',
- ];
- /** @var array Fields that can be filled */
+ = [
+ 'created_at' => 'datetime',
+ 'updated_at' => 'datetime',
+ 'deleted_at' => 'datetime',
+ 'startdate' => 'date',
+ 'targetdate' => 'date',
+ 'order' => 'int',
+ 'active' => 'boolean',
+ 'encrypted' => 'boolean',
+ ];
+
protected $fillable = ['name', 'account_id', 'order', 'targetamount', 'startdate', 'targetdate', 'active'];
- /** @var array Hidden from view */
- protected $hidden = ['targetamount_encrypted', 'encrypted'];
+
+ protected $hidden = ['targetamount_encrypted', 'encrypted'];
/**
* Route binder. Converts the key in the URL to the specified object (or throw 404).
*
- * @param string $value
- *
- * @return PiggyBank
* @throws NotFoundHttpException
*/
- public static function routeBinder(string $value): PiggyBank
+ public static function routeBinder(string $value): self
{
if (auth()->check()) {
$piggyBankId = (int)$value;
$piggyBank = self::where('piggy_banks.id', $piggyBankId)
- ->leftJoin('accounts', 'accounts.id', '=', 'piggy_banks.account_id')
- ->where('accounts.user_id', auth()->user()->id)->first(['piggy_banks.*']);
+ ->leftJoin('accounts', 'accounts.id', '=', 'piggy_banks.account_id')
+ ->where('accounts.user_id', auth()->user()->id)->first(['piggy_banks.*'])
+ ;
if (null !== $piggyBank) {
return $piggyBank;
}
}
+
throw new NotFoundHttpException();
}
- /**
- * @return BelongsTo
- */
public function account(): BelongsTo
{
return $this->belongsTo(Account::class);
}
- /**
- * @return MorphMany
- */
public function attachments(): MorphMany
{
return $this->morphMany(Attachment::class, 'attachable');
}
/**
- * Get all of the piggy bank's notes.
+ * Get all the piggy bank's notes.
*/
public function notes(): MorphMany
{
@@ -155,29 +148,22 @@ class PiggyBank extends Model
/**
* Get all the tags for the post.
*/
- public function objectGroups()
+ public function objectGroups(): MorphToMany
{
return $this->morphToMany(ObjectGroup::class, 'object_groupable');
}
- /**
- * @return HasMany
- */
public function piggyBankEvents(): HasMany
{
return $this->hasMany(PiggyBankEvent::class);
}
- /**
- * @return HasMany
- */
public function piggyBankRepetitions(): HasMany
{
return $this->hasMany(PiggyBankRepetition::class);
}
/**
- *
* @param mixed $value
*/
public function setTargetamountAttribute($value): void
@@ -185,15 +171,27 @@ class PiggyBank extends Model
$this->attributes['targetamount'] = (string)$value;
}
+ protected function accountId(): Attribute
+ {
+ return Attribute::make(
+ get: static fn ($value) => (int)$value,
+ );
+ }
+
+ protected function order(): Attribute
+ {
+ return Attribute::make(
+ get: static fn ($value) => (int)$value,
+ );
+ }
+
/**
* Get the max amount
- *
- * @return Attribute
*/
protected function targetamount(): Attribute
{
return Attribute::make(
- get: fn ($value) => (string)$value,
+ get: static fn ($value) => (string)$value,
);
}
}
diff --git a/app/Models/PiggyBankEvent.php b/app/Models/PiggyBankEvent.php
index 8334aac725..75eef73b50 100644
--- a/app/Models/PiggyBankEvent.php
+++ b/app/Models/PiggyBankEvent.php
@@ -23,25 +23,27 @@ declare(strict_types=1);
namespace FireflyIII\Models;
+use Carbon\Carbon;
use Eloquent;
+use FireflyIII\Support\Models\ReturnsIntegerIdTrait;
use Illuminate\Database\Eloquent\Builder;
use Illuminate\Database\Eloquent\Casts\Attribute;
use Illuminate\Database\Eloquent\Model;
use Illuminate\Database\Eloquent\Relations\BelongsTo;
-use Illuminate\Support\Carbon;
/**
* FireflyIII\Models\PiggyBankEvent
*
- * @property int $id
- * @property Carbon|null $created_at
- * @property Carbon|null $updated_at
- * @property int $piggy_bank_id
- * @property int|null $transaction_journal_id
- * @property Carbon $date
- * @property string $amount
- * @property PiggyBank $piggyBank
- * @property-read TransactionJournal|null $transactionJournal
+ * @property int $id
+ * @property null|Carbon $created_at
+ * @property null|Carbon $updated_at
+ * @property int $piggy_bank_id
+ * @property null|int $transaction_journal_id
+ * @property Carbon $date
+ * @property string $amount
+ * @property PiggyBank $piggyBank
+ * @property null|TransactionJournal $transactionJournal
+ *
* @method static Builder|PiggyBankEvent newModelQuery()
* @method static Builder|PiggyBankEvent newQuery()
* @method static Builder|PiggyBankEvent query()
@@ -52,36 +54,30 @@ use Illuminate\Support\Carbon;
* @method static Builder|PiggyBankEvent wherePiggyBankId($value)
* @method static Builder|PiggyBankEvent whereTransactionJournalId($value)
* @method static Builder|PiggyBankEvent whereUpdatedAt($value)
+ *
* @mixin Eloquent
*/
class PiggyBankEvent extends Model
{
- /**
- * The attributes that should be casted to native types.
- *
- * @var array
- */
- protected $casts
- = [
- 'created_at' => 'datetime',
- 'updated_at' => 'datetime',
- 'date' => 'date',
- ];
- /** @var array Fields that can be filled */
- protected $fillable = ['piggy_bank_id', 'transaction_journal_id', 'date', 'amount'];
- /** @var array Hidden from view */
- protected $hidden = ['amount_encrypted'];
+ use ReturnsIntegerIdTrait;
+
+ protected $casts
+ = [
+ 'created_at' => 'datetime',
+ 'updated_at' => 'datetime',
+ 'date' => 'date',
+ ];
+
+ protected $fillable = ['piggy_bank_id', 'transaction_journal_id', 'date', 'amount'];
+
+ protected $hidden = ['amount_encrypted'];
- /**
- * @return BelongsTo
- */
public function piggyBank(): BelongsTo
{
return $this->belongsTo(PiggyBank::class);
}
/**
- *
* @param mixed $value
*/
public function setAmountAttribute($value): void
@@ -89,9 +85,6 @@ class PiggyBankEvent extends Model
$this->attributes['amount'] = (string)$value;
}
- /**
- * @return BelongsTo
- */
public function transactionJournal(): BelongsTo
{
return $this->belongsTo(TransactionJournal::class);
@@ -99,13 +92,18 @@ class PiggyBankEvent extends Model
/**
* Get the amount
- *
- * @return Attribute
*/
protected function amount(): Attribute
{
return Attribute::make(
- get: fn ($value) => (string)$value,
+ get: static fn ($value) => (string)$value,
+ );
+ }
+
+ protected function piggyBankId(): Attribute
+ {
+ return Attribute::make(
+ get: static fn ($value) => (int)$value,
);
}
}
diff --git a/app/Models/PiggyBankRepetition.php b/app/Models/PiggyBankRepetition.php
index c00650b38c..5926e1a7bc 100644
--- a/app/Models/PiggyBankRepetition.php
+++ b/app/Models/PiggyBankRepetition.php
@@ -25,6 +25,7 @@ namespace FireflyIII\Models;
use Carbon\Carbon;
use Eloquent;
+use FireflyIII\Support\Models\ReturnsIntegerIdTrait;
use Illuminate\Database\Eloquent\Builder as EloquentBuilder;
use Illuminate\Database\Eloquent\Casts\Attribute;
use Illuminate\Database\Eloquent\Model;
@@ -33,14 +34,15 @@ use Illuminate\Database\Eloquent\Relations\BelongsTo;
/**
* FireflyIII\Models\PiggyBankRepetition
*
- * @property int $id
- * @property \Illuminate\Support\Carbon|null $created_at
- * @property \Illuminate\Support\Carbon|null $updated_at
- * @property int $piggy_bank_id
- * @property \Illuminate\Support\Carbon|null $startdate
- * @property \Illuminate\Support\Carbon|null $targetdate
- * @property string $currentamount
- * @property-read PiggyBank $piggyBank
+ * @property int $id
+ * @property null|Carbon $created_at
+ * @property null|Carbon $updated_at
+ * @property int $piggy_bank_id
+ * @property null|Carbon $startdate
+ * @property null|Carbon $targetdate
+ * @property string $currentamount
+ * @property PiggyBank $piggyBank
+ *
* @method static EloquentBuilder|PiggyBankRepetition newModelQuery()
* @method static EloquentBuilder|PiggyBankRepetition newQuery()
* @method static EloquentBuilder|PiggyBankRepetition onDates(Carbon $start, Carbon $target)
@@ -53,71 +55,54 @@ use Illuminate\Database\Eloquent\Relations\BelongsTo;
* @method static EloquentBuilder|PiggyBankRepetition whereStartdate($value)
* @method static EloquentBuilder|PiggyBankRepetition whereTargetdate($value)
* @method static EloquentBuilder|PiggyBankRepetition whereUpdatedAt($value)
+ *
* @mixin Eloquent
*/
class PiggyBankRepetition extends Model
{
- /**
- * The attributes that should be casted to native types.
- *
- * @var array
- */
+ use ReturnsIntegerIdTrait;
+
protected $casts
- = [
- 'created_at' => 'datetime',
- 'updated_at' => 'datetime',
- 'startdate' => 'date',
- 'targetdate' => 'date',
- ];
- /** @var array Fields that can be filled */
+ = [
+ 'created_at' => 'datetime',
+ 'updated_at' => 'datetime',
+ 'startdate' => 'date',
+ 'targetdate' => 'date',
+ ];
+
protected $fillable = ['piggy_bank_id', 'startdate', 'targetdate', 'currentamount'];
- /**
- * @return BelongsTo
- */
public function piggyBank(): BelongsTo
{
return $this->belongsTo(PiggyBank::class);
}
- /**
- *
- * @param EloquentBuilder $query
- * @param Carbon $start
- * @param Carbon $target
- *
- * @return EloquentBuilder
- */
public function scopeOnDates(EloquentBuilder $query, Carbon $start, Carbon $target): EloquentBuilder
{
return $query->where('startdate', $start->format('Y-m-d'))->where('targetdate', $target->format('Y-m-d'));
}
/**
- *
- * @param EloquentBuilder $query
- * @param Carbon $date
- *
* @return EloquentBuilder
*/
public function scopeRelevantOnDate(EloquentBuilder $query, Carbon $date)
{
return $query->where(
- function (EloquentBuilder $q) use ($date) {
+ static function (EloquentBuilder $q) use ($date): void {
$q->where('startdate', '<=', $date->format('Y-m-d 00:00:00'));
$q->orWhereNull('startdate');
}
)
- ->where(
- function (EloquentBuilder $q) use ($date) {
- $q->where('targetdate', '>=', $date->format('Y-m-d 00:00:00'));
- $q->orWhereNull('targetdate');
- }
- );
+ ->where(
+ static function (EloquentBuilder $q) use ($date): void {
+ $q->where('targetdate', '>=', $date->format('Y-m-d 00:00:00'));
+ $q->orWhereNull('targetdate');
+ }
+ )
+ ;
}
/**
- *
* @param mixed $value
*/
public function setCurrentamountAttribute($value): void
@@ -127,13 +112,18 @@ class PiggyBankRepetition extends Model
/**
* Get the amount
- *
- * @return Attribute
*/
protected function currentamount(): Attribute
{
return Attribute::make(
- get: fn ($value) => (string)$value,
+ get: static fn ($value) => (string)$value,
+ );
+ }
+
+ protected function piggyBankId(): Attribute
+ {
+ return Attribute::make(
+ get: static fn ($value) => (int)$value,
);
}
}
diff --git a/app/Models/Preference.php b/app/Models/Preference.php
index e83e2e60d1..005c9769f8 100644
--- a/app/Models/Preference.php
+++ b/app/Models/Preference.php
@@ -23,24 +23,27 @@ declare(strict_types=1);
namespace FireflyIII\Models;
+use Carbon\Carbon;
use Eloquent;
+use FireflyIII\Support\Models\ReturnsIntegerIdTrait;
+use FireflyIII\Support\Models\ReturnsIntegerUserIdTrait;
use FireflyIII\User;
use Illuminate\Database\Eloquent\Builder;
use Illuminate\Database\Eloquent\Model;
use Illuminate\Database\Eloquent\Relations\BelongsTo;
-use Illuminate\Support\Carbon;
use Symfony\Component\HttpKernel\Exception\NotFoundHttpException;
/**
* FireflyIII\Models\Preference
*
* @property int $id
- * @property Carbon|null $created_at
- * @property Carbon|null $updated_at
+ * @property null|Carbon $created_at
+ * @property null|Carbon $updated_at
* @property int $user_id
* @property string $name
- * @property int|string|array|null $data
- * @property-read User $user
+ * @property null|array|int|string $data
+ * @property User $user
+ *
* @method static Builder|Preference newModelQuery()
* @method static Builder|Preference newQuery()
* @method static Builder|Preference query()
@@ -50,39 +53,35 @@ use Symfony\Component\HttpKernel\Exception\NotFoundHttpException;
* @method static Builder|Preference whereName($value)
* @method static Builder|Preference whereUpdatedAt($value)
* @method static Builder|Preference whereUserId($value)
+ *
* @mixin Eloquent
*/
class Preference extends Model
{
- /**
- * The attributes that should be casted to native types.
- *
- * @var array
- */
- protected $casts
- = [
- 'created_at' => 'datetime',
- 'updated_at' => 'datetime',
- 'data' => 'array',
- ];
+ use ReturnsIntegerIdTrait;
+ use ReturnsIntegerUserIdTrait;
+
+ protected $casts
+ = [
+ 'created_at' => 'datetime',
+ 'updated_at' => 'datetime',
+ 'data' => 'array',
+ ];
- /** @var array Fields that can be filled */
protected $fillable = ['user_id', 'data', 'name'];
/**
* Route binder. Converts the key in the URL to the specified object (or throw 404).
*
- * @param string $value
- *
- * @return Preference
* @throws NotFoundHttpException
*/
- public static function routeBinder(string $value): Preference
+ public static function routeBinder(string $value): self
{
if (auth()->check()) {
/** @var User $user */
- $user = auth()->user();
- /** @var Preference|null $preference */
+ $user = auth()->user();
+
+ /** @var null|Preference $preference */
$preference = $user->preferences()->where('name', $value)->first();
if (null === $preference) {
$preference = $user->preferences()->where('id', (int)$value)->first();
@@ -90,23 +89,21 @@ class Preference extends Model
if (null !== $preference) {
return $preference;
}
- $default = config('firefly.default_preferences');
+ $default = config('firefly.default_preferences');
if (array_key_exists($value, $default)) {
- $preference = new Preference();
+ $preference = new self();
$preference->name = $value;
$preference->data = $default[$value];
- $preference->user_id = $user->id;
+ $preference->user_id = (int)$user->id;
$preference->save();
return $preference;
}
}
+
throw new NotFoundHttpException();
}
- /**
- * @return BelongsTo
- */
public function user(): BelongsTo
{
return $this->belongsTo(User::class);
diff --git a/app/Models/Recurrence.php b/app/Models/Recurrence.php
index df6f6f21a3..7b9756c31b 100644
--- a/app/Models/Recurrence.php
+++ b/app/Models/Recurrence.php
@@ -23,8 +23,12 @@ declare(strict_types=1);
namespace FireflyIII\Models;
+use Carbon\Carbon;
use Eloquent;
+use FireflyIII\Support\Models\ReturnsIntegerIdTrait;
+use FireflyIII\Support\Models\ReturnsIntegerUserIdTrait;
use FireflyIII\User;
+use Illuminate\Database\Eloquent\Casts\Attribute;
use Illuminate\Database\Eloquent\Collection;
use Illuminate\Database\Eloquent\Model;
use Illuminate\Database\Eloquent\Relations\BelongsTo;
@@ -32,42 +36,42 @@ use Illuminate\Database\Eloquent\Relations\HasMany;
use Illuminate\Database\Eloquent\Relations\MorphMany;
use Illuminate\Database\Eloquent\SoftDeletes;
use Illuminate\Database\Query\Builder;
-use Illuminate\Support\Carbon;
use Symfony\Component\HttpKernel\Exception\NotFoundHttpException;
/**
* FireflyIII\Models\Recurrence
*
- * @property int $id
- * @property Carbon|null $created_at
- * @property Carbon|null $updated_at
- * @property Carbon|null $deleted_at
- * @property int $user_id
- * @property int $transaction_type_id
- * @property string $title
- * @property string $description
- * @property Carbon $first_date
- * @property Carbon|null $repeat_until
- * @property Carbon|null $latest_date
- * @property int $repetitions
- * @property bool $apply_rules
- * @property bool $active
- * @property-read Collection|Attachment[] $attachments
- * @property-read int|null $attachments_count
- * @property-read Collection|Note[] $notes
- * @property-read int|null $notes_count
- * @property-read Collection|RecurrenceMeta[] $recurrenceMeta
- * @property-read int|null $recurrence_meta_count
- * @property-read Collection|RecurrenceRepetition[] $recurrenceRepetitions
- * @property-read int|null $recurrence_repetitions_count
- * @property-read Collection|RecurrenceTransaction[] $recurrenceTransactions
- * @property-read int|null $recurrence_transactions_count
- * @property-read TransactionCurrency $transactionCurrency
- * @property-read TransactionType $transactionType
- * @property-read User $user
+ * @property int $id
+ * @property null|Carbon $created_at
+ * @property null|Carbon $updated_at
+ * @property null|Carbon $deleted_at
+ * @property int $user_id
+ * @property int $transaction_type_id
+ * @property string $title
+ * @property string $description
+ * @property null|Carbon $first_date
+ * @property null|Carbon $repeat_until
+ * @property null|Carbon $latest_date
+ * @property int|string $repetitions
+ * @property bool $apply_rules
+ * @property bool $active
+ * @property Attachment[]|Collection $attachments
+ * @property null|int $attachments_count
+ * @property Collection|Note[] $notes
+ * @property null|int $notes_count
+ * @property Collection|RecurrenceMeta[] $recurrenceMeta
+ * @property null|int $recurrence_meta_count
+ * @property Collection|RecurrenceRepetition[] $recurrenceRepetitions
+ * @property null|int $recurrence_repetitions_count
+ * @property Collection|RecurrenceTransaction[] $recurrenceTransactions
+ * @property null|int $recurrence_transactions_count
+ * @property TransactionCurrency $transactionCurrency
+ * @property TransactionType $transactionType
+ * @property User $user
+ *
* @method static \Illuminate\Database\Eloquent\Builder|Recurrence newModelQuery()
* @method static \Illuminate\Database\Eloquent\Builder|Recurrence newQuery()
- * @method static Builder|Recurrence onlyTrashed()
+ * @method static Builder|Recurrence onlyTrashed()
* @method static \Illuminate\Database\Eloquent\Builder|Recurrence query()
* @method static \Illuminate\Database\Eloquent\Builder|Recurrence whereActive($value)
* @method static \Illuminate\Database\Eloquent\Builder|Recurrence whereApplyRules($value)
@@ -83,76 +87,71 @@ use Symfony\Component\HttpKernel\Exception\NotFoundHttpException;
* @method static \Illuminate\Database\Eloquent\Builder|Recurrence whereTransactionTypeId($value)
* @method static \Illuminate\Database\Eloquent\Builder|Recurrence whereUpdatedAt($value)
* @method static \Illuminate\Database\Eloquent\Builder|Recurrence whereUserId($value)
- * @method static Builder|Recurrence withTrashed()
- * @method static Builder|Recurrence withoutTrashed()
- * @property int|null $user_group_id
+ * @method static Builder|Recurrence withTrashed()
+ * @method static Builder|Recurrence withoutTrashed()
+ *
+ * @property int $user_group_id
+ *
* @method static \Illuminate\Database\Eloquent\Builder|Recurrence whereUserGroupId($value)
+ *
* @mixin Eloquent
*/
class Recurrence extends Model
{
+ use ReturnsIntegerIdTrait;
+ use ReturnsIntegerUserIdTrait;
use SoftDeletes;
- /**
- * The attributes that should be casted to native types.
- *
- * @var array
- */
protected $casts
- = [
- 'created_at' => 'datetime',
- 'updated_at' => 'datetime',
- 'deleted_at' => 'datetime',
- 'title' => 'string',
- 'id' => 'int',
- 'description' => 'string',
- 'first_date' => 'date',
- 'repeat_until' => 'date',
- 'latest_date' => 'date',
- 'repetitions' => 'int',
- 'active' => 'bool',
- 'apply_rules' => 'bool',
- ];
- /** @var array Fields that can be filled */
+ = [
+ 'created_at' => 'datetime',
+ 'updated_at' => 'datetime',
+ 'deleted_at' => 'datetime',
+ 'title' => 'string',
+ 'id' => 'int',
+ 'description' => 'string',
+ 'first_date' => 'date',
+ 'repeat_until' => 'date',
+ 'latest_date' => 'date',
+ 'repetitions' => 'int',
+ 'active' => 'bool',
+ 'apply_rules' => 'bool',
+ ];
+
protected $fillable
- = ['user_id', 'transaction_type_id', 'title', 'description', 'first_date', 'repeat_until', 'latest_date', 'repetitions', 'apply_rules', 'active'];
+ = ['user_id', 'transaction_type_id', 'title', 'description', 'first_date', 'repeat_until', 'latest_date', 'repetitions', 'apply_rules', 'active'];
+
/** @var string The table to store the data in */
protected $table = 'recurrences';
/**
* Route binder. Converts the key in the URL to the specified object (or throw 404).
*
- * @param string $value
- *
- * @return Recurrence
* @throws NotFoundHttpException
*/
- public static function routeBinder(string $value): Recurrence
+ public static function routeBinder(string $value): self
{
if (auth()->check()) {
$recurrenceId = (int)$value;
+
/** @var User $user */
- $user = auth()->user();
- /** @var Recurrence $recurrence */
- $recurrence = $user->recurrences()->find($recurrenceId);
+ $user = auth()->user();
+
+ /** @var null|Recurrence $recurrence */
+ $recurrence = $user->recurrences()->find($recurrenceId);
if (null !== $recurrence) {
return $recurrence;
}
}
+
throw new NotFoundHttpException();
}
- /**
- * @return BelongsTo
- */
public function user(): BelongsTo
{
return $this->belongsTo(User::class);
}
- /**
- * @return MorphMany
- */
public function attachments(): MorphMany
{
return $this->morphMany(Attachment::class, 'attachable');
@@ -166,43 +165,35 @@ class Recurrence extends Model
return $this->morphMany(Note::class, 'noteable');
}
- /**
- * @return HasMany
- */
public function recurrenceMeta(): HasMany
{
return $this->hasMany(RecurrenceMeta::class);
}
- /**
- * @return HasMany
- */
public function recurrenceRepetitions(): HasMany
{
return $this->hasMany(RecurrenceRepetition::class);
}
- /**
- * @return HasMany
- */
public function recurrenceTransactions(): HasMany
{
return $this->hasMany(RecurrenceTransaction::class);
}
- /**
- * @return BelongsTo
- */
public function transactionCurrency(): BelongsTo
{
return $this->belongsTo(TransactionCurrency::class);
}
- /**
- * @return BelongsTo
- */
public function transactionType(): BelongsTo
{
return $this->belongsTo(TransactionType::class);
}
+
+ protected function transactionTypeId(): Attribute
+ {
+ return Attribute::make(
+ get: static fn ($value) => (int)$value,
+ );
+ }
}
diff --git a/app/Models/RecurrenceMeta.php b/app/Models/RecurrenceMeta.php
index d5e764fb61..d7bd0c060d 100644
--- a/app/Models/RecurrenceMeta.php
+++ b/app/Models/RecurrenceMeta.php
@@ -23,27 +23,30 @@ declare(strict_types=1);
namespace FireflyIII\Models;
+use Carbon\Carbon;
use Eloquent;
+use FireflyIII\Support\Models\ReturnsIntegerIdTrait;
+use Illuminate\Database\Eloquent\Casts\Attribute;
use Illuminate\Database\Eloquent\Model;
use Illuminate\Database\Eloquent\Relations\BelongsTo;
use Illuminate\Database\Eloquent\SoftDeletes;
use Illuminate\Database\Query\Builder;
-use Illuminate\Support\Carbon;
/**
* FireflyIII\Models\RecurrenceMeta
*
- * @property int $id
- * @property Carbon|null $created_at
- * @property Carbon|null $updated_at
- * @property Carbon|null $deleted_at
- * @property int $recurrence_id
- * @property string $name
- * @property mixed $value
- * @property-read Recurrence $recurrence
+ * @property int $id
+ * @property null|Carbon $created_at
+ * @property null|Carbon $updated_at
+ * @property null|Carbon $deleted_at
+ * @property int $recurrence_id
+ * @property string $name
+ * @property mixed $value
+ * @property Recurrence $recurrence
+ *
* @method static \Illuminate\Database\Eloquent\Builder|RecurrenceMeta newModelQuery()
* @method static \Illuminate\Database\Eloquent\Builder|RecurrenceMeta newQuery()
- * @method static Builder|RecurrenceMeta onlyTrashed()
+ * @method static Builder|RecurrenceMeta onlyTrashed()
* @method static \Illuminate\Database\Eloquent\Builder|RecurrenceMeta query()
* @method static \Illuminate\Database\Eloquent\Builder|RecurrenceMeta whereCreatedAt($value)
* @method static \Illuminate\Database\Eloquent\Builder|RecurrenceMeta whereDeletedAt($value)
@@ -52,37 +55,39 @@ use Illuminate\Support\Carbon;
* @method static \Illuminate\Database\Eloquent\Builder|RecurrenceMeta whereRecurrenceId($value)
* @method static \Illuminate\Database\Eloquent\Builder|RecurrenceMeta whereUpdatedAt($value)
* @method static \Illuminate\Database\Eloquent\Builder|RecurrenceMeta whereValue($value)
- * @method static Builder|RecurrenceMeta withTrashed()
- * @method static Builder|RecurrenceMeta withoutTrashed()
+ * @method static Builder|RecurrenceMeta withTrashed()
+ * @method static Builder|RecurrenceMeta withoutTrashed()
+ *
* @mixin Eloquent
*/
class RecurrenceMeta extends Model
{
+ use ReturnsIntegerIdTrait;
use SoftDeletes;
- /**
- * The attributes that should be casted to native types.
- *
- * @var array
- */
protected $casts
- = [
- 'created_at' => 'datetime',
- 'updated_at' => 'datetime',
- 'deleted_at' => 'datetime',
- 'name' => 'string',
- 'value' => 'string',
- ];
- /** @var array Fields that can be filled */
- protected $fillable = ['recurrence_id', 'name', 'value'];
- /** @var string The table to store the data in */
- protected $table = 'recurrences_meta';
+ = [
+ 'created_at' => 'datetime',
+ 'updated_at' => 'datetime',
+ 'deleted_at' => 'datetime',
+ 'name' => 'string',
+ 'value' => 'string',
+ ];
+
+ protected $fillable = ['recurrence_id', 'name', 'value'];
+
+ /** @var string The table to store the data in */
+ protected $table = 'recurrences_meta';
- /**
- * @return BelongsTo
- */
public function recurrence(): BelongsTo
{
return $this->belongsTo(Recurrence::class);
}
+
+ protected function recurrenceId(): Attribute
+ {
+ return Attribute::make(
+ get: static fn ($value) => (int)$value,
+ );
+ }
}
diff --git a/app/Models/RecurrenceRepetition.php b/app/Models/RecurrenceRepetition.php
index 8e8970e4a3..efcb09c1b4 100644
--- a/app/Models/RecurrenceRepetition.php
+++ b/app/Models/RecurrenceRepetition.php
@@ -23,29 +23,32 @@ declare(strict_types=1);
namespace FireflyIII\Models;
+use Carbon\Carbon;
use Eloquent;
+use FireflyIII\Support\Models\ReturnsIntegerIdTrait;
+use Illuminate\Database\Eloquent\Casts\Attribute;
use Illuminate\Database\Eloquent\Model;
use Illuminate\Database\Eloquent\Relations\BelongsTo;
use Illuminate\Database\Eloquent\SoftDeletes;
use Illuminate\Database\Query\Builder;
-use Illuminate\Support\Carbon;
/**
* FireflyIII\Models\RecurrenceRepetition
*
- * @property int $id
- * @property Carbon|null $created_at
- * @property Carbon|null $updated_at
- * @property Carbon|null $deleted_at
- * @property int $recurrence_id
- * @property string $repetition_type
- * @property string $repetition_moment
- * @property int $repetition_skip
- * @property int $weekend
- * @property-read Recurrence $recurrence
+ * @property int $id
+ * @property null|Carbon $created_at
+ * @property null|Carbon $updated_at
+ * @property null|Carbon $deleted_at
+ * @property int $recurrence_id
+ * @property string $repetition_type
+ * @property string $repetition_moment
+ * @property int $repetition_skip
+ * @property int $weekend
+ * @property Recurrence $recurrence
+ *
* @method static \Illuminate\Database\Eloquent\Builder|RecurrenceRepetition newModelQuery()
* @method static \Illuminate\Database\Eloquent\Builder|RecurrenceRepetition newQuery()
- * @method static Builder|RecurrenceRepetition onlyTrashed()
+ * @method static Builder|RecurrenceRepetition onlyTrashed()
* @method static \Illuminate\Database\Eloquent\Builder|RecurrenceRepetition query()
* @method static \Illuminate\Database\Eloquent\Builder|RecurrenceRepetition whereCreatedAt($value)
* @method static \Illuminate\Database\Eloquent\Builder|RecurrenceRepetition whereDeletedAt($value)
@@ -56,44 +59,60 @@ use Illuminate\Support\Carbon;
* @method static \Illuminate\Database\Eloquent\Builder|RecurrenceRepetition whereRepetitionType($value)
* @method static \Illuminate\Database\Eloquent\Builder|RecurrenceRepetition whereUpdatedAt($value)
* @method static \Illuminate\Database\Eloquent\Builder|RecurrenceRepetition whereWeekend($value)
- * @method static Builder|RecurrenceRepetition withTrashed()
- * @method static Builder|RecurrenceRepetition withoutTrashed()
+ * @method static Builder|RecurrenceRepetition withTrashed()
+ * @method static Builder|RecurrenceRepetition withoutTrashed()
+ *
* @mixin Eloquent
*/
class RecurrenceRepetition extends Model
{
+ use ReturnsIntegerIdTrait;
use SoftDeletes;
- public const WEEKEND_DO_NOTHING = 1;
- public const WEEKEND_SKIP_CREATION = 2;
- public const WEEKEND_TO_FRIDAY = 3;
- public const WEEKEND_TO_MONDAY = 4;
+ public const int WEEKEND_DO_NOTHING = 1;
+ public const int WEEKEND_SKIP_CREATION = 2;
+ public const int WEEKEND_TO_FRIDAY = 3;
+ public const int WEEKEND_TO_MONDAY = 4;
- /**
- * The attributes that should be casted to native types.
- *
- * @var array
- */
protected $casts
- = [
- 'created_at' => 'datetime',
- 'updated_at' => 'datetime',
- 'deleted_at' => 'datetime',
- 'repetition_type' => 'string',
- 'repetition_moment' => 'string',
- 'repetition_skip' => 'int',
- 'weekend' => 'int',
- ];
- /** @var array Fields that can be filled */
- protected $fillable = ['recurrence_id', 'weekend', 'repetition_type', 'repetition_moment', 'repetition_skip'];
- /** @var string The table to store the data in */
- protected $table = 'recurrences_repetitions';
+ = [
+ 'created_at' => 'datetime',
+ 'updated_at' => 'datetime',
+ 'deleted_at' => 'datetime',
+ 'repetition_type' => 'string',
+ 'repetition_moment' => 'string',
+ 'repetition_skip' => 'int',
+ 'weekend' => 'int',
+ ];
+
+ protected $fillable = ['recurrence_id', 'weekend', 'repetition_type', 'repetition_moment', 'repetition_skip'];
+
+ /** @var string The table to store the data in */
+ protected $table = 'recurrences_repetitions';
- /**
- * @return BelongsTo
- */
public function recurrence(): BelongsTo
{
return $this->belongsTo(Recurrence::class);
}
+
+ protected function recurrenceId(): Attribute
+ {
+ return Attribute::make(
+ get: static fn ($value) => (int)$value,
+ );
+ }
+
+ protected function repetitionSkip(): Attribute
+ {
+ return Attribute::make(
+ get: static fn ($value) => (int)$value,
+ );
+ }
+
+ protected function weekend(): Attribute
+ {
+ return Attribute::make(
+ get: static fn ($value) => (int)$value,
+ );
+ }
}
diff --git a/app/Models/RecurrenceTransaction.php b/app/Models/RecurrenceTransaction.php
index e7911de4a7..f3bf0a5791 100644
--- a/app/Models/RecurrenceTransaction.php
+++ b/app/Models/RecurrenceTransaction.php
@@ -23,7 +23,9 @@ declare(strict_types=1);
namespace FireflyIII\Models;
+use Carbon\Carbon;
use Eloquent;
+use FireflyIII\Support\Models\ReturnsIntegerIdTrait;
use Illuminate\Database\Eloquent\Casts\Attribute;
use Illuminate\Database\Eloquent\Collection;
use Illuminate\Database\Eloquent\Model;
@@ -31,33 +33,33 @@ use Illuminate\Database\Eloquent\Relations\BelongsTo;
use Illuminate\Database\Eloquent\Relations\HasMany;
use Illuminate\Database\Eloquent\SoftDeletes;
use Illuminate\Database\Query\Builder;
-use Illuminate\Support\Carbon;
/**
* FireflyIII\Models\RecurrenceTransaction
*
- * @property int $id
- * @property Carbon|null $created_at
- * @property Carbon|null $updated_at
- * @property Carbon|null $deleted_at
- * @property int $recurrence_id
- * @property int $transaction_currency_id
- * @property int|null $foreign_currency_id
- * @property int $source_id
- * @property int $destination_id
- * @property string $amount
- * @property string|null $foreign_amount
- * @property string $description
- * @property-read Account $destinationAccount
- * @property-read TransactionCurrency|null $foreignCurrency
- * @property-read Recurrence $recurrence
- * @property-read Collection|RecurrenceTransactionMeta[] $recurrenceTransactionMeta
- * @property-read int|null $recurrence_transaction_meta_count
- * @property-read Account $sourceAccount
- * @property-read TransactionCurrency $transactionCurrency
+ * @property int $id
+ * @property null|Carbon $created_at
+ * @property null|Carbon $updated_at
+ * @property null|Carbon $deleted_at
+ * @property int $recurrence_id
+ * @property int $transaction_currency_id
+ * @property null|int|string $foreign_currency_id
+ * @property int $source_id
+ * @property int $destination_id
+ * @property string $amount
+ * @property string $foreign_amount
+ * @property string $description
+ * @property Account $destinationAccount
+ * @property null|TransactionCurrency $foreignCurrency
+ * @property Recurrence $recurrence
+ * @property Collection|RecurrenceTransactionMeta[] $recurrenceTransactionMeta
+ * @property null|int $recurrence_transaction_meta_count
+ * @property Account $sourceAccount
+ * @property TransactionCurrency $transactionCurrency
+ *
* @method static \Illuminate\Database\Eloquent\Builder|RecurrenceTransaction newModelQuery()
* @method static \Illuminate\Database\Eloquent\Builder|RecurrenceTransaction newQuery()
- * @method static Builder|RecurrenceTransaction onlyTrashed()
+ * @method static Builder|RecurrenceTransaction onlyTrashed()
* @method static \Illuminate\Database\Eloquent\Builder|RecurrenceTransaction query()
* @method static \Illuminate\Database\Eloquent\Builder|RecurrenceTransaction whereAmount($value)
* @method static \Illuminate\Database\Eloquent\Builder|RecurrenceTransaction whereCreatedAt($value)
@@ -71,119 +73,128 @@ use Illuminate\Support\Carbon;
* @method static \Illuminate\Database\Eloquent\Builder|RecurrenceTransaction whereSourceId($value)
* @method static \Illuminate\Database\Eloquent\Builder|RecurrenceTransaction whereTransactionCurrencyId($value)
* @method static \Illuminate\Database\Eloquent\Builder|RecurrenceTransaction whereUpdatedAt($value)
- * @method static Builder|RecurrenceTransaction withTrashed()
- * @method static Builder|RecurrenceTransaction withoutTrashed()
- * @property int|null $transaction_type_id
+ * @method static Builder|RecurrenceTransaction withTrashed()
+ * @method static Builder|RecurrenceTransaction withoutTrashed()
+ *
+ * @property null|int $transaction_type_id
+ *
* @method static \Illuminate\Database\Eloquent\Builder|RecurrenceTransaction whereTransactionTypeId($value)
- * @property-read TransactionType|null $transactionType
+ *
+ * @property null|TransactionType $transactionType
+ *
* @mixin Eloquent
*/
class RecurrenceTransaction extends Model
{
+ use ReturnsIntegerIdTrait;
use SoftDeletes;
- /**
- * The attributes that should be casted to native types.
- *
- * @var array
- */
protected $casts
- = [
- 'created_at' => 'datetime',
- 'updated_at' => 'datetime',
- 'deleted_at' => 'datetime',
- 'amount' => 'string',
- 'foreign_amount' => 'string',
- 'description' => 'string',
- ];
- /** @var array Fields that can be filled */
+ = [
+ 'created_at' => 'datetime',
+ 'updated_at' => 'datetime',
+ 'deleted_at' => 'datetime',
+ 'amount' => 'string',
+ 'foreign_amount' => 'string',
+ 'description' => 'string',
+ ];
+
protected $fillable
- = [
- 'recurrence_id',
- 'transaction_currency_id',
- 'foreign_currency_id',
- 'source_id',
- 'destination_id',
- 'amount',
- 'foreign_amount',
- 'description',
- ];
+ = [
+ 'recurrence_id',
+ 'transaction_currency_id',
+ 'foreign_currency_id',
+ 'source_id',
+ 'destination_id',
+ 'amount',
+ 'foreign_amount',
+ 'description',
+ ];
+
/** @var string The table to store the data in */
protected $table = 'recurrences_transactions';
- /**
- * @return BelongsTo
- */
public function destinationAccount(): BelongsTo
{
return $this->belongsTo(Account::class, 'destination_id');
}
- /**
- * @return BelongsTo
- */
public function foreignCurrency(): BelongsTo
{
return $this->belongsTo(TransactionCurrency::class);
}
- /**
- * @return BelongsTo
- */
public function recurrence(): BelongsTo
{
return $this->belongsTo(Recurrence::class);
}
- /**
- * @return HasMany
- */
public function recurrenceTransactionMeta(): HasMany
{
return $this->hasMany(RecurrenceTransactionMeta::class, 'rt_id');
}
- /**
- * @return BelongsTo
- */
public function sourceAccount(): BelongsTo
{
return $this->belongsTo(Account::class, 'source_id');
}
- /**
- * @return BelongsTo
- */
public function transactionCurrency(): BelongsTo
{
return $this->belongsTo(TransactionCurrency::class);
}
- /**
- * @return BelongsTo
- */
public function transactionType(): BelongsTo
{
return $this->belongsTo(TransactionType::class);
}
- /**
- * @return Attribute
- */
protected function amount(): Attribute
{
return Attribute::make(
- get: fn ($value) => (string)$value,
+ get: static fn ($value) => (string)$value,
+ );
+ }
+
+ protected function destinationId(): Attribute
+ {
+ return Attribute::make(
+ get: static fn ($value) => (int)$value,
);
}
- /**
- * @return Attribute
- */
protected function foreignAmount(): Attribute
{
return Attribute::make(
- get: fn ($value) => (string)$value,
+ get: static fn ($value) => (string)$value,
+ );
+ }
+
+ protected function recurrenceId(): Attribute
+ {
+ return Attribute::make(
+ get: static fn ($value) => (int)$value,
+ );
+ }
+
+ protected function sourceId(): Attribute
+ {
+ return Attribute::make(
+ get: static fn ($value) => (int)$value,
+ );
+ }
+
+ protected function transactionCurrencyId(): Attribute
+ {
+ return Attribute::make(
+ get: static fn ($value) => (int)$value,
+ );
+ }
+
+ protected function userId(): Attribute
+ {
+ return Attribute::make(
+ get: static fn ($value) => (int)$value,
);
}
}
diff --git a/app/Models/RecurrenceTransactionMeta.php b/app/Models/RecurrenceTransactionMeta.php
index c290cba2fb..e0a60d4163 100644
--- a/app/Models/RecurrenceTransactionMeta.php
+++ b/app/Models/RecurrenceTransactionMeta.php
@@ -23,27 +23,30 @@ declare(strict_types=1);
namespace FireflyIII\Models;
+use Carbon\Carbon;
use Eloquent;
+use FireflyIII\Support\Models\ReturnsIntegerIdTrait;
+use Illuminate\Database\Eloquent\Casts\Attribute;
use Illuminate\Database\Eloquent\Model;
use Illuminate\Database\Eloquent\Relations\BelongsTo;
use Illuminate\Database\Eloquent\SoftDeletes;
use Illuminate\Database\Query\Builder;
-use Illuminate\Support\Carbon;
/**
* FireflyIII\Models\RecurrenceTransactionMeta
*
- * @property int $id
- * @property Carbon|null $created_at
- * @property Carbon|null $updated_at
- * @property Carbon|null $deleted_at
- * @property int $rt_id
- * @property string $name
- * @property mixed $value
- * @property-read RecurrenceTransaction $recurrenceTransaction
+ * @property int $id
+ * @property null|Carbon $created_at
+ * @property null|Carbon $updated_at
+ * @property null|Carbon $deleted_at
+ * @property int|string $rt_id
+ * @property string $name
+ * @property mixed $value
+ * @property RecurrenceTransaction $recurrenceTransaction
+ *
* @method static \Illuminate\Database\Eloquent\Builder|RecurrenceTransactionMeta newModelQuery()
* @method static \Illuminate\Database\Eloquent\Builder|RecurrenceTransactionMeta newQuery()
- * @method static Builder|RecurrenceTransactionMeta onlyTrashed()
+ * @method static Builder|RecurrenceTransactionMeta onlyTrashed()
* @method static \Illuminate\Database\Eloquent\Builder|RecurrenceTransactionMeta query()
* @method static \Illuminate\Database\Eloquent\Builder|RecurrenceTransactionMeta whereCreatedAt($value)
* @method static \Illuminate\Database\Eloquent\Builder|RecurrenceTransactionMeta whereDeletedAt($value)
@@ -52,37 +55,39 @@ use Illuminate\Support\Carbon;
* @method static \Illuminate\Database\Eloquent\Builder|RecurrenceTransactionMeta whereRtId($value)
* @method static \Illuminate\Database\Eloquent\Builder|RecurrenceTransactionMeta whereUpdatedAt($value)
* @method static \Illuminate\Database\Eloquent\Builder|RecurrenceTransactionMeta whereValue($value)
- * @method static Builder|RecurrenceTransactionMeta withTrashed()
- * @method static Builder|RecurrenceTransactionMeta withoutTrashed()
+ * @method static Builder|RecurrenceTransactionMeta withTrashed()
+ * @method static Builder|RecurrenceTransactionMeta withoutTrashed()
+ *
* @mixin Eloquent
*/
class RecurrenceTransactionMeta extends Model
{
+ use ReturnsIntegerIdTrait;
use SoftDeletes;
- /**
- * The attributes that should be casted to native types.
- *
- * @var array
- */
protected $casts
- = [
- 'created_at' => 'datetime',
- 'updated_at' => 'datetime',
- 'deleted_at' => 'datetime',
- 'name' => 'string',
- 'value' => 'string',
- ];
- /** @var array Fields that can be filled */
- protected $fillable = ['rt_id', 'name', 'value'];
- /** @var string The table to store the data in */
- protected $table = 'rt_meta';
+ = [
+ 'created_at' => 'datetime',
+ 'updated_at' => 'datetime',
+ 'deleted_at' => 'datetime',
+ 'name' => 'string',
+ 'value' => 'string',
+ ];
+
+ protected $fillable = ['rt_id', 'name', 'value'];
+
+ /** @var string The table to store the data in */
+ protected $table = 'rt_meta';
- /**
- * @return BelongsTo
- */
public function recurrenceTransaction(): BelongsTo
{
return $this->belongsTo(RecurrenceTransaction::class, 'rt_id');
}
+
+ protected function rtId(): Attribute
+ {
+ return Attribute::make(
+ get: static fn ($value) => (int)$value,
+ );
+ }
}
diff --git a/app/Models/Role.php b/app/Models/Role.php
index d9cb20b297..b356c6fc15 100644
--- a/app/Models/Role.php
+++ b/app/Models/Role.php
@@ -23,25 +23,27 @@ declare(strict_types=1);
namespace FireflyIII\Models;
+use Carbon\Carbon;
use Eloquent;
+use FireflyIII\Support\Models\ReturnsIntegerIdTrait;
use FireflyIII\User;
use Illuminate\Database\Eloquent\Builder;
use Illuminate\Database\Eloquent\Collection;
use Illuminate\Database\Eloquent\Model;
use Illuminate\Database\Eloquent\Relations\BelongsToMany;
-use Illuminate\Support\Carbon;
/**
* FireflyIII\Models\Role
*
- * @property int $id
- * @property Carbon|null $created_at
- * @property Carbon|null $updated_at
- * @property string $name
- * @property string|null $display_name
- * @property string|null $description
- * @property-read Collection|User[] $users
- * @property-read int|null $users_count
+ * @property int $id
+ * @property null|Carbon $created_at
+ * @property null|Carbon $updated_at
+ * @property string $name
+ * @property null|string $display_name
+ * @property null|string $description
+ * @property Collection|User[] $users
+ * @property null|int $users_count
+ *
* @method static Builder|Role newModelQuery()
* @method static Builder|Role newQuery()
* @method static Builder|Role query()
@@ -51,27 +53,21 @@ use Illuminate\Support\Carbon;
* @method static Builder|Role whereId($value)
* @method static Builder|Role whereName($value)
* @method static Builder|Role whereUpdatedAt($value)
+ *
* @mixin Eloquent
*/
class Role extends Model
{
- /**
- * The attributes that should be casted to native types.
- *
- * @var array
- */
- protected $casts
- = [
- 'created_at' => 'datetime',
- 'updated_at' => 'datetime',
- ];
+ use ReturnsIntegerIdTrait;
+
+ protected $casts
+ = [
+ 'created_at' => 'datetime',
+ 'updated_at' => 'datetime',
+ ];
- /** @var array Fields that can be filled */
protected $fillable = ['name', 'display_name', 'description'];
- /**
- * @return BelongsToMany
- */
public function users(): BelongsToMany
{
return $this->belongsToMany(User::class);
diff --git a/app/Models/Rule.php b/app/Models/Rule.php
index 7c499ad0d9..8ccc7c44bc 100644
--- a/app/Models/Rule.php
+++ b/app/Models/Rule.php
@@ -23,42 +23,46 @@ declare(strict_types=1);
namespace FireflyIII\Models;
+use Carbon\Carbon;
use Eloquent;
+use FireflyIII\Support\Models\ReturnsIntegerIdTrait;
+use FireflyIII\Support\Models\ReturnsIntegerUserIdTrait;
use FireflyIII\User;
+use Illuminate\Database\Eloquent\Casts\Attribute;
use Illuminate\Database\Eloquent\Collection;
use Illuminate\Database\Eloquent\Model;
use Illuminate\Database\Eloquent\Relations\BelongsTo;
use Illuminate\Database\Eloquent\Relations\HasMany;
use Illuminate\Database\Eloquent\SoftDeletes;
use Illuminate\Database\Query\Builder;
-use Illuminate\Support\Carbon;
use Symfony\Component\HttpKernel\Exception\NotFoundHttpException;
/**
* FireflyIII\Models\Rule
*
- * @property int $id
- * @property Carbon|null $created_at
- * @property Carbon|null $updated_at
- * @property Carbon|null $deleted_at
- * @property int $user_id
- * @property int $rule_group_id
- * @property string $title
- * @property string|null $description
- * @property int $order
- * @property bool $active
- * @property bool $stop_processing
- * @property bool $strict
- * @property-read string $action_value
- * @property-read Collection|RuleAction[] $ruleActions
- * @property-read int|null $rule_actions_count
- * @property-read RuleGroup $ruleGroup
- * @property Collection|RuleTrigger[] $ruleTriggers
- * @property-read int|null $rule_triggers_count
- * @property-read User $user
+ * @property int $id
+ * @property null|Carbon $created_at
+ * @property null|Carbon $updated_at
+ * @property null|Carbon $deleted_at
+ * @property int $user_id
+ * @property int $rule_group_id
+ * @property string $title
+ * @property null|string $description
+ * @property int $order
+ * @property bool $active
+ * @property bool $stop_processing
+ * @property bool $strict
+ * @property string $action_value
+ * @property Collection|RuleAction[] $ruleActions
+ * @property null|int $rule_actions_count
+ * @property RuleGroup $ruleGroup
+ * @property Collection|RuleTrigger[] $ruleTriggers
+ * @property null|int $rule_triggers_count
+ * @property User $user
+ *
* @method static \Illuminate\Database\Eloquent\Builder|Rule newModelQuery()
* @method static \Illuminate\Database\Eloquent\Builder|Rule newQuery()
- * @method static Builder|Rule onlyTrashed()
+ * @method static Builder|Rule onlyTrashed()
* @method static \Illuminate\Database\Eloquent\Builder|Rule query()
* @method static \Illuminate\Database\Eloquent\Builder|Rule whereActive($value)
* @method static \Illuminate\Database\Eloquent\Builder|Rule whereCreatedAt($value)
@@ -72,78 +76,75 @@ use Symfony\Component\HttpKernel\Exception\NotFoundHttpException;
* @method static \Illuminate\Database\Eloquent\Builder|Rule whereTitle($value)
* @method static \Illuminate\Database\Eloquent\Builder|Rule whereUpdatedAt($value)
* @method static \Illuminate\Database\Eloquent\Builder|Rule whereUserId($value)
- * @method static Builder|Rule withTrashed()
- * @method static Builder|Rule withoutTrashed()
- * @property int|null $user_group_id
+ * @method static Builder|Rule withTrashed()
+ * @method static Builder|Rule withoutTrashed()
+ *
+ * @property int $user_group_id
+ *
* @method static \Illuminate\Database\Eloquent\Builder|Rule whereUserGroupId($value)
- * @property-read UserGroup|null $userGroup
+ *
+ * @property null|UserGroup $userGroup
+ *
* @mixin Eloquent
*/
class Rule extends Model
{
+ use ReturnsIntegerIdTrait;
+ use ReturnsIntegerUserIdTrait;
use SoftDeletes;
- /**
- * The attributes that should be casted to native types.
- *
- * @var array
- */
protected $casts
- = [
- 'created_at' => 'datetime',
- 'updated_at' => 'datetime',
- 'deleted_at' => 'datetime',
- 'active' => 'boolean',
- 'order' => 'int',
- 'stop_processing' => 'boolean',
- 'id' => 'int',
- 'strict' => 'boolean',
- ];
- /** @var array Fields that can be filled */
+ = [
+ 'created_at' => 'datetime',
+ 'updated_at' => 'datetime',
+ 'deleted_at' => 'datetime',
+ 'active' => 'boolean',
+ 'order' => 'int',
+ 'stop_processing' => 'boolean',
+ 'id' => 'int',
+ 'strict' => 'boolean',
+ ];
+
protected $fillable = ['rule_group_id', 'order', 'active', 'title', 'description', 'user_id', 'strict'];
/**
* Route binder. Converts the key in the URL to the specified object (or throw 404).
*
- * @param string $value
- *
- * @return Rule
* @throws NotFoundHttpException
*/
- public static function routeBinder(string $value): Rule
+ public static function routeBinder(string $value): self
{
if (auth()->check()) {
$ruleId = (int)$value;
+
/** @var User $user */
- $user = auth()->user();
- /** @var Rule $rule */
- $rule = $user->rules()->find($ruleId);
+ $user = auth()->user();
+
+ /** @var null|Rule $rule */
+ $rule = $user->rules()->find($ruleId);
if (null !== $rule) {
return $rule;
}
}
+
throw new NotFoundHttpException();
}
- /**
- * @return HasMany
- */
+ public function user(): BelongsTo
+ {
+ return $this->belongsTo(User::class);
+ }
+
public function ruleActions(): HasMany
{
return $this->hasMany(RuleAction::class);
}
- /**
- * @return BelongsTo
- */
public function ruleGroup(): BelongsTo
{
return $this->belongsTo(RuleGroup::class);
}
- /**
- * @return HasMany
- */
public function ruleTriggers(): HasMany
{
return $this->hasMany(RuleTrigger::class);
@@ -151,27 +152,28 @@ class Rule extends Model
/**
* @param mixed $value
- *
-
*/
public function setDescriptionAttribute($value): void
{
$this->attributes['description'] = e($value);
}
- /**
- * @return BelongsTo
- */
- public function user(): BelongsTo
- {
- return $this->belongsTo(User::class);
- }
-
- /**
- * @return BelongsTo
- */
public function userGroup(): BelongsTo
{
return $this->belongsTo(UserGroup::class);
}
+
+ protected function order(): Attribute
+ {
+ return Attribute::make(
+ get: static fn ($value) => (int)$value,
+ );
+ }
+
+ protected function ruleGroupId(): Attribute
+ {
+ return Attribute::make(
+ get: static fn ($value) => (int)$value,
+ );
+ }
}
diff --git a/app/Models/RuleAction.php b/app/Models/RuleAction.php
index 977aa71354..f8f8e5fe12 100644
--- a/app/Models/RuleAction.php
+++ b/app/Models/RuleAction.php
@@ -23,25 +23,28 @@ declare(strict_types=1);
namespace FireflyIII\Models;
+use Carbon\Carbon;
use Eloquent;
+use FireflyIII\Support\Models\ReturnsIntegerIdTrait;
use Illuminate\Database\Eloquent\Builder;
+use Illuminate\Database\Eloquent\Casts\Attribute;
use Illuminate\Database\Eloquent\Model;
use Illuminate\Database\Eloquent\Relations\BelongsTo;
-use Illuminate\Support\Carbon;
/**
* FireflyIII\Models\RuleAction
*
* @property int $id
- * @property Carbon|null $created_at
- * @property Carbon|null $updated_at
+ * @property null|Carbon $created_at
+ * @property null|Carbon $updated_at
* @property int $rule_id
- * @property string $action_type
- * @property string $action_value
+ * @property null|string $action_type
+ * @property null|string $action_value
* @property int $order
* @property bool $active
* @property bool $stop_processing
- * @property-read Rule $rule
+ * @property Rule $rule
+ *
* @method static Builder|RuleAction newModelQuery()
* @method static Builder|RuleAction newQuery()
* @method static Builder|RuleAction query()
@@ -54,32 +57,40 @@ use Illuminate\Support\Carbon;
* @method static Builder|RuleAction whereRuleId($value)
* @method static Builder|RuleAction whereStopProcessing($value)
* @method static Builder|RuleAction whereUpdatedAt($value)
+ *
* @mixin Eloquent
*/
class RuleAction extends Model
{
- /**
- * The attributes that should be casted to native types.
- *
- * @var array
- */
- protected $casts
- = [
- 'created_at' => 'datetime',
- 'updated_at' => 'datetime',
- 'active' => 'boolean',
- 'order' => 'int',
- 'stop_processing' => 'boolean',
- ];
+ use ReturnsIntegerIdTrait;
+
+ protected $casts
+ = [
+ 'created_at' => 'datetime',
+ 'updated_at' => 'datetime',
+ 'active' => 'boolean',
+ 'order' => 'int',
+ 'stop_processing' => 'boolean',
+ ];
- /** @var array Fields that can be filled */
protected $fillable = ['rule_id', 'action_type', 'action_value', 'order', 'active', 'stop_processing'];
- /**
- * @return BelongsTo
- */
public function rule(): BelongsTo
{
return $this->belongsTo(Rule::class);
}
+
+ protected function order(): Attribute
+ {
+ return Attribute::make(
+ get: static fn ($value) => (int)$value,
+ );
+ }
+
+ protected function ruleId(): Attribute
+ {
+ return Attribute::make(
+ get: static fn ($value) => (int)$value,
+ );
+ }
}
diff --git a/app/Models/RuleGroup.php b/app/Models/RuleGroup.php
index ae8863fdd3..67e6c42f23 100644
--- a/app/Models/RuleGroup.php
+++ b/app/Models/RuleGroup.php
@@ -23,36 +23,40 @@ declare(strict_types=1);
namespace FireflyIII\Models;
+use Carbon\Carbon;
use Eloquent;
+use FireflyIII\Support\Models\ReturnsIntegerIdTrait;
+use FireflyIII\Support\Models\ReturnsIntegerUserIdTrait;
use FireflyIII\User;
+use Illuminate\Database\Eloquent\Casts\Attribute;
use Illuminate\Database\Eloquent\Collection;
use Illuminate\Database\Eloquent\Model;
use Illuminate\Database\Eloquent\Relations\BelongsTo;
use Illuminate\Database\Eloquent\Relations\HasMany;
use Illuminate\Database\Eloquent\SoftDeletes;
use Illuminate\Database\Query\Builder;
-use Illuminate\Support\Carbon;
use Symfony\Component\HttpKernel\Exception\NotFoundHttpException;
/**
* FireflyIII\Models\RuleGroup
*
* @property int $id
- * @property Carbon|null $created_at
- * @property Carbon|null $updated_at
- * @property Carbon|null $deleted_at
+ * @property null|Carbon $created_at
+ * @property null|Carbon $updated_at
+ * @property null|Carbon $deleted_at
* @property int $user_id
- * @property string $title
- * @property string|null $description
+ * @property null|string $title
+ * @property null|string $description
* @property int $order
* @property bool $active
* @property bool $stop_processing
* @property Collection|Rule[] $rules
- * @property-read int|null $rules_count
- * @property-read User $user
+ * @property null|int $rules_count
+ * @property User $user
+ *
* @method static \Illuminate\Database\Eloquent\Builder|RuleGroup newModelQuery()
* @method static \Illuminate\Database\Eloquent\Builder|RuleGroup newQuery()
- * @method static Builder|RuleGroup onlyTrashed()
+ * @method static Builder|RuleGroup onlyTrashed()
* @method static \Illuminate\Database\Eloquent\Builder|RuleGroup query()
* @method static \Illuminate\Database\Eloquent\Builder|RuleGroup whereActive($value)
* @method static \Illuminate\Database\Eloquent\Builder|RuleGroup whereCreatedAt($value)
@@ -64,70 +68,70 @@ use Symfony\Component\HttpKernel\Exception\NotFoundHttpException;
* @method static \Illuminate\Database\Eloquent\Builder|RuleGroup whereTitle($value)
* @method static \Illuminate\Database\Eloquent\Builder|RuleGroup whereUpdatedAt($value)
* @method static \Illuminate\Database\Eloquent\Builder|RuleGroup whereUserId($value)
- * @method static Builder|RuleGroup withTrashed()
- * @method static Builder|RuleGroup withoutTrashed()
- * @property int|null $user_group_id
+ * @method static Builder|RuleGroup withTrashed()
+ * @method static Builder|RuleGroup withoutTrashed()
+ *
+ * @property int $user_group_id
+ *
* @method static \Illuminate\Database\Eloquent\Builder|RuleGroup whereUserGroupId($value)
+ *
* @mixin Eloquent
*/
class RuleGroup extends Model
{
+ use ReturnsIntegerIdTrait;
+ use ReturnsIntegerUserIdTrait;
use SoftDeletes;
- /**
- * The attributes that should be casted to native types.
- *
- * @var array
- */
protected $casts
- = [
- 'created_at' => 'datetime',
- 'updated_at' => 'datetime',
- 'deleted_at' => 'datetime',
- 'active' => 'boolean',
- 'stop_processing' => 'boolean',
- 'order' => 'int',
- ];
+ = [
+ 'created_at' => 'datetime',
+ 'updated_at' => 'datetime',
+ 'deleted_at' => 'datetime',
+ 'active' => 'boolean',
+ 'stop_processing' => 'boolean',
+ 'order' => 'int',
+ ];
- /** @var array Fields that can be filled */
protected $fillable = ['user_id', 'user_group_id', 'stop_processing', 'order', 'title', 'description', 'active'];
/**
* Route binder. Converts the key in the URL to the specified object (or throw 404).
*
- * @param string $value
- *
- * @return RuleGroup
* @throws NotFoundHttpException
*/
- public static function routeBinder(string $value): RuleGroup
+ public static function routeBinder(string $value): self
{
if (auth()->check()) {
$ruleGroupId = (int)$value;
+
/** @var User $user */
- $user = auth()->user();
- /** @var RuleGroup $ruleGroup */
- $ruleGroup = $user->ruleGroups()->find($ruleGroupId);
+ $user = auth()->user();
+
+ /** @var null|RuleGroup $ruleGroup */
+ $ruleGroup = $user->ruleGroups()->find($ruleGroupId);
if (null !== $ruleGroup) {
return $ruleGroup;
}
}
+
throw new NotFoundHttpException();
}
- /**
- * @return BelongsTo
- */
public function user(): BelongsTo
{
return $this->belongsTo(User::class);
}
- /**
- * @return HasMany
- */
public function rules(): HasMany
{
return $this->hasMany(Rule::class);
}
+
+ protected function order(): Attribute
+ {
+ return Attribute::make(
+ get: static fn ($value) => (int)$value,
+ );
+ }
}
diff --git a/app/Models/RuleTrigger.php b/app/Models/RuleTrigger.php
index 20cf189375..e617ee8b21 100644
--- a/app/Models/RuleTrigger.php
+++ b/app/Models/RuleTrigger.php
@@ -23,25 +23,28 @@ declare(strict_types=1);
namespace FireflyIII\Models;
+use Carbon\Carbon;
use Eloquent;
+use FireflyIII\Support\Models\ReturnsIntegerIdTrait;
use Illuminate\Database\Eloquent\Builder;
+use Illuminate\Database\Eloquent\Casts\Attribute;
use Illuminate\Database\Eloquent\Model;
use Illuminate\Database\Eloquent\Relations\BelongsTo;
-use Illuminate\Support\Carbon;
/**
* FireflyIII\Models\RuleTrigger
*
* @property int $id
- * @property Carbon|null $created_at
- * @property Carbon|null $updated_at
+ * @property null|Carbon $created_at
+ * @property null|Carbon $updated_at
* @property int $rule_id
- * @property string $trigger_type
- * @property string $trigger_value
+ * @property null|string $trigger_type
+ * @property null|string $trigger_value
* @property int $order
* @property bool $active
* @property bool $stop_processing
- * @property-read Rule $rule
+ * @property Rule $rule
+ *
* @method static Builder|RuleTrigger newModelQuery()
* @method static Builder|RuleTrigger newQuery()
* @method static Builder|RuleTrigger query()
@@ -54,32 +57,40 @@ use Illuminate\Support\Carbon;
* @method static Builder|RuleTrigger whereTriggerType($value)
* @method static Builder|RuleTrigger whereTriggerValue($value)
* @method static Builder|RuleTrigger whereUpdatedAt($value)
+ *
* @mixin Eloquent
*/
class RuleTrigger extends Model
{
- /**
- * The attributes that should be casted to native types.
- *
- * @var array
- */
- protected $casts
- = [
- 'created_at' => 'datetime',
- 'updated_at' => 'datetime',
- 'active' => 'boolean',
- 'order' => 'int',
- 'stop_processing' => 'boolean',
- ];
+ use ReturnsIntegerIdTrait;
+
+ protected $casts
+ = [
+ 'created_at' => 'datetime',
+ 'updated_at' => 'datetime',
+ 'active' => 'boolean',
+ 'order' => 'int',
+ 'stop_processing' => 'boolean',
+ ];
- /** @var array Fields that can be filled */
protected $fillable = ['rule_id', 'trigger_type', 'trigger_value', 'order', 'active', 'stop_processing'];
- /**
- * @return BelongsTo
- */
public function rule(): BelongsTo
{
return $this->belongsTo(Rule::class);
}
+
+ protected function order(): Attribute
+ {
+ return Attribute::make(
+ get: static fn ($value) => (int)$value,
+ );
+ }
+
+ protected function ruleId(): Attribute
+ {
+ return Attribute::make(
+ get: static fn ($value) => (int)$value,
+ );
+ }
}
diff --git a/app/Models/Tag.php b/app/Models/Tag.php
index 1e0e28fd14..9ba92bc9f3 100644
--- a/app/Models/Tag.php
+++ b/app/Models/Tag.php
@@ -23,7 +23,10 @@ declare(strict_types=1);
namespace FireflyIII\Models;
+use Carbon\Carbon;
use Eloquent;
+use FireflyIII\Support\Models\ReturnsIntegerIdTrait;
+use FireflyIII\Support\Models\ReturnsIntegerUserIdTrait;
use FireflyIII\User;
use Illuminate\Database\Eloquent\Collection;
use Illuminate\Database\Eloquent\Model;
@@ -32,34 +35,34 @@ use Illuminate\Database\Eloquent\Relations\BelongsToMany;
use Illuminate\Database\Eloquent\Relations\MorphMany;
use Illuminate\Database\Eloquent\SoftDeletes;
use Illuminate\Database\Query\Builder;
-use Illuminate\Support\Carbon;
use Symfony\Component\HttpKernel\Exception\NotFoundHttpException;
/**
* FireflyIII\Models\Tag
*
- * @property int $id
- * @property Carbon|null $created_at
- * @property Carbon|null $updated_at
- * @property Carbon|null $deleted_at
- * @property int $user_id
- * @property string $tag
- * @property string $tagMode
- * @property Carbon|null $date
- * @property string|null $description
- * @property float|null $latitude
- * @property float|null $longitude
- * @property int|null $zoomLevel
- * @property-read Collection|Attachment[] $attachments
- * @property-read int|null $attachments_count
- * @property-read Collection|Location[] $locations
- * @property-read int|null $locations_count
- * @property-read Collection|TransactionJournal[] $transactionJournals
- * @property-read int|null $transaction_journals_count
- * @property-read User $user
+ * @property int $id
+ * @property null|Carbon $created_at
+ * @property null|Carbon $updated_at
+ * @property null|Carbon $deleted_at
+ * @property int $user_id
+ * @property string $tag
+ * @property string $tagMode
+ * @property null|Carbon $date
+ * @property null|string $description
+ * @property null|float $latitude
+ * @property null|float $longitude
+ * @property null|int $zoomLevel
+ * @property Attachment[]|Collection $attachments
+ * @property null|int $attachments_count
+ * @property Collection|Location[] $locations
+ * @property null|int $locations_count
+ * @property Collection|TransactionJournal[] $transactionJournals
+ * @property null|int $transaction_journals_count
+ * @property User $user
+ *
* @method static \Illuminate\Database\Eloquent\Builder|Tag newModelQuery()
* @method static \Illuminate\Database\Eloquent\Builder|Tag newQuery()
- * @method static Builder|Tag onlyTrashed()
+ * @method static Builder|Tag onlyTrashed()
* @method static \Illuminate\Database\Eloquent\Builder|Tag query()
* @method static \Illuminate\Database\Eloquent\Builder|Tag whereCreatedAt($value)
* @method static \Illuminate\Database\Eloquent\Builder|Tag whereDate($value)
@@ -73,86 +76,74 @@ use Symfony\Component\HttpKernel\Exception\NotFoundHttpException;
* @method static \Illuminate\Database\Eloquent\Builder|Tag whereUpdatedAt($value)
* @method static \Illuminate\Database\Eloquent\Builder|Tag whereUserId($value)
* @method static \Illuminate\Database\Eloquent\Builder|Tag whereZoomLevel($value)
- * @method static Builder|Tag withTrashed()
- * @method static Builder|Tag withoutTrashed()
- * @property int|null $user_group_id
+ * @method static Builder|Tag withTrashed()
+ * @method static Builder|Tag withoutTrashed()
+ *
+ * @property int $user_group_id
+ *
* @method static \Illuminate\Database\Eloquent\Builder|Tag whereUserGroupId($value)
+ *
* @mixin Eloquent
*/
class Tag extends Model
{
+ use ReturnsIntegerIdTrait;
+ use ReturnsIntegerUserIdTrait;
use SoftDeletes;
- /**
- * The attributes that should be casted to native types.
- *
- * @var array
- */
protected $casts
- = [
- 'created_at' => 'datetime',
- 'updated_at' => 'datetime',
- 'deleted_at' => 'datetime',
- 'date' => 'date',
- 'zoomLevel' => 'int',
- 'latitude' => 'float',
- 'longitude' => 'float',
- ];
- /** @var array Fields that can be filled */
+ = [
+ 'created_at' => 'datetime',
+ 'updated_at' => 'datetime',
+ 'deleted_at' => 'datetime',
+ 'date' => 'date',
+ 'zoomLevel' => 'int',
+ 'latitude' => 'float',
+ 'longitude' => 'float',
+ ];
+
protected $fillable = ['user_id', 'user_group_id', 'tag', 'date', 'description', 'tagMode'];
- protected $hidden = ['zoomLevel', 'latitude', 'longitude'];
+ protected $hidden = ['zoomLevel', 'latitude', 'longitude'];
/**
* Route binder. Converts the key in the URL to the specified object (or throw 404).
*
- * @param string $value
- *
- * @return Tag
* @throws NotFoundHttpException
*/
- public static function routeBinder(string $value): Tag
+ public static function routeBinder(string $value): self
{
if (auth()->check()) {
$tagId = (int)$value;
+
/** @var User $user */
- $user = auth()->user();
- /** @var Tag $tag */
- $tag = $user->tags()->find($tagId);
+ $user = auth()->user();
+
+ /** @var null|Tag $tag */
+ $tag = $user->tags()->find($tagId);
if (null !== $tag) {
return $tag;
}
}
+
throw new NotFoundHttpException();
}
- /**
- * @return BelongsTo
- */
public function user(): BelongsTo
{
return $this->belongsTo(User::class);
}
- /**
- * @return MorphMany
- */
public function attachments(): MorphMany
{
return $this->morphMany(Attachment::class, 'attachable');
}
- /**
- * @return MorphMany
- */
public function locations(): MorphMany
{
return $this->morphMany(Location::class, 'locatable');
}
- /**
- * @return BelongsToMany
- */
public function transactionJournals(): BelongsToMany
{
return $this->belongsToMany(TransactionJournal::class);
diff --git a/app/Models/Transaction.php b/app/Models/Transaction.php
index b726594471..974cc3d7a7 100644
--- a/app/Models/Transaction.php
+++ b/app/Models/Transaction.php
@@ -25,6 +25,7 @@ namespace FireflyIII\Models;
use Carbon\Carbon;
use Eloquent;
+use FireflyIII\Support\Models\ReturnsIntegerIdTrait;
use Illuminate\Database\Eloquent\Builder;
use Illuminate\Database\Eloquent\Casts\Attribute;
use Illuminate\Database\Eloquent\Collection;
@@ -37,96 +38,94 @@ use Illuminate\Database\Eloquent\SoftDeletes;
/**
* FireflyIII\Models\Transaction
*
- * @property int $id
- * @property \Illuminate\Support\Carbon|null $created_at
- * @property \Illuminate\Support\Carbon|null $updated_at
- * @property \Illuminate\Support\Carbon|null $deleted_at
- * @property bool $reconciled
- * @property int $account_id
- * @property int $transaction_journal_id
- * @property string|null $description
- * @property int|null $transaction_currency_id
- * @property string $modified
- * @property string $modified_foreign
- * @property string $date
- * @property string $max_date
- * @property string $amount
- * @property string|null $foreign_amount
- * @property int|null $foreign_currency_id
- * @property int $identifier
- * @property-read Account $account
- * @property-read Collection|Budget[] $budgets
- * @property-read int|null $budgets_count
- * @property-read Collection|Category[] $categories
- * @property-read int|null $categories_count
- * @property-read TransactionCurrency|null $foreignCurrency
- * @property-read TransactionCurrency|null $transactionCurrency
- * @property-read TransactionJournal $transactionJournal
- * @method static Builder|Transaction after(Carbon $date)
- * @method static Builder|Transaction before(Carbon $date)
- * @method static Builder|Transaction newModelQuery()
- * @method static Builder|Transaction newQuery()
+ * @property int $id
+ * @property null|Carbon $created_at
+ * @property null|Carbon $updated_at
+ * @property null|Carbon $deleted_at
+ * @property bool $reconciled
+ * @property int $account_id
+ * @property int $transaction_journal_id
+ * @property null|string $description
+ * @property null|int $transaction_currency_id
+ * @property null|int|string $modified
+ * @property null|int|string $modified_foreign
+ * @property string $date
+ * @property string $max_date
+ * @property string $amount
+ * @property null|string $foreign_amount
+ * @property null|int $foreign_currency_id
+ * @property int $identifier
+ * @property Account $account
+ * @property Budget[]|Collection $budgets
+ * @property null|int $budgets_count
+ * @property Category[]|Collection $categories
+ * @property null|int $categories_count
+ * @property null|TransactionCurrency $foreignCurrency
+ * @property null|TransactionCurrency $transactionCurrency
+ * @property TransactionJournal $transactionJournal
+ *
+ * @method static Builder|Transaction after(Carbon $date)
+ * @method static Builder|Transaction before(Carbon $date)
+ * @method static Builder|Transaction newModelQuery()
+ * @method static Builder|Transaction newQuery()
* @method static \Illuminate\Database\Query\Builder|Transaction onlyTrashed()
- * @method static Builder|Transaction query()
- * @method static Builder|Transaction transactionTypes($types)
- * @method static Builder|Transaction whereAccountId($value)
- * @method static Builder|Transaction whereAmount($value)
- * @method static Builder|Transaction whereCreatedAt($value)
- * @method static Builder|Transaction whereDeletedAt($value)
- * @method static Builder|Transaction whereDescription($value)
- * @method static Builder|Transaction whereForeignAmount($value)
- * @method static Builder|Transaction whereForeignCurrencyId($value)
- * @method static Builder|Transaction whereId($value)
- * @method static Builder|Transaction whereIdentifier($value)
- * @method static Builder|Transaction whereReconciled($value)
- * @method static Builder|Transaction whereTransactionCurrencyId($value)
- * @method static Builder|Transaction whereTransactionJournalId($value)
- * @method static Builder|Transaction whereUpdatedAt($value)
+ * @method static Builder|Transaction query()
+ * @method static Builder|Transaction transactionTypes($types)
+ * @method static Builder|Transaction whereAccountId($value)
+ * @method static Builder|Transaction whereAmount($value)
+ * @method static Builder|Transaction whereCreatedAt($value)
+ * @method static Builder|Transaction whereDeletedAt($value)
+ * @method static Builder|Transaction whereDescription($value)
+ * @method static Builder|Transaction whereForeignAmount($value)
+ * @method static Builder|Transaction whereForeignCurrencyId($value)
+ * @method static Builder|Transaction whereId($value)
+ * @method static Builder|Transaction whereIdentifier($value)
+ * @method static Builder|Transaction whereReconciled($value)
+ * @method static Builder|Transaction whereTransactionCurrencyId($value)
+ * @method static Builder|Transaction whereTransactionJournalId($value)
+ * @method static Builder|Transaction whereUpdatedAt($value)
* @method static \Illuminate\Database\Query\Builder|Transaction withTrashed()
* @method static \Illuminate\Database\Query\Builder|Transaction withoutTrashed()
- * @property int $the_count
+ *
+ * @property int|string $the_count
+ *
* @mixin Eloquent
*/
class Transaction extends Model
{
- use SoftDeletes;
use HasFactory;
+ use ReturnsIntegerIdTrait;
+ use SoftDeletes;
- /**
- * The attributes that should be casted to native types.
- *
- * @var array
- */
protected $casts
- = [
- 'created_at' => 'datetime',
- 'updated_at' => 'datetime',
- 'deleted_at' => 'datetime',
- 'identifier' => 'int',
- 'encrypted' => 'boolean', // model does not have these fields though
- 'bill_name_encrypted' => 'boolean',
- 'reconciled' => 'boolean',
- ];
- /** @var array Fields that can be filled */
+ = [
+ 'created_at' => 'datetime',
+ 'updated_at' => 'datetime',
+ 'deleted_at' => 'datetime',
+ 'identifier' => 'int',
+ 'encrypted' => 'boolean', // model does not have these fields though
+ 'bill_name_encrypted' => 'boolean',
+ 'reconciled' => 'boolean',
+ 'date' => 'datetime',
+ ];
+
protected $fillable
- = [
- 'account_id',
- 'transaction_journal_id',
- 'description',
- 'amount',
- 'identifier',
- 'transaction_currency_id',
- 'foreign_currency_id',
- 'foreign_amount',
- 'reconciled',
- ];
- /** @var array Hidden from view */
+ = [
+ 'account_id',
+ 'transaction_journal_id',
+ 'description',
+ 'amount',
+ 'identifier',
+ 'transaction_currency_id',
+ 'foreign_currency_id',
+ 'foreign_amount',
+ 'reconciled',
+ ];
+
protected $hidden = ['encrypted'];
/**
* Get the account this object belongs to.
- *
- * @return BelongsTo
*/
public function account(): BelongsTo
{
@@ -135,8 +134,6 @@ class Transaction extends Model
/**
* Get the budget(s) this object belongs to.
- *
- * @return BelongsToMany
*/
public function budgets(): BelongsToMany
{
@@ -145,8 +142,6 @@ class Transaction extends Model
/**
* Get the category(ies) this object belongs to.
- *
- * @return BelongsToMany
*/
public function categories(): BelongsToMany
{
@@ -155,8 +150,6 @@ class Transaction extends Model
/**
* Get the currency this object belongs to.
- *
- * @return BelongsTo
*/
public function foreignCurrency(): BelongsTo
{
@@ -165,10 +158,6 @@ class Transaction extends Model
/**
* Check for transactions AFTER a specified date.
- *
- *
- * @param Builder $query
- * @param Carbon $date
*/
public function scopeAfter(Builder $query, Carbon $date): void
{
@@ -180,18 +169,11 @@ class Transaction extends Model
/**
* Check if a table is joined.
- *
- * @param Builder $query
- * @param string $table
- *
- * @return bool
*/
public static function isJoined(Builder $query, string $table): bool
{
$joins = $query->getQuery()->joins;
- if (null === $joins) {
- return false;
- }
+
foreach ($joins as $join) {
if ($join->table === $table) {
return true;
@@ -203,10 +185,6 @@ class Transaction extends Model
/**
* Check for transactions BEFORE the specified date.
- *
- *
- * @param Builder $query
- * @param Carbon $date
*/
public function scopeBefore(Builder $query, Carbon $date): void
{
@@ -216,11 +194,6 @@ class Transaction extends Model
$query->where('transaction_journals.date', '<=', $date->format('Y-m-d 23:59:59'));
}
- /**
- *
- * @param Builder $query
- * @param array $types
- */
public function scopeTransactionTypes(Builder $query, array $types): void
{
if (!self::isJoined($query, 'transaction_journals')) {
@@ -234,7 +207,6 @@ class Transaction extends Model
}
/**
- *
* @param mixed $value
*/
public function setAmountAttribute($value): void
@@ -242,43 +214,47 @@ class Transaction extends Model
$this->attributes['amount'] = (string)$value;
}
- /**
- * @return BelongsTo
- */
public function transactionCurrency(): BelongsTo
{
return $this->belongsTo(TransactionCurrency::class);
}
- /**
- * @return BelongsTo
- */
public function transactionJournal(): BelongsTo
{
return $this->belongsTo(TransactionJournal::class);
}
+ protected function accountId(): Attribute
+ {
+ return Attribute::make(
+ get: static fn ($value) => (int)$value,
+ );
+ }
+
/**
* Get the amount
- *
- * @return Attribute
*/
protected function amount(): Attribute
{
return Attribute::make(
- get: fn ($value) => (string)$value,
+ get: static fn ($value) => (string)$value,
);
}
/**
* Get the foreign amount
- *
- * @return Attribute
*/
protected function foreignAmount(): Attribute
{
return Attribute::make(
- get: fn ($value) => (string)$value,
+ get: static fn ($value) => (string)$value,
+ );
+ }
+
+ protected function transactionJournalId(): Attribute
+ {
+ return Attribute::make(
+ get: static fn ($value) => (int)$value,
);
}
}
diff --git a/app/Models/TransactionCurrency.php b/app/Models/TransactionCurrency.php
index 5d34e44419..886bc8a4c8 100644
--- a/app/Models/TransactionCurrency.php
+++ b/app/Models/TransactionCurrency.php
@@ -23,36 +23,43 @@ declare(strict_types=1);
namespace FireflyIII\Models;
+use Carbon\Carbon;
use Eloquent;
+use FireflyIII\Support\Models\ReturnsIntegerIdTrait;
+use FireflyIII\User;
+use Illuminate\Database\Eloquent\Casts\Attribute;
use Illuminate\Database\Eloquent\Collection;
use Illuminate\Database\Eloquent\Model;
+use Illuminate\Database\Eloquent\Relations\BelongsToMany;
use Illuminate\Database\Eloquent\Relations\HasMany;
use Illuminate\Database\Eloquent\SoftDeletes;
use Illuminate\Database\Query\Builder;
-use Illuminate\Support\Carbon;
use Symfony\Component\HttpKernel\Exception\NotFoundHttpException;
/**
* FireflyIII\Models\TransactionCurrency
*
- * @property int $id
- * @property Carbon|null $created_at
- * @property Carbon|null $updated_at
- * @property Carbon|null $deleted_at
- * @property bool $enabled
- * @property string $code
- * @property string $name
- * @property string $symbol
- * @property int $decimal_places
- * @property-read Collection|BudgetLimit[] $budgetLimits
- * @property-read int|null $budget_limits_count
- * @property-read Collection|TransactionJournal[] $transactionJournals
- * @property-read int|null $transaction_journals_count
- * @property-read Collection|Transaction[] $transactions
- * @property-read int|null $transactions_count
+ * @property int $id
+ * @property null|Carbon $created_at
+ * @property null|Carbon $updated_at
+ * @property null|Carbon $deleted_at
+ * @property bool $enabled
+ * @property null|bool $userGroupDefault
+ * @property null|bool $userGroupEnabled
+ * @property string $code
+ * @property string $name
+ * @property string $symbol
+ * @property int $decimal_places
+ * @property BudgetLimit[]|Collection $budgetLimits
+ * @property null|int $budget_limits_count
+ * @property Collection|TransactionJournal[] $transactionJournals
+ * @property null|int $transaction_journals_count
+ * @property Collection|Transaction[] $transactions
+ * @property null|int $transactions_count
+ *
* @method static \Illuminate\Database\Eloquent\Builder|TransactionCurrency newModelQuery()
* @method static \Illuminate\Database\Eloquent\Builder|TransactionCurrency newQuery()
- * @method static Builder|TransactionCurrency onlyTrashed()
+ * @method static Builder|TransactionCurrency onlyTrashed()
* @method static \Illuminate\Database\Eloquent\Builder|TransactionCurrency query()
* @method static \Illuminate\Database\Eloquent\Builder|TransactionCurrency whereCode($value)
* @method static \Illuminate\Database\Eloquent\Builder|TransactionCurrency whereCreatedAt($value)
@@ -63,71 +70,97 @@ use Symfony\Component\HttpKernel\Exception\NotFoundHttpException;
* @method static \Illuminate\Database\Eloquent\Builder|TransactionCurrency whereName($value)
* @method static \Illuminate\Database\Eloquent\Builder|TransactionCurrency whereSymbol($value)
* @method static \Illuminate\Database\Eloquent\Builder|TransactionCurrency whereUpdatedAt($value)
- * @method static Builder|TransactionCurrency withTrashed()
- * @method static Builder|TransactionCurrency withoutTrashed()
+ * @method static Builder|TransactionCurrency withTrashed()
+ * @method static Builder|TransactionCurrency withoutTrashed()
+ *
+ * @property Collection $userGroups
+ * @property null|int $user_groups_count
+ * @property Collection $users
+ * @property null|int $users_count
+ *
* @mixin Eloquent
*/
class TransactionCurrency extends Model
{
+ use ReturnsIntegerIdTrait;
use SoftDeletes;
- /**
- * The attributes that should be casted to native types.
- *
- * @var array
- */
+ public ?bool $userGroupDefault;
+ public ?bool $userGroupEnabled;
protected $casts
- = [
- 'created_at' => 'datetime',
- 'updated_at' => 'datetime',
- 'deleted_at' => 'datetime',
- 'decimal_places' => 'int',
- 'enabled' => 'bool',
- ];
- /** @var array Fields that can be filled */
+ = [
+ 'created_at' => 'datetime',
+ 'updated_at' => 'datetime',
+ 'deleted_at' => 'datetime',
+ 'decimal_places' => 'int',
+ 'enabled' => 'bool',
+ ];
+
protected $fillable = ['name', 'code', 'symbol', 'decimal_places', 'enabled'];
/**
* Route binder. Converts the key in the URL to the specified object (or throw 404).
*
- * @param string $value
- *
- * @return TransactionCurrency
* @throws NotFoundHttpException
*/
- public static function routeBinder(string $value): TransactionCurrency
+ public static function routeBinder(string $value): self
{
if (auth()->check()) {
$currencyId = (int)$value;
$currency = self::find($currencyId);
if (null !== $currency) {
+ $currency->refreshForUser(auth()->user());
+
return $currency;
}
}
+
throw new NotFoundHttpException();
}
- /**
- * @return HasMany
- */
+ public function refreshForUser(User $user): void
+ {
+ $current = $user->userGroup->currencies()->where('transaction_currencies.id', $this->id)->first();
+ $default = app('amount')->getDefaultCurrencyByUserGroup($user->userGroup);
+ $this->userGroupDefault = $default->id === $this->id;
+ $this->userGroupEnabled = null !== $current;
+ }
+
public function budgetLimits(): HasMany
{
return $this->hasMany(BudgetLimit::class);
}
- /**
- * @return HasMany
- */
public function transactionJournals(): HasMany
{
return $this->hasMany(TransactionJournal::class);
}
- /**
- * @return HasMany
- */
public function transactions(): HasMany
{
return $this->hasMany(Transaction::class);
}
+
+ /**
+ * Link to user groups
+ */
+ public function userGroups(): BelongsToMany
+ {
+ return $this->belongsToMany(UserGroup::class)->withTimestamps()->withPivot('group_default');
+ }
+
+ /**
+ * Link to users
+ */
+ public function users(): BelongsToMany
+ {
+ return $this->belongsToMany(User::class)->withTimestamps()->withPivot('user_default');
+ }
+
+ protected function decimalPlaces(): Attribute
+ {
+ return Attribute::make(
+ get: static fn ($value) => (int)$value,
+ );
+ }
}
diff --git a/app/Models/TransactionGroup.php b/app/Models/TransactionGroup.php
index 06a58e9257..76e4d64a82 100644
--- a/app/Models/TransactionGroup.php
+++ b/app/Models/TransactionGroup.php
@@ -23,7 +23,10 @@ declare(strict_types=1);
namespace FireflyIII\Models;
+use Carbon\Carbon;
use Eloquent;
+use FireflyIII\Support\Models\ReturnsIntegerIdTrait;
+use FireflyIII\Support\Models\ReturnsIntegerUserIdTrait;
use FireflyIII\User;
use Illuminate\Database\Eloquent\Collection;
use Illuminate\Database\Eloquent\Model;
@@ -31,25 +34,24 @@ use Illuminate\Database\Eloquent\Relations\BelongsTo;
use Illuminate\Database\Eloquent\Relations\HasMany;
use Illuminate\Database\Eloquent\SoftDeletes;
use Illuminate\Database\Query\Builder;
-use Illuminate\Support\Carbon;
-use Illuminate\Support\Facades\Log;
use Symfony\Component\HttpKernel\Exception\NotFoundHttpException;
/**
* FireflyIII\Models\TransactionGroup
*
- * @property int $id
- * @property Carbon|null $created_at
- * @property Carbon|null $updated_at
- * @property Carbon|null $deleted_at
- * @property int $user_id
- * @property string|null $title
- * @property-read Collection|TransactionJournal[] $transactionJournals
- * @property-read int|null $transaction_journals_count
- * @property-read User $user
+ * @property int $id
+ * @property null|Carbon $created_at
+ * @property null|Carbon $updated_at
+ * @property null|Carbon $deleted_at
+ * @property int $user_id
+ * @property null|string $title
+ * @property Collection|TransactionJournal[] $transactionJournals
+ * @property null|int $transaction_journals_count
+ * @property User $user
+ *
* @method static \Illuminate\Database\Eloquent\Builder|TransactionGroup newModelQuery()
* @method static \Illuminate\Database\Eloquent\Builder|TransactionGroup newQuery()
- * @method static Builder|TransactionGroup onlyTrashed()
+ * @method static Builder|TransactionGroup onlyTrashed()
* @method static \Illuminate\Database\Eloquent\Builder|TransactionGroup query()
* @method static \Illuminate\Database\Eloquent\Builder|TransactionGroup whereCreatedAt($value)
* @method static \Illuminate\Database\Eloquent\Builder|TransactionGroup whereDeletedAt($value)
@@ -57,84 +59,76 @@ use Symfony\Component\HttpKernel\Exception\NotFoundHttpException;
* @method static \Illuminate\Database\Eloquent\Builder|TransactionGroup whereTitle($value)
* @method static \Illuminate\Database\Eloquent\Builder|TransactionGroup whereUpdatedAt($value)
* @method static \Illuminate\Database\Eloquent\Builder|TransactionGroup whereUserId($value)
- * @method static Builder|TransactionGroup withTrashed()
- * @method static Builder|TransactionGroup withoutTrashed()
- * @property int|null $user_group_id
+ * @method static Builder|TransactionGroup withTrashed()
+ * @method static Builder|TransactionGroup withoutTrashed()
+ *
+ * @property int $user_group_id
+ *
* @method static \Illuminate\Database\Eloquent\Builder|TransactionGroup whereUserGroupId($value)
- * @property-read UserGroup|null $userGroup
+ *
+ * @property null|UserGroup $userGroup
+ *
* @mixin Eloquent
*/
class TransactionGroup extends Model
{
+ use ReturnsIntegerIdTrait;
+ use ReturnsIntegerUserIdTrait;
use SoftDeletes;
- /**
- * The attributes that should be casted to native types.
- *
- * @var array
- */
protected $casts
- = [
- 'id' => 'integer',
- 'created_at' => 'datetime',
- 'updated_at' => 'datetime',
- 'deleted_at' => 'datetime',
- 'title' => 'string',
- 'date' => 'datetime',
- ];
+ = [
+ 'id' => 'integer',
+ 'created_at' => 'datetime',
+ 'updated_at' => 'datetime',
+ 'deleted_at' => 'datetime',
+ 'title' => 'string',
+ 'date' => 'datetime',
+ ];
- /** @var array Fields that can be filled */
protected $fillable = ['user_id', 'user_group_id', 'title'];
/**
* Route binder. Converts the key in the URL to the specified object (or throw 404).
*
- * @param string $value
- *
- * @return TransactionGroup
* @throws NotFoundHttpException
*/
- public static function routeBinder(string $value): TransactionGroup
+ public static function routeBinder(string $value): self
{
- Log::debug(sprintf('Now in %s("%s")', __METHOD__, $value));
+ app('log')->debug(sprintf('Now in %s("%s")', __METHOD__, $value));
if (auth()->check()) {
$groupId = (int)$value;
+
/** @var User $user */
- $user = auth()->user();
- Log::debug(sprintf('User authenticated as %s', $user->email));
- /** @var TransactionGroup $group */
- $group = $user->transactionGroups()
- ->with(['transactionJournals', 'transactionJournals.transactions'])
- ->where('transaction_groups.id', $groupId)->first(['transaction_groups.*']);
+ $user = auth()->user();
+ app('log')->debug(sprintf('User authenticated as %s', $user->email));
+
+ /** @var null|TransactionGroup $group */
+ $group = $user->transactionGroups()
+ ->with(['transactionJournals', 'transactionJournals.transactions'])
+ ->where('transaction_groups.id', $groupId)->first(['transaction_groups.*'])
+ ;
if (null !== $group) {
- Log::debug(sprintf('Found group #%d.', $group->id));
+ app('log')->debug(sprintf('Found group #%d.', $group->id));
+
return $group;
}
}
- Log::debug('Found no group.');
+ app('log')->debug('Found no group.');
throw new NotFoundHttpException();
}
- /**
- * @return BelongsTo
- */
public function user(): BelongsTo
{
return $this->belongsTo(User::class);
}
- /**
- * @return HasMany
- */
public function transactionJournals(): HasMany
{
return $this->hasMany(TransactionJournal::class);
}
- /**
- * @return BelongsTo
- */
public function userGroup(): BelongsTo
{
return $this->belongsTo(UserGroup::class);
diff --git a/app/Models/TransactionJournal.php b/app/Models/TransactionJournal.php
index 166cb72b53..b5e77ee825 100644
--- a/app/Models/TransactionJournal.php
+++ b/app/Models/TransactionJournal.php
@@ -25,9 +25,12 @@ namespace FireflyIII\Models;
use Carbon\Carbon;
use Eloquent;
+use FireflyIII\Support\Models\ReturnsIntegerIdTrait;
+use FireflyIII\Support\Models\ReturnsIntegerUserIdTrait;
use FireflyIII\User;
use Illuminate\Database\Eloquent\Builder;
use Illuminate\Database\Eloquent\Builder as EloquentBuilder;
+use Illuminate\Database\Eloquent\Casts\Attribute;
use Illuminate\Database\Eloquent\Collection;
use Illuminate\Database\Eloquent\Factories\HasFactory;
use Illuminate\Database\Eloquent\Model;
@@ -41,144 +44,144 @@ use Symfony\Component\HttpKernel\Exception\NotFoundHttpException;
/**
* FireflyIII\Models\TransactionJournal
*
- * @property int $id
- * @property Carbon|null $created_at
- * @property Carbon|null $updated_at
- * @property Carbon|null $deleted_at
- * @property int $user_id
- * @property int $transaction_type_id
- * @property int|null $transaction_group_id
- * @property int|null $bill_id
- * @property int|null $transaction_currency_id
- * @property string $description
- * @property Carbon $date
- * @property Carbon|null $interest_date
- * @property Carbon|null $book_date
- * @property Carbon|null $process_date
- * @property int $order
- * @property int $tag_count
- * @property string $transaction_type_type
- * @property bool $encrypted
- * @property bool $completed
- * @property-read Collection|Attachment[] $attachments
- * @property-read int|null $attachments_count
- * @property-read Bill|null $bill
- * @property-read Collection|Budget[] $budgets
- * @property-read int|null $budgets_count
- * @property-read Collection|Category[] $categories
- * @property-read int|null $categories_count
- * @property-read Collection|TransactionJournalLink[] $destJournalLinks
- * @property-read int|null $dest_journal_links_count
- * @property-read Collection|Note[] $notes
- * @property-read int|null $notes_count
- * @property-read Collection|PiggyBankEvent[] $piggyBankEvents
- * @property-read int|null $piggy_bank_events_count
- * @property-read Collection|TransactionJournalLink[] $sourceJournalLinks
- * @property-read int|null $source_journal_links_count
- * @property-read Collection|Tag[] $tags
- * @property-read int|null $tags_count
- * @property-read TransactionCurrency|null $transactionCurrency
- * @property-read TransactionGroup|null $transactionGroup
- * @property-read Collection|TransactionJournalMeta[] $transactionJournalMeta
- * @property-read int|null $transaction_journal_meta_count
- * @property-read TransactionType $transactionType
- * @property-read Collection|Transaction[] $transactions
- * @property-read int|null $transactions_count
- * @property-read User $user
- * @method static EloquentBuilder|TransactionJournal after(Carbon $date)
- * @method static EloquentBuilder|TransactionJournal before(Carbon $date)
- * @method static EloquentBuilder|TransactionJournal newModelQuery()
- * @method static EloquentBuilder|TransactionJournal newQuery()
+ * @property int $id
+ * @property null|Carbon $created_at
+ * @property null|Carbon $updated_at
+ * @property null|Carbon $deleted_at
+ * @property int $user_id
+ * @property int $transaction_type_id
+ * @property null|int|string $transaction_group_id
+ * @property null|int|string $bill_id
+ * @property null|int|string $transaction_currency_id
+ * @property null|string $description
+ * @property Carbon $date
+ * @property null|Carbon $interest_date
+ * @property null|Carbon $book_date
+ * @property null|Carbon $process_date
+ * @property int $order
+ * @property int $tag_count
+ * @property string $transaction_type_type
+ * @property bool $encrypted
+ * @property bool $completed
+ * @property Attachment[]|Collection $attachments
+ * @property null|int $attachments_count
+ * @property null|Bill $bill
+ * @property Budget[]|Collection $budgets
+ * @property null|int $budgets_count
+ * @property Category[]|Collection $categories
+ * @property null|int $categories_count
+ * @property Collection|TransactionJournalLink[] $destJournalLinks
+ * @property null|int $dest_journal_links_count
+ * @property Collection|Note[] $notes
+ * @property null|int $notes_count
+ * @property Collection|PiggyBankEvent[] $piggyBankEvents
+ * @property null|int $piggy_bank_events_count
+ * @property Collection|TransactionJournalLink[] $sourceJournalLinks
+ * @property null|int $source_journal_links_count
+ * @property Collection|Tag[] $tags
+ * @property null|int $tags_count
+ * @property null|TransactionCurrency $transactionCurrency
+ * @property null|TransactionGroup $transactionGroup
+ * @property Collection|TransactionJournalMeta[] $transactionJournalMeta
+ * @property null|int $transaction_journal_meta_count
+ * @property TransactionType $transactionType
+ * @property Collection|Transaction[] $transactions
+ * @property null|int $transactions_count
+ * @property User $user
+ *
+ * @method static EloquentBuilder|TransactionJournal after(Carbon $date)
+ * @method static EloquentBuilder|TransactionJournal before(Carbon $date)
+ * @method static EloquentBuilder|TransactionJournal newModelQuery()
+ * @method static EloquentBuilder|TransactionJournal newQuery()
* @method static \Illuminate\Database\Query\Builder|TransactionJournal onlyTrashed()
- * @method static EloquentBuilder|TransactionJournal query()
- * @method static EloquentBuilder|TransactionJournal transactionTypes($types)
- * @method static EloquentBuilder|TransactionJournal whereBillId($value)
- * @method static EloquentBuilder|TransactionJournal whereBookDate($value)
- * @method static EloquentBuilder|TransactionJournal whereCompleted($value)
- * @method static EloquentBuilder|TransactionJournal whereCreatedAt($value)
- * @method static EloquentBuilder|TransactionJournal whereDate($value)
- * @method static EloquentBuilder|TransactionJournal whereDeletedAt($value)
- * @method static EloquentBuilder|TransactionJournal whereDescription($value)
- * @method static EloquentBuilder|TransactionJournal whereEncrypted($value)
- * @method static EloquentBuilder|TransactionJournal whereId($value)
- * @method static EloquentBuilder|TransactionJournal whereInterestDate($value)
- * @method static EloquentBuilder|TransactionJournal whereOrder($value)
- * @method static EloquentBuilder|TransactionJournal whereProcessDate($value)
- * @method static EloquentBuilder|TransactionJournal whereTagCount($value)
- * @method static EloquentBuilder|TransactionJournal whereTransactionCurrencyId($value)
- * @method static EloquentBuilder|TransactionJournal whereTransactionGroupId($value)
- * @method static EloquentBuilder|TransactionJournal whereTransactionTypeId($value)
- * @method static EloquentBuilder|TransactionJournal whereUpdatedAt($value)
- * @method static EloquentBuilder|TransactionJournal whereUserId($value)
+ * @method static EloquentBuilder|TransactionJournal query()
+ * @method static EloquentBuilder|TransactionJournal transactionTypes($types)
+ * @method static EloquentBuilder|TransactionJournal whereBillId($value)
+ * @method static EloquentBuilder|TransactionJournal whereBookDate($value)
+ * @method static EloquentBuilder|TransactionJournal whereCompleted($value)
+ * @method static EloquentBuilder|TransactionJournal whereCreatedAt($value)
+ * @method static EloquentBuilder|TransactionJournal whereDate($value)
+ * @method static EloquentBuilder|TransactionJournal whereDeletedAt($value)
+ * @method static EloquentBuilder|TransactionJournal whereDescription($value)
+ * @method static EloquentBuilder|TransactionJournal whereEncrypted($value)
+ * @method static EloquentBuilder|TransactionJournal whereId($value)
+ * @method static EloquentBuilder|TransactionJournal whereInterestDate($value)
+ * @method static EloquentBuilder|TransactionJournal whereOrder($value)
+ * @method static EloquentBuilder|TransactionJournal whereProcessDate($value)
+ * @method static EloquentBuilder|TransactionJournal whereTagCount($value)
+ * @method static EloquentBuilder|TransactionJournal whereTransactionCurrencyId($value)
+ * @method static EloquentBuilder|TransactionJournal whereTransactionGroupId($value)
+ * @method static EloquentBuilder|TransactionJournal whereTransactionTypeId($value)
+ * @method static EloquentBuilder|TransactionJournal whereUpdatedAt($value)
+ * @method static EloquentBuilder|TransactionJournal whereUserId($value)
* @method static \Illuminate\Database\Query\Builder|TransactionJournal withTrashed()
* @method static \Illuminate\Database\Query\Builder|TransactionJournal withoutTrashed()
- * @property-read Collection|Location[] $locations
- * @property-read int|null $locations_count
- * @property int $the_count
- * @property int|null $user_group_id
+ *
+ * @property Collection|Location[] $locations
+ * @property null|int $locations_count
+ * @property int|string $the_count
+ * @property int $user_group_id
+ *
* @method static EloquentBuilder|TransactionJournal whereUserGroupId($value)
- * @property-read Collection $auditLogEntries
- * @property-read int|null $audit_log_entries_count
+ *
+ * @property Collection $auditLogEntries
+ * @property null|int $audit_log_entries_count
+ *
* @mixin Eloquent
*/
class TransactionJournal extends Model
{
- use SoftDeletes;
use HasFactory;
+ use ReturnsIntegerIdTrait;
+ use ReturnsIntegerUserIdTrait;
+ use SoftDeletes;
- /**
- * The attributes that should be casted to native types.
- *
- * @var array
- */
protected $casts
- = [
- 'created_at' => 'datetime',
- 'updated_at' => 'datetime',
- 'deleted_at' => 'datetime',
- 'date' => 'datetime',
- 'interest_date' => 'date',
- 'book_date' => 'date',
- 'process_date' => 'date',
- 'order' => 'int',
- 'tag_count' => 'int',
- 'encrypted' => 'boolean',
- 'completed' => 'boolean',
- ];
+ = [
+ 'created_at' => 'datetime',
+ 'updated_at' => 'datetime',
+ 'deleted_at' => 'datetime',
+ 'date' => 'datetime',
+ 'interest_date' => 'date',
+ 'book_date' => 'date',
+ 'process_date' => 'date',
+ 'order' => 'int',
+ 'tag_count' => 'int',
+ 'encrypted' => 'boolean',
+ 'completed' => 'boolean',
+ ];
- /** @var array Fields that can be filled */
protected $fillable
- = [
- 'user_id',
- 'user_group_id',
- 'transaction_type_id',
- 'bill_id',
- 'tag_count',
- 'transaction_currency_id',
- 'description',
- 'completed',
- 'order',
- 'date',
- ];
- /** @var array Hidden from view */
+ = [
+ 'user_id',
+ 'user_group_id',
+ 'transaction_type_id',
+ 'bill_id',
+ 'tag_count',
+ 'transaction_currency_id',
+ 'description',
+ 'completed',
+ 'order',
+ 'date',
+ ];
+
protected $hidden = ['encrypted'];
/**
* Route binder. Converts the key in the URL to the specified object (or throw 404).
*
- * @param string $value
- *
- * @return TransactionJournal
* @throws NotFoundHttpException
*/
- public static function routeBinder(string $value): TransactionJournal
+ public static function routeBinder(string $value): self
{
if (auth()->check()) {
$journalId = (int)$value;
+
/** @var User $user */
- $user = auth()->user();
- /** @var TransactionJournal $journal */
- $journal = $user->transactionJournals()->where('transaction_journals.id', $journalId)->first(['transaction_journals.*']);
+ $user = auth()->user();
+
+ /** @var null|TransactionJournal $journal */
+ $journal = $user->transactionJournals()->where('transaction_journals.id', $journalId)->first(['transaction_journals.*']);
if (null !== $journal) {
return $journal;
}
@@ -187,65 +190,41 @@ class TransactionJournal extends Model
throw new NotFoundHttpException();
}
- /**
- * @return BelongsTo
- */
public function user(): BelongsTo
{
return $this->belongsTo(User::class);
}
- /**
- * @return MorphMany
- */
public function attachments(): MorphMany
{
return $this->morphMany(Attachment::class, 'attachable');
}
- /**
- * @return MorphMany
- */
public function auditLogEntries(): MorphMany
{
return $this->morphMany(AuditLogEntry::class, 'auditable');
}
- /**
- * @return BelongsTo
- */
public function bill(): BelongsTo
{
return $this->belongsTo(Bill::class);
}
- /**
- * @return BelongsToMany
- */
public function budgets(): BelongsToMany
{
return $this->belongsToMany(Budget::class);
}
- /**
- * @return BelongsToMany
- */
public function categories(): BelongsToMany
{
return $this->belongsToMany(Category::class);
}
- /**
- * @return HasMany
- */
public function destJournalLinks(): HasMany
{
return $this->hasMany(TransactionJournalLink::class, 'destination_id');
}
- /**
- * @return bool
- */
public function isTransfer(): bool
{
if (null !== $this->transaction_type_type) {
@@ -255,9 +234,6 @@ class TransactionJournal extends Model
return $this->transactionType->isTransfer();
}
- /**
- * @return MorphMany
- */
public function locations(): MorphMany
{
return $this->morphMany(Location::class, 'locatable');
@@ -271,43 +247,21 @@ class TransactionJournal extends Model
return $this->morphMany(Note::class, 'noteable');
}
- /**
- * @return HasMany
- */
public function piggyBankEvents(): HasMany
{
return $this->hasMany(PiggyBankEvent::class);
}
- /**
- *
- * @param EloquentBuilder $query
- * @param Carbon $date
- *
- * @return EloquentBuilder
- */
public function scopeAfter(EloquentBuilder $query, Carbon $date): EloquentBuilder
{
return $query->where('transaction_journals.date', '>=', $date->format('Y-m-d 00:00:00'));
}
- /**
- *
- * @param EloquentBuilder $query
- * @param Carbon $date
- *
- * @return EloquentBuilder
- */
public function scopeBefore(EloquentBuilder $query, Carbon $date): EloquentBuilder
{
return $query->where('transaction_journals.date', '<=', $date->format('Y-m-d 00:00:00'));
}
- /**
- *
- * @param EloquentBuilder $query
- * @param array $types
- */
public function scopeTransactionTypes(EloquentBuilder $query, array $types): void
{
if (!self::isJoined($query, 'transaction_types')) {
@@ -320,19 +274,10 @@ class TransactionJournal extends Model
/**
* Checks if tables are joined.
- *
- *
- * @param Builder $query
- * @param string $table
- *
- * @return bool
*/
public static function isJoined(Builder $query, string $table): bool
{
$joins = $query->getQuery()->joins;
- if (null === $joins) {
- return false;
- }
foreach ($joins as $join) {
if ($join->table === $table) {
return true;
@@ -342,59 +287,52 @@ class TransactionJournal extends Model
return false;
}
- /**
- * @return HasMany
- */
public function sourceJournalLinks(): HasMany
{
return $this->hasMany(TransactionJournalLink::class, 'source_id');
}
- /**
- * @return BelongsToMany
- */
public function tags(): BelongsToMany
{
return $this->belongsToMany(Tag::class);
}
- /**
- * @return BelongsTo
- */
public function transactionCurrency(): BelongsTo
{
return $this->belongsTo(TransactionCurrency::class);
}
- /**
- * @return BelongsTo
- */
public function transactionGroup(): BelongsTo
{
return $this->belongsTo(TransactionGroup::class);
}
- /**
- * @return HasMany
- */
public function transactionJournalMeta(): HasMany
{
return $this->hasMany(TransactionJournalMeta::class);
}
- /**
- * @return BelongsTo
- */
public function transactionType(): BelongsTo
{
return $this->belongsTo(TransactionType::class);
}
- /**
- * @return HasMany
- */
public function transactions(): HasMany
{
return $this->hasMany(Transaction::class);
}
+
+ protected function order(): Attribute
+ {
+ return Attribute::make(
+ get: static fn ($value) => (int)$value,
+ );
+ }
+
+ protected function transactionTypeId(): Attribute
+ {
+ return Attribute::make(
+ get: static fn ($value) => (int)$value,
+ );
+ }
}
diff --git a/app/Models/TransactionJournalLink.php b/app/Models/TransactionJournalLink.php
index 30740c9990..f3237f4664 100644
--- a/app/Models/TransactionJournalLink.php
+++ b/app/Models/TransactionJournalLink.php
@@ -23,32 +23,35 @@ declare(strict_types=1);
namespace FireflyIII\Models;
+use Carbon\Carbon;
use Eloquent;
+use FireflyIII\Support\Models\ReturnsIntegerIdTrait;
use Illuminate\Database\Eloquent\Builder;
+use Illuminate\Database\Eloquent\Casts\Attribute;
use Illuminate\Database\Eloquent\Collection;
use Illuminate\Database\Eloquent\Model;
use Illuminate\Database\Eloquent\Relations\BelongsTo;
use Illuminate\Database\Eloquent\Relations\MorphMany;
-use Illuminate\Support\Carbon;
use Symfony\Component\HttpKernel\Exception\NotFoundHttpException;
/**
* FireflyIII\Models\TransactionJournalLink
*
- * @property int $id
- * @property Carbon|null $created_at
- * @property Carbon|null $updated_at
- * @property int $link_type_id
- * @property int $source_id
- * @property int $destination_id
- * @property string|null $comment
- * @property-read TransactionJournal $destination
- * @property-read LinkType $linkType
- * @property-read Collection|Note[] $notes
- * @property-read int|null $notes_count
- * @property-read TransactionJournal $source
- * @property-read string $inward
- * @property-read string $outward
+ * @property int $id
+ * @property null|Carbon $created_at
+ * @property null|Carbon $updated_at
+ * @property int $link_type_id
+ * @property int $source_id
+ * @property int $destination_id
+ * @property null|string $comment
+ * @property TransactionJournal $destination
+ * @property LinkType $linkType
+ * @property Collection|Note[] $notes
+ * @property null|int $notes_count
+ * @property TransactionJournal $source
+ * @property string $inward
+ * @property string $outward
+ *
* @method static Builder|TransactionJournalLink newModelQuery()
* @method static Builder|TransactionJournalLink newQuery()
* @method static Builder|TransactionJournalLink query()
@@ -59,60 +62,51 @@ use Symfony\Component\HttpKernel\Exception\NotFoundHttpException;
* @method static Builder|TransactionJournalLink whereLinkTypeId($value)
* @method static Builder|TransactionJournalLink whereSourceId($value)
* @method static Builder|TransactionJournalLink whereUpdatedAt($value)
+ *
* @mixin Eloquent
*/
class TransactionJournalLink extends Model
{
- /**
- * The attributes that should be casted to native types.
- *
- * @var array
- */
+ use ReturnsIntegerIdTrait;
+
protected $casts
- = [
- 'created_at' => 'datetime',
- 'updated_at' => 'datetime',
- ];
+ = [
+ 'created_at' => 'datetime',
+ 'updated_at' => 'datetime',
+ ];
+
/** @var string The table to store the data in */
protected $table = 'journal_links';
/**
* Route binder. Converts the key in the URL to the specified object (or throw 404).
*
- * @param string $value
- *
- * @return TransactionJournalLink
- *
* @throws NotFoundHttpException
*/
- public static function routeBinder(string $value): TransactionJournalLink
+ public static function routeBinder(string $value): self
{
if (auth()->check()) {
$linkId = (int)$value;
$link = self::where('journal_links.id', $linkId)
- ->leftJoin('transaction_journals as t_a', 't_a.id', '=', 'source_id')
- ->leftJoin('transaction_journals as t_b', 't_b.id', '=', 'destination_id')
- ->where('t_a.user_id', auth()->user()->id)
- ->where('t_b.user_id', auth()->user()->id)
- ->first(['journal_links.*']);
+ ->leftJoin('transaction_journals as t_a', 't_a.id', '=', 'source_id')
+ ->leftJoin('transaction_journals as t_b', 't_b.id', '=', 'destination_id')
+ ->where('t_a.user_id', auth()->user()->id)
+ ->where('t_b.user_id', auth()->user()->id)
+ ->first(['journal_links.*'])
+ ;
if (null !== $link) {
return $link;
}
}
+
throw new NotFoundHttpException();
}
- /**
- * @return BelongsTo
- */
public function destination(): BelongsTo
{
return $this->belongsTo(TransactionJournal::class, 'destination_id');
}
- /**
- * @return BelongsTo
- */
public function linkType(): BelongsTo
{
return $this->belongsTo(LinkType::class);
@@ -126,11 +120,29 @@ class TransactionJournalLink extends Model
return $this->morphMany(Note::class, 'noteable');
}
- /**
- * @return BelongsTo
- */
public function source(): BelongsTo
{
return $this->belongsTo(TransactionJournal::class, 'source_id');
}
+
+ protected function destinationId(): Attribute
+ {
+ return Attribute::make(
+ get: static fn ($value) => (int)$value,
+ );
+ }
+
+ protected function linkTypeId(): Attribute
+ {
+ return Attribute::make(
+ get: static fn ($value) => (int)$value,
+ );
+ }
+
+ protected function sourceId(): Attribute
+ {
+ return Attribute::make(
+ get: static fn ($value) => (int)$value,
+ );
+ }
}
diff --git a/app/Models/TransactionJournalMeta.php b/app/Models/TransactionJournalMeta.php
index 7c27a31e88..2b94815cfa 100644
--- a/app/Models/TransactionJournalMeta.php
+++ b/app/Models/TransactionJournalMeta.php
@@ -23,28 +23,31 @@ declare(strict_types=1);
namespace FireflyIII\Models;
+use Carbon\Carbon;
use Eloquent;
+use FireflyIII\Support\Models\ReturnsIntegerIdTrait;
+use Illuminate\Database\Eloquent\Casts\Attribute;
use Illuminate\Database\Eloquent\Model;
use Illuminate\Database\Eloquent\Relations\BelongsTo;
use Illuminate\Database\Eloquent\SoftDeletes;
use Illuminate\Database\Query\Builder;
-use Illuminate\Support\Carbon;
/**
* FireflyIII\Models\TransactionJournalMeta
*
- * @property int $id
- * @property Carbon|null $created_at
- * @property Carbon|null $updated_at
- * @property int $transaction_journal_id
- * @property string $name
- * @property mixed $data
- * @property string $hash
- * @property Carbon|null $deleted_at
- * @property-read TransactionJournal $transactionJournal
+ * @property int $id
+ * @property null|Carbon $created_at
+ * @property null|Carbon $updated_at
+ * @property int $transaction_journal_id
+ * @property string $name
+ * @property mixed $data
+ * @property string $hash
+ * @property null|Carbon $deleted_at
+ * @property TransactionJournal $transactionJournal
+ *
* @method static \Illuminate\Database\Eloquent\Builder|TransactionJournalMeta newModelQuery()
* @method static \Illuminate\Database\Eloquent\Builder|TransactionJournalMeta newQuery()
- * @method static Builder|TransactionJournalMeta onlyTrashed()
+ * @method static Builder|TransactionJournalMeta onlyTrashed()
* @method static \Illuminate\Database\Eloquent\Builder|TransactionJournalMeta query()
* @method static \Illuminate\Database\Eloquent\Builder|TransactionJournalMeta whereCreatedAt($value)
* @method static \Illuminate\Database\Eloquent\Builder|TransactionJournalMeta whereData($value)
@@ -54,32 +57,29 @@ use Illuminate\Support\Carbon;
* @method static \Illuminate\Database\Eloquent\Builder|TransactionJournalMeta whereName($value)
* @method static \Illuminate\Database\Eloquent\Builder|TransactionJournalMeta whereTransactionJournalId($value)
* @method static \Illuminate\Database\Eloquent\Builder|TransactionJournalMeta whereUpdatedAt($value)
- * @method static Builder|TransactionJournalMeta withTrashed()
- * @method static Builder|TransactionJournalMeta withoutTrashed()
+ * @method static Builder|TransactionJournalMeta withTrashed()
+ * @method static Builder|TransactionJournalMeta withoutTrashed()
+ *
* @mixin Eloquent
*/
class TransactionJournalMeta extends Model
{
+ use ReturnsIntegerIdTrait;
use SoftDeletes;
- /**
- * The attributes that should be casted to native types.
- *
- * @var array
- */
protected $casts
- = [
- 'created_at' => 'datetime',
- 'updated_at' => 'datetime',
- 'deleted_at' => 'datetime',
- ];
- /** @var array Fields that can be filled */
+ = [
+ 'created_at' => 'datetime',
+ 'updated_at' => 'datetime',
+ 'deleted_at' => 'datetime',
+ ];
+
protected $fillable = ['transaction_journal_id', 'name', 'data', 'hash'];
+
/** @var string The table to store the data in */
- protected $table = 'journal_meta';
+ protected $table = 'journal_meta';
/**
- *
* @param mixed $value
*
* @return mixed
@@ -90,21 +90,24 @@ class TransactionJournalMeta extends Model
}
/**
- *
* @param mixed $value
*/
public function setDataAttribute($value): void
{
$data = json_encode($value);
$this->attributes['data'] = $data;
- $this->attributes['hash'] = hash('sha256', $data);
+ $this->attributes['hash'] = hash('sha256', (string)$data);
}
- /**
- * @return BelongsTo
- */
public function transactionJournal(): BelongsTo
{
return $this->belongsTo(TransactionJournal::class);
}
+
+ protected function transactionJournalId(): Attribute
+ {
+ return Attribute::make(
+ get: static fn ($value) => (int)$value,
+ );
+ }
}
diff --git a/app/Models/TransactionType.php b/app/Models/TransactionType.php
index 3fc2d21efc..7e9c4551bc 100644
--- a/app/Models/TransactionType.php
+++ b/app/Models/TransactionType.php
@@ -23,67 +23,68 @@ declare(strict_types=1);
namespace FireflyIII\Models;
+use Carbon\Carbon;
use Eloquent;
+use FireflyIII\Support\Models\ReturnsIntegerIdTrait;
use Illuminate\Database\Eloquent\Collection;
use Illuminate\Database\Eloquent\Model;
use Illuminate\Database\Eloquent\Relations\HasMany;
use Illuminate\Database\Eloquent\SoftDeletes;
use Illuminate\Database\Query\Builder;
-use Illuminate\Support\Carbon;
use Symfony\Component\HttpKernel\Exception\NotFoundHttpException;
/**
* FireflyIII\Models\TransactionType
*
- * @property int $id
- * @property Carbon|null $created_at
- * @property Carbon|null $updated_at
- * @property Carbon|null $deleted_at
- * @property string $type
- * @property-read Collection|TransactionJournal[] $transactionJournals
- * @property-read int|null $transaction_journals_count
+ * @property int $id
+ * @property null|Carbon $created_at
+ * @property null|Carbon $updated_at
+ * @property null|Carbon $deleted_at
+ * @property string $type
+ * @property Collection|TransactionJournal[] $transactionJournals
+ * @property null|int $transaction_journals_count
+ *
* @method static \Illuminate\Database\Eloquent\Builder|TransactionType newModelQuery()
* @method static \Illuminate\Database\Eloquent\Builder|TransactionType newQuery()
- * @method static Builder|TransactionType onlyTrashed()
+ * @method static Builder|TransactionType onlyTrashed()
* @method static \Illuminate\Database\Eloquent\Builder|TransactionType query()
* @method static \Illuminate\Database\Eloquent\Builder|TransactionType whereCreatedAt($value)
* @method static \Illuminate\Database\Eloquent\Builder|TransactionType whereDeletedAt($value)
* @method static \Illuminate\Database\Eloquent\Builder|TransactionType whereId($value)
* @method static \Illuminate\Database\Eloquent\Builder|TransactionType whereType($value)
* @method static \Illuminate\Database\Eloquent\Builder|TransactionType whereUpdatedAt($value)
- * @method static Builder|TransactionType withTrashed()
- * @method static Builder|TransactionType withoutTrashed()
+ * @method static Builder|TransactionType withTrashed()
+ * @method static Builder|TransactionType withoutTrashed()
+ *
* @mixin Eloquent
*/
class TransactionType extends Model
{
+ use ReturnsIntegerIdTrait;
use SoftDeletes;
- public const DEPOSIT = 'Deposit';
- public const INVALID = 'Invalid';
- public const LIABILITY_CREDIT = 'Liability credit';
- public const OPENING_BALANCE = 'Opening balance';
- public const RECONCILIATION = 'Reconciliation';
- public const TRANSFER = 'Transfer';
- public const WITHDRAWAL = 'Withdrawal';
+ public const string DEPOSIT = 'Deposit';
+ public const string INVALID = 'Invalid';
+ public const string LIABILITY_CREDIT = 'Liability credit';
+ public const string OPENING_BALANCE = 'Opening balance';
+ public const string RECONCILIATION = 'Reconciliation';
+ public const string TRANSFER = 'Transfer';
+ public const string WITHDRAWAL = 'Withdrawal';
protected $casts
- = [
- 'created_at' => 'datetime',
- 'updated_at' => 'datetime',
- 'deleted_at' => 'datetime',
- ];
- protected $fillable = ['type'];
+ = [
+ 'created_at' => 'datetime',
+ 'updated_at' => 'datetime',
+ 'deleted_at' => 'datetime',
+ ];
+ protected $fillable = ['type'];
/**
* Route binder. Converts the key in the URL to the specified object (or throw 404).
*
- * @param string $type
- *
- * @return TransactionType
* @throws NotFoundHttpException
*/
- public static function routeBinder(string $type): TransactionType
+ public static function routeBinder(string $type): self
{
if (!auth()->check()) {
throw new NotFoundHttpException();
@@ -92,44 +93,30 @@ class TransactionType extends Model
if (null !== $transactionType) {
return $transactionType;
}
+
throw new NotFoundHttpException();
}
- /**
- * @return bool
- */
public function isDeposit(): bool
{
return self::DEPOSIT === $this->type;
}
- /**
- * @return bool
- */
public function isOpeningBalance(): bool
{
return self::OPENING_BALANCE === $this->type;
}
- /**
- * @return bool
- */
public function isTransfer(): bool
{
return self::TRANSFER === $this->type;
}
- /**
- * @return bool
- */
public function isWithdrawal(): bool
{
return self::WITHDRAWAL === $this->type;
}
- /**
- * @return HasMany
- */
public function transactionJournals(): HasMany
{
return $this->hasMany(TransactionJournal::class);
diff --git a/app/Models/UserGroup.php b/app/Models/UserGroup.php
index 5be2e89e81..34cf18f84e 100644
--- a/app/Models/UserGroup.php
+++ b/app/Models/UserGroup.php
@@ -24,27 +24,30 @@ declare(strict_types=1);
namespace FireflyIII\Models;
+use Carbon\Carbon;
use Eloquent;
use FireflyIII\Enums\UserRoleEnum;
+use FireflyIII\Support\Models\ReturnsIntegerIdTrait;
use FireflyIII\User;
use Illuminate\Database\Eloquent\Builder;
use Illuminate\Database\Eloquent\Collection;
use Illuminate\Database\Eloquent\Model;
+use Illuminate\Database\Eloquent\Relations\BelongsToMany;
use Illuminate\Database\Eloquent\Relations\HasMany;
use Illuminate\Database\Eloquent\Relations\HasManyThrough;
-use Illuminate\Support\Carbon;
use Symfony\Component\HttpKernel\Exception\NotFoundHttpException;
/**
* Class UserGroup
*
- * @property int $id
- * @property Carbon|null $created_at
- * @property Carbon|null $updated_at
- * @property string|null $deleted_at
- * @property string $title
- * @property-read Collection|GroupMembership[] $groupMemberships
- * @property-read int|null $group_memberships_count
+ * @property int $id
+ * @property null|Carbon $created_at
+ * @property null|Carbon $updated_at
+ * @property null|string $deleted_at
+ * @property string $title
+ * @property Collection|GroupMembership[] $groupMemberships
+ * @property null|int $group_memberships_count
+ *
* @method static Builder|UserGroup newModelQuery()
* @method static Builder|UserGroup newQuery()
* @method static Builder|UserGroup query()
@@ -53,76 +56,81 @@ use Symfony\Component\HttpKernel\Exception\NotFoundHttpException;
* @method static Builder|UserGroup whereId($value)
* @method static Builder|UserGroup whereTitle($value)
* @method static Builder|UserGroup whereUpdatedAt($value)
- * @property-read Collection $accounts
- * @property-read int|null $accounts_count
- * @property-read Collection $availableBudgets
- * @property-read int|null $available_budgets_count
- * @property-read Collection $bills
- * @property-read int|null $bills_count
- * @property-read Collection $budgets
- * @property-read int|null $budgets_count
- * @property-read Collection $piggyBanks
- * @property-read int|null $piggy_banks_count
- * @property-read Collection $transactionJournals
- * @property-read int|null $transaction_journals_count
- * @property-read Collection $attachments
- * @property-read int|null $attachments_count
- * @property-read Collection $categories
- * @property-read int|null $categories_count
- * @property-read Collection $currencyExchangeRates
- * @property-read int|null $currency_exchange_rates_count
- * @property-read Collection $objectGroups
- * @property-read int|null $object_groups_count
- * @property-read Collection $recurrences
- * @property-read int|null $recurrences_count
- * @property-read Collection $ruleGroups
- * @property-read int|null $rule_groups_count
- * @property-read Collection $rules
- * @property-read int|null $rules_count
- * @property-read Collection $tags
- * @property-read int|null $tags_count
- * @property-read Collection $transactionGroups
- * @property-read int|null $transaction_groups_count
- * @property-read Collection $webhooks
- * @property-read int|null $webhooks_count
+ *
+ * @property Collection $accounts
+ * @property null|int $accounts_count
+ * @property Collection $availableBudgets
+ * @property null|int $available_budgets_count
+ * @property Collection $bills
+ * @property null|int $bills_count
+ * @property Collection $budgets
+ * @property null|int $budgets_count
+ * @property Collection $piggyBanks
+ * @property null|int $piggy_banks_count
+ * @property Collection $transactionJournals
+ * @property null|int $transaction_journals_count
+ * @property Collection $attachments
+ * @property null|int $attachments_count
+ * @property Collection $categories
+ * @property null|int $categories_count
+ * @property Collection $currencyExchangeRates
+ * @property null|int $currency_exchange_rates_count
+ * @property Collection $objectGroups
+ * @property null|int $object_groups_count
+ * @property Collection $recurrences
+ * @property null|int $recurrences_count
+ * @property Collection $ruleGroups
+ * @property null|int $rule_groups_count
+ * @property Collection $rules
+ * @property null|int $rules_count
+ * @property Collection $tags
+ * @property null|int $tags_count
+ * @property Collection $transactionGroups
+ * @property null|int $transaction_groups_count
+ * @property Collection $webhooks
+ * @property null|int $webhooks_count
+ * @property Collection $currencies
+ * @property null|int $currencies_count
+ *
* @mixin Eloquent
*/
class UserGroup extends Model
{
+ use ReturnsIntegerIdTrait;
+
protected $fillable = ['title'];
/**
* Route binder. Converts the key in the URL to the specified object (or throw 404).
*
- * @param string $value
- *
- * @return UserGroup
* @throws NotFoundHttpException
*/
- public static function routeBinder(string $value): UserGroup
+ public static function routeBinder(string $value): self
{
if (auth()->check()) {
$userGroupId = (int)$value;
+
/** @var User $user */
- $user = auth()->user();
- /** @var UserGroup $userGroup */
- $userGroup = UserGroup::find($userGroupId);
+ $user = auth()->user();
+
+ /** @var null|UserGroup $userGroup */
+ $userGroup = self::find($userGroupId);
if (null === $userGroup) {
throw new NotFoundHttpException();
}
// need at least ready only to be aware of the user group's existence,
// but owner/full role (in the group) or global owner role may overrule this.
- if ($user->hasRoleInGroup($userGroup, UserRoleEnum::READ_ONLY, true, true)) {
+ $access = $user->hasRoleInGroupOrOwner($userGroup, UserRoleEnum::READ_ONLY) || $user->hasRole('owner');
+ if ($access) {
return $userGroup;
}
}
+
throw new NotFoundHttpException();
}
/**
* Link to accounts.
- *
- * @return HasMany
*/
public function accounts(): HasMany
{
@@ -131,8 +139,6 @@ class UserGroup extends Model
/**
* Link to attachments.
- *
- * @return HasMany
*/
public function attachments(): HasMany
{
@@ -141,8 +147,6 @@ class UserGroup extends Model
/**
* Link to bills.
- *
- * @return HasMany
*/
public function availableBudgets(): HasMany
{
@@ -151,8 +155,6 @@ class UserGroup extends Model
/**
* Link to bills.
- *
- * @return HasMany
*/
public function bills(): HasMany
{
@@ -161,8 +163,6 @@ class UserGroup extends Model
/**
* Link to budgets.
- *
- * @return HasMany
*/
public function budgets(): HasMany
{
@@ -171,36 +171,33 @@ class UserGroup extends Model
/**
* Link to categories.
- *
- * @return HasMany
*/
public function categories(): HasMany
{
return $this->hasMany(Category::class);
}
+ /**
+ * Link to currencies
+ */
+ public function currencies(): BelongsToMany
+ {
+ return $this->belongsToMany(TransactionCurrency::class)->withTimestamps()->withPivot('group_default');
+ }
+
/**
* Link to exchange rates.
- *
- * @return HasMany
*/
public function currencyExchangeRates(): HasMany
{
return $this->hasMany(CurrencyExchangeRate::class);
}
- /**
- *
- * @return HasMany
- */
public function groupMemberships(): HasMany
{
return $this->hasMany(GroupMembership::class);
}
- /**
- * @return HasMany
- */
public function objectGroups(): HasMany
{
return $this->hasMany(ObjectGroup::class);
@@ -208,49 +205,32 @@ class UserGroup extends Model
/**
* Link to piggy banks.
- *
- * @return HasManyThrough
*/
public function piggyBanks(): HasManyThrough
{
return $this->hasManyThrough(PiggyBank::class, Account::class);
}
- /**
- * @return HasMany
- */
public function recurrences(): HasMany
{
return $this->hasMany(Recurrence::class);
}
- /**
- * @return HasMany
- */
public function ruleGroups(): HasMany
{
return $this->hasMany(RuleGroup::class);
}
- /**
- * @return HasMany
- */
public function rules(): HasMany
{
return $this->hasMany(Rule::class);
}
- /**
- * @return HasMany
- */
public function tags(): HasMany
{
return $this->hasMany(Tag::class);
}
- /**
- * @return HasMany
- */
public function transactionGroups(): HasMany
{
return $this->hasMany(TransactionGroup::class);
@@ -258,17 +238,12 @@ class UserGroup extends Model
/**
* Link to transaction journals.
- *
- * @return HasMany
*/
public function transactionJournals(): HasMany
{
return $this->hasMany(TransactionJournal::class);
}
- /**
- * @return HasMany
- */
public function webhooks(): HasMany
{
return $this->hasMany(Webhook::class);
diff --git a/app/Models/UserRole.php b/app/Models/UserRole.php
index 5dbfa9b27c..3b18b0262d 100644
--- a/app/Models/UserRole.php
+++ b/app/Models/UserRole.php
@@ -24,23 +24,25 @@ declare(strict_types=1);
namespace FireflyIII\Models;
+use Carbon\Carbon;
use Eloquent;
+use FireflyIII\Support\Models\ReturnsIntegerIdTrait;
use Illuminate\Database\Eloquent\Builder;
use Illuminate\Database\Eloquent\Collection;
use Illuminate\Database\Eloquent\Model;
use Illuminate\Database\Eloquent\Relations\HasMany;
-use Illuminate\Support\Carbon;
/**
* Class UserRole
*
- * @property int $id
- * @property Carbon|null $created_at
- * @property Carbon|null $updated_at
- * @property string|null $deleted_at
- * @property string $title
- * @property-read Collection|GroupMembership[] $groupMemberships
- * @property-read int|null $group_memberships_count
+ * @property int $id
+ * @property null|Carbon $created_at
+ * @property null|Carbon $updated_at
+ * @property null|string $deleted_at
+ * @property string $title
+ * @property Collection|GroupMembership[] $groupMemberships
+ * @property null|int $group_memberships_count
+ *
* @method static Builder|UserRole newModelQuery()
* @method static Builder|UserRole newQuery()
* @method static Builder|UserRole query()
@@ -49,16 +51,15 @@ use Illuminate\Support\Carbon;
* @method static Builder|UserRole whereId($value)
* @method static Builder|UserRole whereTitle($value)
* @method static Builder|UserRole whereUpdatedAt($value)
+ *
* @mixin Eloquent
*/
class UserRole extends Model
{
+ use ReturnsIntegerIdTrait;
+
protected $fillable = ['title'];
- /**
- *
- * @return HasMany
- */
public function groupMemberships(): HasMany
{
return $this->hasMany(GroupMembership::class);
diff --git a/app/Models/Webhook.php b/app/Models/Webhook.php
index 4d8a64bf7f..e33059a0d4 100644
--- a/app/Models/Webhook.php
+++ b/app/Models/Webhook.php
@@ -23,10 +23,13 @@ declare(strict_types=1);
namespace FireflyIII\Models;
+use Carbon\Carbon;
use Eloquent;
use FireflyIII\Enums\WebhookDelivery;
use FireflyIII\Enums\WebhookResponse;
use FireflyIII\Enums\WebhookTrigger;
+use FireflyIII\Support\Models\ReturnsIntegerIdTrait;
+use FireflyIII\Support\Models\ReturnsIntegerUserIdTrait;
use FireflyIII\User;
use Illuminate\Database\Eloquent\Builder;
use Illuminate\Database\Eloquent\Collection;
@@ -34,65 +37,69 @@ use Illuminate\Database\Eloquent\Model;
use Illuminate\Database\Eloquent\Relations\BelongsTo;
use Illuminate\Database\Eloquent\Relations\HasMany;
use Illuminate\Database\Eloquent\SoftDeletes;
-use Illuminate\Support\Carbon;
use Symfony\Component\HttpKernel\Exception\NotFoundHttpException;
/**
* FireflyIII\Models\Webhook
*
- * @property int $id
- * @property Carbon|null $created_at
- * @property Carbon|null $updated_at
- * @property Carbon|null $deleted_at
- * @property int $user_id
- * @property bool $active
- * @property int $trigger
- * @property int $response
- * @property int $delivery
- * @property string $url
- * @property-read User $user
- * @property-read Collection|WebhookMessage[] $webhookMessages
- * @property-read int|null $webhook_messages_count
- * @method static Builder|Webhook newModelQuery()
- * @method static Builder|Webhook newQuery()
+ * @property int $id
+ * @property null|Carbon $created_at
+ * @property null|Carbon $updated_at
+ * @property null|Carbon $deleted_at
+ * @property int $user_id
+ * @property bool $active
+ * @property int $trigger
+ * @property int $response
+ * @property int $delivery
+ * @property string $url
+ * @property User $user
+ * @property Collection|WebhookMessage[] $webhookMessages
+ * @property null|int $webhook_messages_count
+ *
+ * @method static Builder|Webhook newModelQuery()
+ * @method static Builder|Webhook newQuery()
* @method static \Illuminate\Database\Query\Builder|Webhook onlyTrashed()
- * @method static Builder|Webhook query()
- * @method static Builder|Webhook whereActive($value)
- * @method static Builder|Webhook whereCreatedAt($value)
- * @method static Builder|Webhook whereDeletedAt($value)
- * @method static Builder|Webhook whereDelivery($value)
- * @method static Builder|Webhook whereId($value)
- * @method static Builder|Webhook whereResponse($value)
- * @method static Builder|Webhook whereTrigger($value)
- * @method static Builder|Webhook whereUpdatedAt($value)
- * @method static Builder|Webhook whereUrl($value)
- * @method static Builder|Webhook whereUserId($value)
+ * @method static Builder|Webhook query()
+ * @method static Builder|Webhook whereActive($value)
+ * @method static Builder|Webhook whereCreatedAt($value)
+ * @method static Builder|Webhook whereDeletedAt($value)
+ * @method static Builder|Webhook whereDelivery($value)
+ * @method static Builder|Webhook whereId($value)
+ * @method static Builder|Webhook whereResponse($value)
+ * @method static Builder|Webhook whereTrigger($value)
+ * @method static Builder|Webhook whereUpdatedAt($value)
+ * @method static Builder|Webhook whereUrl($value)
+ * @method static Builder|Webhook whereUserId($value)
* @method static \Illuminate\Database\Query\Builder|Webhook withTrashed()
* @method static \Illuminate\Database\Query\Builder|Webhook withoutTrashed()
- * @property string $title
- * @property string $secret
+ *
+ * @property string $title
+ * @property string $secret
+ *
* @method static Builder|Webhook whereSecret($value)
* @method static Builder|Webhook whereTitle($value)
- * @property int|null $user_group_id
+ *
+ * @property int $user_group_id
+ *
* @method static Builder|Webhook whereUserGroupId($value)
+ *
* @mixin Eloquent
*/
class Webhook extends Model
{
+ use ReturnsIntegerIdTrait;
+ use ReturnsIntegerUserIdTrait;
use SoftDeletes;
protected $casts
= [
- 'active' => 'boolean',
- 'trigger' => 'integer',
- 'response' => 'integer',
- 'delivery' => 'integer',
- ];
+ 'active' => 'boolean',
+ 'trigger' => 'integer',
+ 'response' => 'integer',
+ 'delivery' => 'integer',
+ ];
protected $fillable = ['active', 'trigger', 'response', 'delivery', 'user_id', 'user_group_id', 'url', 'title', 'secret'];
- /**
- * @return array
- */
public static function getDeliveries(): array
{
$array = [];
@@ -100,12 +107,10 @@ class Webhook extends Model
foreach ($set as $item) {
$array[$item->value] = $item->name;
}
+
return $array;
}
- /**
- * @return array
- */
public static function getDeliveriesForValidation(): array
{
$array = [];
@@ -114,12 +119,10 @@ class Webhook extends Model
$array[$item->name] = $item->value;
$array[$item->value] = $item->value;
}
+
return $array;
}
- /**
- * @return array
- */
public static function getResponses(): array
{
$array = [];
@@ -127,12 +130,10 @@ class Webhook extends Model
foreach ($set as $item) {
$array[$item->value] = $item->name;
}
+
return $array;
}
- /**
- * @return array
- */
public static function getResponsesForValidation(): array
{
$array = [];
@@ -141,12 +142,10 @@ class Webhook extends Model
$array[$item->name] = $item->value;
$array[$item->value] = $item->value;
}
+
return $array;
}
- /**
- * @return array
- */
public static function getTriggers(): array
{
$array = [];
@@ -154,12 +153,10 @@ class Webhook extends Model
foreach ($set as $item) {
$array[$item->value] = $item->name;
}
+
return $array;
}
- /**
- * @return array
- */
public static function getTriggersForValidation(): array
{
$array = [];
@@ -168,43 +165,38 @@ class Webhook extends Model
$array[$item->name] = $item->value;
$array[$item->value] = $item->value;
}
+
return $array;
}
/**
* Route binder. Converts the key in the URL to the specified object (or throw 404).
*
- * @param string $value
- *
- * @return Webhook
* @throws NotFoundHttpException
*/
- public static function routeBinder(string $value): Webhook
+ public static function routeBinder(string $value): self
{
if (auth()->check()) {
$webhookId = (int)$value;
+
/** @var User $user */
- $user = auth()->user();
- /** @var Webhook $webhook */
- $webhook = $user->webhooks()->find($webhookId);
+ $user = auth()->user();
+
+ /** @var null|Webhook $webhook */
+ $webhook = $user->webhooks()->find($webhookId);
if (null !== $webhook) {
return $webhook;
}
}
+
throw new NotFoundHttpException();
}
- /**
- * @return BelongsTo
- */
public function user(): BelongsTo
{
return $this->belongsTo(User::class);
}
- /**
- * @return HasMany
- */
public function webhookMessages(): HasMany
{
return $this->hasMany(WebhookMessage::class);
diff --git a/app/Models/WebhookAttempt.php b/app/Models/WebhookAttempt.php
index 2dd236663e..76d1a110b4 100644
--- a/app/Models/WebhookAttempt.php
+++ b/app/Models/WebhookAttempt.php
@@ -23,27 +23,30 @@ declare(strict_types=1);
namespace FireflyIII\Models;
+use Carbon\Carbon;
use Eloquent;
+use FireflyIII\Support\Models\ReturnsIntegerIdTrait;
use FireflyIII\User;
+use Illuminate\Database\Eloquent\Casts\Attribute;
use Illuminate\Database\Eloquent\Model;
use Illuminate\Database\Eloquent\Relations\BelongsTo;
use Illuminate\Database\Eloquent\SoftDeletes;
use Illuminate\Database\Query\Builder;
-use Illuminate\Support\Carbon;
use Symfony\Component\HttpKernel\Exception\NotFoundHttpException;
/**
* Class WebhookAttempt
*
- * @property int $id
- * @property Carbon|null $created_at
- * @property Carbon|null $updated_at
- * @property string|null $deleted_at
- * @property int $webhook_message_id
- * @property int $status_code
- * @property string|null $logs
- * @property string|null $response
- * @property-read WebhookMessage $webhookMessage
+ * @property int $id
+ * @property null|Carbon $created_at
+ * @property null|Carbon $updated_at
+ * @property null|string $deleted_at
+ * @property int $webhook_message_id
+ * @property int|string $status_code
+ * @property null|string $logs
+ * @property null|string $response
+ * @property WebhookMessage $webhookMessage
+ *
* @method static \Illuminate\Database\Eloquent\Builder|WebhookAttempt newModelQuery()
* @method static \Illuminate\Database\Eloquent\Builder|WebhookAttempt newQuery()
* @method static \Illuminate\Database\Eloquent\Builder|WebhookAttempt query()
@@ -55,43 +58,49 @@ use Symfony\Component\HttpKernel\Exception\NotFoundHttpException;
* @method static \Illuminate\Database\Eloquent\Builder|WebhookAttempt whereStatusCode($value)
* @method static \Illuminate\Database\Eloquent\Builder|WebhookAttempt whereUpdatedAt($value)
* @method static \Illuminate\Database\Eloquent\Builder|WebhookAttempt whereWebhookMessageId($value)
- * @method static Builder|WebhookAttempt onlyTrashed()
- * @method static Builder|WebhookAttempt withTrashed()
- * @method static Builder|WebhookAttempt withoutTrashed()
+ * @method static Builder|WebhookAttempt onlyTrashed()
+ * @method static Builder|WebhookAttempt withTrashed()
+ * @method static Builder|WebhookAttempt withoutTrashed()
+ *
* @mixin Eloquent
*/
class WebhookAttempt extends Model
{
+ use ReturnsIntegerIdTrait;
use SoftDeletes;
/**
* Route binder. Converts the key in the URL to the specified object (or throw 404).
*
- * @param string $value
- *
- * @return WebhookAttempt
* @throws NotFoundHttpException
*/
- public static function routeBinder(string $value): WebhookAttempt
+ public static function routeBinder(string $value): self
{
if (auth()->check()) {
$attemptId = (int)$value;
+
/** @var User $user */
- $user = auth()->user();
- /** @var WebhookAttempt $attempt */
- $attempt = self::find($attemptId);
+ $user = auth()->user();
+
+ /** @var null|WebhookAttempt $attempt */
+ $attempt = self::find($attemptId);
if (null !== $attempt && $attempt->webhookMessage->webhook->user_id === $user->id) {
return $attempt;
}
}
+
throw new NotFoundHttpException();
}
- /**
- * @return BelongsTo
- */
public function webhookMessage(): BelongsTo
{
return $this->belongsTo(WebhookMessage::class);
}
+
+ protected function webhookMessageId(): Attribute
+ {
+ return Attribute::make(
+ get: static fn ($value) => (int)$value,
+ );
+ }
}
diff --git a/app/Models/WebhookMessage.php b/app/Models/WebhookMessage.php
index f04bafae99..8b27dde551 100644
--- a/app/Models/WebhookMessage.php
+++ b/app/Models/WebhookMessage.php
@@ -23,7 +23,9 @@ declare(strict_types=1);
namespace FireflyIII\Models;
+use Carbon\Carbon;
use Eloquent;
+use FireflyIII\Support\Models\ReturnsIntegerIdTrait;
use FireflyIII\User;
use Illuminate\Database\Eloquent\Builder;
use Illuminate\Database\Eloquent\Casts\Attribute;
@@ -31,24 +33,24 @@ use Illuminate\Database\Eloquent\Collection;
use Illuminate\Database\Eloquent\Model;
use Illuminate\Database\Eloquent\Relations\BelongsTo;
use Illuminate\Database\Eloquent\Relations\HasMany;
-use Illuminate\Support\Carbon;
use Symfony\Component\HttpKernel\Exception\NotFoundHttpException;
/**
* FireflyIII\Models\WebhookMessage
*
- * @property int $id
- * @property Carbon|null $created_at
- * @property Carbon|null $updated_at
- * @property string|null $deleted_at
- * @property int $webhook_id
- * @property bool $sent
- * @property bool $errored
- * @property int $attempts
- * @property string $uuid
- * @property array $message
- * @property array|null $logs
- * @property-read Webhook $webhook
+ * @property int $id
+ * @property null|Carbon $created_at
+ * @property null|Carbon $updated_at
+ * @property null|string $deleted_at
+ * @property int $webhook_id
+ * @property bool $sent
+ * @property bool $errored
+ * @property int $attempts
+ * @property string $uuid
+ * @property array $message
+ * @property null|array $logs
+ * @property Webhook $webhook
+ *
* @method static Builder|WebhookMessage newModelQuery()
* @method static Builder|WebhookMessage newQuery()
* @method static Builder|WebhookMessage query()
@@ -63,12 +65,16 @@ use Symfony\Component\HttpKernel\Exception\NotFoundHttpException;
* @method static Builder|WebhookMessage whereUpdatedAt($value)
* @method static Builder|WebhookMessage whereUuid($value)
* @method static Builder|WebhookMessage whereWebhookId($value)
- * @property-read Collection|WebhookAttempt[] $webhookAttempts
- * @property-read int|null $webhook_attempts_count
+ *
+ * @property Collection|WebhookAttempt[] $webhookAttempts
+ * @property null|int $webhook_attempts_count
+ *
* @mixin Eloquent
*/
class WebhookMessage extends Model
{
+ use ReturnsIntegerIdTrait;
+
protected $casts
= [
'sent' => 'boolean',
@@ -81,37 +87,31 @@ class WebhookMessage extends Model
/**
* Route binder. Converts the key in the URL to the specified object (or throw 404).
*
- * @param string $value
- *
- * @return WebhookMessage
* @throws NotFoundHttpException
*/
- public static function routeBinder(string $value): WebhookMessage
+ public static function routeBinder(string $value): self
{
if (auth()->check()) {
$messageId = (int)$value;
+
/** @var User $user */
- $user = auth()->user();
- /** @var WebhookMessage $message */
- $message = self::find($messageId);
+ $user = auth()->user();
+
+ /** @var null|WebhookMessage $message */
+ $message = self::find($messageId);
if (null !== $message && $message->webhook->user_id === $user->id) {
return $message;
}
}
+
throw new NotFoundHttpException();
}
- /**
- * @return BelongsTo
- */
public function webhook(): BelongsTo
{
return $this->belongsTo(Webhook::class);
}
- /**
- * @return HasMany
- */
public function webhookAttempts(): HasMany
{
return $this->hasMany(WebhookAttempt::class);
@@ -119,13 +119,18 @@ class WebhookMessage extends Model
/**
* Get the amount
- *
- * @return Attribute
*/
protected function sent(): Attribute
{
return Attribute::make(
- get: fn ($value) => (bool)$value,
+ get: static fn ($value) => (bool)$value,
+ );
+ }
+
+ protected function webhookId(): Attribute
+ {
+ return Attribute::make(
+ get: static fn ($value) => (int)$value,
);
}
}
diff --git a/app/Notifications/Admin/TestNotification.php b/app/Notifications/Admin/TestNotification.php
index b79a21f36d..03b52e93d6 100644
--- a/app/Notifications/Admin/TestNotification.php
+++ b/app/Notifications/Admin/TestNotification.php
@@ -25,7 +25,6 @@ declare(strict_types=1);
namespace FireflyIII\Notifications\Admin;
use FireflyIII\Support\Notifications\UrlValidator;
-use FireflyIII\User;
use Illuminate\Bus\Queueable;
use Illuminate\Notifications\Messages\MailMessage;
use Illuminate\Notifications\Messages\SlackMessage;
@@ -42,8 +41,6 @@ class TestNotification extends Notification
/**
* Create a new notification instance.
- *
- * @return void
*/
public function __construct(string $address)
{
@@ -55,12 +52,13 @@ class TestNotification extends Notification
*
* @param mixed $notifiable
*
+ * @SuppressWarnings(PHPMD.UnusedFormalParameter)
+ *
* @return array
*/
public function toArray($notifiable)
{
return [
- //
];
}
@@ -69,13 +67,16 @@ class TestNotification extends Notification
*
* @param mixed $notifiable
*
+ * @SuppressWarnings(PHPMD.UnusedFormalParameter)
+ *
* @return MailMessage
*/
public function toMail($notifiable)
{
return (new MailMessage())
->markdown('emails.admin-test', ['email' => $this->address])
- ->subject((string)trans('email.admin_test_subject'));
+ ->subject((string)trans('email.admin_test_subject'))
+ ;
}
/**
@@ -83,6 +84,8 @@ class TestNotification extends Notification
*
* @param mixed $notifiable
*
+ * @SuppressWarnings(PHPMD.UnusedFormalParameter)
+ *
* @return SlackMessage
*/
public function toSlack($notifiable)
@@ -93,6 +96,8 @@ class TestNotification extends Notification
/**
* Get the notification's delivery channels.
*
+ * @SuppressWarnings(PHPMD.UnusedFormalParameter)
+ *
* @param mixed $notifiable
*
* @return array
@@ -103,6 +108,7 @@ class TestNotification extends Notification
if (UrlValidator::isValidWebhookURL($slackUrl)) {
return ['mail', 'slack'];
}
+
return ['mail'];
}
}
diff --git a/app/Notifications/Admin/UserInvitation.php b/app/Notifications/Admin/UserInvitation.php
index 60d05bab97..15d97d1aa2 100644
--- a/app/Notifications/Admin/UserInvitation.php
+++ b/app/Notifications/Admin/UserInvitation.php
@@ -26,7 +26,6 @@ namespace FireflyIII\Notifications\Admin;
use FireflyIII\Models\InvitedUser;
use FireflyIII\Support\Notifications\UrlValidator;
-use FireflyIII\User;
use Illuminate\Bus\Queueable;
use Illuminate\Notifications\Messages\MailMessage;
use Illuminate\Notifications\Messages\SlackMessage;
@@ -43,8 +42,6 @@ class UserInvitation extends Notification
/**
* Create a new notification instance.
- *
- * @return void
*/
public function __construct(InvitedUser $invitee)
{
@@ -57,11 +54,12 @@ class UserInvitation extends Notification
* @param mixed $notifiable
*
* @return array
+ *
+ * @SuppressWarnings(PHPMD.UnusedFormalParameter)
*/
public function toArray($notifiable)
{
return [
- //
];
}
@@ -71,12 +69,15 @@ class UserInvitation extends Notification
* @param mixed $notifiable
*
* @return MailMessage
+ *
+ * @SuppressWarnings(PHPMD.UnusedFormalParameter)
*/
public function toMail($notifiable)
{
return (new MailMessage())
->markdown('emails.invitation-created', ['email' => $this->invitee->user->email, 'invitee' => $this->invitee->email])
- ->subject((string)trans('email.invitation_created_subject'));
+ ->subject((string)trans('email.invitation_created_subject'))
+ ;
}
/**
@@ -85,6 +86,8 @@ class UserInvitation extends Notification
* @param mixed $notifiable
*
* @return SlackMessage
+ *
+ * @SuppressWarnings(PHPMD.UnusedFormalParameter)
*/
public function toSlack($notifiable)
{
@@ -99,6 +102,8 @@ class UserInvitation extends Notification
* @param mixed $notifiable
*
* @return array
+ *
+ * @SuppressWarnings(PHPMD.UnusedFormalParameter)
*/
public function via($notifiable)
{
@@ -106,6 +111,7 @@ class UserInvitation extends Notification
if (UrlValidator::isValidWebhookURL($slackUrl)) {
return ['mail', 'slack'];
}
+
return ['mail'];
}
}
diff --git a/app/Notifications/Admin/UserRegistration.php b/app/Notifications/Admin/UserRegistration.php
index 4b0bce8971..759e200d82 100644
--- a/app/Notifications/Admin/UserRegistration.php
+++ b/app/Notifications/Admin/UserRegistration.php
@@ -42,8 +42,6 @@ class UserRegistration extends Notification
/**
* Create a new notification instance.
- *
- * @return void
*/
public function __construct(User $user)
{
@@ -56,11 +54,12 @@ class UserRegistration extends Notification
* @param mixed $notifiable
*
* @return array
+ *
+ * @SuppressWarnings(PHPMD.UnusedFormalParameter)
*/
public function toArray($notifiable)
{
return [
- //
];
}
@@ -70,12 +69,15 @@ class UserRegistration extends Notification
* @param mixed $notifiable
*
* @return MailMessage
+ *
+ * @SuppressWarnings(PHPMD.UnusedFormalParameter)
*/
public function toMail($notifiable)
{
return (new MailMessage())
->markdown('emails.registered-admin', ['email' => $this->user->email, 'id' => $this->user->id])
- ->subject((string)trans('email.registered_subject_admin'));
+ ->subject((string)trans('email.registered_subject_admin'))
+ ;
}
/**
@@ -84,6 +86,8 @@ class UserRegistration extends Notification
* @param mixed $notifiable
*
* @return SlackMessage
+ *
+ * @SuppressWarnings(PHPMD.UnusedFormalParameter)
*/
public function toSlack($notifiable)
{
@@ -96,6 +100,8 @@ class UserRegistration extends Notification
* @param mixed $notifiable
*
* @return array
+ *
+ * @SuppressWarnings(PHPMD.UnusedFormalParameter)
*/
public function via($notifiable)
{
@@ -103,6 +109,7 @@ class UserRegistration extends Notification
if (UrlValidator::isValidWebhookURL($slackUrl)) {
return ['mail', 'slack'];
}
+
return ['mail'];
}
}
diff --git a/app/Notifications/Admin/VersionCheckResult.php b/app/Notifications/Admin/VersionCheckResult.php
index 95af203bfd..7ee75e8933 100644
--- a/app/Notifications/Admin/VersionCheckResult.php
+++ b/app/Notifications/Admin/VersionCheckResult.php
@@ -25,7 +25,6 @@ declare(strict_types=1);
namespace FireflyIII\Notifications\Admin;
use FireflyIII\Support\Notifications\UrlValidator;
-use FireflyIII\User;
use Illuminate\Bus\Queueable;
use Illuminate\Notifications\Messages\MailMessage;
use Illuminate\Notifications\Messages\SlackMessage;
@@ -33,7 +32,6 @@ use Illuminate\Notifications\Notification;
/**
* Class VersionCheckResult
- *
*/
class VersionCheckResult extends Notification
{
@@ -43,8 +41,6 @@ class VersionCheckResult extends Notification
/**
* Create a new notification instance.
- *
- * @return void
*/
public function __construct(string $message)
{
@@ -57,11 +53,12 @@ class VersionCheckResult extends Notification
* @param mixed $notifiable
*
* @return array
+ *
+ * @SuppressWarnings(PHPMD.UnusedFormalParameter)
*/
public function toArray($notifiable)
{
return [
- //
];
}
@@ -71,12 +68,15 @@ class VersionCheckResult extends Notification
* @param mixed $notifiable
*
* @return MailMessage
+ *
+ * @SuppressWarnings(PHPMD.UnusedFormalParameter)
*/
public function toMail($notifiable)
{
return (new MailMessage())
->markdown('emails.new-version', ['message' => $this->message])
- ->subject((string)trans('email.new_version_email_subject'));
+ ->subject((string)trans('email.new_version_email_subject'))
+ ;
}
/**
@@ -85,13 +85,16 @@ class VersionCheckResult extends Notification
* @param mixed $notifiable
*
* @return SlackMessage
+ *
+ * @SuppressWarnings(PHPMD.UnusedFormalParameter)
*/
public function toSlack($notifiable)
{
return (new SlackMessage())->content($this->message)
- ->attachment(function ($attachment) {
- $attachment->title('Firefly III @ GitHub', 'https://github.com/firefly-iii/firefly-iii/releases');
- });
+ ->attachment(static function ($attachment): void {
+ $attachment->title('Firefly III @ GitHub', 'https://github.com/firefly-iii/firefly-iii/releases');
+ })
+ ;
}
/**
@@ -100,6 +103,8 @@ class VersionCheckResult extends Notification
* @param mixed $notifiable
*
* @return array
+ *
+ * @SuppressWarnings(PHPMD.UnusedFormalParameter)
*/
public function via($notifiable)
{
@@ -107,6 +112,7 @@ class VersionCheckResult extends Notification
if (UrlValidator::isValidWebhookURL($slackUrl)) {
return ['mail', 'slack'];
}
+
return ['mail'];
}
}
diff --git a/app/Notifications/User/BillReminder.php b/app/Notifications/User/BillReminder.php
index d3824aca52..36d93b84e6 100644
--- a/app/Notifications/User/BillReminder.php
+++ b/app/Notifications/User/BillReminder.php
@@ -45,8 +45,6 @@ class BillReminder extends Notification
/**
* Create a new notification instance.
- *
- * @return void
*/
public function __construct(Bill $bill, string $field, int $diff)
{
@@ -61,11 +59,12 @@ class BillReminder extends Notification
* @param mixed $notifiable
*
* @return array
+ *
+ * @SuppressWarnings(PHPMD.UnusedFormalParameter)
*/
public function toArray($notifiable)
{
return [
- //
];
}
@@ -75,6 +74,8 @@ class BillReminder extends Notification
* @param mixed $notifiable
*
* @return MailMessage
+ *
+ * @SuppressWarnings(PHPMD.UnusedFormalParameter)
*/
public function toMail($notifiable)
{
@@ -85,7 +86,8 @@ class BillReminder extends Notification
return (new MailMessage())
->markdown('emails.bill-warning', ['field' => $this->field, 'diff' => $this->diff, 'bill' => $this->bill])
- ->subject($subject);
+ ->subject($subject)
+ ;
}
/**
@@ -94,6 +96,8 @@ class BillReminder extends Notification
* @param mixed $notifiable
*
* @return SlackMessage
+ *
+ * @SuppressWarnings(PHPMD.UnusedFormalParameter)
*/
public function toSlack($notifiable)
{
@@ -101,14 +105,16 @@ class BillReminder extends Notification
if (0 === $this->diff) {
$message = (string)trans(sprintf('email.bill_warning_subject_now_%s', $this->field), ['diff' => $this->diff, 'name' => $this->bill->name]);
}
- $bill = $this->bill;
- $url = route('bills.show', [$bill->id]);
+ $bill = $this->bill;
+ $url = route('bills.show', [$bill->id]);
+
return (new SlackMessage())
->warning()
- ->attachment(function ($attachment) use ($bill, $url) {
+ ->attachment(static function ($attachment) use ($bill, $url): void {
$attachment->title((string)trans('firefly.visit_bill', ['name' => $bill->name]), $url);
})
- ->content($message);
+ ->content($message)
+ ;
}
/**
@@ -117,15 +123,21 @@ class BillReminder extends Notification
* @param mixed $notifiable
*
* @return array
+ *
+ * @SuppressWarnings(PHPMD.UnusedFormalParameter)
*/
public function via($notifiable)
{
- /** @var User|null $user */
+ /** @var null|User $user */
$user = auth()->user();
- $slackUrl = null === $user ? '' : (string)app('preferences')->getForUser(auth()->user(), 'slack_webhook_url', '')->data;
- if (UrlValidator::isValidWebhookURL($slackUrl)) {
+ $slackUrl = null === $user ? '' : app('preferences')->getForUser(auth()->user(), 'slack_webhook_url', '')->data;
+ if (is_array($slackUrl)) {
+ $slackUrl = '';
+ }
+ if (UrlValidator::isValidWebhookURL((string)$slackUrl)) {
return ['mail', 'slack'];
}
+
return ['mail'];
}
}
diff --git a/app/Notifications/User/NewAccessToken.php b/app/Notifications/User/NewAccessToken.php
index 907d27df9e..b32192d089 100644
--- a/app/Notifications/User/NewAccessToken.php
+++ b/app/Notifications/User/NewAccessToken.php
@@ -40,12 +40,8 @@ class NewAccessToken extends Notification
/**
* Create a new notification instance.
- *
- * @return void
*/
- public function __construct()
- {
- }
+ public function __construct() {}
/**
* Get the array representation of the notification.
@@ -53,11 +49,12 @@ class NewAccessToken extends Notification
* @param mixed $notifiable
*
* @return array
+ *
+ * @SuppressWarnings(PHPMD.UnusedFormalParameter)
*/
public function toArray($notifiable)
{
return [
- //
];
}
@@ -67,12 +64,15 @@ class NewAccessToken extends Notification
* @param mixed $notifiable
*
* @return MailMessage
+ *
+ * @SuppressWarnings(PHPMD.UnusedFormalParameter)
*/
public function toMail($notifiable)
{
return (new MailMessage())
->markdown('emails.token-created')
- ->subject((string)trans('email.access_token_created_subject'));
+ ->subject((string)trans('email.access_token_created_subject'))
+ ;
}
/**
@@ -81,6 +81,8 @@ class NewAccessToken extends Notification
* @param mixed $notifiable
*
* @return SlackMessage
+ *
+ * @SuppressWarnings(PHPMD.UnusedFormalParameter)
*/
public function toSlack($notifiable)
{
@@ -93,15 +95,21 @@ class NewAccessToken extends Notification
* @param mixed $notifiable
*
* @return array
+ *
+ * @SuppressWarnings(PHPMD.UnusedFormalParameter)
*/
public function via($notifiable)
{
- /** @var User|null $user */
+ /** @var null|User $user */
$user = auth()->user();
- $slackUrl = null === $user ? '' : (string)app('preferences')->getForUser(auth()->user(), 'slack_webhook_url', '')->data;
- if (UrlValidator::isValidWebhookURL($slackUrl)) {
+ $slackUrl = null === $user ? '' : app('preferences')->getForUser(auth()->user(), 'slack_webhook_url', '')->data;
+ if (is_array($slackUrl)) {
+ $slackUrl = '';
+ }
+ if (UrlValidator::isValidWebhookURL((string)$slackUrl)) {
return ['mail', 'slack'];
}
+
return ['mail'];
}
}
diff --git a/app/Notifications/User/RuleActionFailed.php b/app/Notifications/User/RuleActionFailed.php
index caeef8a5b4..669d8b8e7b 100644
--- a/app/Notifications/User/RuleActionFailed.php
+++ b/app/Notifications/User/RuleActionFailed.php
@@ -45,19 +45,15 @@ class RuleActionFailed extends Notification
/**
* Create a new notification instance.
- *
- * @return void
*/
public function __construct(array $params)
{
[$mainMessage, $groupTitle, $groupLink, $ruleTitle, $ruleLink] = $params;
- $this->message = $mainMessage;
- $this->groupTitle = $groupTitle;
- $this->groupLink = $groupLink;
- $this->ruleTitle = $ruleTitle;
- $this->ruleLink = $ruleLink;
-
-
+ $this->message = $mainMessage;
+ $this->groupTitle = $groupTitle;
+ $this->groupLink = $groupLink;
+ $this->ruleTitle = $ruleTitle;
+ $this->ruleLink = $ruleLink;
}
/**
@@ -66,11 +62,12 @@ class RuleActionFailed extends Notification
* @param mixed $notifiable
*
* @return array
+ *
+ * @SuppressWarnings(PHPMD.UnusedFormalParameter)
*/
public function toArray($notifiable)
{
return [
- //
];
}
@@ -80,6 +77,8 @@ class RuleActionFailed extends Notification
* @param mixed $notifiable
*
* @return SlackMessage
+ *
+ * @SuppressWarnings(PHPMD.UnusedFormalParameter)
*/
public function toSlack($notifiable)
{
@@ -88,9 +87,9 @@ class RuleActionFailed extends Notification
$ruleTitle = $this->ruleTitle;
$ruleLink = $this->ruleLink;
- return (new SlackMessage())->content($this->message)->attachment(function ($attachment) use ($groupTitle, $groupLink) {
+ return (new SlackMessage())->content($this->message)->attachment(static function ($attachment) use ($groupTitle, $groupLink): void {
$attachment->title((string)trans('rules.inspect_transaction', ['title' => $groupTitle]), $groupLink);
- })->attachment(function ($attachment) use ($ruleTitle, $ruleLink) {
+ })->attachment(static function ($attachment) use ($ruleTitle, $ruleLink): void {
$attachment->title((string)trans('rules.inspect_rule', ['title' => $ruleTitle]), $ruleLink);
});
}
@@ -101,17 +100,24 @@ class RuleActionFailed extends Notification
* @param mixed $notifiable
*
* @return array
+ *
+ * @SuppressWarnings(PHPMD.UnusedFormalParameter)
*/
public function via($notifiable)
{
- /** @var User|null $user */
+ /** @var null|User $user */
$user = auth()->user();
- $slackUrl = null === $user ? '' : (string)app('preferences')->getForUser(auth()->user(), 'slack_webhook_url', '')->data;
- if (UrlValidator::isValidWebhookURL($slackUrl)) {
- app('log')->debug('Will send ruleActionFailed through Slack!');
+ $slackUrl = null === $user ? '' : app('preferences')->getForUser(auth()->user(), 'slack_webhook_url', '')->data;
+ if (is_array($slackUrl)) {
+ $slackUrl = '';
+ }
+ if (UrlValidator::isValidWebhookURL((string)$slackUrl)) {
+ app('log')->debug('Will send ruleActionFailed through Slack or Discord!');
+
return ['slack'];
}
- app('log')->debug('Will NOT send ruleActionFailed through Slack');
+ app('log')->debug('Will NOT send ruleActionFailed through Slack or Discord');
+
return [];
}
}
diff --git a/app/Notifications/User/TransactionCreation.php b/app/Notifications/User/TransactionCreation.php
index ee41ce8e72..fcf9f95fc0 100644
--- a/app/Notifications/User/TransactionCreation.php
+++ b/app/Notifications/User/TransactionCreation.php
@@ -39,8 +39,6 @@ class TransactionCreation extends Notification
/**
* Create a new notification instance.
- *
- * @return void
*/
public function __construct(array $collection)
{
@@ -53,11 +51,12 @@ class TransactionCreation extends Notification
* @param mixed $notifiable
*
* @return array
+ *
+ * @SuppressWarnings(PHPMD.UnusedFormalParameter)
*/
public function toArray($notifiable)
{
return [
- //
];
}
@@ -67,12 +66,15 @@ class TransactionCreation extends Notification
* @param mixed $notifiable
*
* @return MailMessage
+ *
+ * @SuppressWarnings(PHPMD.UnusedFormalParameter)
*/
public function toMail($notifiable)
{
return (new MailMessage())
->markdown('emails.report-new-journals', ['transformed' => $this->collection])
- ->subject((string)trans_choice('email.new_journals_subject', count($this->collection)));
+ ->subject(trans_choice('email.new_journals_subject', count($this->collection)))
+ ;
}
/**
@@ -81,6 +83,8 @@ class TransactionCreation extends Notification
* @param mixed $notifiable
*
* @return array
+ *
+ * @SuppressWarnings(PHPMD.UnusedFormalParameter)
*/
public function via($notifiable)
{
diff --git a/app/Notifications/User/UserLogin.php b/app/Notifications/User/UserLogin.php
index 0e6ddd5cdb..e7fc4e8a53 100644
--- a/app/Notifications/User/UserLogin.php
+++ b/app/Notifications/User/UserLogin.php
@@ -29,9 +29,8 @@ use FireflyIII\Support\Notifications\UrlValidator;
use FireflyIII\User;
use Illuminate\Bus\Queueable;
use Illuminate\Notifications\Messages\MailMessage;
-use Illuminate\Notifications\Notification;
-use Illuminate\Support\Facades\Log;
use Illuminate\Notifications\Messages\SlackMessage;
+use Illuminate\Notifications\Notification;
/**
* Class UserLogin
@@ -44,8 +43,6 @@ class UserLogin extends Notification
/**
* Create a new notification instance.
- *
- * @return void
*/
public function __construct(string $ip)
{
@@ -58,11 +55,12 @@ class UserLogin extends Notification
* @param mixed $notifiable
*
* @return array
+ *
+ * @SuppressWarnings(PHPMD.UnusedFormalParameter)
*/
public function toArray($notifiable)
{
return [
- //
];
}
@@ -72,15 +70,18 @@ class UserLogin extends Notification
* @param mixed $notifiable
*
* @return MailMessage
+ *
+ * @SuppressWarnings(PHPMD.UnusedFormalParameter)
*/
public function toMail($notifiable)
{
$time = now(config('app.timezone'))->isoFormat((string)trans('config.date_time_js'));
$host = '';
+
try {
$hostName = app('steam')->getHostName($this->ip);
} catch (FireflyException $e) {
- Log::error($e->getMessage());
+ app('log')->error($e->getMessage());
$hostName = $this->ip;
}
if ($hostName !== $this->ip) {
@@ -89,7 +90,8 @@ class UserLogin extends Notification
return (new MailMessage())
->markdown('emails.new-ip', ['time' => $time, 'ipAddress' => $this->ip, 'host' => $host])
- ->subject((string)trans('email.login_from_new_ip'));
+ ->subject((string)trans('email.login_from_new_ip'))
+ ;
}
/**
@@ -98,14 +100,17 @@ class UserLogin extends Notification
* @param mixed $notifiable
*
* @return SlackMessage
+ *
+ * @SuppressWarnings(PHPMD.UnusedFormalParameter)
*/
public function toSlack($notifiable)
{
$host = '';
+
try {
$hostName = app('steam')->getHostName($this->ip);
} catch (FireflyException $e) {
- Log::error($e->getMessage());
+ app('log')->error($e->getMessage());
$hostName = $this->ip;
}
if ($hostName !== $this->ip) {
@@ -121,15 +126,21 @@ class UserLogin extends Notification
* @param mixed $notifiable
*
* @return array
+ *
+ * @SuppressWarnings(PHPMD.UnusedFormalParameter)
*/
public function via($notifiable)
{
- /** @var User|null $user */
+ /** @var null|User $user */
$user = auth()->user();
- $slackUrl = null === $user ? '' : (string)app('preferences')->getForUser(auth()->user(), 'slack_webhook_url', '')->data;
- if (UrlValidator::isValidWebhookURL($slackUrl)) {
+ $slackUrl = null === $user ? '' : app('preferences')->getForUser(auth()->user(), 'slack_webhook_url', '')->data;
+ if (is_array($slackUrl)) {
+ $slackUrl = '';
+ }
+ if (UrlValidator::isValidWebhookURL((string)$slackUrl)) {
return ['mail', 'slack'];
}
+
return ['mail'];
}
}
diff --git a/app/Notifications/User/UserNewPassword.php b/app/Notifications/User/UserNewPassword.php
index 4d69465717..e4090984d5 100644
--- a/app/Notifications/User/UserNewPassword.php
+++ b/app/Notifications/User/UserNewPassword.php
@@ -39,8 +39,6 @@ class UserNewPassword extends Notification
/**
* Create a new notification instance.
- *
- * @return void
*/
public function __construct(string $url)
{
@@ -53,11 +51,12 @@ class UserNewPassword extends Notification
* @param mixed $notifiable
*
* @return array
+ *
+ * @SuppressWarnings(PHPMD.UnusedFormalParameter)
*/
public function toArray($notifiable)
{
return [
- //
];
}
@@ -67,12 +66,15 @@ class UserNewPassword extends Notification
* @param mixed $notifiable
*
* @return MailMessage
+ *
+ * @SuppressWarnings(PHPMD.UnusedFormalParameter)
*/
public function toMail($notifiable)
{
return (new MailMessage())
->markdown('emails.password', ['url' => $this->url])
- ->subject((string)trans('email.reset_pw_subject'));
+ ->subject((string)trans('email.reset_pw_subject'))
+ ;
}
/**
@@ -81,6 +83,8 @@ class UserNewPassword extends Notification
* @param mixed $notifiable
*
* @return array
+ *
+ * @SuppressWarnings(PHPMD.UnusedFormalParameter)
*/
public function via($notifiable)
{
diff --git a/app/Notifications/User/UserRegistration.php b/app/Notifications/User/UserRegistration.php
index dab21b71ba..50aae568a3 100644
--- a/app/Notifications/User/UserRegistration.php
+++ b/app/Notifications/User/UserRegistration.php
@@ -37,12 +37,8 @@ class UserRegistration extends Notification
/**
* Create a new notification instance.
- *
- * @return void
*/
- public function __construct()
- {
- }
+ public function __construct() {}
/**
* Get the array representation of the notification.
@@ -50,11 +46,12 @@ class UserRegistration extends Notification
* @param mixed $notifiable
*
* @return array
+ *
+ * @SuppressWarnings(PHPMD.UnusedFormalParameter)
*/
public function toArray($notifiable)
{
return [
- //
];
}
@@ -64,12 +61,15 @@ class UserRegistration extends Notification
* @param mixed $notifiable
*
* @return MailMessage
+ *
+ * @SuppressWarnings(PHPMD.UnusedFormalParameter)
*/
public function toMail($notifiable)
{
return (new MailMessage())
->markdown('emails.registered', ['address' => route('index')])
- ->subject((string)trans('email.registered_subject'));
+ ->subject((string)trans('email.registered_subject'))
+ ;
}
/**
@@ -78,6 +78,8 @@ class UserRegistration extends Notification
* @param mixed $notifiable
*
* @return array
+ *
+ * @SuppressWarnings(PHPMD.UnusedFormalParameter)
*/
public function via($notifiable)
{
diff --git a/app/Providers/AccountServiceProvider.php b/app/Providers/AccountServiceProvider.php
index e0e40daea8..3f18539064 100644
--- a/app/Providers/AccountServiceProvider.php
+++ b/app/Providers/AccountServiceProvider.php
@@ -42,9 +42,7 @@ class AccountServiceProvider extends ServiceProvider
/**
* Bootstrap the application services.
*/
- public function boot(): void
- {
- }
+ public function boot(): void {}
/**
* Register the application services.
@@ -62,7 +60,7 @@ class AccountServiceProvider extends ServiceProvider
{
$this->app->bind(
AccountRepositoryInterface::class,
- function (Application $app) {
+ static function (Application $app) {
/** @var AccountRepositoryInterface $repository */
$repository = app(AccountRepository::class);
@@ -77,7 +75,7 @@ class AccountServiceProvider extends ServiceProvider
$this->app->bind(
AdminAccountRepositoryInterface::class,
- function (Application $app) {
+ static function (Application $app) {
/** @var AdminAccountRepositoryInterface $repository */
$repository = app(AdminAccountRepository::class);
@@ -113,7 +111,7 @@ class AccountServiceProvider extends ServiceProvider
{
$this->app->bind(
AccountTaskerInterface::class,
- function (Application $app) {
+ static function (Application $app) {
/** @var AccountTaskerInterface $tasker */
$tasker = app(AccountTasker::class);
diff --git a/app/Providers/AdminServiceProvider.php b/app/Providers/AdminServiceProvider.php
index baa781b603..307efca1ff 100644
--- a/app/Providers/AdminServiceProvider.php
+++ b/app/Providers/AdminServiceProvider.php
@@ -36,9 +36,7 @@ class AdminServiceProvider extends ServiceProvider
/**
* Bootstrap the application services.
*/
- public function boot(): void
- {
- }
+ public function boot(): void {}
/**
* Register the application services.
@@ -55,7 +53,7 @@ class AdminServiceProvider extends ServiceProvider
{
$this->app->bind(
LinkTypeRepositoryInterface::class,
- function (Application $app) {
+ static function (Application $app) {
/** @var LinkTypeRepository $repository */
$repository = app(LinkTypeRepository::class);
// reference to auth is not understood by phpstan.
diff --git a/app/Providers/AppServiceProvider.php b/app/Providers/AppServiceProvider.php
index c71588decc..b5a1183717 100644
--- a/app/Providers/AppServiceProvider.php
+++ b/app/Providers/AppServiceProvider.php
@@ -23,12 +23,12 @@ declare(strict_types=1);
namespace FireflyIII\Providers;
+use Illuminate\Support\Facades\Blade;
use Illuminate\Support\Facades\Response;
use Illuminate\Support\Facades\Schema;
use Illuminate\Support\ServiceProvider;
use Laravel\Passport\Passport;
use Laravel\Sanctum\Sanctum;
-use URL;
/**
* Class AppServiceProvider
@@ -37,8 +37,6 @@ class AppServiceProvider extends ServiceProvider
{
/**
* Bootstrap any application services.
- *
- * @return void
*/
public function boot(): void
{
@@ -48,19 +46,37 @@ class AppServiceProvider extends ServiceProvider
'Cache-Control' => 'no-store',
];
$uuid = (string)request()->header('X-Trace-Id');
- if ('' !== trim($uuid) && (preg_match('/^[a-f\d]{8}(-[a-f\d]{4}){4}[a-f\d]{8}$/i', trim($uuid)) === 1)) {
+ if ('' !== trim($uuid) && (1 === preg_match('/^[a-f\d]{8}(-[a-f\d]{4}){4}[a-f\d]{8}$/i', trim($uuid)))) {
$headers['X-Trace-Id'] = $uuid;
}
+
return response()
->json($value)
- ->withHeaders($headers);
+ ->withHeaders($headers)
+ ;
+ });
+
+ // blade extension
+ Blade::directive('activeXRoutePartial', function (string $route) {
+ $name = \Route::getCurrentRoute()->getName() ?? '';
+ if (str_contains($name, $route)) {
+ return 'menu-open';
+ }
+
+ return '';
+ });
+ Blade::if('partialroute', function (string $route) {
+ $name = \Route::getCurrentRoute()->getName() ?? '';
+ if (str_contains($name, $route)) {
+ return true;
+ }
+
+ return false;
});
}
/**
* Register any application services.
- *
- * @return void
*/
public function register(): void
{
diff --git a/app/Providers/AttachmentServiceProvider.php b/app/Providers/AttachmentServiceProvider.php
index c6ba8cae34..6947d5d8a1 100644
--- a/app/Providers/AttachmentServiceProvider.php
+++ b/app/Providers/AttachmentServiceProvider.php
@@ -36,9 +36,7 @@ class AttachmentServiceProvider extends ServiceProvider
/**
* Bootstrap the application services.
*/
- public function boot(): void
- {
- }
+ public function boot(): void {}
/**
* Register the application services.
@@ -47,7 +45,7 @@ class AttachmentServiceProvider extends ServiceProvider
{
$this->app->bind(
AttachmentRepositoryInterface::class,
- function (Application $app) {
+ static function (Application $app) {
/** @var AttachmentRepositoryInterface $repository */
$repository = app(AttachmentRepository::class);
// reference to auth is not understood by phpstan.
diff --git a/app/Providers/AuthServiceProvider.php b/app/Providers/AuthServiceProvider.php
index 331499dab6..6ad1fc165b 100644
--- a/app/Providers/AuthServiceProvider.php
+++ b/app/Providers/AuthServiceProvider.php
@@ -34,11 +34,6 @@ use Laravel\Passport\Passport;
*/
class AuthServiceProvider extends ServiceProvider
{
- /**
- * The policy mappings for the application.
- *
- * @var array
- */
protected $policies
= [
// 'FireflyIII\Model' => 'FireflyIII\Policies\ModelPolicy',
@@ -47,13 +42,13 @@ class AuthServiceProvider extends ServiceProvider
/**
* Register any authentication / authorization services.
*
- * @return void
+ * @SuppressWarnings(PHPMD.UnusedFormalParameter)
*/
public function boot(): void
{
Auth::provider(
'remote_user_provider',
- function ($app, array $config) {
+ static function ($app, array $config) {
return new RemoteUserProvider();
}
);
diff --git a/app/Providers/BillServiceProvider.php b/app/Providers/BillServiceProvider.php
index dac9f83a73..409b3ba4a7 100644
--- a/app/Providers/BillServiceProvider.php
+++ b/app/Providers/BillServiceProvider.php
@@ -38,9 +38,7 @@ class BillServiceProvider extends ServiceProvider
/**
* Bootstrap the application services.
*/
- public function boot(): void
- {
- }
+ public function boot(): void {}
/**
* Register the application services.
@@ -49,7 +47,7 @@ class BillServiceProvider extends ServiceProvider
{
$this->app->bind(
BillRepositoryInterface::class,
- function (Application $app) {
+ static function (Application $app) {
/** @var BillRepositoryInterface $repository */
$repository = app(BillRepository::class);
@@ -65,7 +63,7 @@ class BillServiceProvider extends ServiceProvider
// administration variant
$this->app->bind(
AdminBillRepositoryInterface::class,
- function (Application $app) {
+ static function (Application $app) {
/** @var AdminBillRepositoryInterface $repository */
$repository = app(AdminBillRepository::class);
diff --git a/app/Providers/BudgetServiceProvider.php b/app/Providers/BudgetServiceProvider.php
index 6f7b2ab1d0..1c31ea805f 100644
--- a/app/Providers/BudgetServiceProvider.php
+++ b/app/Providers/BudgetServiceProvider.php
@@ -50,12 +50,12 @@ class BudgetServiceProvider extends ServiceProvider
/**
* Bootstrap the application services.
*/
- public function boot(): void
- {
- }
+ public function boot(): void {}
/**
* Register the application services.
+ *
+ * @SuppressWarnings(PHPMD.ExcessiveMethodLength)
*/
public function register(): void
{
diff --git a/app/Providers/CategoryServiceProvider.php b/app/Providers/CategoryServiceProvider.php
index c5c27b54b7..abfcd31037 100644
--- a/app/Providers/CategoryServiceProvider.php
+++ b/app/Providers/CategoryServiceProvider.php
@@ -29,6 +29,8 @@ use FireflyIII\Repositories\Category\NoCategoryRepository;
use FireflyIII\Repositories\Category\NoCategoryRepositoryInterface;
use FireflyIII\Repositories\Category\OperationsRepository;
use FireflyIII\Repositories\Category\OperationsRepositoryInterface;
+use FireflyIII\Repositories\UserGroups\Category\CategoryRepository as UserGroupCategoryRepository;
+use FireflyIII\Repositories\UserGroups\Category\CategoryRepositoryInterface as UserGroupCategoryRepositoryInterface;
use Illuminate\Foundation\Application;
use Illuminate\Support\ServiceProvider;
@@ -40,9 +42,7 @@ class CategoryServiceProvider extends ServiceProvider
/**
* Bootstrap the application services.
*/
- public function boot(): void
- {
- }
+ public function boot(): void {}
/**
* Register the application services.
@@ -63,6 +63,20 @@ class CategoryServiceProvider extends ServiceProvider
}
);
+ // phpstan does not understand reference to 'auth'.
+ $this->app->bind(
+ UserGroupCategoryRepositoryInterface::class,
+ static function (Application $app) {
+ /** @var UserGroupCategoryRepository $repository */
+ $repository = app(UserGroupCategoryRepository::class);
+ if ($app->auth->check()) { // @phpstan-ignore-line
+ $repository->setUser(auth()->user());
+ }
+
+ return $repository;
+ }
+ );
+
$this->app->bind(
OperationsRepositoryInterface::class,
static function (Application $app) {
diff --git a/app/Providers/CurrencyServiceProvider.php b/app/Providers/CurrencyServiceProvider.php
index a543385757..6643cfa4c4 100644
--- a/app/Providers/CurrencyServiceProvider.php
+++ b/app/Providers/CurrencyServiceProvider.php
@@ -25,6 +25,8 @@ namespace FireflyIII\Providers;
use FireflyIII\Repositories\Currency\CurrencyRepository;
use FireflyIII\Repositories\Currency\CurrencyRepositoryInterface;
+use FireflyIII\Repositories\UserGroups\Currency\CurrencyRepository as GroupCurrencyRepository;
+use FireflyIII\Repositories\UserGroups\Currency\CurrencyRepositoryInterface as GroupCurrencyRepositoryInterface;
use Illuminate\Foundation\Application;
use Illuminate\Support\ServiceProvider;
@@ -36,9 +38,7 @@ class CurrencyServiceProvider extends ServiceProvider
/**
* Bootstrap the application services.
*/
- public function boot(): void
- {
- }
+ public function boot(): void {}
/**
* Register the application services.
@@ -47,7 +47,7 @@ class CurrencyServiceProvider extends ServiceProvider
{
$this->app->bind(
CurrencyRepositoryInterface::class,
- function (Application $app) {
+ static function (Application $app) {
/** @var CurrencyRepository $repository */
$repository = app(CurrencyRepository::class);
// phpstan does not get the reference to auth
@@ -55,6 +55,19 @@ class CurrencyServiceProvider extends ServiceProvider
$repository->setUser(auth()->user());
}
+ return $repository;
+ }
+ );
+ $this->app->bind(
+ GroupCurrencyRepositoryInterface::class,
+ static function (Application $app) {
+ /** @var GroupCurrencyRepository $repository */
+ $repository = app(GroupCurrencyRepository::class);
+ // phpstan does not get the reference to auth
+ if ($app->auth->check()) { // @phpstan-ignore-line
+ $repository->setUser(auth()->user());
+ }
+
return $repository;
}
);
diff --git a/app/Providers/EventServiceProvider.php b/app/Providers/EventServiceProvider.php
index 0d93ba7b23..6893d62c6b 100644
--- a/app/Providers/EventServiceProvider.php
+++ b/app/Providers/EventServiceProvider.php
@@ -32,7 +32,6 @@ use FireflyIII\Events\Model\BudgetLimit\Created;
use FireflyIII\Events\Model\BudgetLimit\Deleted;
use FireflyIII\Events\Model\BudgetLimit\Updated;
use FireflyIII\Events\Model\PiggyBank\ChangedAmount;
-use FireflyIII\Events\Model\PiggyBank\ChangedPiggyBankAmount;
use FireflyIII\Events\Model\Rule\RuleActionFailedOnArray;
use FireflyIII\Events\Model\Rule\RuleActionFailedOnObject;
use FireflyIII\Events\NewVersionAvailable;
@@ -87,15 +86,10 @@ use Laravel\Passport\Events\AccessTokenCreated;
/**
* Class EventServiceProvider.
*
-
+ * @SuppressWarnings(PHPMD.CouplingBetweenObjects)
*/
class EventServiceProvider extends ServiceProvider
{
- /**
- * The event listener mappings for the application.
- *
- * @var array
- */
protected $listen
= [
// is a User related event.
@@ -211,7 +205,6 @@ class EventServiceProvider extends ServiceProvider
RuleActionFailedOnObject::class => [
'FireflyIII\Handlers\Events\Model\RuleHandler@ruleActionFailedOnObject',
],
-
];
/**
@@ -222,9 +215,6 @@ class EventServiceProvider extends ServiceProvider
$this->registerObservers();
}
- /**
- * @return void
- */
private function registerObservers(): void
{
Attachment::observe(new AttachmentObserver());
diff --git a/app/Providers/FireflyServiceProvider.php b/app/Providers/FireflyServiceProvider.php
index d4accbf037..3f304c33da 100644
--- a/app/Providers/FireflyServiceProvider.php
+++ b/app/Providers/FireflyServiceProvider.php
@@ -72,13 +72,11 @@ use FireflyIII\TransactionRules\Engine\SearchRuleEngine;
use FireflyIII\Validation\FireflyValidator;
use Illuminate\Foundation\Application;
use Illuminate\Support\ServiceProvider;
-use Validator;
/**
- *
* Class FireflyServiceProvider.
*
- *
+ * @SuppressWarnings(PHPMD.CouplingBetweenObjects)
*/
class FireflyServiceProvider extends ServiceProvider
{
@@ -87,7 +85,7 @@ class FireflyServiceProvider extends ServiceProvider
*/
public function boot(): void
{
- Validator::resolver(
+ \Validator::resolver(
static function ($translator, $data, $rules, $messages) {
return new FireflyValidator($translator, $data, $rules, $messages);
}
@@ -97,6 +95,7 @@ class FireflyServiceProvider extends ServiceProvider
/**
* Register stuff.
*
+ * @SuppressWarnings(PHPMD.ExcessiveMethodLength)
*/
public function register(): void
{
diff --git a/app/Providers/FireflySessionProvider.php b/app/Providers/FireflySessionProvider.php
index f07474003c..3ffeb23a0d 100644
--- a/app/Providers/FireflySessionProvider.php
+++ b/app/Providers/FireflySessionProvider.php
@@ -51,7 +51,7 @@ class FireflySessionProvider extends ServiceProvider
{
$this->app->singleton(
'session',
- function ($app) {
+ static function ($app) {
return new SessionManager($app);
}
);
@@ -64,7 +64,7 @@ class FireflySessionProvider extends ServiceProvider
{
$this->app->singleton(
'session.store',
- function ($app) {
+ static function ($app) {
// First, we will create the session manager which is responsible for the
// creation of the various session drivers when they are needed by the
// application instance, and will resolve them on a lazy load basis.
diff --git a/app/Providers/JournalServiceProvider.php b/app/Providers/JournalServiceProvider.php
index fa8dd0c960..a70532dc81 100644
--- a/app/Providers/JournalServiceProvider.php
+++ b/app/Providers/JournalServiceProvider.php
@@ -31,10 +31,10 @@ use FireflyIII\Repositories\Journal\JournalCLIRepository;
use FireflyIII\Repositories\Journal\JournalCLIRepositoryInterface;
use FireflyIII\Repositories\Journal\JournalRepository;
use FireflyIII\Repositories\Journal\JournalRepositoryInterface;
-use FireflyIII\Repositories\UserGroups\Journal\JournalRepository as GroupJournalRepository;
-use FireflyIII\Repositories\UserGroups\Journal\JournalRepositoryInterface as GroupJournalRepositoryInterface;
use FireflyIII\Repositories\TransactionGroup\TransactionGroupRepository;
use FireflyIII\Repositories\TransactionGroup\TransactionGroupRepositoryInterface;
+use FireflyIII\Repositories\UserGroups\Journal\JournalRepository as GroupJournalRepository;
+use FireflyIII\Repositories\UserGroups\Journal\JournalRepositoryInterface as GroupJournalRepositoryInterface;
use Illuminate\Foundation\Application;
use Illuminate\Support\ServiceProvider;
@@ -46,9 +46,7 @@ class JournalServiceProvider extends ServiceProvider
/**
* Bootstrap the application services.
*/
- public function boot(): void
- {
- }
+ public function boot(): void {}
/**
* Register the application services.
@@ -139,9 +137,6 @@ class JournalServiceProvider extends ServiceProvider
);
}
- /**
- *
- */
private function registerGroupCollector(): void
{
$this->app->bind(
diff --git a/app/Providers/PiggyBankServiceProvider.php b/app/Providers/PiggyBankServiceProvider.php
index 061bc311c0..ec3c9653b4 100644
--- a/app/Providers/PiggyBankServiceProvider.php
+++ b/app/Providers/PiggyBankServiceProvider.php
@@ -25,10 +25,8 @@ namespace FireflyIII\Providers;
use FireflyIII\Repositories\PiggyBank\PiggyBankRepository;
use FireflyIII\Repositories\PiggyBank\PiggyBankRepositoryInterface;
-
use FireflyIII\Repositories\UserGroups\PiggyBank\PiggyBankRepository as AdminPiggyBankRepository;
use FireflyIII\Repositories\UserGroups\PiggyBank\PiggyBankRepositoryInterface as AdminPiggyBankRepositoryInterface;
-
use Illuminate\Foundation\Application;
use Illuminate\Support\ServiceProvider;
@@ -40,9 +38,7 @@ class PiggyBankServiceProvider extends ServiceProvider
/**
* Bootstrap the application services.
*/
- public function boot(): void
- {
- }
+ public function boot(): void {}
/**
* Register the application services.
@@ -51,7 +47,7 @@ class PiggyBankServiceProvider extends ServiceProvider
{
$this->app->bind(
PiggyBankRepositoryInterface::class,
- function (Application $app) {
+ static function (Application $app) {
/** @var PiggyBankRepository $repository */
$repository = app(PiggyBankRepository::class);
if ($app->auth->check()) { // @phpstan-ignore-line (phpstan does not understand the reference to auth)
@@ -64,12 +60,13 @@ class PiggyBankServiceProvider extends ServiceProvider
$this->app->bind(
AdminPiggyBankRepositoryInterface::class,
- function (Application $app) {
+ static function (Application $app) {
/** @var AdminPiggyBankRepository $repository */
$repository = app(AdminPiggyBankRepository::class);
if ($app->auth->check()) { // @phpstan-ignore-line (phpstan does not understand the reference to auth)
$repository->setUser(auth()->user());
}
+
return $repository;
}
);
diff --git a/app/Providers/RecurringServiceProvider.php b/app/Providers/RecurringServiceProvider.php
index b954885476..884dc1f036 100644
--- a/app/Providers/RecurringServiceProvider.php
+++ b/app/Providers/RecurringServiceProvider.php
@@ -36,9 +36,7 @@ class RecurringServiceProvider extends ServiceProvider
/**
* Bootstrap the application services.
*/
- public function boot(): void
- {
- }
+ public function boot(): void {}
/**
* Register the application services.
@@ -47,7 +45,7 @@ class RecurringServiceProvider extends ServiceProvider
{
$this->app->bind(
RecurringRepositoryInterface::class,
- function (Application $app) {
+ static function (Application $app) {
/** @var RecurringRepositoryInterface $repository */
$repository = app(RecurringRepository::class);
diff --git a/app/Providers/RouteServiceProvider.php b/app/Providers/RouteServiceProvider.php
index 2950640f53..4382229f44 100644
--- a/app/Providers/RouteServiceProvider.php
+++ b/app/Providers/RouteServiceProvider.php
@@ -31,40 +31,31 @@ use Illuminate\Support\Facades\Route;
*/
class RouteServiceProvider extends ServiceProvider
{
- /**
- * The path to the "home" route for your application.
- *
- * @var string
- */
- public const HOME = '/';
- /**
- * This namespace is applied to your controller routes.
- *
- * In addition, it is set as the URL generator's root namespace.
- *
- * @var string
- */
- protected $namespace = '';
+ public const string HOME = '/';
+ protected $namespace = '';
/**
* Define the routes for the application.
*/
public function boot(): void
{
- $this->routes(function () {
+ $this->routes(function (): void {
Route::prefix('api')
- ->middleware('api')
- ->namespace($this->namespace)
- ->group(base_path('routes/api.php'));
+ ->middleware('api')
+ ->namespace($this->namespace)
+ ->group(base_path('routes/api.php'))
+ ;
Route::prefix('api/v1/cron')
- ->middleware('api_basic')
- ->namespace($this->namespace)
- ->group(base_path('routes/api-noauth.php'));
+ ->middleware('api_basic')
+ ->namespace($this->namespace)
+ ->group(base_path('routes/api-noauth.php'))
+ ;
Route::middleware('web')
- ->namespace($this->namespace)
- ->group(base_path('routes/web.php'));
+ ->namespace($this->namespace)
+ ->group(base_path('routes/web.php'))
+ ;
});
}
}
diff --git a/app/Providers/RuleGroupServiceProvider.php b/app/Providers/RuleGroupServiceProvider.php
index 01297995ae..e43ee595e2 100644
--- a/app/Providers/RuleGroupServiceProvider.php
+++ b/app/Providers/RuleGroupServiceProvider.php
@@ -36,9 +36,7 @@ class RuleGroupServiceProvider extends ServiceProvider
/**
* Bootstrap the application services.
*/
- public function boot(): void
- {
- }
+ public function boot(): void {}
/**
* Register the application services.
@@ -47,7 +45,7 @@ class RuleGroupServiceProvider extends ServiceProvider
{
$this->app->bind(
RuleGroupRepositoryInterface::class,
- function (Application $app) {
+ static function (Application $app) {
/** @var RuleGroupRepository $repository */
$repository = app(RuleGroupRepository::class);
if ($app->auth->check()) { // @phpstan-ignore-line (phpstan does not understand the reference to auth)
diff --git a/app/Providers/RuleServiceProvider.php b/app/Providers/RuleServiceProvider.php
index 62dfb0e3e7..9073b9cc7d 100644
--- a/app/Providers/RuleServiceProvider.php
+++ b/app/Providers/RuleServiceProvider.php
@@ -36,9 +36,7 @@ class RuleServiceProvider extends ServiceProvider
/**
* Bootstrap the application services.
*/
- public function boot(): void
- {
- }
+ public function boot(): void {}
/**
* Register the application services.
@@ -47,7 +45,7 @@ class RuleServiceProvider extends ServiceProvider
{
$this->app->bind(
RuleRepositoryInterface::class,
- function (Application $app) {
+ static function (Application $app) {
/** @var RuleRepository $repository */
$repository = app(RuleRepository::class);
if ($app->auth->check()) { // @phpstan-ignore-line (phpstan does not understand the reference to auth)
diff --git a/app/Providers/SearchServiceProvider.php b/app/Providers/SearchServiceProvider.php
index 3bdbcdf5e6..0bb2b1056b 100644
--- a/app/Providers/SearchServiceProvider.php
+++ b/app/Providers/SearchServiceProvider.php
@@ -36,9 +36,7 @@ class SearchServiceProvider extends ServiceProvider
/**
* Bootstrap the application services.
*/
- public function boot(): void
- {
- }
+ public function boot(): void {}
/**
* Register the application services.
@@ -47,7 +45,7 @@ class SearchServiceProvider extends ServiceProvider
{
$this->app->bind(
SearchInterface::class,
- function (Application $app) {
+ static function (Application $app) {
/** @var OperatorQuerySearch $search */
$search = app(OperatorQuerySearch::class);
if ($app->auth->check()) { // @phpstan-ignore-line (phpstan does not understand the reference to auth)
diff --git a/app/Providers/TagServiceProvider.php b/app/Providers/TagServiceProvider.php
index 17f5e107d2..c226dc5e9d 100644
--- a/app/Providers/TagServiceProvider.php
+++ b/app/Providers/TagServiceProvider.php
@@ -27,6 +27,8 @@ use FireflyIII\Repositories\Tag\OperationsRepository;
use FireflyIII\Repositories\Tag\OperationsRepositoryInterface;
use FireflyIII\Repositories\Tag\TagRepository;
use FireflyIII\Repositories\Tag\TagRepositoryInterface;
+use FireflyIII\Repositories\UserGroups\Tag\TagRepository as UserGroupTagRepository;
+use FireflyIII\Repositories\UserGroups\Tag\TagRepositoryInterface as UserGroupTagRepositoryInterface;
use Illuminate\Foundation\Application;
use Illuminate\Support\ServiceProvider;
@@ -38,9 +40,7 @@ class TagServiceProvider extends ServiceProvider
/**
* Bootstrap the application services.
*/
- public function boot(): void
- {
- }
+ public function boot(): void {}
/**
* Register the application services.
@@ -49,7 +49,7 @@ class TagServiceProvider extends ServiceProvider
{
$this->app->bind(
TagRepositoryInterface::class,
- function (Application $app) {
+ static function (Application $app) {
/** @var TagRepository $repository */
$repository = app(TagRepository::class);
@@ -61,9 +61,23 @@ class TagServiceProvider extends ServiceProvider
}
);
+ $this->app->bind(
+ UserGroupTagRepositoryInterface::class,
+ static function (Application $app) {
+ /** @var UserGroupTagRepository $repository */
+ $repository = app(UserGroupTagRepository::class);
+
+ if ($app->auth->check()) { // @phpstan-ignore-line (phpstan does not understand the reference to auth)
+ $repository->setUser(auth()->user());
+ }
+
+ return $repository;
+ }
+ );
+
$this->app->bind(
OperationsRepositoryInterface::class,
- function (Application $app) {
+ static function (Application $app) {
/** @var OperationsRepository $repository */
$repository = app(OperationsRepository::class);
diff --git a/app/Repositories/Account/AccountRepository.php b/app/Repositories/Account/AccountRepository.php
index 80bdd00a9e..90ea3ceaf5 100644
--- a/app/Repositories/Account/AccountRepository.php
+++ b/app/Repositories/Account/AccountRepository.php
@@ -42,13 +42,9 @@ use Illuminate\Contracts\Auth\Authenticatable;
use Illuminate\Database\Eloquent\Builder as EloquentBuilder;
use Illuminate\Database\Eloquent\Relations\HasMany;
use Illuminate\Support\Collection;
-use Illuminate\Support\Facades\Log;
-use JsonException;
-use Storage;
/**
* Class AccountRepository.
- *
*/
class AccountRepository implements AccountRepositoryInterface
{
@@ -56,13 +52,6 @@ class AccountRepository implements AccountRepositoryInterface
/**
* Moved here from account CRUD.
- *
- * @param Account $account
- * @param Account|null $moveTo
- *
- * @return bool
- *
-
*/
public function destroy(Account $account, ?Account $moveTo): bool
{
@@ -75,29 +64,30 @@ class AccountRepository implements AccountRepositoryInterface
/**
* Find account with same name OR same IBAN or both, but not the same type or ID.
- *
- * @param Collection $accounts
- *
- * @return Collection
*/
public function expandWithDoubles(Collection $accounts): Collection
{
$result = new Collection();
+
/** @var Account $account */
foreach ($accounts as $account) {
$byName = $this->user->accounts()->where('name', $account->name)
- ->where('id', '!=', $account->id)->first();
+ ->where('id', '!=', $account->id)->first()
+ ;
if (null !== $byName) {
$result->push($account);
$result->push($byName);
+
continue;
}
if (null !== $account->iban) {
$byIban = $this->user->accounts()->where('iban', $account->iban)
- ->where('id', '!=', $account->id)->first();
+ ->where('id', '!=', $account->id)->first()
+ ;
if (null !== $byIban) {
$result->push($account);
$result->push($byIban);
+
continue;
}
}
@@ -107,9 +97,6 @@ class AccountRepository implements AccountRepositoryInterface
return $result;
}
- /**
- * @inheritDoc
- */
public function findByAccountNumber(string $number, array $types): ?Account
{
$dbQuery = $this->user
@@ -117,27 +104,23 @@ class AccountRepository implements AccountRepositoryInterface
->leftJoin('account_meta', 'accounts.id', '=', 'account_meta.account_id')
->where('accounts.active', true)
->where(
- function (EloquentBuilder $q1) use ($number) {
+ static function (EloquentBuilder $q1) use ($number): void { // @phpstan-ignore-line
$json = json_encode($number);
$q1->where('account_meta.name', '=', 'account_number');
$q1->where('account_meta.data', '=', $json);
}
- );
+ )
+ ;
if (0 !== count($types)) {
$dbQuery->leftJoin('account_types', 'accounts.account_type_id', '=', 'account_types.id');
$dbQuery->whereIn('account_types.type', $types);
}
- /** @var Account|null */
+
+ // @var Account|null
return $dbQuery->first(['accounts.*']);
}
- /**
- * @param string $iban
- * @param array $types
- *
- * @return Account|null
- */
public function findByIbanNull(string $iban, array $types): ?Account
{
$query = $this->user->accounts()->where('iban', '!=', '')->whereNotNull('iban');
@@ -147,56 +130,42 @@ class AccountRepository implements AccountRepositoryInterface
$query->whereIn('account_types.type', $types);
}
- /** @var Account|null */
+ // @var Account|null
return $query->where('iban', $iban)->first(['accounts.*']);
}
- /**
- * @param string $name
- * @param array $types
- *
- * @return Account|null
- */
public function findByName(string $name, array $types): ?Account
{
- $query = $this->user->accounts();
+ $query = $this->user->accounts();
if (0 !== count($types)) {
$query->leftJoin('account_types', 'accounts.account_type_id', '=', 'account_types.id');
$query->whereIn('account_types.type', $types);
}
- Log::debug(sprintf('Searching for account named "%s" (of user #%d) of the following type(s)', $name, $this->user->id), ['types' => $types]);
+ app('log')->debug(sprintf('Searching for account named "%s" (of user #%d) of the following type(s)', $name, $this->user->id), ['types' => $types]);
$query->where('accounts.name', $name);
- /** @var Account $account */
+
+ /** @var null|Account $account */
$account = $query->first(['accounts.*']);
if (null === $account) {
- Log::debug(sprintf('There is no account with name "%s" of types', $name), $types);
+ app('log')->debug(sprintf('There is no account with name "%s" of types', $name), $types);
return null;
}
- Log::debug(sprintf('Found #%d (%s) with type id %d', $account->id, $account->name, $account->account_type_id));
+ app('log')->debug(sprintf('Found #%d (%s) with type id %d', $account->id, $account->name, $account->account_type_id));
return $account;
}
/**
* Return account type or null if not found.
- *
- * @param string $type
- *
- * @return AccountType|null
*/
public function getAccountTypeByType(string $type): ?AccountType
{
return AccountType::whereType(ucfirst($type))->first();
}
- /**
- * @param array $accountIds
- *
- * @return Collection
- */
public function getAccountsById(array $accountIds): Collection
{
$query = $this->user->accounts();
@@ -211,16 +180,11 @@ class AccountRepository implements AccountRepositoryInterface
return $query->get(['accounts.*']);
}
- /**
- * @param array $types
- *
- * @return Collection
- */
public function getActiveAccountsByType(array $types): Collection
{
$query = $this->user->accounts()->with(
[
- 'accountmeta' => function (HasMany $query) {
+ 'accountmeta' => static function (HasMany $query): void {
$query->where('name', 'account_role');
},
'attachments',
@@ -237,21 +201,18 @@ class AccountRepository implements AccountRepositoryInterface
return $query->get(['accounts.*']);
}
- /**
- * @inheritDoc
- */
public function getAttachments(Account $account): Collection
{
- $set = $account->attachments()->get();
+ $set = $account->attachments()->get();
- /** @var Storage $disk */
- $disk = Storage::disk('upload');
+ /** @var \Storage $disk */
+ $disk = \Storage::disk('upload');
return $set->each(
static function (Attachment $attachment) use ($disk) {
$notes = $attachment->notes()->first();
$attachment->file_exists = $disk->exists($attachment->fileName());
- $attachment->notes = $notes ? $notes->text : '';
+ $attachment->notes_text = null !== $notes ? $notes->text : '';
return $attachment;
}
@@ -259,15 +220,13 @@ class AccountRepository implements AccountRepositoryInterface
}
/**
- * @return Account
- *
* @throws FireflyException
- * @throws JsonException
*/
public function getCashAccount(): Account
{
/** @var AccountType $type */
- $type = AccountType::where('type', AccountType::CASH)->first();
+ $type = AccountType::where('type', AccountType::CASH)->first();
+
/** @var AccountFactory $factory */
$factory = app(AccountFactory::class);
$factory->setUser($this->user);
@@ -275,38 +234,29 @@ class AccountRepository implements AccountRepositoryInterface
return $factory->findOrCreate('Cash account', $type->type);
}
- /**
- * @param User|Authenticatable|null $user
- */
- public function setUser(User | Authenticatable | null $user): void
+ public function setUser(null|Authenticatable|User $user): void
{
- if (null !== $user) {
+ if ($user instanceof User) {
$this->user = $user;
}
}
- /**
- * @inheritDoc
- */
public function getCreditTransactionGroup(Account $account): ?TransactionGroup
{
$journal = TransactionJournal::leftJoin('transactions', 'transactions.transaction_journal_id', '=', 'transaction_journals.id')
- ->where('transactions.account_id', $account->id)
- ->transactionTypes([TransactionType::LIABILITY_CREDIT])
- ->first(['transaction_journals.*']);
+ ->where('transactions.account_id', $account->id)
+ ->transactionTypes([TransactionType::LIABILITY_CREDIT])
+ ->first(['transaction_journals.*'])
+ ;
+
return $journal?->transactionGroup;
}
- /**
- * @param array $types
- *
- * @return Collection
- */
public function getInactiveAccountsByType(array $types): Collection
{
$query = $this->user->accounts()->with(
[
- 'accountmeta' => function (HasMany $query) {
+ 'accountmeta' => static function (HasMany $query): void {
$query->where('name', 'account_role');
},
]
@@ -322,21 +272,14 @@ class AccountRepository implements AccountRepositoryInterface
return $query->get(['accounts.*']);
}
- /**
- * @inheritDoc
- */
public function getLocation(Account $account): ?Location
{
- /** @var Location|null */
+ // @var Location|null
return $account->locations()->first();
}
/**
* Get note text or null.
- *
- * @param Account $account
- *
- * @return null|string
*/
public function getNoteText(Account $account): ?string
{
@@ -345,17 +288,14 @@ class AccountRepository implements AccountRepositoryInterface
/**
* Returns the amount of the opening balance for this account.
- *
- * @param Account $account
- *
- * @return string|null
*/
public function getOpeningBalanceAmount(Account $account): ?string
{
- $journal = TransactionJournal::leftJoin('transactions', 'transactions.transaction_journal_id', '=', 'transaction_journals.id')
- ->where('transactions.account_id', $account->id)
- ->transactionTypes([TransactionType::OPENING_BALANCE, TransactionType::LIABILITY_CREDIT])
- ->first(['transaction_journals.*']);
+ $journal = TransactionJournal::leftJoin('transactions', 'transactions.transaction_journal_id', '=', 'transaction_journals.id')
+ ->where('transactions.account_id', $account->id)
+ ->transactionTypes([TransactionType::OPENING_BALANCE, TransactionType::LIABILITY_CREDIT])
+ ->first(['transaction_journals.*'])
+ ;
if (null === $journal) {
return null;
}
@@ -364,29 +304,21 @@ class AccountRepository implements AccountRepositoryInterface
return null;
}
- return (string)$transaction->amount;
+ return $transaction->amount;
}
/**
* Return date of opening balance as string or null.
- *
- * @param Account $account
- *
- * @return null|string
*/
public function getOpeningBalanceDate(Account $account): ?string
{
return TransactionJournal::leftJoin('transactions', 'transactions.transaction_journal_id', '=', 'transaction_journals.id')
- ->where('transactions.account_id', $account->id)
- ->transactionTypes([TransactionType::OPENING_BALANCE, TransactionType::LIABILITY_CREDIT])
- ->first(['transaction_journals.*'])?->date->format('Y-m-d H:i:s');
+ ->where('transactions.account_id', $account->id)
+ ->transactionTypes([TransactionType::OPENING_BALANCE, TransactionType::LIABILITY_CREDIT])
+ ->first(['transaction_journals.*'])?->date->format('Y-m-d H:i:s')
+ ;
}
- /**
- * @param Account $account
- *
- * @return TransactionGroup|null
- */
public function getOpeningBalanceGroup(Account $account): ?TransactionGroup
{
$journal = $this->getOpeningBalance($account);
@@ -394,36 +326,22 @@ class AccountRepository implements AccountRepositoryInterface
return $journal?->transactionGroup;
}
- /**
- * @param Account $account
- *
- * @return TransactionJournal|null
- */
public function getOpeningBalance(Account $account): ?TransactionJournal
{
return TransactionJournal::leftJoin('transactions', 'transactions.transaction_journal_id', '=', 'transaction_journals.id')
- ->where('transactions.account_id', $account->id)
- ->transactionTypes([TransactionType::OPENING_BALANCE])
- ->first(['transaction_journals.*']);
+ ->where('transactions.account_id', $account->id)
+ ->transactionTypes([TransactionType::OPENING_BALANCE])
+ ->first(['transaction_journals.*'])
+ ;
}
- /**
- * @param Account $account
- *
- * @return Collection
- */
public function getPiggyBanks(Account $account): Collection
{
return $account->piggyBanks()->get();
}
/**
- * @param Account $account
- *
- * @return Account|null
- *
* @throws FireflyException
- * @throws JsonException
*/
public function getReconciliation(Account $account): ?Account
{
@@ -434,17 +352,19 @@ class AccountRepository implements AccountRepositoryInterface
$name = trans('firefly.reconciliation_account_name', ['name' => $account->name, 'currency' => $currency->code]);
/** @var AccountType $type */
- $type = AccountType::where('type', AccountType::RECONCILIATION)->first();
- $current = $this->user->accounts()->where('account_type_id', $type->id)
- ->where('name', $name)
- ->first();
+ $type = AccountType::where('type', AccountType::RECONCILIATION)->first();
+
+ /** @var null|Account $current */
+ $current = $this->user->accounts()->where('account_type_id', $type->id)
+ ->where('name', $name)
+ ->first()
+ ;
- /** @var Account $current */
if (null !== $current) {
return $current;
}
- $data = [
+ $data = [
'account_type_id' => null,
'account_type_name' => AccountType::RECONCILIATION,
'active' => true,
@@ -454,21 +374,16 @@ class AccountRepository implements AccountRepositoryInterface
];
/** @var AccountFactory $factory */
- $factory = app(AccountFactory::class);
+ $factory = app(AccountFactory::class);
$factory->setUser($account->user);
return $factory->create($data);
}
- /**
- * @param Account $account
- *
- * @return TransactionCurrency|null
- */
public function getAccountCurrency(Account $account): ?TransactionCurrency
{
- $type = $account->accountType->type;
- $list = config('firefly.valid_currency_account_types');
+ $type = $account->accountType->type;
+ $list = config('firefly.valid_currency_account_types');
// return null if not in this list.
if (!in_array($type, $list, true)) {
@@ -484,16 +399,11 @@ class AccountRepository implements AccountRepositoryInterface
/**
* Return meta value for account. Null if not found.
- *
- * @param Account $account
- * @param string $field
- *
- * @return null|string
*/
public function getMetaValue(Account $account, string $field): ?string
{
$result = $account->accountMeta->filter(
- function (AccountMeta $meta) use ($field) {
+ static function (AccountMeta $meta) use ($field) {
return strtolower($meta->name) === strtolower($field);
}
);
@@ -507,29 +417,16 @@ class AccountRepository implements AccountRepositoryInterface
return null;
}
- /**
- * @param array $types
- *
- * @return int
- */
public function count(array $types): int
{
return $this->user->accounts()->accountTypeIn($types)->count();
}
- /**
- * @param int $accountId
- *
- * @return Account|null
- */
public function find(int $accountId): ?Account
{
return $this->user->accounts()->find($accountId);
}
- /**
- * @inheritDoc
- */
public function getUsedCurrencies(Account $account): Collection
{
$info = $account->transactions()->get(['transaction_currency_id', 'foreign_currency_id'])->toArray();
@@ -543,22 +440,14 @@ class AccountRepository implements AccountRepositoryInterface
return TransactionCurrency::whereIn('id', $currencyIds)->get();
}
- /**
- * @param Account $account
- *
- * @return bool
- */
public function isLiability(Account $account): bool
{
return in_array($account->accountType->type, [AccountType::CREDITCARD, AccountType::LOAN, AccountType::DEBT, AccountType::MORTGAGE], true);
}
- /**
- * @inheritDoc
- */
public function maxOrder(string $type): int
{
- $sets = [
+ $sets = [
AccountType::ASSET => [AccountType::DEFAULT, AccountType::ASSET],
AccountType::EXPENSE => [AccountType::EXPENSE, AccountType::BENEFICIARY],
AccountType::REVENUE => [AccountType::REVENUE],
@@ -568,24 +457,18 @@ class AccountRepository implements AccountRepositoryInterface
];
if (array_key_exists(ucfirst($type), $sets)) {
$order = (int)$this->getAccountsByType($sets[ucfirst($type)])->max('order');
- Log::debug(sprintf('Return max order of "%s" set: %d', $type, $order));
+ app('log')->debug(sprintf('Return max order of "%s" set: %d', $type, $order));
return $order;
}
$specials = [AccountType::CASH, AccountType::INITIAL_BALANCE, AccountType::IMPORT, AccountType::RECONCILIATION];
- $order = (int)$this->getAccountsByType($specials)->max('order');
- Log::debug(sprintf('Return max order of "%s" set (specials!): %d', $type, $order));
+ $order = (int)$this->getAccountsByType($specials)->max('order');
+ app('log')->debug(sprintf('Return max order of "%s" set (specials!): %d', $type, $order));
return $order;
}
- /**
- * @param array $types
- * @param array|null $sort
- *
- * @return Collection
- */
public function getAccountsByType(array $types, ?array $sort = []): Collection
{
$res = array_intersect([AccountType::ASSET, AccountType::MORTGAGE, AccountType::LOAN, AccountType::DEBT], $types);
@@ -614,10 +497,6 @@ class AccountRepository implements AccountRepositoryInterface
/**
* Returns the date of the very first transaction in this account.
- *
- * @param Account $account
- *
- * @return Carbon|null
*/
public function oldestJournalDate(Account $account): ?Carbon
{
@@ -628,38 +507,33 @@ class AccountRepository implements AccountRepositoryInterface
/**
* Returns the date of the very first transaction in this account.
- *
- * @param Account $account
- *
- * @return TransactionJournal|null
*/
public function oldestJournal(Account $account): ?TransactionJournal
{
+ /** @var null|TransactionJournal $first */
$first = $account->transactions()
- ->leftJoin('transaction_journals', 'transaction_journals.id', '=', 'transactions.transaction_journal_id')
- ->orderBy('transaction_journals.date', 'ASC')
- ->orderBy('transaction_journals.order', 'DESC')
- ->where('transaction_journals.user_id', $this->user->id)
- ->orderBy('transaction_journals.id', 'ASC')
- ->first(['transaction_journals.id']);
+ ->leftJoin('transaction_journals', 'transaction_journals.id', '=', 'transactions.transaction_journal_id')
+ ->orderBy('transaction_journals.date', 'ASC')
+ ->orderBy('transaction_journals.order', 'DESC')
+ ->where('transaction_journals.user_id', $this->user->id)
+ ->orderBy('transaction_journals.id', 'ASC')
+ ->first(['transaction_journals.id'])
+ ;
if (null !== $first) {
- return TransactionJournal::find((int)$first->id);
+ return TransactionJournal::find($first->id);
}
return null;
}
- /**
- * @inheritDoc
- */
public function resetAccountOrder(): void
{
$sets = [
[AccountType::DEFAULT, AccountType::ASSET],
- //[AccountType::EXPENSE, AccountType::BENEFICIARY],
- //[AccountType::REVENUE],
+ // [AccountType::EXPENSE, AccountType::BENEFICIARY],
+ // [AccountType::REVENUE],
[AccountType::LOAN, AccountType::DEBT, AccountType::CREDITCARD, AccountType::MORTGAGE],
- //[AccountType::CASH, AccountType::INITIAL_BALANCE, AccountType::IMPORT, AccountType::RECONCILIATION],
+ // [AccountType::CASH, AccountType::INITIAL_BALANCE, AccountType::IMPORT, AccountType::RECONCILIATION],
];
foreach ($sets as $set) {
$list = $this->getAccountsByType($set);
@@ -667,33 +541,28 @@ class AccountRepository implements AccountRepositoryInterface
foreach ($list as $account) {
if (false === $account->active) {
$account->order = 0;
+
continue;
}
if ($index !== (int)$account->order) {
- Log::debug(sprintf('Account #%d ("%s"): order should %d be but is %d.', $account->id, $account->name, $index, $account->order));
+ app('log')->debug(sprintf('Account #%d ("%s"): order should %d be but is %d.', $account->id, $account->name, $index, $account->order));
$account->order = $index;
$account->save();
}
- $index++;
+ ++$index;
}
}
}
- /**
- * @param string $query
- * @param array $types
- * @param int $limit
- *
- * @return Collection
- */
public function searchAccount(string $query, array $types, int $limit): Collection
{
$dbQuery = $this->user->accounts()
- ->where('active', true)
- ->orderBy('accounts.order', 'ASC')
- ->orderBy('accounts.account_type_id', 'ASC')
- ->orderBy('accounts.name', 'ASC')
- ->with(['accountType']);
+ ->where('active', true)
+ ->orderBy('accounts.order', 'ASC')
+ ->orderBy('accounts.account_type_id', 'ASC')
+ ->orderBy('accounts.name', 'ASC')
+ ->with(['accountType'])
+ ;
if ('' !== $query) {
// split query on spaces just in case:
$parts = explode(' ', $query);
@@ -710,28 +579,26 @@ class AccountRepository implements AccountRepositoryInterface
return $dbQuery->take($limit)->get(['accounts.*']);
}
- /**
- * @inheritDoc
- */
public function searchAccountNr(string $query, array $types, int $limit): Collection
{
$dbQuery = $this->user->accounts()->distinct()
- ->leftJoin('account_meta', 'accounts.id', '=', 'account_meta.account_id')
- ->where('accounts.active', true)
- ->orderBy('accounts.order', 'ASC')
- ->orderBy('accounts.account_type_id', 'ASC')
- ->orderBy('accounts.name', 'ASC')
- ->with(['accountType', 'accountMeta']);
+ ->leftJoin('account_meta', 'accounts.id', '=', 'account_meta.account_id')
+ ->where('accounts.active', true)
+ ->orderBy('accounts.order', 'ASC')
+ ->orderBy('accounts.account_type_id', 'ASC')
+ ->orderBy('accounts.name', 'ASC')
+ ->with(['accountType', 'accountMeta'])
+ ;
if ('' !== $query) {
// split query on spaces just in case:
$parts = explode(' ', $query);
foreach ($parts as $part) {
$search = sprintf('%%%s%%', $part);
$dbQuery->where(
- function (EloquentBuilder $q1) use ($search) {
+ static function (EloquentBuilder $q1) use ($search): void { // @phpstan-ignore-line
$q1->where('accounts.iban', 'LIKE', $search);
$q1->orWhere(
- function (EloquentBuilder $q2) use ($search) {
+ static function (EloquentBuilder $q2) use ($search): void {
$q2->where('account_meta.name', '=', 'account_number');
$q2->where('account_meta.data', 'LIKE', $search);
}
@@ -749,11 +616,7 @@ class AccountRepository implements AccountRepositoryInterface
}
/**
- * @param array $data
- *
- * @return Account
* @throws FireflyException
- * @throws JsonException
*/
public function store(array $data): Account
{
@@ -765,12 +628,7 @@ class AccountRepository implements AccountRepositoryInterface
}
/**
- * @param Account $account
- * @param array $data
- *
- * @return Account
* @throws FireflyException
- * @throws JsonException
*/
public function update(Account $account, array $data): Account
{
diff --git a/app/Repositories/Account/AccountRepositoryInterface.php b/app/Repositories/Account/AccountRepositoryInterface.php
index 4e71af2b63..8b301a7621 100644
--- a/app/Repositories/Account/AccountRepositoryInterface.php
+++ b/app/Repositories/Account/AccountRepositoryInterface.php
@@ -41,241 +41,100 @@ interface AccountRepositoryInterface
{
/**
* Moved here from account CRUD.
- *
- * @param array $types
- *
- * @return int
*/
public function count(array $types): int;
-
/**
* Moved here from account CRUD.
- *
- * @param Account $account
- * @param Account|null $moveTo
- *
- * @return bool
*/
public function destroy(Account $account, ?Account $moveTo): bool;
/**
* Find account with same name OR same IBAN or both, but not the same type or ID.
- *
- * @param Collection $accounts
- *
- * @return Collection
*/
public function expandWithDoubles(Collection $accounts): Collection;
- /**
- * @param int $accountId
- *
- * @return Account|null
- */
public function find(int $accountId): ?Account;
- /**
- * @param string $number
- * @param array $types
- *
- * @return Account|null
- */
public function findByAccountNumber(string $number, array $types): ?Account;
- /**
- * @param string $iban
- * @param array $types
- *
- * @return Account|null
- */
public function findByIbanNull(string $iban, array $types): ?Account;
- /**
- * @param string $name
- * @param array $types
- *
- * @return Account|null
- */
public function findByName(string $name, array $types): ?Account;
- /**
- * @param Account $account
- *
- * @return TransactionCurrency|null
- */
public function getAccountCurrency(Account $account): ?TransactionCurrency;
/**
* Return account type or null if not found.
- *
- * @param string $type
- *
- * @return AccountType|null
*/
public function getAccountTypeByType(string $type): ?AccountType;
- /**
- * @param array $accountIds
- *
- * @return Collection
- */
public function getAccountsById(array $accountIds): Collection;
/**
- * @param array $types
- * @param array|null $sort
- *
- * @return Collection
+ * @param array $types
*/
public function getAccountsByType(array $types, ?array $sort = []): Collection;
- /**
- * @param array $types
- *
- * @return Collection
- */
public function getActiveAccountsByType(array $types): Collection;
- /**
- * @param Account $account
- *
- * @return Collection
- */
public function getAttachments(Account $account): Collection;
- /**
- * @return Account
- */
public function getCashAccount(): Account;
- /**
- * @param Account $account
- *
- * @return TransactionGroup|null
- */
public function getCreditTransactionGroup(Account $account): ?TransactionGroup;
- /**
- * @param array $types
- *
- * @return Collection
- */
public function getInactiveAccountsByType(array $types): Collection;
/**
* Get account location, if any.
- *
- * @param Account $account
- *
- * @return Location|null
*/
public function getLocation(Account $account): ?Location;
/**
* Return meta value for account. Null if not found.
- *
- * @param Account $account
- * @param string $field
- *
- * @return null|string
*/
public function getMetaValue(Account $account, string $field): ?string;
/**
* Get note text or null.
- *
- * @param Account $account
- *
- * @return null|string
*/
public function getNoteText(Account $account): ?string;
- /**
- * @param Account $account
- *
- * @return TransactionJournal|null
- *
- */
public function getOpeningBalance(Account $account): ?TransactionJournal;
/**
* Returns the amount of the opening balance for this account.
- *
- * @param Account $account
- *
- * @return string|null
*/
public function getOpeningBalanceAmount(Account $account): ?string;
/**
* Return date of opening balance as string or null.
- *
- * @param Account $account
- *
- * @return null|string
*/
public function getOpeningBalanceDate(Account $account): ?string;
- /**
- * @param Account $account
- *
- * @return TransactionGroup|null
- */
public function getOpeningBalanceGroup(Account $account): ?TransactionGroup;
- /**
- * @param Account $account
- *
- * @return Collection
- */
public function getPiggyBanks(Account $account): Collection;
/**
* Find or create the opposing reconciliation account.
- *
- * @param Account $account
- *
- * @return Account|null
*/
public function getReconciliation(Account $account): ?Account;
- /**
- * @param Account $account
- *
- * @return Collection
- */
public function getUsedCurrencies(Account $account): Collection;
- /**
- * @param Account $account
- *
- * @return bool
- */
public function isLiability(Account $account): bool;
- /**
- * @param string $type
- *
- * @return int
- */
public function maxOrder(string $type): int;
/**
* Returns the date of the very first transaction in this account.
- *
- * @param Account $account
- *
- * @return TransactionJournal|null
*/
public function oldestJournal(Account $account): ?TransactionJournal;
/**
* Returns the date of the very first transaction in this account.
- *
- * @param Account $account
- *
- * @return Carbon|null
*/
public function oldestJournalDate(Account $account): ?Carbon;
@@ -284,41 +143,13 @@ interface AccountRepositoryInterface
*/
public function resetAccountOrder(): void;
- /**
- * @param string $query
- * @param array $types
- * @param int $limit
- *
- * @return Collection
- */
public function searchAccount(string $query, array $types, int $limit): Collection;
- /**
- * @param string $query
- * @param array $types
- * @param int $limit
- *
- * @return Collection
- */
public function searchAccountNr(string $query, array $types, int $limit): Collection;
- /**
- * @param User|Authenticatable|null $user
- */
- public function setUser(User | Authenticatable | null $user): void;
+ public function setUser(null|Authenticatable|User $user): void;
- /**
- * @param array $data
- *
- * @return Account
- */
public function store(array $data): Account;
- /**
- * @param Account $account
- * @param array $data
- *
- * @return Account
- */
public function update(Account $account, array $data): Account;
}
diff --git a/app/Repositories/Account/AccountTasker.php b/app/Repositories/Account/AccountTasker.php
index bb34482089..000d4a0589 100644
--- a/app/Repositories/Account/AccountTasker.php
+++ b/app/Repositories/Account/AccountTasker.php
@@ -28,12 +28,10 @@ use FireflyIII\Exceptions\FireflyException;
use FireflyIII\Helpers\Collector\GroupCollectorInterface;
use FireflyIII\Models\Account;
use FireflyIII\Models\TransactionType;
-use FireflyIII\Repositories\Currency\CurrencyRepositoryInterface;
+use FireflyIII\Repositories\UserGroups\Currency\CurrencyRepositoryInterface;
use FireflyIII\User;
use Illuminate\Contracts\Auth\Authenticatable;
use Illuminate\Support\Collection;
-use Illuminate\Support\Facades\Log;
-use JsonException;
/**
* Class AccountTasker.
@@ -43,36 +41,30 @@ class AccountTasker implements AccountTaskerInterface
private User $user;
/**
- * @param Collection $accounts
- * @param Carbon $start
- * @param Carbon $end
- *
- * @return array
* @throws FireflyException
- * @throws JsonException
*/
public function getAccountReport(Collection $accounts, Carbon $start, Carbon $end): array
{
- $yesterday = clone $start;
+ $yesterday = clone $start;
$yesterday->subDay();
- $startSet = app('steam')->balancesByAccounts($accounts, $yesterday);
- $endSet = app('steam')->balancesByAccounts($accounts, $end);
- Log::debug('Start of accountreport');
+ $startSet = app('steam')->balancesByAccounts($accounts, $yesterday);
+ $endSet = app('steam')->balancesByAccounts($accounts, $end);
+ app('log')->debug('Start of accountreport');
/** @var AccountRepositoryInterface $repository */
$repository = app(AccountRepositoryInterface::class);
- $defaultCurrency = app('amount')->getDefaultCurrencyByUser($this->user);
+ $defaultCurrency = app('amount')->getDefaultCurrencyByUserGroup($this->user->userGroup);
- $return = [
+ $return = [
'accounts' => [],
'sums' => [],
];
/** @var Account $account */
foreach ($accounts as $account) {
- $id = $account->id;
- $currency = $repository->getAccountCurrency($account) ?? $defaultCurrency;
- $return['sums'][$currency->id] = $return['sums'][$currency->id] ?? [
+ $id = $account->id;
+ $currency = $repository->getAccountCurrency($account) ?? $defaultCurrency;
+ $return['sums'][$currency->id] ??= [
'start' => '0',
'end' => '0',
'difference' => '0',
@@ -82,7 +74,7 @@ class AccountTasker implements AccountTaskerInterface
'currency_name' => $currency->name,
'currency_decimal_places' => $currency->decimal_places,
];
- $entry = [
+ $entry = [
'name' => $account->name,
'id' => $account->id,
'currency_id' => $currency->id,
@@ -93,15 +85,15 @@ class AccountTasker implements AccountTaskerInterface
];
// get first journal date:
- $first = $repository->oldestJournal($account);
- $entry['start_balance'] = $startSet[$account->id] ?? '0';
- $entry['end_balance'] = $endSet[$account->id] ?? '0';
+ $first = $repository->oldestJournal($account);
+ $entry['start_balance'] = $startSet[$account->id] ?? '0';
+ $entry['end_balance'] = $endSet[$account->id] ?? '0';
// first journal exists, and is on start, then this is the actual opening balance:
if (null !== $first && $first->date->isSameDay($start) && TransactionType::OPENING_BALANCE === $first->transactionType->type) {
- Log::debug(sprintf('Date of first journal for %s is %s', $account->name, $first->date->format('Y-m-d')));
+ app('log')->debug(sprintf('Date of first journal for %s is %s', $account->name, $first->date->format('Y-m-d')));
$entry['start_balance'] = $first->transactions()->where('account_id', $account->id)->first()->amount;
- Log::debug(sprintf('Account %s was opened on %s, so opening balance is %f', $account->name, $start->format('Y-m-d'), $entry['start_balance']));
+ app('log')->debug(sprintf('Account %s was opened on %s, so opening balance is %f', $account->name, $start->format('Y-m-d'), $entry['start_balance']));
}
$return['sums'][$currency->id]['start'] = bcadd($return['sums'][$currency->id]['start'], $entry['start_balance']);
$return['sums'][$currency->id]['end'] = bcadd($return['sums'][$currency->id]['end'], $entry['end_balance']);
@@ -116,13 +108,7 @@ class AccountTasker implements AccountTaskerInterface
}
/**
- * @param Carbon $start
- * @param Carbon $end
- * @param Collection $accounts
- *
- * @return array
* @throws FireflyException
- * @throws JsonException
*/
public function getExpenseReport(Carbon $start, Carbon $end, Collection $accounts): array
{
@@ -136,13 +122,13 @@ class AccountTasker implements AccountTaskerInterface
$collector->setSourceAccounts($accounts)->setRange($start, $end);
$collector->excludeDestinationAccounts($accounts);
$collector->setTypes([TransactionType::WITHDRAWAL, TransactionType::TRANSFER])->withAccountInformation();
- $journals = $collector->getExtractedJournals();
+ $journals = $collector->getExtractedJournals();
- $report = $this->groupExpenseByDestination($journals);
+ $report = $this->groupExpenseByDestination($journals);
// sort the result
// Obtain a list of columns
- $sum = [];
+ $sum = [];
foreach ($report['accounts'] as $accountId => $row) {
$sum[$accountId] = (float)$row['sum']; // intentional float
}
@@ -153,19 +139,16 @@ class AccountTasker implements AccountTaskerInterface
}
/**
- * @param array $array
- *
- * @return array
* @throws FireflyException
- * @throws JsonException
*/
private function groupExpenseByDestination(array $array): array
{
- $defaultCurrency = app('amount')->getDefaultCurrencyByUser($this->user);
+ $defaultCurrency = app('amount')->getDefaultCurrencyByUserGroup($this->user->userGroup);
+
/** @var CurrencyRepositoryInterface $currencyRepos */
- $currencyRepos = app(CurrencyRepositoryInterface::class);
- $currencies = [$defaultCurrency->id => $defaultCurrency,];
- $report = [
+ $currencyRepos = app(CurrencyRepositoryInterface::class);
+ $currencies = [$defaultCurrency->id => $defaultCurrency];
+ $report = [
'accounts' => [],
'sums' => [],
];
@@ -175,8 +158,8 @@ class AccountTasker implements AccountTaskerInterface
$sourceId = (int)$journal['destination_account_id'];
$currencyId = (int)$journal['currency_id'];
$key = sprintf('%s-%s', $sourceId, $currencyId);
- $currencies[$currencyId] = $currencies[$currencyId] ?? $currencyRepos->find($currencyId);
- $report['accounts'][$key] = $report['accounts'][$key] ?? [
+ $currencies[$currencyId] ??= $currencyRepos->find($currencyId);
+ $report['accounts'][$key] ??= [
'id' => $sourceId,
'name' => $journal['destination_account_name'],
'sum' => '0',
@@ -190,7 +173,7 @@ class AccountTasker implements AccountTaskerInterface
];
$report['accounts'][$key]['sum'] = bcadd($report['accounts'][$key]['sum'], $journal['amount']);
- Log::debug(sprintf('Sum for %s is now %s', $journal['destination_account_name'], $report['accounts'][$key]['sum']));
+ app('log')->debug(sprintf('Sum for %s is now %s', $journal['destination_account_name'], $report['accounts'][$key]['sum']));
++$report['accounts'][$key]['count'];
}
@@ -201,7 +184,7 @@ class AccountTasker implements AccountTaskerInterface
$report['accounts'][$key]['average'] = bcdiv($report['accounts'][$key]['sum'], (string)$report['accounts'][$key]['count']);
}
$currencyId = $report['accounts'][$key]['currency_id'];
- $report['sums'][$currencyId] = $report['sums'][$currencyId] ?? [
+ $report['sums'][$currencyId] ??= [
'sum' => '0',
'currency_id' => $report['accounts'][$key]['currency_id'],
'currency_name' => $report['accounts'][$key]['currency_name'],
@@ -216,13 +199,7 @@ class AccountTasker implements AccountTaskerInterface
}
/**
- * @param Carbon $start
- * @param Carbon $end
- * @param Collection $accounts
- *
- * @return array
* @throws FireflyException
- * @throws JsonException
*/
public function getIncomeReport(Carbon $start, Carbon $end, Collection $accounts): array
{
@@ -235,11 +212,11 @@ class AccountTasker implements AccountTaskerInterface
$collector->setDestinationAccounts($accounts)->setRange($start, $end);
$collector->excludeSourceAccounts($accounts);
$collector->setTypes([TransactionType::DEPOSIT, TransactionType::TRANSFER])->withAccountInformation();
- $report = $this->groupIncomeBySource($collector->getExtractedJournals());
+ $report = $this->groupIncomeBySource($collector->getExtractedJournals());
// sort the result
// Obtain a list of columns
- $sum = [];
+ $sum = [];
foreach ($report['accounts'] as $accountId => $row) {
$sum[$accountId] = (float)$row['sum']; // intentional float
}
@@ -250,30 +227,27 @@ class AccountTasker implements AccountTaskerInterface
}
/**
- * @param array $array
- *
- * @return array
* @throws FireflyException
- * @throws JsonException
*/
private function groupIncomeBySource(array $array): array
{
- $defaultCurrency = app('amount')->getDefaultCurrencyByUser($this->user);
+ $defaultCurrency = app('amount')->getDefaultCurrencyByUserGroup($this->user->userGroup);
+
/** @var CurrencyRepositoryInterface $currencyRepos */
- $currencyRepos = app(CurrencyRepositoryInterface::class);
- $currencies = [$defaultCurrency->id => $defaultCurrency,];
- $report = [
+ $currencyRepos = app(CurrencyRepositoryInterface::class);
+ $currencies = [$defaultCurrency->id => $defaultCurrency];
+ $report = [
'accounts' => [],
'sums' => [],
];
/** @var array $journal */
foreach ($array as $journal) {
- $sourceId = (int)$journal['source_account_id'];
- $currencyId = (int)$journal['currency_id'];
- $key = sprintf('%s-%s', $sourceId, $currencyId);
+ $sourceId = (int)$journal['source_account_id'];
+ $currencyId = (int)$journal['currency_id'];
+ $key = sprintf('%s-%s', $sourceId, $currencyId);
if (!array_key_exists($key, $report['accounts'])) {
- $currencies[$currencyId] = $currencies[$currencyId] ?? $currencyRepos->find($currencyId);
+ $currencies[$currencyId] ??= $currencyRepos->find($currencyId);
$report['accounts'][$key] = [
'id' => $sourceId,
'name' => $journal['source_account_name'],
@@ -297,7 +271,7 @@ class AccountTasker implements AccountTaskerInterface
$report['accounts'][$key]['average'] = bcdiv($report['accounts'][$key]['sum'], (string)$report['accounts'][$key]['count']);
}
$currencyId = $report['accounts'][$key]['currency_id'];
- $report['sums'][$currencyId] = $report['sums'][$currencyId] ?? [
+ $report['sums'][$currencyId] ??= [
'sum' => '0',
'currency_id' => $report['accounts'][$key]['currency_id'],
'currency_name' => $report['accounts'][$key]['currency_name'],
@@ -311,12 +285,9 @@ class AccountTasker implements AccountTaskerInterface
return $report;
}
- /**
- * @param User|Authenticatable|null $user
- */
- public function setUser(User | Authenticatable | null $user): void
+ public function setUser(null|Authenticatable|User $user): void
{
- if (null !== $user) {
+ if ($user instanceof User) {
$this->user = $user;
}
}
diff --git a/app/Repositories/Account/AccountTaskerInterface.php b/app/Repositories/Account/AccountTaskerInterface.php
index 7bbb1c0c75..74438f7882 100644
--- a/app/Repositories/Account/AccountTaskerInterface.php
+++ b/app/Repositories/Account/AccountTaskerInterface.php
@@ -33,35 +33,11 @@ use Illuminate\Support\Collection;
*/
interface AccountTaskerInterface
{
- /**
- * @param Collection $accounts
- * @param Carbon $start
- * @param Carbon $end
- *
- * @return array
- */
public function getAccountReport(Collection $accounts, Carbon $start, Carbon $end): array;
- /**
- * @param Carbon $start
- * @param Carbon $end
- * @param Collection $accounts
- *
- * @return array
- */
public function getExpenseReport(Carbon $start, Carbon $end, Collection $accounts): array;
- /**
- * @param Carbon $start
- * @param Carbon $end
- * @param Collection $accounts
- *
- * @return array
- */
public function getIncomeReport(Carbon $start, Carbon $end, Collection $accounts): array;
- /**
- * @param User|Authenticatable|null $user
- */
- public function setUser(User | Authenticatable | null $user): void;
+ public function setUser(null|Authenticatable|User $user): void;
}
diff --git a/app/Repositories/Account/OperationsRepository.php b/app/Repositories/Account/OperationsRepository.php
index df5a0fa99e..c4b8002d85 100644
--- a/app/Repositories/Account/OperationsRepository.php
+++ b/app/Repositories/Account/OperationsRepository.php
@@ -32,7 +32,6 @@ use Illuminate\Contracts\Auth\Authenticatable;
use Illuminate\Support\Collection;
/**
- *
* Class OperationsRepository
*/
class OperationsRepository implements OperationsRepositoryInterface
@@ -43,12 +42,6 @@ class OperationsRepository implements OperationsRepositoryInterface
* This method returns a list of all the withdrawal transaction journals (as arrays) set in that period
* which have the specified accounts. It's grouped per currency, with as few details in the array
* as possible. Amounts are always negative.
- *
- * @param Carbon $start
- * @param Carbon $end
- * @param Collection $accounts
- *
- * @return array
*/
public function listExpenses(Carbon $start, Carbon $end, Collection $accounts): array
{
@@ -59,13 +52,6 @@ class OperationsRepository implements OperationsRepositoryInterface
/**
* Collect transactions with some parameters
- *
- * @param Carbon $start
- * @param Carbon $end
- * @param Collection $accounts
- * @param string $type
- *
- * @return array
*/
private function getTransactions(Carbon $start, Carbon $end, Collection $accounts, string $type): array
{
@@ -78,30 +64,20 @@ class OperationsRepository implements OperationsRepositoryInterface
return $collector->getExtractedJournals();
}
- /**
- * @param User|Authenticatable|null $user
- */
- public function setUser(User | Authenticatable | null $user): void
+ public function setUser(null|Authenticatable|User $user): void
{
- if (null !== $user) {
+ if ($user instanceof User) {
$this->user = $user;
}
}
- /**
- * @param array $journals
- * @param string $direction
- *
- * @return array
- */
private function sortByCurrency(array $journals, string $direction): array
{
$array = [];
foreach ($journals as $journal) {
- $currencyId = (int)$journal['currency_id'];
- $journalId = (int)$journal['transaction_journal_id'];
- $array[$currencyId] = $array[$currencyId] ?? [
-
+ $currencyId = (int)$journal['currency_id'];
+ $journalId = (int)$journal['transaction_journal_id'];
+ $array[$currencyId] ??= [
'currency_id' => $journal['currency_id'],
'currency_name' => $journal['currency_name'],
'currency_symbol' => $journal['currency_symbol'],
@@ -111,7 +87,7 @@ class OperationsRepository implements OperationsRepositoryInterface
];
$array[$currencyId]['transaction_journals'][$journalId] = [
- 'amount' => app('steam')->$direction((string)$journal['amount']),
+ 'amount' => app('steam')->{$direction}((string)$journal['amount']), // @phpstan-ignore-line
'date' => $journal['date'],
'transaction_journal_id' => $journalId,
'budget_name' => $journal['budget_name'],
@@ -135,12 +111,6 @@ class OperationsRepository implements OperationsRepositoryInterface
* This method returns a list of all the deposit transaction journals (as arrays) set in that period
* which have the specified accounts. It's grouped per currency, with as few details in the array
* as possible. Amounts are always positive.
- *
- * @param Carbon $start
- * @param Carbon $end
- * @param Collection|null $accounts
- *
- * @return array
*/
public function listIncome(Carbon $start, Carbon $end, ?Collection $accounts = null): array
{
@@ -150,7 +120,7 @@ class OperationsRepository implements OperationsRepositoryInterface
}
/**
- * @inheritDoc
+ * @SuppressWarnings(PHPMD.ExcessiveParameterList)
*/
public function sumExpenses(
Carbon $start,
@@ -165,14 +135,8 @@ class OperationsRepository implements OperationsRepositoryInterface
}
/**
- * @param Carbon $start
- * @param Carbon $end
- * @param Collection|null $accounts
- * @param Collection|null $opposing
- * @param TransactionCurrency|null $currency
- * @param string $type
- *
- * @return array
+ * @SuppressWarnings(PHPMD.ExcessiveParameterList)
+ * @SuppressWarnings(PHPMD.NPathComplexity)
*/
private function getTransactionsForSum(
string $type,
@@ -214,14 +178,15 @@ class OperationsRepository implements OperationsRepositoryInterface
if (null !== $currency) {
$collector->setCurrency($currency);
}
- $journals = $collector->getExtractedJournals();
+ $journals = $collector->getExtractedJournals();
// same but for foreign currencies:
if (null !== $currency) {
/** @var GroupCollectorInterface $collector */
$collector = app(GroupCollectorInterface::class);
$collector->setUser($this->user)->setRange($start, $end)->setTypes([$type])->withAccountInformation()
- ->setForeignCurrency($currency);
+ ->setForeignCurrency($currency)
+ ;
if (TransactionType::WITHDRAWAL === $type) {
if (null !== $accounts) {
$collector->setSourceAccounts($accounts);
@@ -239,28 +204,22 @@ class OperationsRepository implements OperationsRepositoryInterface
}
}
- $result = $collector->getExtractedJournals();
+ $result = $collector->getExtractedJournals();
// do not use array_merge because you want keys to overwrite (otherwise you get double results):
- $journals = $result + $journals;
+ $journals = $result + $journals;
}
return $journals;
}
- /**
- * @param array $journals
- * @param string $direction
- *
- * @return array
- */
private function groupByCurrency(array $journals, string $direction): array
{
$array = [];
foreach ($journals as $journal) {
$currencyId = (int)$journal['currency_id'];
- $array[$currencyId] = $array[$currencyId] ?? [
+ $array[$currencyId] ??= [
'sum' => '0',
'currency_id' => $currencyId,
'currency_name' => $journal['currency_name'],
@@ -268,12 +227,12 @@ class OperationsRepository implements OperationsRepositoryInterface
'currency_code' => $journal['currency_code'],
'currency_decimal_places' => $journal['currency_decimal_places'],
];
- $array[$currencyId]['sum'] = bcadd($array[$currencyId]['sum'], app('steam')->$direction($journal['amount']));
+ $array[$currencyId]['sum'] = bcadd($array[$currencyId]['sum'], app('steam')->{$direction}($journal['amount'])); // @phpstan-ignore-line
// also do foreign amount:
- $foreignId = (int)$journal['foreign_currency_id'];
+ $foreignId = (int)$journal['foreign_currency_id'];
if (0 !== $foreignId) {
- $array[$foreignId] = $array[$foreignId] ?? [
+ $array[$foreignId] ??= [
'sum' => '0',
'currency_id' => $foreignId,
'currency_name' => $journal['foreign_currency_name'],
@@ -281,7 +240,7 @@ class OperationsRepository implements OperationsRepositoryInterface
'currency_code' => $journal['foreign_currency_code'],
'currency_decimal_places' => $journal['foreign_currency_decimal_places'],
];
- $array[$foreignId]['sum'] = bcadd($array[$foreignId]['sum'], app('steam')->$direction($journal['foreign_amount']));
+ $array[$foreignId]['sum'] = bcadd($array[$foreignId]['sum'], app('steam')->{$direction}($journal['foreign_amount'])); // @phpstan-ignore-line
}
}
@@ -289,7 +248,7 @@ class OperationsRepository implements OperationsRepositoryInterface
}
/**
- * @inheritDoc
+ * @SuppressWarnings(PHPMD.ExcessiveParameterList)
*/
public function sumExpensesByDestination(
Carbon $start,
@@ -303,13 +262,6 @@ class OperationsRepository implements OperationsRepositoryInterface
return $this->groupByDirection($journals, 'destination', 'negative');
}
- /**
- * @param array $journals
- * @param string $direction
- * @param string $method
- *
- * @return array
- */
private function groupByDirection(array $journals, string $direction, string $method): array
{
$array = [];
@@ -318,7 +270,7 @@ class OperationsRepository implements OperationsRepositoryInterface
foreach ($journals as $journal) {
$key = sprintf('%s-%s', $journal[$idKey], $journal['currency_id']);
- $array[$key] = $array[$key] ?? [
+ $array[$key] ??= [
'id' => $journal[$idKey],
'name' => $journal[$nameKey],
'sum' => '0',
@@ -328,12 +280,12 @@ class OperationsRepository implements OperationsRepositoryInterface
'currency_code' => $journal['currency_code'],
'currency_decimal_places' => $journal['currency_decimal_places'],
];
- $array[$key]['sum'] = bcadd($array[$key]['sum'], app('steam')->$method((string)$journal['amount']));
+ $array[$key]['sum'] = bcadd($array[$key]['sum'], app('steam')->{$method}((string)$journal['amount'])); // @phpstan-ignore-line
// also do foreign amount:
if (0 !== (int)$journal['foreign_currency_id']) {
$key = sprintf('%s-%s', $journal[$idKey], $journal['foreign_currency_id']);
- $array[$key] = $array[$key] ?? [
+ $array[$key] ??= [
'id' => $journal[$idKey],
'name' => $journal[$nameKey],
'sum' => '0',
@@ -343,7 +295,7 @@ class OperationsRepository implements OperationsRepositoryInterface
'currency_code' => $journal['foreign_currency_code'],
'currency_decimal_places' => $journal['foreign_currency_decimal_places'],
];
- $array[$key]['sum'] = bcadd($array[$key]['sum'], app('steam')->$method((string)$journal['foreign_amount']));
+ $array[$key]['sum'] = bcadd($array[$key]['sum'], app('steam')->{$method}((string)$journal['foreign_amount'])); // @phpstan-ignore-line
}
}
@@ -351,7 +303,7 @@ class OperationsRepository implements OperationsRepositoryInterface
}
/**
- * @inheritDoc
+ * @SuppressWarnings(PHPMD.ExcessiveParameterList)
*/
public function sumExpensesBySource(
Carbon $start,
@@ -366,7 +318,7 @@ class OperationsRepository implements OperationsRepositoryInterface
}
/**
- * @inheritDoc
+ * @SuppressWarnings(PHPMD.ExcessiveParameterList)
*/
public function sumIncome(
Carbon $start,
@@ -381,7 +333,7 @@ class OperationsRepository implements OperationsRepositoryInterface
}
/**
- * @inheritDoc
+ * @SuppressWarnings(PHPMD.ExcessiveParameterList)
*/
public function sumIncomeByDestination(
Carbon $start,
@@ -396,7 +348,7 @@ class OperationsRepository implements OperationsRepositoryInterface
}
/**
- * @inheritDoc
+ * @SuppressWarnings(PHPMD.ExcessiveParameterList)
*/
public function sumIncomeBySource(
Carbon $start,
@@ -410,9 +362,6 @@ class OperationsRepository implements OperationsRepositoryInterface
return $this->groupByDirection($journals, 'source', 'positive');
}
- /**
- * @inheritDoc
- */
public function sumTransfers(Carbon $start, Carbon $end, ?Collection $accounts = null, ?TransactionCurrency $currency = null): array
{
$journals = $this->getTransactionsForSum(TransactionType::TRANSFER, $start, $end, $accounts, null, $currency);
@@ -420,19 +369,15 @@ class OperationsRepository implements OperationsRepositoryInterface
return $this->groupByEither($journals);
}
- /**
- * @param array $journals
- *
- * @return array
- */
private function groupByEither(array $journals): array
{
$return = [];
+
/** @var array $journal */
foreach ($journals as $journal) {
$return = $this->groupByEitherJournal($return, $journal);
}
- $final = [];
+ $final = [];
foreach ($return as $array) {
$array['difference_float'] = (float)$array['difference'];
$array['in_float'] = (float)$array['in'];
@@ -443,23 +388,17 @@ class OperationsRepository implements OperationsRepositoryInterface
return $final;
}
- /**
- * @param array $return
- * @param array $journal
- *
- * @return array
- */
private function groupByEitherJournal(array $return, array $journal): array
{
- $sourceId = $journal['source_account_id'];
- $destinationId = $journal['destination_account_id'];
- $currencyId = $journal['currency_id'];
- $sourceKey = sprintf('%d-%d', $currencyId, $sourceId);
- $destKey = sprintf('%d-%d', $currencyId, $destinationId);
- $amount = app('steam')->positive($journal['amount']);
+ $sourceId = $journal['source_account_id'];
+ $destinationId = $journal['destination_account_id'];
+ $currencyId = $journal['currency_id'];
+ $sourceKey = sprintf('%d-%d', $currencyId, $sourceId);
+ $destKey = sprintf('%d-%d', $currencyId, $destinationId);
+ $amount = app('steam')->positive($journal['amount']);
// source first
- $return[$sourceKey] = $return[$sourceKey] ?? [
+ $return[$sourceKey] ??= [
'id' => (string)$sourceId,
'name' => $journal['source_account_name'],
'difference' => '0',
@@ -473,7 +412,7 @@ class OperationsRepository implements OperationsRepositoryInterface
];
// dest next:
- $return[$destKey] = $return[$destKey] ?? [
+ $return[$destKey] ??= [
'id' => (string)$destinationId,
'name' => $journal['destination_account_name'],
'difference' => '0',
@@ -491,19 +430,19 @@ class OperationsRepository implements OperationsRepositoryInterface
$return[$sourceKey]['difference'] = bcadd($return[$sourceKey]['out'], $return[$sourceKey]['in']);
// destination account? money comes in:
- $return[$destKey]['in'] = bcadd($return[$destKey]['in'], $amount);
- $return[$destKey]['difference'] = bcadd($return[$destKey]['out'], $return[$destKey]['in']);
+ $return[$destKey]['in'] = bcadd($return[$destKey]['in'], $amount);
+ $return[$destKey]['difference'] = bcadd($return[$destKey]['out'], $return[$destKey]['in']);
// foreign currency
if (null !== $journal['foreign_currency_id'] && null !== $journal['foreign_amount']) {
- $currencyId = $journal['foreign_currency_id'];
- $sourceKey = sprintf('%d-%d', $currencyId, $sourceId);
- $destKey = sprintf('%d-%d', $currencyId, $destinationId);
- $amount = app('steam')->positive($journal['foreign_amount']);
+ $currencyId = $journal['foreign_currency_id'];
+ $sourceKey = sprintf('%d-%d', $currencyId, $sourceId);
+ $destKey = sprintf('%d-%d', $currencyId, $destinationId);
+ $amount = app('steam')->positive($journal['foreign_amount']);
// same as above:
// source first
- $return[$sourceKey] = $return[$sourceKey] ?? [
+ $return[$sourceKey] ??= [
'id' => (string)$sourceId,
'name' => $journal['source_account_name'],
'difference' => '0',
@@ -517,7 +456,7 @@ class OperationsRepository implements OperationsRepositoryInterface
];
// dest next:
- $return[$destKey] = $return[$destKey] ?? [
+ $return[$destKey] ??= [
'id' => (string)$destinationId,
'name' => $journal['destination_account_name'],
'difference' => '0',
@@ -534,8 +473,8 @@ class OperationsRepository implements OperationsRepositoryInterface
$return[$sourceKey]['difference'] = bcadd($return[$sourceKey]['out'], $return[$sourceKey]['in']);
// destination account? money comes in:
- $return[$destKey]['in'] = bcadd($return[$destKey]['in'], $amount);
- $return[$destKey]['difference'] = bcadd($return[$destKey]['out'], $return[$destKey]['in']);
+ $return[$destKey]['in'] = bcadd($return[$destKey]['in'], $amount);
+ $return[$destKey]['difference'] = bcadd($return[$destKey]['out'], $return[$destKey]['in']);
}
return $return;
diff --git a/app/Repositories/Account/OperationsRepositoryInterface.php b/app/Repositories/Account/OperationsRepositoryInterface.php
index 3e02b58cb8..b1867da02b 100644
--- a/app/Repositories/Account/OperationsRepositoryInterface.php
+++ b/app/Repositories/Account/OperationsRepositoryInterface.php
@@ -38,12 +38,6 @@ interface OperationsRepositoryInterface
* This method returns a list of all the withdrawal transaction journals (as arrays) set in that period
* which have the specified accounts. It's grouped per currency, with as few details in the array
* as possible. Amounts are always negative.
- *
- * @param Carbon $start
- * @param Carbon $end
- * @param Collection $accounts
- *
- * @return array
*/
public function listExpenses(Carbon $start, Carbon $end, Collection $accounts): array;
@@ -51,30 +45,15 @@ interface OperationsRepositoryInterface
* This method returns a list of all the deposit transaction journals (as arrays) set in that period
* which have the specified accounts. It's grouped per currency, with as few details in the array
* as possible. Amounts are always positive.
- *
- * @param Carbon $start
- * @param Carbon $end
- * @param Collection|null $accounts
- *
- * @return array
*/
public function listIncome(Carbon $start, Carbon $end, ?Collection $accounts = null): array;
- /**
- * @param User|Authenticatable|null $user
- */
- public function setUser(User | Authenticatable | null $user): void;
+ public function setUser(null|Authenticatable|User $user): void;
/**
* Sum of withdrawal journals in period for a set of accounts, grouped per currency. Amounts are always negative.
*
- * @param Carbon $start
- * @param Carbon $end
- * @param Collection|null $accounts
- * @param Collection|null $expense
- * @param TransactionCurrency|null $currency
- *
- * @return array
+ * @SuppressWarnings(PHPMD.ExcessiveParameterList)
*/
public function sumExpenses(
Carbon $start,
@@ -88,13 +67,7 @@ interface OperationsRepositoryInterface
* Sum of withdrawal journals in period for a set of accounts, grouped per destination / currency. Amounts are
* always negative.
*
- * @param Carbon $start
- * @param Carbon $end
- * @param Collection|null $accounts
- * @param Collection|null $expense
- * @param TransactionCurrency|null $currency
- *
- * @return array
+ * @SuppressWarnings(PHPMD.ExcessiveParameterList)
*/
public function sumExpensesByDestination(
Carbon $start,
@@ -108,13 +81,7 @@ interface OperationsRepositoryInterface
* Sum of withdrawal journals in period for a set of accounts, grouped per source / currency. Amounts are always
* negative.
*
- * @param Carbon $start
- * @param Carbon $end
- * @param Collection|null $accounts
- * @param Collection|null $expense
- * @param TransactionCurrency|null $currency
- *
- * @return array
+ * @SuppressWarnings(PHPMD.ExcessiveParameterList)
*/
public function sumExpensesBySource(
Carbon $start,
@@ -127,13 +94,7 @@ interface OperationsRepositoryInterface
/**
* Sum of income journals in period for a set of accounts, grouped per currency. Amounts are always positive.
*
- * @param Carbon $start
- * @param Carbon $end
- * @param Collection|null $accounts
- * @param Collection|null $revenue
- * @param TransactionCurrency|null $currency
- *
- * @return array
+ * @SuppressWarnings(PHPMD.ExcessiveParameterList)
*/
public function sumIncome(
Carbon $start,
@@ -147,13 +108,7 @@ interface OperationsRepositoryInterface
* Sum of income journals in period for a set of accounts, grouped per destination + currency. Amounts are always
* positive.
*
- * @param Carbon $start
- * @param Carbon $end
- * @param Collection|null $accounts
- * @param Collection|null $revenue
- * @param TransactionCurrency|null $currency
- *
- * @return array
+ * @SuppressWarnings(PHPMD.ExcessiveParameterList)
*/
public function sumIncomeByDestination(
Carbon $start,
@@ -167,13 +122,7 @@ interface OperationsRepositoryInterface
* Sum of income journals in period for a set of accounts, grouped per source + currency. Amounts are always
* positive.
*
- * @param Carbon $start
- * @param Carbon $end
- * @param Collection|null $accounts
- * @param Collection|null $revenue
- * @param TransactionCurrency|null $currency
- *
- * @return array
+ * @SuppressWarnings(PHPMD.ExcessiveParameterList)
*/
public function sumIncomeBySource(
Carbon $start,
@@ -185,13 +134,6 @@ interface OperationsRepositoryInterface
/**
* Sum of transfers in period for a set of accounts, grouped per currency. Amounts are always positive.
- *
- * @param Carbon $start
- * @param Carbon $end
- * @param Collection|null $accounts
- * @param TransactionCurrency|null $currency
- *
- * @return array
*/
public function sumTransfers(Carbon $start, Carbon $end, ?Collection $accounts = null, ?TransactionCurrency $currency = null): array;
}
diff --git a/app/Repositories/Attachment/AttachmentRepository.php b/app/Repositories/Attachment/AttachmentRepository.php
index 3b65837c20..98d0af2961 100644
--- a/app/Repositories/Attachment/AttachmentRepository.php
+++ b/app/Repositories/Attachment/AttachmentRepository.php
@@ -23,8 +23,6 @@ declare(strict_types=1);
namespace FireflyIII\Repositories\Attachment;
-use Crypt;
-use Exception;
use FireflyIII\Exceptions\FireflyException;
use FireflyIII\Factory\AttachmentFactory;
use FireflyIII\Helpers\Attachments\AttachmentHelperInterface;
@@ -34,14 +32,11 @@ use FireflyIII\User;
use Illuminate\Contracts\Auth\Authenticatable;
use Illuminate\Contracts\Encryption\DecryptException;
use Illuminate\Support\Collection;
-use Illuminate\Support\Facades\Log;
use Illuminate\Support\Facades\Storage;
use League\Flysystem\UnableToDeleteFile;
-use LogicException;
/**
* Class AttachmentRepository.
- *
*/
class AttachmentRepository implements AttachmentRepositoryInterface
{
@@ -49,17 +44,15 @@ class AttachmentRepository implements AttachmentRepositoryInterface
private $user;
/**
- * @param Attachment $attachment
- *
- * @return bool
- * @throws Exception
+ * @throws \Exception
*/
public function destroy(Attachment $attachment): bool
{
/** @var AttachmentHelperInterface $helper */
$helper = app(AttachmentHelperInterface::class);
- $path = $helper->getAttachmentLocation($attachment);
+ $path = $helper->getAttachmentLocation($attachment);
+
try {
Storage::disk('upload')->delete($path);
} catch (UnableToDeleteFile $e) {
@@ -70,11 +63,6 @@ class AttachmentRepository implements AttachmentRepositoryInterface
return true;
}
- /**
- * @param Attachment $attachment
- *
- * @return string
- */
public function getContent(Attachment $attachment): string
{
// create a disk.
@@ -84,10 +72,11 @@ class AttachmentRepository implements AttachmentRepositoryInterface
if ($disk->exists($file)) {
$encryptedContent = (string)$disk->get($file);
+
try {
- $unencryptedContent = Crypt::decrypt($encryptedContent); // verified
+ $unencryptedContent = \Crypt::decrypt($encryptedContent); // verified
} catch (DecryptException $e) {
- Log::debug(sprintf('Could not decrypt attachment #%d but this is fine: %s', $attachment->id, $e->getMessage()));
+ app('log')->debug(sprintf('Could not decrypt attachment #%d but this is fine: %s', $attachment->id, $e->getMessage()));
$unencryptedContent = $encryptedContent;
}
}
@@ -95,11 +84,6 @@ class AttachmentRepository implements AttachmentRepositoryInterface
return $unencryptedContent;
}
- /**
- * @param Attachment $attachment
- *
- * @return bool
- */
public function exists(Attachment $attachment): bool
{
/** @var Storage $disk */
@@ -108,9 +92,6 @@ class AttachmentRepository implements AttachmentRepositoryInterface
return $disk->exists($attachment->fileName());
}
- /**
- * @return Collection
- */
public function get(): Collection
{
return $this->user->attachments()->get();
@@ -118,10 +99,6 @@ class AttachmentRepository implements AttachmentRepositoryInterface
/**
* Get attachment note text or empty string.
- *
- * @param Attachment $attachment
- *
- * @return string|null
*/
public function getNoteText(Attachment $attachment): ?string
{
@@ -134,9 +111,6 @@ class AttachmentRepository implements AttachmentRepositoryInterface
}
/**
- * @param array $data
- *
- * @return Attachment
* @throws FireflyException
*/
public function store(array $data): Attachment
@@ -144,7 +118,7 @@ class AttachmentRepository implements AttachmentRepositoryInterface
/** @var AttachmentFactory $factory */
$factory = app(AttachmentFactory::class);
$factory->setUser($this->user);
- $result = $factory->create($data);
+ $result = $factory->create($data);
if (null === $result) {
throw new FireflyException('Could not store attachment.');
}
@@ -152,22 +126,13 @@ class AttachmentRepository implements AttachmentRepositoryInterface
return $result;
}
- /**
- * @param User|Authenticatable|null $user
- */
- public function setUser(User | Authenticatable | null $user): void
+ public function setUser(null|Authenticatable|User $user): void
{
- if (null !== $user) {
+ if ($user instanceof User) {
$this->user = $user;
}
}
- /**
- * @param Attachment $attachment
- * @param array $data
- *
- * @return Attachment
- */
public function update(Attachment $attachment, array $data): Attachment
{
if (array_key_exists('title', $data)) {
@@ -193,12 +158,6 @@ class AttachmentRepository implements AttachmentRepositoryInterface
return $attachment;
}
- /**
- * @param Attachment $attachment
- * @param string $note
- *
- * @return bool
- */
public function updateNote(Attachment $attachment, string $note): bool
{
if ('' === $note) {
@@ -206,14 +165,14 @@ class AttachmentRepository implements AttachmentRepositoryInterface
if (null !== $dbNote) {
try {
$dbNote->delete();
- } catch (LogicException $e) {
- Log::error($e->getMessage());
+ } catch (\LogicException $e) {
+ app('log')->error($e->getMessage());
}
}
return true;
}
- $dbNote = $attachment->notes()->first();
+ $dbNote = $attachment->notes()->first();
if (null === $dbNote) {
$dbNote = new Note();
$dbNote->noteable()->associate($attachment);
diff --git a/app/Repositories/Attachment/AttachmentRepositoryInterface.php b/app/Repositories/Attachment/AttachmentRepositoryInterface.php
index b3a8b879aa..e48a8df323 100644
--- a/app/Repositories/Attachment/AttachmentRepositoryInterface.php
+++ b/app/Repositories/Attachment/AttachmentRepositoryInterface.php
@@ -34,59 +34,25 @@ use Illuminate\Support\Collection;
*/
interface AttachmentRepositoryInterface
{
- /**
- * @param Attachment $attachment
- *
- * @return bool
- */
public function destroy(Attachment $attachment): bool;
- /**
- * @param Attachment $attachment
- *
- * @return bool
- */
public function exists(Attachment $attachment): bool;
- /**
- * @return Collection
- */
public function get(): Collection;
- /**
- * @param Attachment $attachment
- *
- * @return string
- */
public function getContent(Attachment $attachment): string;
/**
* Get attachment note text or empty string.
- *
- * @param Attachment $attachment
- *
- * @return string|null
*/
public function getNoteText(Attachment $attachment): ?string;
- /**
- * @param User|Authenticatable|null $user
- */
- public function setUser(User | Authenticatable | null $user): void;
+ public function setUser(null|Authenticatable|User $user): void;
/**
- * @param array $data
- *
- * @return Attachment
* @throws FireflyException
*/
public function store(array $data): Attachment;
- /**
- * @param Attachment $attachment
- * @param array $attachmentData
- *
- * @return Attachment
- */
public function update(Attachment $attachment, array $attachmentData): Attachment;
}
diff --git a/app/Repositories/AuditLogEntry/ALERepository.php b/app/Repositories/AuditLogEntry/ALERepository.php
index 8e3af7ca94..92b84f9e37 100644
--- a/app/Repositories/AuditLogEntry/ALERepository.php
+++ b/app/Repositories/AuditLogEntry/ALERepository.php
@@ -33,21 +33,15 @@ use Illuminate\Support\Collection;
*/
class ALERepository implements ALERepositoryInterface
{
- /**
- * @inheritDoc
- */
public function getForObject(Model $model): Collection
{
// all Models have an ID.
return AuditLogEntry::where('auditable_id', $model->id)->where('auditable_type', get_class($model))->get(); // @phpstan-ignore-line
}
- /**
- * @inheritDoc
- */
public function store(array $data): AuditLogEntry
{
- $auditLogEntry = new AuditLogEntry();
+ $auditLogEntry = new AuditLogEntry();
$auditLogEntry->auditable()->associate($data['auditable']);
$auditLogEntry->changer()->associate($data['changer']);
@@ -55,6 +49,7 @@ class ALERepository implements ALERepositoryInterface
$auditLogEntry->before = $data['before'];
$auditLogEntry->after = $data['after'];
$auditLogEntry->save();
+
return $auditLogEntry;
}
}
diff --git a/app/Repositories/AuditLogEntry/ALERepositoryInterface.php b/app/Repositories/AuditLogEntry/ALERepositoryInterface.php
index d0153beb83..84b48b8ad9 100644
--- a/app/Repositories/AuditLogEntry/ALERepositoryInterface.php
+++ b/app/Repositories/AuditLogEntry/ALERepositoryInterface.php
@@ -33,17 +33,7 @@ use Illuminate\Support\Collection;
*/
interface ALERepositoryInterface
{
- /**
- * @param Model $model
- *
- * @return Collection
- */
public function getForObject(Model $model): Collection;
- /**
- * @param array $data
- *
- * @return AuditLogEntry
- */
public function store(array $data): AuditLogEntry;
}
diff --git a/app/Repositories/Bill/BillRepository.php b/app/Repositories/Bill/BillRepository.php
index cc3f91b14c..d078d79432 100644
--- a/app/Repositories/Bill/BillRepository.php
+++ b/app/Repositories/Bill/BillRepository.php
@@ -24,7 +24,6 @@ declare(strict_types=1);
namespace FireflyIII\Repositories\Bill;
use Carbon\Carbon;
-use DB;
use FireflyIII\Exceptions\FireflyException;
use FireflyIII\Factory\BillFactory;
use FireflyIII\Models\Attachment;
@@ -44,12 +43,9 @@ use Illuminate\Database\Query\JoinClause;
use Illuminate\Pagination\LengthAwarePaginator;
use Illuminate\Support\Collection;
use Illuminate\Support\Facades\Log;
-use JsonException;
-use Storage;
/**
* Class BillRepository.
- *
*/
class BillRepository implements BillRepositoryInterface
{
@@ -57,9 +53,6 @@ class BillRepository implements BillRepositoryInterface
private User $user;
- /**
- * @inheritDoc
- */
public function billEndsWith(string $query, int $limit): Collection
{
$search = $this->user->bills();
@@ -67,14 +60,12 @@ class BillRepository implements BillRepositoryInterface
$search->where('name', 'LIKE', sprintf('%%%s', $query));
}
$search->orderBy('name', 'ASC')
- ->where('active', true);
+ ->where('active', true)
+ ;
return $search->take($limit)->get();
}
- /**
- * @inheritDoc
- */
public function billStartsWith(string $query, int $limit): Collection
{
$search = $this->user->bills();
@@ -82,7 +73,8 @@ class BillRepository implements BillRepositoryInterface
$search->where('name', 'LIKE', sprintf('%s%%', $query));
}
$search->orderBy('name', 'ASC')
- ->where('active', true);
+ ->where('active', true)
+ ;
return $search->take($limit)->get();
}
@@ -95,21 +87,14 @@ class BillRepository implements BillRepositoryInterface
$set = $this->user->bills()->orderBy('order', 'ASC')->get();
$current = 1;
foreach ($set as $bill) {
- if ((int)$bill->order !== $current) {
+ if ($bill->order !== $current) {
$bill->order = $current;
$bill->save();
}
- $current++;
+ ++$current;
}
}
- /**
- * @param Bill $bill
- *
- * @return bool
- *
-
- */
public function destroy(Bill $bill): bool
{
/** @var BillDestroyService $service */
@@ -119,51 +104,40 @@ class BillRepository implements BillRepositoryInterface
return true;
}
- /**
- * @inheritDoc
- */
public function destroyAll(): void
{
+ Log::channel('audit')->info('Delete all bills through destroyAll');
$this->user->bills()->delete();
}
/**
* Find bill by parameters.
- *
- * @param int|null $billId
- * @param string|null $billName
- *
- * @return Bill|null
*/
public function findBill(?int $billId, ?string $billName): ?Bill
{
if (null !== $billId) {
- $searchResult = $this->find((int)$billId);
+ $searchResult = $this->find($billId);
if (null !== $searchResult) {
- Log::debug(sprintf('Found bill based on #%d, will return it.', $billId));
+ app('log')->debug(sprintf('Found bill based on #%d, will return it.', $billId));
return $searchResult;
}
}
if (null !== $billName) {
- $searchResult = $this->findByName((string)$billName);
+ $searchResult = $this->findByName($billName);
if (null !== $searchResult) {
- Log::debug(sprintf('Found bill based on "%s", will return it.', $billName));
+ app('log')->debug(sprintf('Found bill based on "%s", will return it.', $billName));
return $searchResult;
}
}
- Log::debug('Found nothing');
+ app('log')->debug('Found nothing');
return null;
}
/**
* Find a bill by ID.
- *
- * @param int $billId
- *
- * @return Bill|null
*/
public function find(int $billId): ?Bill
{
@@ -172,10 +146,6 @@ class BillRepository implements BillRepositoryInterface
/**
* Find a bill by name.
- *
- * @param string $name
- *
- * @return Bill|null
*/
public function findByName(string $name): ?Bill
{
@@ -184,45 +154,34 @@ class BillRepository implements BillRepositoryInterface
/**
* Get all attachments.
- *
- * @param Bill $bill
- *
- * @return Collection
*/
public function getAttachments(Bill $bill): Collection
{
- $set = $bill->attachments()->get();
+ $set = $bill->attachments()->get();
- /** @var Storage $disk */
- $disk = Storage::disk('upload');
+ /** @var \Storage $disk */
+ $disk = \Storage::disk('upload');
return $set->each(
static function (Attachment $attachment) use ($disk) {
$notes = $attachment->notes()->first();
$attachment->file_exists = $disk->exists($attachment->fileName());
- $attachment->notes = $notes ? $notes->text : '';
+ $attachment->notes_text = null !== $notes ? $notes->text : '';
return $attachment;
}
);
}
- /**
- * @return Collection
- */
public function getBills(): Collection
{
return $this->user->bills()
- ->orderBy('order', 'ASC')
- ->orderBy('active', 'DESC')
- ->orderBy('name', 'ASC')->get();
+ ->orderBy('order', 'ASC')
+ ->orderBy('active', 'DESC')
+ ->orderBy('name', 'ASC')->get()
+ ;
}
- /**
- * @param Collection $accounts
- *
- * @return Collection
- */
public function getBillsForAccounts(Collection $accounts): Collection
{
$fields = [
@@ -244,32 +203,29 @@ class BillRepository implements BillRepositoryInterface
$ids = $accounts->pluck('id')->toArray();
return $this->user->bills()
- ->leftJoin(
- 'transaction_journals',
- static function (JoinClause $join) {
- $join->on('transaction_journals.bill_id', '=', 'bills.id')->whereNull('transaction_journals.deleted_at');
- }
- )
- ->leftJoin(
- 'transactions',
- static function (JoinClause $join) {
- $join->on('transaction_journals.id', '=', 'transactions.transaction_journal_id')->where('transactions.amount', '<', 0);
- }
- )
- ->whereIn('transactions.account_id', $ids)
- ->whereNull('transaction_journals.deleted_at')
- ->orderBy('bills.active', 'DESC')
- ->orderBy('bills.name', 'ASC')
- ->groupBy($fields)
- ->get($fields);
+ ->leftJoin(
+ 'transaction_journals',
+ static function (JoinClause $join): void {
+ $join->on('transaction_journals.bill_id', '=', 'bills.id')->whereNull('transaction_journals.deleted_at');
+ }
+ )
+ ->leftJoin(
+ 'transactions',
+ static function (JoinClause $join): void {
+ $join->on('transaction_journals.id', '=', 'transactions.transaction_journal_id')->where('transactions.amount', '<', 0);
+ }
+ )
+ ->whereIn('transactions.account_id', $ids)
+ ->whereNull('transaction_journals.deleted_at')
+ ->orderBy('bills.active', 'DESC')
+ ->orderBy('bills.name', 'ASC')
+ ->groupBy($fields)
+ ->get($fields)
+ ;
}
/**
* Get all bills with these ID's.
- *
- * @param array $billIds
- *
- * @return Collection
*/
public function getByIds(array $billIds): Collection
{
@@ -278,31 +234,19 @@ class BillRepository implements BillRepositoryInterface
/**
* Get text or return empty string.
- *
- * @param Bill $bill
- *
- * @return string
*/
public function getNoteText(Bill $bill): string
{
- /** @var Note $note */
+ /** @var null|Note $note */
$note = $bill->notes()->first();
- if (null !== $note) {
- return (string)$note->text;
- }
- return '';
+ return (string)$note?->text;
}
- /**
- * @param Bill $bill
- *
- * @return array
- */
public function getOverallAverage(Bill $bill): array
{
/** @var JournalRepositoryInterface $repos */
- $repos = app(JournalRepositoryInterface::class);
+ $repos = app(JournalRepositoryInterface::class);
$repos->setUser($this->user);
// get and sort on currency
@@ -315,7 +259,7 @@ class BillRepository implements BillRepositoryInterface
$transaction = $journal->transactions()->where('amount', '<', 0)->first();
$currencyId = (int)$journal->transaction_currency_id;
$currency = $journal->transactionCurrency;
- $result[$currencyId] = $result[$currencyId] ?? [
+ $result[$currencyId] ??= [
'sum' => '0',
'count' => 0,
'avg' => '0',
@@ -325,7 +269,7 @@ class BillRepository implements BillRepositoryInterface
'currency_decimal_places' => $currency->decimal_places,
];
$result[$currencyId]['sum'] = bcadd($result[$currencyId]['sum'], $transaction->amount);
- $result[$currencyId]['count']++;
+ ++$result[$currencyId]['count'];
}
// after loop, re-loop for avg.
@@ -340,65 +284,50 @@ class BillRepository implements BillRepositoryInterface
return $result;
}
- /**
- * @param User|Authenticatable|null $user
- */
- public function setUser(User | Authenticatable | null $user): void
+ public function setUser(null|Authenticatable|User $user): void
{
- if (null !== $user) {
+ if ($user instanceof User) {
$this->user = $user;
}
}
- /**
- * @param int $size
- *
- * @return LengthAwarePaginator
- */
public function getPaginator(int $size): LengthAwarePaginator
{
return $this->user->bills()
- ->orderBy('active', 'DESC')
- ->orderBy('name', 'ASC')->paginate($size);
+ ->orderBy('active', 'DESC')
+ ->orderBy('name', 'ASC')->paginate($size)
+ ;
}
/**
* The "paid dates" list is a list of dates of transaction journals that are linked to this bill.
- *
- * @param Bill $bill
- * @param Carbon $start
- * @param Carbon $end
- *
- * @return Collection
*/
public function getPaidDatesInRange(Bill $bill, Carbon $start, Carbon $end): Collection
{
- //Log::debug('Now in getPaidDatesInRange()');
+ // app('log')->debug('Now in getPaidDatesInRange()');
return $bill->transactionJournals()
- ->before($end)->after($start)->get(
- [
+ ->before($end)->after($start)->get(
+ [
'transaction_journals.id',
'transaction_journals.date',
'transaction_journals.transaction_group_id',
]
- );
+ )
+ ;
}
/**
* Return all rules for one bill
- *
- * @param Bill $bill
- *
- * @return Collection
*/
public function getRulesForBill(Bill $bill): Collection
{
return $this->user->rules()
- ->leftJoin('rule_actions', 'rule_actions.rule_id', '=', 'rules.id')
- ->where('rule_actions.action_type', 'link_to_bill')
- ->where('rule_actions.action_value', $bill->name)
- ->get(['rules.*']);
+ ->leftJoin('rule_actions', 'rule_actions.rule_id', '=', 'rules.id')
+ ->where('rule_actions.action_type', 'link_to_bill')
+ ->where('rule_actions.action_value', $bill->name)
+ ->get(['rules.*'])
+ ;
}
/**
@@ -406,21 +335,19 @@ class BillRepository implements BillRepositoryInterface
* 5= billid
*
* 5 => [['id' => 1, 'title' => 'Some rule'],['id' => 2, 'title' => 'Some other rule']]
- *
- * @param Collection $collection
- *
- * @return array
*/
public function getRulesForBills(Collection $collection): array
{
- $rules = $this->user->rules()
- ->leftJoin('rule_actions', 'rule_actions.rule_id', '=', 'rules.id')
- ->where('rule_actions.action_type', 'link_to_bill')
- ->get(['rules.id', 'rules.title', 'rule_actions.action_value', 'rules.active']);
- $array = [];
+ $rules = $this->user->rules()
+ ->leftJoin('rule_actions', 'rule_actions.rule_id', '=', 'rules.id')
+ ->where('rule_actions.action_type', 'link_to_bill')
+ ->get(['rules.id', 'rules.title', 'rule_actions.action_value', 'rules.active'])
+ ;
+ $array = [];
+
/** @var Rule $rule */
foreach ($rules as $rule) {
- $array[$rule->action_value] = $array[$rule->action_value] ?? [];
+ $array[$rule->action_value] ??= [];
$array[$rule->action_value][] = ['id' => $rule->id, 'title' => $rule->title, 'active' => $rule->active];
}
$return = [];
@@ -431,36 +358,31 @@ class BillRepository implements BillRepositoryInterface
return $return;
}
- /**
- * @param Bill $bill
- * @param Carbon $date
- *
- * @return array
- */
public function getYearAverage(Bill $bill, Carbon $date): array
{
/** @var JournalRepositoryInterface $repos */
- $repos = app(JournalRepositoryInterface::class);
+ $repos = app(JournalRepositoryInterface::class);
$repos->setUser($this->user);
// get and sort on currency
- $result = [];
+ $result = [];
$journals = $bill->transactionJournals()
- ->where('date', '>=', $date->year . '-01-01 00:00:00')
- ->where('date', '<=', $date->year . '-12-31 23:59:59')
- ->get();
+ ->where('date', '>=', $date->year.'-01-01 00:00:00')
+ ->where('date', '<=', $date->year.'-12-31 23:59:59')
+ ->get()
+ ;
/** @var TransactionJournal $journal */
foreach ($journals as $journal) {
- /** @var Transaction $transaction */
- $transaction = $journal->transactions()->where('amount', '<', 0)->first();
+ /** @var null|Transaction $transaction */
+ $transaction = $journal->transactions()->where('amount', '<', 0)->first();
if (null === $transaction) {
continue;
}
$currencyId = (int)$journal->transaction_currency_id;
$currency = $journal->transactionCurrency;
- $result[$currencyId] = $result[$currencyId] ?? [
+ $result[$currencyId] ??= [
'sum' => '0',
'count' => 0,
'avg' => '0',
@@ -470,7 +392,7 @@ class BillRepository implements BillRepositoryInterface
'currency_decimal_places' => $currency->decimal_places,
];
$result[$currencyId]['sum'] = bcadd($result[$currencyId]['sum'], $transaction->amount);
- $result[$currencyId]['count']++;
+ ++$result[$currencyId]['count'];
}
// after loop, re-loop for avg.
@@ -487,9 +409,6 @@ class BillRepository implements BillRepositoryInterface
/**
* Link a set of journals to a bill.
- *
- * @param Bill $bill
- * @param array $transactions
*/
public function linkCollectionToBill(Bill $bill, array $transactions): void
{
@@ -498,22 +417,16 @@ class BillRepository implements BillRepositoryInterface
$journal = $bill->user->transactionJournals()->find((int)$transaction['transaction_journal_id']);
$journal->bill_id = $bill->id;
$journal->save();
- Log::debug(sprintf('Linked journal #%d to bill #%d', $journal->id, $bill->id));
+ app('log')->debug(sprintf('Linked journal #%d to bill #%d', $journal->id, $bill->id));
}
}
/**
* Given the date in $date, this method will return a moment in the future where the bill is expected to be paid.
- *
- * @param Bill $bill
- * @param Carbon $date
- *
- * @return Carbon
- * @throws JsonException
*/
public function nextExpectedMatch(Bill $bill, Carbon $date): Carbon
{
- $cache = new CacheProperties();
+ $cache = new CacheProperties();
$cache->addProperty($bill->id);
$cache->addProperty('nextExpectedMatch');
$cache->addProperty($date);
@@ -521,28 +434,28 @@ class BillRepository implements BillRepositoryInterface
return $cache->get();
}
// find the most recent date for this bill NOT in the future. Cache this date:
- $start = clone $bill->date;
- Log::debug('nextExpectedMatch: Start is ' . $start->format('Y-m-d'));
+ $start = clone $bill->date;
+ app('log')->debug('nextExpectedMatch: Start is '.$start->format('Y-m-d'));
while ($start < $date) {
- Log::debug(sprintf('$start (%s) < $date (%s)', $start->format('Y-m-d'), $date->format('Y-m-d')));
+ app('log')->debug(sprintf('$start (%s) < $date (%s)', $start->format('Y-m-d'), $date->format('Y-m-d')));
$start = app('navigation')->addPeriod($start, $bill->repeat_freq, $bill->skip);
- Log::debug('Start is now ' . $start->format('Y-m-d'));
+ app('log')->debug('Start is now '.$start->format('Y-m-d'));
}
- $end = app('navigation')->addPeriod($start, $bill->repeat_freq, $bill->skip);
+ $end = app('navigation')->addPeriod($start, $bill->repeat_freq, $bill->skip);
// see if the bill was paid in this period.
$journalCount = $bill->transactionJournals()->before($end)->after($start)->count();
if ($journalCount > 0) {
// this period had in fact a bill. The new start is the current end, and we create a new end.
- Log::debug(sprintf('Journal count is %d, so start becomes %s', $journalCount, $end->format('Y-m-d')));
+ app('log')->debug(sprintf('Journal count is %d, so start becomes %s', $journalCount, $end->format('Y-m-d')));
$start = clone $end;
$end = app('navigation')->addPeriod($start, $bill->repeat_freq, $bill->skip);
}
- Log::debug('nextExpectedMatch: Final start is ' . $start->format('Y-m-d'));
- Log::debug('nextExpectedMatch: Matching end is ' . $end->format('Y-m-d'));
+ app('log')->debug('nextExpectedMatch: Final start is '.$start->format('Y-m-d'));
+ app('log')->debug('nextExpectedMatch: Matching end is '.$end->format('Y-m-d'));
$cache->store($start);
@@ -550,11 +463,7 @@ class BillRepository implements BillRepositoryInterface
}
/**
- * @param array $data
- *
- * @return Bill
* @throws FireflyException
- * @throws JsonException
*/
public function store(array $data): Bill
{
@@ -565,9 +474,6 @@ class BillRepository implements BillRepositoryInterface
return $factory->create($data);
}
- /**
- * @inheritDoc
- */
public function removeObjectGroup(Bill $bill): Bill
{
$bill->objectGroups()->sync([]);
@@ -575,12 +481,6 @@ class BillRepository implements BillRepositoryInterface
return $bill;
}
- /**
- * @param string $query
- * @param int $limit
- *
- * @return Collection
- */
public function searchBill(string $query, int $limit): Collection
{
$query = sprintf('%%%s%%', $query);
@@ -588,9 +488,6 @@ class BillRepository implements BillRepositoryInterface
return $this->user->bills()->where('name', 'LIKE', $query)->take($limit)->get();
}
- /**
- * @inheritDoc
- */
public function setObjectGroup(Bill $bill, string $objectGroupTitle): Bill
{
$objectGroup = $this->findOrCreateObjectGroup($objectGroupTitle);
@@ -601,29 +498,24 @@ class BillRepository implements BillRepositoryInterface
return $bill;
}
- /**
- * @inheritDoc
- */
public function setOrder(Bill $bill, int $order): void
{
$bill->order = $order;
$bill->save();
}
- /**
- * @inheritDoc
- */
public function sumPaidInRange(Carbon $start, Carbon $end): array
{
$bills = $this->getActiveBills();
$return = [];
+
/** @var Bill $bill */
foreach ($bills as $bill) {
/** @var Collection $set */
$set = $bill->transactionJournals()->after($start)->before($end)->get(['transaction_journals.*']);
$currency = $bill->transactionCurrency;
- $return[$currency->id] = $return[$currency->id] ?? [
+ $return[$currency->id] ??= [
'id' => (string)$currency->id,
'name' => $currency->name,
'symbol' => $currency->symbol,
@@ -634,11 +526,11 @@ class BillRepository implements BillRepositoryInterface
/** @var TransactionJournal $transactionJournal */
foreach ($set as $transactionJournal) {
- /** @var Transaction|null $sourceTransaction */
+ /** @var null|Transaction $sourceTransaction */
$sourceTransaction = $transactionJournal->transactions()->where('amount', '<', 0)->first();
if (null !== $sourceTransaction) {
- $amount = (string)$sourceTransaction->amount;
- if ((int)$sourceTransaction->foreign_currency_id === (int)$currency->id) {
+ $amount = $sourceTransaction->amount;
+ if ((int)$sourceTransaction->foreign_currency_id === $currency->id) {
// use foreign amount instead!
$amount = (string)$sourceTransaction->foreign_amount;
}
@@ -646,41 +538,38 @@ class BillRepository implements BillRepositoryInterface
}
}
}
+
return $return;
}
- /**
- * @return Collection
- */
public function getActiveBills(): Collection
{
return $this->user->bills()
- ->where('active', true)
- ->orderBy('bills.name', 'ASC')
- ->get(['bills.*', DB::raw('((bills.amount_min + bills.amount_max) / 2) AS expectedAmount'),]);
+ ->where('active', true)
+ ->orderBy('bills.name', 'ASC')
+ ->get(['bills.*', \DB::raw('((bills.amount_min + bills.amount_max) / 2) AS expectedAmount')]) // @phpstan-ignore-line
+ ;
}
- /**
- * @inheritDoc
- */
public function sumUnpaidInRange(Carbon $start, Carbon $end): array
{
app('log')->debug(sprintf('Now in sumUnpaidInRange("%s", "%s")', $start->format('Y-m-d'), $end->format('Y-m-d')));
$bills = $this->getActiveBills();
$return = [];
+
/** @var Bill $bill */
foreach ($bills as $bill) {
- app('log')->debug(sprintf('Processing bill #%d ("%s")', $bill->id, $bill->name));
+ // app('log')->debug(sprintf('Processing bill #%d ("%s")', $bill->id, $bill->name));
$dates = $this->getPayDatesInRange($bill, $start, $end);
$count = $bill->transactionJournals()->after($start)->before($end)->count();
$total = $dates->count() - $count;
- app('log')->debug(sprintf('Pay dates: %d, count: %d, left: %d', $dates->count(), $count, $total));
- app('log')->debug('dates', $dates->toArray());
+ // app('log')->debug(sprintf('Pay dates: %d, count: %d, left: %d', $dates->count(), $count, $total));
+ // app('log')->debug('dates', $dates->toArray());
if ($total > 0) {
$currency = $bill->transactionCurrency;
$average = bcdiv(bcadd($bill->amount_max, $bill->amount_min), '2');
- $return[$currency->id] = $return[$currency->id] ?? [
+ $return[$currency->id] ??= [
'id' => (string)$currency->id,
'name' => $currency->name,
'symbol' => $currency->symbol,
@@ -697,34 +586,28 @@ class BillRepository implements BillRepositoryInterface
/**
* Between start and end, tells you on which date(s) the bill is expected to hit.
- *
- * @param Bill $bill
- * @param Carbon $start
- * @param Carbon $end
- *
- * @return Collection
*/
public function getPayDatesInRange(Bill $bill, Carbon $start, Carbon $end): Collection
{
$set = new Collection();
$currentStart = clone $start;
- //Log::debug(sprintf('Now at bill "%s" (%s)', $bill->name, $bill->repeat_freq));
- //Log::debug(sprintf('First currentstart is %s', $currentStart->format('Y-m-d')));
+ // app('log')->debug(sprintf('Now at bill "%s" (%s)', $bill->name, $bill->repeat_freq));
+ // app('log')->debug(sprintf('First currentstart is %s', $currentStart->format('Y-m-d')));
while ($currentStart <= $end) {
- //Log::debug(sprintf('Currentstart is now %s.', $currentStart->format('Y-m-d')));
+ // app('log')->debug(sprintf('Currentstart is now %s.', $currentStart->format('Y-m-d')));
$nextExpectedMatch = $this->nextDateMatch($bill, $currentStart);
- //Log::debug(sprintf('Next Date match after %s is %s', $currentStart->format('Y-m-d'), $nextExpectedMatch->format('Y-m-d')));
+ // app('log')->debug(sprintf('Next Date match after %s is %s', $currentStart->format('Y-m-d'), $nextExpectedMatch->format('Y-m-d')));
if ($nextExpectedMatch > $end) {// If nextExpectedMatch is after end, we continue
break;
}
$set->push(clone $nextExpectedMatch);
- //Log::debug(sprintf('Now %d dates in set.', $set->count()));
+ // app('log')->debug(sprintf('Now %d dates in set.', $set->count()));
$nextExpectedMatch->addDay();
- //Log::debug(sprintf('Currentstart (%s) has become %s.', $currentStart->format('Y-m-d'), $nextExpectedMatch->format('Y-m-d')));
+ // app('log')->debug(sprintf('Currentstart (%s) has become %s.', $currentStart->format('Y-m-d'), $nextExpectedMatch->format('Y-m-d')));
- $currentStart = clone $nextExpectedMatch;
+ $currentStart = clone $nextExpectedMatch;
}
return $set;
@@ -733,11 +616,6 @@ class BillRepository implements BillRepositoryInterface
/**
* Given a bill and a date, this method will tell you at which moment this bill expects its next
* transaction. Whether or not it is there already, is not relevant.
- *
- * @param Bill $bill
- * @param Carbon $date
- *
- * @return Carbon
*/
public function nextDateMatch(Bill $bill, Carbon $date): Carbon
{
@@ -759,21 +637,13 @@ class BillRepository implements BillRepositoryInterface
return $start;
}
- /**
- * @param Bill $bill
- */
public function unlinkAll(Bill $bill): void
{
$this->user->transactionJournals()->where('bill_id', $bill->id)->update(['bill_id' => null]);
}
/**
- * @param Bill $bill
- * @param array $data
- *
- * @return Bill
* @throws FireflyException
- * @throws JsonException
*/
public function update(Bill $bill, array $data): Bill
{
diff --git a/app/Repositories/Bill/BillRepositoryInterface.php b/app/Repositories/Bill/BillRepositoryInterface.php
index 6232bec837..c74467cc31 100644
--- a/app/Repositories/Bill/BillRepositoryInterface.php
+++ b/app/Repositories/Bill/BillRepositoryInterface.php
@@ -36,20 +36,8 @@ use Illuminate\Support\Collection;
*/
interface BillRepositoryInterface
{
- /**
- * @param string $query
- * @param int $limit
- *
- * @return Collection
- */
public function billEndsWith(string $query, int $limit): Collection;
- /**
- * @param string $query
- * @param int $limit
- *
- * @return Collection
- */
public function billStartsWith(string $query, int $limit): Collection;
/**
@@ -57,132 +45,62 @@ interface BillRepositoryInterface
*/
public function correctOrder(): void;
- /**
- * @param Bill $bill
- *
- * @return bool
- */
public function destroy(Bill $bill): bool;
- /**
- *
- */
public function destroyAll(): void;
/**
* Find a bill by ID.
- *
- * @param int $billId
- *
- * @return Bill|null
*/
public function find(int $billId): ?Bill;
/**
* Find bill by parameters.
- *
- * @param int|null $billId
- * @param string|null $billName
- *
- * @return Bill|null
*/
public function findBill(?int $billId, ?string $billName): ?Bill;
/**
* Find a bill by name.
- *
- * @param string $name
- *
- * @return Bill|null
*/
public function findByName(string $name): ?Bill;
- /**
- * @return Collection
- */
public function getActiveBills(): Collection;
/**
* Get all attachments.
- *
- * @param Bill $bill
- *
- * @return Collection
*/
public function getAttachments(Bill $bill): Collection;
- /**
- * @return Collection
- */
public function getBills(): Collection;
/**
* Gets the bills which have some kind of relevance to the accounts mentioned.
- *
- * @param Collection $accounts
- *
- * @return Collection
*/
public function getBillsForAccounts(Collection $accounts): Collection;
/**
* Get all bills with these ID's.
- *
- * @param array $billIds
- *
- * @return Collection
*/
public function getByIds(array $billIds): Collection;
/**
* Get text or return empty string.
- *
- * @param Bill $bill
- *
- * @return string
*/
public function getNoteText(Bill $bill): string;
- /**
- * @param Bill $bill
- *
- * @return array
- */
public function getOverallAverage(Bill $bill): array;
- /**
- * @param int $size
- *
- * @return LengthAwarePaginator
- */
public function getPaginator(int $size): LengthAwarePaginator;
- /**
- * @param Bill $bill
- * @param Carbon $start
- * @param Carbon $end
- *
- * @return Collection
- */
public function getPaidDatesInRange(Bill $bill, Carbon $start, Carbon $end): Collection;
/**
* Between start and end, tells you on which date(s) the bill is expected to hit.
- *
- * @param Bill $bill
- * @param Carbon $start
- * @param Carbon $end
- *
- * @return Collection
*/
public function getPayDatesInRange(Bill $bill, Carbon $start, Carbon $end): Collection;
/**
* Return all rules for one bill
- *
- * @param Bill $bill
- *
- * @return Collection
*/
public function getRulesForBill(Bill $bill): Collection;
@@ -191,122 +109,53 @@ interface BillRepositoryInterface
* 5= billid
*
* 5 => [['id' => 1, 'title' => 'Some rule'],['id' => 2, 'title' => 'Some other rule']]
- *
- * @param Collection $collection
- *
- * @return array
*/
public function getRulesForBills(Collection $collection): array;
- /**
- * @param Bill $bill
- * @param Carbon $date
- *
- * @return array
- */
public function getYearAverage(Bill $bill, Carbon $date): array;
/**
* Link a set of journals to a bill.
- *
- * @param Bill $bill
- * @param array $transactions
*/
public function linkCollectionToBill(Bill $bill, array $transactions): void;
/**
* Given a bill and a date, this method will tell you at which moment this bill expects its next
* transaction. Whether or not it is there already, is not relevant.
- *
- * @param Bill $bill
- * @param Carbon $date
- *
- * @return Carbon
*/
public function nextDateMatch(Bill $bill, Carbon $date): Carbon;
- /**
- * @param Bill $bill
- * @param Carbon $date
- *
- * @return Carbon
- */
public function nextExpectedMatch(Bill $bill, Carbon $date): Carbon;
- /**
- * @param Bill $bill
- *
- * @return Bill
- */
public function removeObjectGroup(Bill $bill): Bill;
- /**
- * @param string $query
- * @param int $limit
- *
- * @return Collection
- */
public function searchBill(string $query, int $limit): Collection;
- /**
- * @param Bill $bill
- * @param string $objectGroupTitle
- *
- * @return Bill
- */
public function setObjectGroup(Bill $bill, string $objectGroupTitle): Bill;
/**
* Set specific piggy bank to specific order.
- *
- * @param Bill $bill
- * @param int $order
*/
public function setOrder(Bill $bill, int $order): void;
- /**
- * @param User|Authenticatable|null $user
- */
- public function setUser(User | Authenticatable | null $user): void;
+ public function setUser(null|Authenticatable|User $user): void;
/**
- * @param array $data
- *
- * @return Bill
* @throws FireflyException
*/
public function store(array $data): Bill;
/**
* Collect multi-currency of sum of bills already paid.
- *
- * @param Carbon $start
- * @param Carbon $end
- *
- * @return array
*/
public function sumPaidInRange(Carbon $start, Carbon $end): array;
/**
* Collect multi-currency of sum of bills yet to pay.
- *
- * @param Carbon $start
- * @param Carbon $end
- *
- * @return array
*/
public function sumUnpaidInRange(Carbon $start, Carbon $end): array;
- /**
- * @param Bill $bill
- */
public function unlinkAll(Bill $bill): void;
- /**
- * @param Bill $bill
- * @param array $data
- *
- * @return Bill
- */
public function update(Bill $bill, array $data): Bill;
}
diff --git a/app/Repositories/Budget/AvailableBudgetRepository.php b/app/Repositories/Budget/AvailableBudgetRepository.php
index 86ef18f8c4..7aac372c31 100644
--- a/app/Repositories/Budget/AvailableBudgetRepository.php
+++ b/app/Repositories/Budget/AvailableBudgetRepository.php
@@ -30,27 +30,25 @@ use FireflyIII\User;
use Illuminate\Contracts\Auth\Authenticatable;
use Illuminate\Database\Eloquent\Builder;
use Illuminate\Support\Collection;
+use Illuminate\Support\Facades\Log;
/**
- *
* Class AvailableBudgetRepository
*/
class AvailableBudgetRepository implements AvailableBudgetRepositoryInterface
{
private User $user;
- /**
- * @inheritDoc
- */
public function cleanup(): void
{
$exists = [];
$availableBudgets = $this->user->availableBudgets()->get();
+
/** @var AvailableBudget $availableBudget */
foreach ($availableBudgets as $availableBudget) {
- $start = $availableBudget->start_date->format('Y-m-d');
- $end = $availableBudget->end_date->format('Y-m-d');
- $key = sprintf('%s-%s-%s', $availableBudget->transaction_currency_id, $start, $end);
+ $start = $availableBudget->start_date->format('Y-m-d');
+ $end = $availableBudget->end_date->format('Y-m-d');
+ $key = sprintf('%s-%s-%s', $availableBudget->transaction_currency_id, $start, $end);
if (array_key_exists($key, $exists)) {
app('log')->debug(sprintf('Found duplicate AB: %s %s, %s-%s. Has been deleted', $availableBudget->transaction_currency_id, $availableBudget->amount, $start, $end));
$availableBudget->delete();
@@ -61,18 +59,13 @@ class AvailableBudgetRepository implements AvailableBudgetRepositoryInterface
/**
* Return a list of all available budgets (in all currencies) (for the selected period).
- *
- * @param Carbon|null $start
- * @param Carbon|null $end
- *
- * @return Collection
*/
public function get(?Carbon $start = null, ?Carbon $end = null): Collection
{
$query = $this->user->availableBudgets()->with(['transactionCurrency']);
if (null !== $start && null !== $end) {
$query->where(
- static function (Builder $q1) use ($start, $end) {
+ static function (Builder $q1) use ($start, $end): void { // @phpstan-ignore-line
$q1->where('start_date', '=', $start->format('Y-m-d'));
$q1->where('end_date', '=', $end->format('Y-m-d'));
}
@@ -87,20 +80,15 @@ class AvailableBudgetRepository implements AvailableBudgetRepositoryInterface
*/
public function destroyAll(): void
{
+ Log::channel('audit')->info('Delete all available budgets through destroyAll');
$this->user->availableBudgets()->delete();
}
- /**
- * @param AvailableBudget $availableBudget
- */
public function destroyAvailableBudget(AvailableBudget $availableBudget): void
{
$availableBudget->delete();
}
- /**
- * @inheritDoc
- */
public function findById(int $id): ?AvailableBudget
{
return $this->user->availableBudgets->find($id);
@@ -108,55 +96,42 @@ class AvailableBudgetRepository implements AvailableBudgetRepositoryInterface
/**
* Find existing AB.
- *
- * @param TransactionCurrency $currency
- * @param Carbon $start
- * @param Carbon $end
- *
- * @return AvailableBudget|null
*/
public function find(TransactionCurrency $currency, Carbon $start, Carbon $end): ?AvailableBudget
{
return $this->user->availableBudgets()
- ->where('transaction_currency_id', $currency->id)
- ->where('start_date', $start->format('Y-m-d'))
- ->where('end_date', $end->format('Y-m-d'))
- ->first();
+ ->where('transaction_currency_id', $currency->id)
+ ->where('start_date', $start->format('Y-m-d'))
+ ->where('end_date', $end->format('Y-m-d'))
+ ->first()
+ ;
}
- /**
- * @param TransactionCurrency $currency
- * @param Carbon $start
- * @param Carbon $end
- *
- * @return string
- */
public function getAvailableBudget(TransactionCurrency $currency, Carbon $start, Carbon $end): string
{
$amount = '0';
+
+ /** @var null|AvailableBudget $availableBudget */
$availableBudget = $this->user->availableBudgets()
- ->where('transaction_currency_id', $currency->id)
- ->where('start_date', $start->format('Y-m-d'))
- ->where('end_date', $end->format('Y-m-d'))->first();
+ ->where('transaction_currency_id', $currency->id)
+ ->where('start_date', $start->format('Y-m-d'))
+ ->where('end_date', $end->format('Y-m-d'))->first()
+ ;
if (null !== $availableBudget) {
- $amount = (string)$availableBudget->amount;
+ $amount = $availableBudget->amount;
}
return $amount;
}
- /**
- * @param Carbon $start
- * @param Carbon $end
- *
- * @return array
- */
public function getAvailableBudgetWithCurrency(Carbon $start, Carbon $end): array
{
$return = [];
$availableBudgets = $this->user->availableBudgets()
- ->where('start_date', $start->format('Y-m-d'))
- ->where('end_date', $end->format('Y-m-d'))->get();
+ ->where('start_date', $start->format('Y-m-d'))
+ ->where('end_date', $end->format('Y-m-d'))->get()
+ ;
+
/** @var AvailableBudget $availableBudget */
foreach ($availableBudgets as $availableBudget) {
$return[$availableBudget->transaction_currency_id] = $availableBudget->amount;
@@ -167,10 +142,6 @@ class AvailableBudgetRepository implements AvailableBudgetRepositoryInterface
/**
* Returns all available budget objects.
- *
- * @param TransactionCurrency $currency
- *
- * @return Collection
*/
public function getAvailableBudgetsByCurrency(TransactionCurrency $currency): Collection
{
@@ -179,12 +150,6 @@ class AvailableBudgetRepository implements AvailableBudgetRepositoryInterface
/**
* Returns all available budget objects.
- *
- * @param Carbon|null $start
- * @param Carbon|null $end
- *
- * @return Collection
- *
*/
public function getAvailableBudgetsByDate(?Carbon $start, ?Carbon $end): Collection
{
@@ -202,54 +167,42 @@ class AvailableBudgetRepository implements AvailableBudgetRepositoryInterface
/**
* Returns all available budget objects.
- *
- * @param Carbon $start
- * @param Carbon $end
- *
- * @return Collection
- *
*/
public function getAvailableBudgetsByExactDate(Carbon $start, Carbon $end): Collection
{
return $this->user->availableBudgets()
- ->where('start_date', '=', $start->format('Y-m-d'))
- ->where('end_date', '=', $end->format('Y-m-d'))
- ->get();
+ ->where('start_date', '=', $start->format('Y-m-d'))
+ ->where('end_date', '=', $end->format('Y-m-d'))
+ ->get()
+ ;
}
- /**
- * @inheritDoc
- */
public function getByCurrencyDate(Carbon $start, Carbon $end, TransactionCurrency $currency): ?AvailableBudget
{
return $this->user
->availableBudgets()
->where('transaction_currency_id', $currency->id)
->where('start_date', $start->format('Y-m-d'))
- ->where('end_date', $end->format('Y-m-d'))->first();
+ ->where('end_date', $end->format('Y-m-d'))->first()
+ ;
}
/**
- * @param TransactionCurrency $currency
- * @param Carbon $start
- * @param Carbon $end
- * @param string $amount
- *
- * @return AvailableBudget
* @deprecated
*/
public function setAvailableBudget(TransactionCurrency $currency, Carbon $start, Carbon $end, string $amount): AvailableBudget
{
- $availableBudget = $this->user->availableBudgets()
- ->where('transaction_currency_id', $currency->id)
- ->where('start_date', $start->format('Y-m-d'))
- ->where('end_date', $end->format('Y-m-d'))->first();
+ $availableBudget = $this->user->availableBudgets()
+ ->where('transaction_currency_id', $currency->id)
+ ->where('start_date', $start->format('Y-m-d'))
+ ->where('end_date', $end->format('Y-m-d'))->first()
+ ;
if (null === $availableBudget) {
- $availableBudget = new AvailableBudget();
+ $availableBudget = new AvailableBudget();
$availableBudget->user()->associate($this->user);
$availableBudget->transactionCurrency()->associate($currency);
- $availableBudget->start_date = $start->format('Y-m-d');
- $availableBudget->end_date = $end->format('Y-m-d');
+ $availableBudget->start_date = $start->startOfDay()->format('Y-m-d'); // @phpstan-ignore-line
+ $availableBudget->end_date = $end->endOfDay()->format('Y-m-d'); // @phpstan-ignore-line
}
$availableBudget->amount = $amount;
$availableBudget->save();
@@ -257,28 +210,20 @@ class AvailableBudgetRepository implements AvailableBudgetRepositoryInterface
return $availableBudget;
}
- /**
- * @param User|Authenticatable|null $user
- */
- public function setUser(User | Authenticatable | null $user): void
+ public function setUser(null|Authenticatable|User $user): void
{
- if (null !== $user) {
+ if ($user instanceof User) {
$this->user = $user;
}
}
- /**
- * @param array $data
- *
- * @return AvailableBudget|null
- */
public function store(array $data): ?AvailableBudget
{
$start = $data['start'];
if ($start instanceof Carbon) {
$start = $data['start']->startOfDay();
}
- $end = $data['end'];
+ $end = $data['end'];
if ($end instanceof Carbon) {
$end = $data['end']->endOfDay();
}
@@ -289,19 +234,12 @@ class AvailableBudgetRepository implements AvailableBudgetRepositoryInterface
'user_group_id' => $this->user->user_group_id,
'transaction_currency_id' => $data['currency_id'],
'amount' => $data['amount'],
- 'start_date' => $start,
- 'end_date' => $end,
-
+ 'start_date' => $start->format('Y-m-d'),
+ 'end_date' => $end->format('Y-m-d'),
]
);
}
- /**
- * @param AvailableBudget $availableBudget
- * @param array $data
- *
- * @return AvailableBudget
- */
public function update(AvailableBudget $availableBudget, array $data): AvailableBudget
{
if (array_key_exists('amount', $data)) {
@@ -312,19 +250,13 @@ class AvailableBudgetRepository implements AvailableBudgetRepositoryInterface
return $availableBudget;
}
- /**
- * @param AvailableBudget $availableBudget
- * @param array $data
- *
- * @return AvailableBudget
- */
public function updateAvailableBudget(AvailableBudget $availableBudget, array $data): AvailableBudget
{
if (array_key_exists('start', $data)) {
$start = $data['start'];
if ($start instanceof Carbon) {
$start = $data['start']->startOfDay();
- $availableBudget->start_date = $start;
+ $availableBudget->start_date = $start->format('Y-m-d');
$availableBudget->save();
}
}
@@ -333,7 +265,7 @@ class AvailableBudgetRepository implements AvailableBudgetRepositoryInterface
$end = $data['end'];
if ($end instanceof Carbon) {
$end = $data['end']->endOfDay();
- $availableBudget->end_date = $end;
+ $availableBudget->end_date = $end->format('Y-m-d');
$availableBudget->save();
}
}
diff --git a/app/Repositories/Budget/AvailableBudgetRepositoryInterface.php b/app/Repositories/Budget/AvailableBudgetRepositoryInterface.php
index fd2c004e6e..80a23307cf 100644
--- a/app/Repositories/Budget/AvailableBudgetRepositoryInterface.php
+++ b/app/Repositories/Budget/AvailableBudgetRepositoryInterface.php
@@ -35,9 +35,6 @@ use Illuminate\Support\Collection;
*/
interface AvailableBudgetRepositoryInterface
{
- /**
- * @return void
- */
public function cleanup(): void;
/**
@@ -45,132 +42,54 @@ interface AvailableBudgetRepositoryInterface
*/
public function destroyAll(): void;
- /**
- * @param AvailableBudget $availableBudget
- */
public function destroyAvailableBudget(AvailableBudget $availableBudget): void;
/**
* Find existing AB.
- *
- * @param TransactionCurrency $currency
- * @param Carbon $start
- * @param Carbon $end
- *
- * @return AvailableBudget|null
*/
public function find(TransactionCurrency $currency, Carbon $start, Carbon $end): ?AvailableBudget;
- /**
- * @param int $id
- *
- * @return AvailableBudget|null
- */
public function findById(int $id): ?AvailableBudget;
/**
* Return a list of all available budgets (in all currencies) (for the selected period).
- *
- * @param Carbon|null $start
- * @param Carbon|null $end
- *
- * @return Collection
*/
public function get(?Carbon $start = null, ?Carbon $end = null): Collection;
/**
- * @param TransactionCurrency $currency
- * @param Carbon $start
- * @param Carbon $end
- *
- * @return string
* @deprecated
*/
public function getAvailableBudget(TransactionCurrency $currency, Carbon $start, Carbon $end): string;
- /**
- * @param Carbon $start
- * @param Carbon $end
- *
- * @return array
- */
public function getAvailableBudgetWithCurrency(Carbon $start, Carbon $end): array;
/**
* Returns all available budget objects.
- *
- * @param TransactionCurrency $currency
- *
- * @return Collection
*/
public function getAvailableBudgetsByCurrency(TransactionCurrency $currency): Collection;
/**
* Returns all available budget objects.
- *
- * @param Carbon|null $start
- * @param Carbon|null $end
- *
- * @return Collection
- *
*/
public function getAvailableBudgetsByDate(?Carbon $start, ?Carbon $end): Collection;
- /**
- * @param Carbon $start
- * @param Carbon $end
- *
- * @return Collection
- */
public function getAvailableBudgetsByExactDate(Carbon $start, Carbon $end): Collection;
/**
* Get by transaction currency and date. Should always result in one entry or NULL.
- *
- * @param Carbon $start
- * @param Carbon $end
- * @param TransactionCurrency $currency
- *
- * @return null|AvailableBudget
*/
public function getByCurrencyDate(Carbon $start, Carbon $end, TransactionCurrency $currency): ?AvailableBudget;
/**
- * @param TransactionCurrency $currency
- * @param Carbon $start
- * @param Carbon $end
- * @param string $amount
- *
- * @return AvailableBudget
* @deprecated
*/
public function setAvailableBudget(TransactionCurrency $currency, Carbon $start, Carbon $end, string $amount): AvailableBudget;
- /**
- * @param User|Authenticatable|null $user
- */
- public function setUser(User | Authenticatable | null $user): void;
+ public function setUser(null|Authenticatable|User $user): void;
- /**
- * @param array $data
- *
- * @return AvailableBudget|null
- */
public function store(array $data): ?AvailableBudget;
- /**
- * @param AvailableBudget $availableBudget
- * @param array $data
- *
- * @return AvailableBudget
- */
public function update(AvailableBudget $availableBudget, array $data): AvailableBudget;
- /**
- * @param AvailableBudget $availableBudget
- * @param array $data
- *
- * @return AvailableBudget
- */
public function updateAvailableBudget(AvailableBudget $availableBudget, array $data): AvailableBudget;
}
diff --git a/app/Repositories/Budget/BudgetLimitRepository.php b/app/Repositories/Budget/BudgetLimitRepository.php
index 23c41a4c1d..0975c9f943 100644
--- a/app/Repositories/Budget/BudgetLimitRepository.php
+++ b/app/Repositories/Budget/BudgetLimitRepository.php
@@ -34,10 +34,8 @@ use Illuminate\Contracts\Auth\Authenticatable;
use Illuminate\Database\Eloquent\Builder;
use Illuminate\Support\Collection;
use Illuminate\Support\Facades\Log;
-use JsonException;
/**
- *
* Class BudgetLimitRepository
*/
class BudgetLimitRepository implements BudgetLimitRepositoryInterface
@@ -47,56 +45,53 @@ class BudgetLimitRepository implements BudgetLimitRepositoryInterface
/**
* Tells you which amount has been budgeted (for the given budgets)
* in the selected query. Returns a positive amount as a string.
- *
- * @param Carbon $start
- * @param Carbon $end
- * @param TransactionCurrency $currency
- * @param Collection|null $budgets
- *
- * @return string
*/
public function budgeted(Carbon $start, Carbon $end, TransactionCurrency $currency, ?Collection $budgets = null): string
{
- $query = BudgetLimit::leftJoin('budgets', 'budgets.id', '=', 'budget_limits.budget_id')
+ $query = BudgetLimit::leftJoin('budgets', 'budgets.id', '=', 'budget_limits.budget_id')
// same complex where query as below.
- ->where(
- static function (Builder $q5) use ($start, $end) {
- $q5->where(
- static function (Builder $q1) use ($start, $end) {
- $q1->where(
- static function (Builder $q2) use ($start, $end) {
- $q2->where('budget_limits.end_date', '>=', $start->format('Y-m-d'));
- $q2->where('budget_limits.end_date', '<=', $end->format('Y-m-d'));
- }
- )
- ->orWhere(
- static function (Builder $q3) use ($start, $end) {
- $q3->where('budget_limits.start_date', '>=', $start->format('Y-m-d'));
- $q3->where('budget_limits.start_date', '<=', $end->format('Y-m-d'));
- }
- );
- }
- )
- ->orWhere(
- static function (Builder $q4) use ($start, $end) {
- // or start is before start AND end is after end.
- $q4->where('budget_limits.start_date', '<=', $start->format('Y-m-d'));
- $q4->where('budget_limits.end_date', '>=', $end->format('Y-m-d'));
- }
- );
+ ->where(
+ static function (Builder $q5) use ($start, $end): void {
+ $q5->where(
+ static function (Builder $q1) use ($start, $end): void {
+ $q1->where(
+ static function (Builder $q2) use ($start, $end): void {
+ $q2->where('budget_limits.end_date', '>=', $start->format('Y-m-d'));
+ $q2->where('budget_limits.end_date', '<=', $end->format('Y-m-d'));
}
)
- ->where('budget_limits.transaction_currency_id', $currency->id)
- ->whereNull('budgets.deleted_at')
- ->where('budgets.active', true)
- ->where('budgets.user_id', $this->user->id);
+ ->orWhere(
+ static function (Builder $q3) use ($start, $end): void {
+ $q3->where('budget_limits.start_date', '>=', $start->format('Y-m-d'));
+ $q3->where('budget_limits.start_date', '<=', $end->format('Y-m-d'));
+ }
+ )
+ ;
+ }
+ )
+ ->orWhere(
+ static function (Builder $q4) use ($start, $end): void {
+ // or start is before start AND end is after end.
+ $q4->where('budget_limits.start_date', '<=', $start->format('Y-m-d'));
+ $q4->where('budget_limits.end_date', '>=', $end->format('Y-m-d'));
+ }
+ )
+ ;
+ }
+ )
+ ->where('budget_limits.transaction_currency_id', $currency->id)
+ ->whereNull('budgets.deleted_at')
+ ->where('budgets.active', true)
+ ->where('budgets.user_id', $this->user->id)
+ ;
if (null !== $budgets && $budgets->count() > 0) {
$query->whereIn('budget_limits.budget_id', $budgets->pluck('id')->toArray());
}
$set = $query->get(['budget_limits.*']);
$result = '0';
+
/** @var BudgetLimit $budgetLimit */
foreach ($set as $budgetLimit) {
$result = bcadd($budgetLimit->amount, $result);
@@ -111,29 +106,22 @@ class BudgetLimitRepository implements BudgetLimitRepositoryInterface
public function destroyAll(): void
{
$budgets = $this->user->budgets()->get();
+
/** @var Budget $budget */
foreach ($budgets as $budget) {
+ Log::channel('audit')->info(sprintf('Delete all budget limits of budget #%d ("%s") through destroyAll', $budget->id, $budget->name));
$budget->budgetlimits()->delete();
}
}
/**
* Destroy a budget limit.
- *
- * @param BudgetLimit $budgetLimit
*/
public function destroyBudgetLimit(BudgetLimit $budgetLimit): void
{
$budgetLimit->delete();
}
- /**
- * @param TransactionCurrency $currency
- * @param Carbon|null $start
- * @param Carbon|null $end
- *
- * @return Collection
- */
public function getAllBudgetLimitsByCurrency(TransactionCurrency $currency, Carbon $start = null, Carbon $end = null): Collection
{
return $this->getAllBudgetLimits($start, $end)->filter(
@@ -143,28 +131,24 @@ class BudgetLimitRepository implements BudgetLimitRepositoryInterface
);
}
- /**
- * @param Carbon|null $start
- * @param Carbon|null $end
- *
- * @return Collection
- */
public function getAllBudgetLimits(Carbon $start = null, Carbon $end = null): Collection
{
// both are NULL:
if (null === $start && null === $end) {
return BudgetLimit::leftJoin('budgets', 'budgets.id', '=', 'budget_limits.budget_id')
- ->with(['budget'])
- ->where('budgets.user_id', $this->user->id)
- ->whereNull('budgets.deleted_at')
- ->get(['budget_limits.*']);
+ ->with(['budget'])
+ ->where('budgets.user_id', $this->user->id)
+ ->whereNull('budgets.deleted_at')
+ ->get(['budget_limits.*'])
+ ;
}
// one of the two is NULL.
if (null === $start xor null === $end) {
$query = BudgetLimit::leftJoin('budgets', 'budgets.id', '=', 'budget_limits.budget_id')
- ->with(['budget'])
- ->whereNull('budgets.deleted_at')
- ->where('budgets.user_id', $this->user->id);
+ ->with(['budget'])
+ ->whereNull('budgets.deleted_at')
+ ->where('budgets.user_id', $this->user->id)
+ ;
if (null !== $end) {
// end date must be before $end.
$query->where('end_date', '<=', $end->format('Y-m-d 00:00:00'));
@@ -179,45 +163,41 @@ class BudgetLimitRepository implements BudgetLimitRepositoryInterface
// neither are NULL:
return BudgetLimit::leftJoin('budgets', 'budgets.id', '=', 'budget_limits.budget_id')
- ->with(['budget'])
- ->where('budgets.user_id', $this->user->id)
- ->whereNull('budgets.deleted_at')
- ->where(
- static function (Builder $q5) use ($start, $end) {
- $q5->where(
- static function (Builder $q1) use ($start, $end) {
- $q1->where(
- static function (Builder $q2) use ($start, $end) {
- $q2->where('budget_limits.end_date', '>=', $start->format('Y-m-d'));
- $q2->where('budget_limits.end_date', '<=', $end->format('Y-m-d'));
- }
- )
- ->orWhere(
- static function (Builder $q3) use ($start, $end) {
- $q3->where('budget_limits.start_date', '>=', $start->format('Y-m-d'));
- $q3->where('budget_limits.start_date', '<=', $end->format('Y-m-d'));
- }
- );
- }
- )
- ->orWhere(
- static function (Builder $q4) use ($start, $end) {
- // or start is before start AND end is after end.
- $q4->where('budget_limits.start_date', '<=', $start->format('Y-m-d'));
- $q4->where('budget_limits.end_date', '>=', $end->format('Y-m-d'));
- }
- );
- }
- )->get(['budget_limits.*']);
+ ->with(['budget'])
+ ->where('budgets.user_id', $this->user->id)
+ ->whereNull('budgets.deleted_at')
+ ->where(
+ static function (Builder $q5) use ($start, $end): void {
+ $q5->where(
+ static function (Builder $q1) use ($start, $end): void {
+ $q1->where(
+ static function (Builder $q2) use ($start, $end): void {
+ $q2->where('budget_limits.end_date', '>=', $start->format('Y-m-d'));
+ $q2->where('budget_limits.end_date', '<=', $end->format('Y-m-d'));
+ }
+ )
+ ->orWhere(
+ static function (Builder $q3) use ($start, $end): void {
+ $q3->where('budget_limits.start_date', '>=', $start->format('Y-m-d'));
+ $q3->where('budget_limits.start_date', '<=', $end->format('Y-m-d'));
+ }
+ )
+ ;
+ }
+ )
+ ->orWhere(
+ static function (Builder $q4) use ($start, $end): void {
+ // or start is before start AND end is after end.
+ $q4->where('budget_limits.start_date', '<=', $start->format('Y-m-d'));
+ $q4->where('budget_limits.end_date', '>=', $end->format('Y-m-d'));
+ }
+ )
+ ;
+ }
+ )->get(['budget_limits.*'])
+ ;
}
- /**
- * @param Budget $budget
- * @param Carbon|null $start
- * @param Carbon|null $end
- *
- * @return Collection
- */
public function getBudgetLimits(Budget $budget, Carbon $start = null, Carbon $end = null): Collection
{
if (null === $end && null === $start) {
@@ -240,129 +220,114 @@ class BudgetLimitRepository implements BudgetLimitRepositoryInterface
// when both dates are set:
return $budget->budgetlimits()
- ->where(
- static function (Builder $q5) use ($start, $end) {
- $q5->where(
- static function (Builder $q1) use ($start, $end) {
- // budget limit ends within period
- $q1->where(
- static function (Builder $q2) use ($start, $end) {
- $q2->where('budget_limits.end_date', '>=', $start->format('Y-m-d 00:00:00'));
- $q2->where('budget_limits.end_date', '<=', $end->format('Y-m-d 23:59:59'));
- }
- )
- // budget limit start within period
- ->orWhere(
- static function (Builder $q3) use ($start, $end) {
- $q3->where('budget_limits.start_date', '>=', $start->format('Y-m-d 00:00:00'));
- $q3->where('budget_limits.start_date', '<=', $end->format('Y-m-d 23:59:59'));
- }
- );
- }
- )
- ->orWhere(
- static function (Builder $q4) use ($start, $end) {
- // or start is before start AND end is after end.
- $q4->where('budget_limits.start_date', '<=', $start->format('Y-m-d 23:59:59'));
- $q4->where('budget_limits.end_date', '>=', $end->format('Y-m-d 00:00:00'));
- }
- );
- }
- )->orderBy('budget_limits.start_date', 'DESC')->get(['budget_limits.*']);
+ ->where(
+ static function (Builder $q5) use ($start, $end): void { // @phpstan-ignore-line
+ $q5->where(
+ static function (Builder $q1) use ($start, $end): void {
+ // budget limit ends within period
+ $q1->where(
+ static function (Builder $q2) use ($start, $end): void {
+ $q2->where('budget_limits.end_date', '>=', $start->format('Y-m-d 00:00:00'));
+ $q2->where('budget_limits.end_date', '<=', $end->format('Y-m-d 23:59:59'));
+ }
+ )
+ // budget limit start within period
+ ->orWhere(
+ static function (Builder $q3) use ($start, $end): void {
+ $q3->where('budget_limits.start_date', '>=', $start->format('Y-m-d 00:00:00'));
+ $q3->where('budget_limits.start_date', '<=', $end->format('Y-m-d 23:59:59'));
+ }
+ )
+ ;
+ }
+ )
+ ->orWhere(
+ static function (Builder $q4) use ($start, $end): void {
+ // or start is before start AND end is after end.
+ $q4->where('budget_limits.start_date', '<=', $start->format('Y-m-d 23:59:59'));
+ $q4->where('budget_limits.end_date', '>=', $end->format('Y-m-d 00:00:00'));
+ }
+ )
+ ;
+ }
+ )->orderBy('budget_limits.start_date', 'DESC')->get(['budget_limits.*'])
+ ;
}
- /**
- * @param User|Authenticatable|null $user
- */
- public function setUser(User | Authenticatable | null $user): void
+ public function setUser(null|Authenticatable|User $user): void
{
- if (null !== $user) {
+ if ($user instanceof User) {
$this->user = $user;
}
}
/**
- * @param array $data
- *
- * @return BudgetLimit
* @throws FireflyException
- * @throws JsonException
*/
public function store(array $data): BudgetLimit
{
// if no currency has been provided, use the user's default currency:
/** @var TransactionCurrencyFactory $factory */
- $factory = app(TransactionCurrencyFactory::class);
- $currency = $factory->find($data['currency_id'] ?? null, $data['currency_code'] ?? null);
+ $factory = app(TransactionCurrencyFactory::class);
+ $currency = $factory->find($data['currency_id'] ?? null, $data['currency_code'] ?? null);
if (null === $currency) {
- $currency = app('amount')->getDefaultCurrencyByUser($this->user);
+ $currency = app('amount')->getDefaultCurrencyByUserGroup($this->user->userGroup);
}
- $currency->enabled = true;
+ $currency->enabled = true;
$currency->save();
// find the budget:
- $budget = $this->user->budgets()->find((int)$data['budget_id']);
+ $budget = $this->user->budgets()->find((int)$data['budget_id']);
if (null === $budget) {
throw new FireflyException('200004: Budget does not exist.');
}
// find limit with same date range and currency.
- $limit = $budget->budgetlimits()
- ->where('budget_limits.start_date', $data['start_date']->format('Y-m-d'))
- ->where('budget_limits.end_date', $data['end_date']->format('Y-m-d'))
- ->where('budget_limits.transaction_currency_id', $currency->id)
- ->first(['budget_limits.*']);
+ $limit = $budget->budgetlimits()
+ ->where('budget_limits.start_date', $data['start_date']->format('Y-m-d'))
+ ->where('budget_limits.end_date', $data['end_date']->format('Y-m-d'))
+ ->where('budget_limits.transaction_currency_id', $currency->id)
+ ->first(['budget_limits.*'])
+ ;
if (null !== $limit) {
throw new FireflyException('200027: Budget limit already exists.');
}
- Log::debug('No existing budget limit, create a new one');
+ app('log')->debug('No existing budget limit, create a new one');
// or create one and return it.
- $limit = new BudgetLimit();
+ $limit = new BudgetLimit();
$limit->budget()->associate($budget);
$limit->start_date = $data['start_date']->format('Y-m-d');
$limit->end_date = $data['end_date']->format('Y-m-d');
$limit->amount = $data['amount'];
$limit->transaction_currency_id = $currency->id;
$limit->save();
- Log::debug(sprintf('Created new budget limit with ID #%d and amount %s', $limit->id, $data['amount']));
+ app('log')->debug(sprintf('Created new budget limit with ID #%d and amount %s', $limit->id, $data['amount']));
return $limit;
}
- /**
- * @param Budget $budget
- * @param TransactionCurrency $currency
- * @param Carbon $start
- * @param Carbon $end
- *
- * @return BudgetLimit|null
- */
public function find(Budget $budget, TransactionCurrency $currency, Carbon $start, Carbon $end): ?BudgetLimit
{
return $budget->budgetlimits()
- ->where('transaction_currency_id', $currency->id)
- ->where('start_date', $start->format('Y-m-d'))
- ->where('end_date', $end->format('Y-m-d'))->first();
+ ->where('transaction_currency_id', $currency->id)
+ ->where('start_date', $start->format('Y-m-d'))
+ ->where('end_date', $end->format('Y-m-d'))->first()
+ ;
}
/**
- * @param BudgetLimit $budgetLimit
- * @param array $data
- *
- * @return BudgetLimit
* @throws FireflyException
- * @throws JsonException
*/
public function update(BudgetLimit $budgetLimit, array $data): BudgetLimit
{
- $budgetLimit->amount = array_key_exists('amount', $data) ? $data['amount'] : $budgetLimit->amount;
- $budgetLimit->budget_id = array_key_exists('budget_id', $data) ? $data['budget_id'] : $budgetLimit->budget_id;
- $budgetLimit->start_date = array_key_exists('start', $data) ? $data['start']->format('Y-m-d 00:00:00') : $budgetLimit->start_date;
- $budgetLimit->end_date = array_key_exists('end', $data) ? $data['end']->format('Y-m-d 23:59:59') : $budgetLimit->end_date;
+ $budgetLimit->amount = array_key_exists('amount', $data) ? $data['amount'] : $budgetLimit->amount;
+ $budgetLimit->budget_id = array_key_exists('budget_id', $data) ? $data['budget_id'] : $budgetLimit->budget_id;
+ $budgetLimit->start_date = array_key_exists('start', $data) ? $data['start']->format('Y-m-d 00:00:00') : $budgetLimit->start_date;
+ $budgetLimit->end_date = array_key_exists('end', $data) ? $data['end']->format('Y-m-d 23:59:59') : $budgetLimit->end_date;
// if no currency has been provided, use the user's default currency:
- $currency = null;
+ $currency = null;
// update if relevant:
if (array_key_exists('currency_id', $data) || array_key_exists('currency_code', $data)) {
@@ -372,9 +337,9 @@ class BudgetLimitRepository implements BudgetLimitRepositoryInterface
}
// catch unexpected null:
if (null === $currency) {
- $currency = $budgetLimit->transactionCurrency ?? app('amount')->getDefaultCurrencyByUser($this->user);
+ $currency = $budgetLimit->transactionCurrency ?? app('amount')->getDefaultCurrencyByUserGroup($this->user->userGroup);
}
- $currency->enabled = true;
+ $currency->enabled = true;
$currency->save();
$budgetLimit->transaction_currency_id = $currency->id;
@@ -383,66 +348,60 @@ class BudgetLimitRepository implements BudgetLimitRepositoryInterface
return $budgetLimit;
}
- /**
- * @param Budget $budget
- * @param Carbon $start
- * @param Carbon $end
- * @param string $amount
- *
- * @return BudgetLimit|null
- *
- */
public function updateLimitAmount(Budget $budget, Carbon $start, Carbon $end, string $amount): ?BudgetLimit
{
// count the limits:
- $limits = $budget->budgetlimits()
- ->where('budget_limits.start_date', $start->format('Y-m-d 00:00:00'))
- ->where('budget_limits.end_date', $end->format('Y-m-d 00:00:00'))
- ->count(['budget_limits.*']);
- Log::debug(sprintf('Found %d budget limits.', $limits));
+ $limits = $budget->budgetlimits()
+ ->where('budget_limits.start_date', $start->format('Y-m-d 00:00:00'))
+ ->where('budget_limits.end_date', $end->format('Y-m-d 00:00:00'))
+ ->count('budget_limits.*')
+ ;
+ app('log')->debug(sprintf('Found %d budget limits.', $limits));
// there might be a budget limit for these dates:
- /** @var BudgetLimit $limit */
- $limit = $budget->budgetlimits()
- ->where('budget_limits.start_date', $start->format('Y-m-d 00:00:00'))
- ->where('budget_limits.end_date', $end->format('Y-m-d 00:00:00'))
- ->first(['budget_limits.*']);
+ /** @var null|BudgetLimit $limit */
+ $limit = $budget->budgetlimits()
+ ->where('budget_limits.start_date', $start->format('Y-m-d 00:00:00'))
+ ->where('budget_limits.end_date', $end->format('Y-m-d 00:00:00'))
+ ->first(['budget_limits.*'])
+ ;
// if more than 1 limit found, delete the others:
if ($limits > 1 && null !== $limit) {
- Log::debug(sprintf('Found more than 1, delete all except #%d', $limit->id));
+ app('log')->debug(sprintf('Found more than 1, delete all except #%d', $limit->id));
$budget->budgetlimits()
- ->where('budget_limits.start_date', $start->format('Y-m-d 00:00:00'))
- ->where('budget_limits.end_date', $end->format('Y-m-d 00:00:00'))
- ->where('budget_limits.id', '!=', $limit->id)->delete();
+ ->where('budget_limits.start_date', $start->format('Y-m-d 00:00:00'))
+ ->where('budget_limits.end_date', $end->format('Y-m-d 00:00:00'))
+ ->where('budget_limits.id', '!=', $limit->id)->delete()
+ ;
}
// delete if amount is zero.
// Returns 0 if the two operands are equal,
// 1 if the left_operand is larger than the right_operand, -1 otherwise.
if (null !== $limit && bccomp($amount, '0') <= 0) {
- Log::debug(sprintf('%s is zero, delete budget limit #%d', $amount, $limit->id));
+ app('log')->debug(sprintf('%s is zero, delete budget limit #%d', $amount, $limit->id));
$limit->delete();
return null;
}
// update if exists:
if (null !== $limit) {
- Log::debug(sprintf('Existing budget limit is #%d, update this to amount %s', $limit->id, $amount));
+ app('log')->debug(sprintf('Existing budget limit is #%d, update this to amount %s', $limit->id, $amount));
$limit->amount = $amount;
$limit->save();
return $limit;
}
- Log::debug('No existing budget limit, create a new one');
+ app('log')->debug('No existing budget limit, create a new one');
// or create one and return it.
- $limit = new BudgetLimit();
+ $limit = new BudgetLimit();
$limit->budget()->associate($budget);
$limit->start_date = $start->startOfDay();
$limit->end_date = $end->startOfDay();
$limit->amount = $amount;
$limit->save();
- Log::debug(sprintf('Created new budget limit with ID #%d and amount %s', $limit->id, $amount));
+ app('log')->debug(sprintf('Created new budget limit with ID #%d and amount %s', $limit->id, $amount));
return $limit;
}
diff --git a/app/Repositories/Budget/BudgetLimitRepositoryInterface.php b/app/Repositories/Budget/BudgetLimitRepositoryInterface.php
index 7ddd85cadf..eaee27707b 100644
--- a/app/Repositories/Budget/BudgetLimitRepositoryInterface.php
+++ b/app/Repositories/Budget/BudgetLimitRepositoryInterface.php
@@ -39,13 +39,6 @@ interface BudgetLimitRepositoryInterface
/**
* Tells you which amount has been budgeted (for the given budgets)
* in the selected query. Returns a positive amount as a string.
- *
- * @param Carbon $start
- * @param Carbon $end
- * @param TransactionCurrency $currency
- * @param Collection|null $budgets
- *
- * @return string
*/
public function budgeted(Carbon $start, Carbon $end, TransactionCurrency $currency, ?Collection $budgets = null): string;
@@ -56,76 +49,25 @@ interface BudgetLimitRepositoryInterface
/**
* Destroy a budget limit.
- *
- * @param BudgetLimit $budgetLimit
*/
public function destroyBudgetLimit(BudgetLimit $budgetLimit): void;
- /**
- * @param Budget $budget
- * @param TransactionCurrency $currency
- * @param Carbon $start
- * @param Carbon $end
- *
- * @return BudgetLimit|null
- */
public function find(Budget $budget, TransactionCurrency $currency, Carbon $start, Carbon $end): ?BudgetLimit;
/**
* TODO this method is not multi currency aware.
- *
- * @param Carbon|null $start
- * @param Carbon|null $end
- *
- * @return Collection
*/
public function getAllBudgetLimits(Carbon $start = null, Carbon $end = null): Collection;
- /**
- * @param TransactionCurrency $currency
- * @param Carbon|null $start
- * @param Carbon|null $end
- *
- * @return Collection
- */
public function getAllBudgetLimitsByCurrency(TransactionCurrency $currency, Carbon $start = null, Carbon $end = null): Collection;
- /**
- * @param Budget $budget
- * @param Carbon|null $start
- * @param Carbon|null $end
- *
- * @return Collection
- */
public function getBudgetLimits(Budget $budget, Carbon $start = null, Carbon $end = null): Collection;
- /**
- * @param User|Authenticatable|null $user
- */
- public function setUser(User | Authenticatable | null $user): void;
+ public function setUser(null|Authenticatable|User $user): void;
- /**
- * @param array $data
- *
- * @return BudgetLimit
- */
public function store(array $data): BudgetLimit;
- /**
- * @param BudgetLimit $budgetLimit
- * @param array $data
- *
- * @return BudgetLimit
- */
public function update(BudgetLimit $budgetLimit, array $data): BudgetLimit;
- /**
- * @param Budget $budget
- * @param Carbon $start
- * @param Carbon $end
- * @param string $amount
- *
- * @return BudgetLimit|null
- */
public function updateLimitAmount(Budget $budget, Carbon $start, Carbon $end, string $amount): ?BudgetLimit;
}
diff --git a/app/Repositories/Budget/BudgetRepository.php b/app/Repositories/Budget/BudgetRepository.php
index 7c3ae8dd94..6f8fcf45b5 100644
--- a/app/Repositories/Budget/BudgetRepository.php
+++ b/app/Repositories/Budget/BudgetRepository.php
@@ -24,7 +24,6 @@ declare(strict_types=1);
namespace FireflyIII\Repositories\Budget;
use Carbon\Carbon;
-use DB;
use FireflyIII\Exceptions\FireflyException;
use FireflyIII\Helpers\Collector\GroupCollectorInterface;
use FireflyIII\Models\Account;
@@ -38,27 +37,22 @@ use FireflyIII\Models\RuleAction;
use FireflyIII\Models\RuleTrigger;
use FireflyIII\Models\TransactionType;
use FireflyIII\Repositories\Account\AccountRepositoryInterface;
-use FireflyIII\Repositories\Currency\CurrencyRepositoryInterface;
+use FireflyIII\Repositories\UserGroups\Currency\CurrencyRepositoryInterface;
use FireflyIII\Services\Internal\Destroy\BudgetDestroyService;
+use FireflyIII\Support\Http\Api\ExchangeRateConverter;
use FireflyIII\User;
use Illuminate\Contracts\Auth\Authenticatable;
use Illuminate\Database\QueryException;
use Illuminate\Support\Collection;
use Illuminate\Support\Facades\Log;
-use JsonException;
-use Storage;
/**
* Class BudgetRepository.
- *
*/
class BudgetRepository implements BudgetRepositoryInterface
{
private User $user;
- /**
- * @inheritDoc
- */
public function budgetEndsWith(string $query, int $limit): Collection
{
$search = $this->user->budgets();
@@ -66,14 +60,12 @@ class BudgetRepository implements BudgetRepositoryInterface
$search->where('name', 'LIKE', sprintf('%%%s', $query));
}
$search->orderBy('order', 'ASC')
- ->orderBy('name', 'ASC')->where('active', true);
+ ->orderBy('name', 'ASC')->where('active', true)
+ ;
return $search->take($limit)->get();
}
- /**
- * @inheritDoc
- */
public function budgetStartsWith(string $query, int $limit): Collection
{
$search = $this->user->budgets();
@@ -81,58 +73,74 @@ class BudgetRepository implements BudgetRepositoryInterface
$search->where('name', 'LIKE', sprintf('%s%%', $query));
}
$search->orderBy('order', 'ASC')
- ->orderBy('name', 'ASC')->where('active', true);
+ ->orderBy('name', 'ASC')->where('active', true)
+ ;
return $search->take($limit)->get();
}
- /**
- * @inheritDoc
- */
public function budgetedInPeriod(Carbon $start, Carbon $end): array
{
- Log::debug(sprintf('Now in budgetedInPeriod("%s", "%s")', $start->format('Y-m-d'), $end->format('Y-m-d')));
- $return = [];
+ app('log')->debug(sprintf('Now in budgetedInPeriod("%s", "%s")', $start->format('Y-m-d'), $end->format('Y-m-d')));
+ $return = [];
+
/** @var BudgetLimitRepository $limitRepository */
$limitRepository = app(BudgetLimitRepository::class);
$limitRepository->setUser($this->user);
- $budgets = $this->getActiveBudgets();
+ $budgets = $this->getActiveBudgets();
+ $defaultCurrency = app('amount')->getDefaultCurrency();
+ $converter = new ExchangeRateConverter();
+
/** @var Budget $budget */
foreach ($budgets as $budget) {
- Log::debug(sprintf('Budget #%d: "%s"', $budget->id, $budget->name));
+ app('log')->debug(sprintf('Budget #%d: "%s"', $budget->id, $budget->name));
$limits = $limitRepository->getBudgetLimits($budget, $start, $end);
+
/** @var BudgetLimit $limit */
foreach ($limits as $limit) {
- Log::debug(sprintf('Budget limit #%d', $limit->id));
- $currency = $limit->transactionCurrency;
- $return[$currency->id] = $return[$currency->id] ?? [
- 'id' => (string)$currency->id,
- 'name' => $currency->name,
- 'symbol' => $currency->symbol,
- 'code' => $currency->code,
- 'decimal_places' => $currency->decimal_places,
- 'sum' => '0',
+ app('log')->debug(sprintf('Budget limit #%d', $limit->id));
+ $currency = $limit->transactionCurrency;
+ $rate = $converter->getCurrencyRate($currency, $defaultCurrency, $end);
+ $currencyCode = $currency->code;
+ $return[$currencyCode] ??= [
+ 'currency_id' => (string)$currency->id,
+ 'currency_name' => $currency->name,
+ 'currency_symbol' => $currency->symbol,
+ 'currency_code' => $currency->code,
+ 'currency_decimal_places' => $currency->decimal_places,
+ 'native_currency_id' => (string)$defaultCurrency->id,
+ 'native_currency_name' => $defaultCurrency->name,
+ 'native_currency_symbol' => $defaultCurrency->symbol,
+ 'native_currency_code' => $defaultCurrency->code,
+ 'native_currency_decimal_places' => $defaultCurrency->decimal_places,
+ 'sum' => '0',
+ 'native_sum' => '0',
];
// same period
if ($limit->start_date->isSameDay($start) && $limit->end_date->isSameDay($end)) {
- $return[$currency->id]['sum'] = bcadd($return[$currency->id]['sum'], (string)$limit->amount);
- Log::debug(sprintf('Add full amount [1]: %s', $limit->amount));
+ $return[$currencyCode]['sum'] = bcadd($return[$currencyCode]['sum'], $limit->amount);
+ $return[$currencyCode]['native_sum'] = bcmul($rate, $return[$currencyCode]['sum']);
+ app('log')->debug(sprintf('Add full amount [1]: %s', $limit->amount));
+
continue;
}
// limit is inside of date range
if ($start->lte($limit->start_date) && $end->gte($limit->end_date)) {
- $return[$currency->id]['sum'] = bcadd($return[$currency->id]['sum'], (string)$limit->amount);
- Log::debug(sprintf('Add full amount [2]: %s', $limit->amount));
+ $return[$currencyCode]['sum'] = bcadd($return[$currencyCode]['sum'], $limit->amount);
+ $return[$currencyCode]['native_sum'] = bcmul($rate, $return[$currencyCode]['sum']);
+ app('log')->debug(sprintf('Add full amount [2]: %s', $limit->amount));
+
continue;
}
- $total = $limit->start_date->diffInDays($limit->end_date) + 1; // include the day itself.
- $days = $this->daysInOverlap($limit, $start, $end);
- $amount = bcmul(bcdiv((string)$limit->amount, (string)$total), (string)$days);
- $return[$currency->id]['sum'] = bcadd($return[$currency->id]['sum'], $amount);
- Log::debug(
+ $total = $limit->start_date->diffInDays($limit->end_date) + 1; // include the day itself.
+ $days = $this->daysInOverlap($limit, $start, $end);
+ $amount = bcmul(bcdiv($limit->amount, (string)$total), (string)$days);
+ $return[$currencyCode]['sum'] = bcadd($return[$currencyCode]['sum'], $amount);
+ $return[$currencyCode]['native_sum'] = bcmul($rate, $return[$currencyCode]['sum']);
+ app('log')->debug(
sprintf(
'Amount per day: %s (%s over %d days). Total amount for %d days: %s',
- bcdiv((string)$limit->amount, (string)$total),
+ bcdiv($limit->amount, (string)$total),
$limit->amount,
$total,
$days,
@@ -141,38 +149,28 @@ class BudgetRepository implements BudgetRepositoryInterface
);
}
}
+
return $return;
}
- /**
- * @param User|Authenticatable|null $user
- */
- public function setUser(User | Authenticatable | null $user): void
+ public function setUser(null|Authenticatable|User $user): void
{
- if (null !== $user) {
+ if ($user instanceof User) {
$this->user = $user;
}
}
- /**
- * @return Collection
- */
public function getActiveBudgets(): Collection
{
return $this->user->budgets()->where('active', true)
- ->orderBy('order', 'ASC')
- ->orderBy('name', 'ASC')
- ->get();
+ ->orderBy('order', 'ASC')
+ ->orderBy('name', 'ASC')
+ ->get()
+ ;
}
/**
* How many days of this budget limit are between start and end?
- *
- * @param BudgetLimit $limit
- * @param Carbon $start
- * @param Carbon $end
- *
- * @return int
*/
private function daysInOverlap(BudgetLimit $limit, Carbon $start, Carbon $end): int
{
@@ -201,27 +199,27 @@ class BudgetRepository implements BudgetRepositoryInterface
// return days in the range $limit_start - $end
return $limit->start_date->diffInDays($end) + 1; // add one day, the day itself
}
+
return 0;
}
- /**
- * @inheritDoc
- */
public function budgetedInPeriodForBudget(Budget $budget, Carbon $start, Carbon $end): array
{
- Log::debug(sprintf('Now in budgetedInPeriod(#%d, "%s", "%s")', $budget->id, $start->format('Y-m-d'), $end->format('Y-m-d')));
- $return = [];
+ app('log')->debug(sprintf('Now in budgetedInPeriod(#%d, "%s", "%s")', $budget->id, $start->format('Y-m-d'), $end->format('Y-m-d')));
+ $return = [];
+
/** @var BudgetLimitRepository $limitRepository */
$limitRepository = app(BudgetLimitRepository::class);
$limitRepository->setUser($this->user);
- Log::debug(sprintf('Budget #%d: "%s"', $budget->id, $budget->name));
- $limits = $limitRepository->getBudgetLimits($budget, $start, $end);
+ app('log')->debug(sprintf('Budget #%d: "%s"', $budget->id, $budget->name));
+ $limits = $limitRepository->getBudgetLimits($budget, $start, $end);
+
/** @var BudgetLimit $limit */
foreach ($limits as $limit) {
- Log::debug(sprintf('Budget limit #%d', $limit->id));
- $currency = $limit->transactionCurrency;
- $return[$currency->id] = $return[$currency->id] ?? [
+ app('log')->debug(sprintf('Budget limit #%d', $limit->id));
+ $currency = $limit->transactionCurrency;
+ $return[$currency->id] ??= [
'id' => (string)$currency->id,
'name' => $currency->name,
'symbol' => $currency->symbol,
@@ -231,24 +229,26 @@ class BudgetRepository implements BudgetRepositoryInterface
];
// same period
if ($limit->start_date->isSameDay($start) && $limit->end_date->isSameDay($end)) {
- $return[$currency->id]['sum'] = bcadd($return[$currency->id]['sum'], (string)$limit->amount);
- Log::debug(sprintf('Add full amount [1]: %s', $limit->amount));
+ $return[$currency->id]['sum'] = bcadd($return[$currency->id]['sum'], $limit->amount);
+ app('log')->debug(sprintf('Add full amount [1]: %s', $limit->amount));
+
continue;
}
// limit is inside of date range
if ($start->lte($limit->start_date) && $end->gte($limit->end_date)) {
- $return[$currency->id]['sum'] = bcadd($return[$currency->id]['sum'], (string)$limit->amount);
- Log::debug(sprintf('Add full amount [2]: %s', $limit->amount));
+ $return[$currency->id]['sum'] = bcadd($return[$currency->id]['sum'], $limit->amount);
+ app('log')->debug(sprintf('Add full amount [2]: %s', $limit->amount));
+
continue;
}
$total = $limit->start_date->diffInDays($limit->end_date) + 1; // include the day itself.
$days = $this->daysInOverlap($limit, $start, $end);
- $amount = bcmul(bcdiv((string)$limit->amount, (string)$total), (string)$days);
+ $amount = bcmul(bcdiv($limit->amount, (string)$total), (string)$days);
$return[$currency->id]['sum'] = bcadd($return[$currency->id]['sum'], $amount);
- Log::debug(
+ app('log')->debug(
sprintf(
'Amount per day: %s (%s over %d days). Total amount for %d days: %s',
- bcdiv((string)$limit->amount, (string)$total),
+ bcdiv($limit->amount, (string)$total),
$limit->amount,
$total,
$days,
@@ -256,17 +256,16 @@ class BudgetRepository implements BudgetRepositoryInterface
)
);
}
+
return $return;
}
- /**
- * @return bool
- */
public function cleanupBudgets(): bool
{
// delete limits with amount 0:
BudgetLimit::where('amount', 0)->delete();
$budgets = $this->getActiveBudgets();
+
/**
* @var int $index
* @var Budget $budget
@@ -282,18 +281,13 @@ class BudgetRepository implements BudgetRepositoryInterface
}
/**
- * @param Budget $budget
- * @param array $data
- *
- * @return Budget
* @throws FireflyException
- * @throws JsonException
*/
public function update(Budget $budget, array $data): Budget
{
- Log::debug('Now in update()');
+ app('log')->debug('Now in update()');
- $oldName = $budget->name;
+ $oldName = $budget->name;
if (array_key_exists('name', $data)) {
$budget->name = $data['name'];
$this->updateRuleActions($oldName, $budget->name);
@@ -308,7 +302,7 @@ class BudgetRepository implements BudgetRepositoryInterface
$budget->save();
// update or create auto-budget:
- $autoBudget = $this->getAutoBudget($budget);
+ $autoBudget = $this->getAutoBudget($budget);
// first things first: delete when no longer required:
$autoBudgetType = array_key_exists('auto_budget_type', $data) ? $data['auto_budget_type'] : null;
@@ -330,54 +324,44 @@ class BudgetRepository implements BudgetRepositoryInterface
return $budget;
}
- /**
- * @param string $oldName
- * @param string $newName
- */
private function updateRuleActions(string $oldName, string $newName): void
{
- $types = ['set_budget',];
+ $types = ['set_budget'];
$actions = RuleAction::leftJoin('rules', 'rules.id', '=', 'rule_actions.rule_id')
- ->where('rules.user_id', $this->user->id)
- ->whereIn('rule_actions.action_type', $types)
- ->where('rule_actions.action_value', $oldName)
- ->get(['rule_actions.*']);
- Log::debug(sprintf('Found %d actions to update.', $actions->count()));
+ ->where('rules.user_id', $this->user->id)
+ ->whereIn('rule_actions.action_type', $types)
+ ->where('rule_actions.action_value', $oldName)
+ ->get(['rule_actions.*'])
+ ;
+ app('log')->debug(sprintf('Found %d actions to update.', $actions->count()));
+
/** @var RuleAction $action */
foreach ($actions as $action) {
$action->action_value = $newName;
$action->save();
- Log::debug(sprintf('Updated action %d: %s', $action->id, $action->action_value));
+ app('log')->debug(sprintf('Updated action %d: %s', $action->id, $action->action_value));
}
}
- /**
- * @param string $oldName
- * @param string $newName
- */
private function updateRuleTriggers(string $oldName, string $newName): void
{
- $types = ['budget_is',];
+ $types = ['budget_is'];
$triggers = RuleTrigger::leftJoin('rules', 'rules.id', '=', 'rule_triggers.rule_id')
- ->where('rules.user_id', $this->user->id)
- ->whereIn('rule_triggers.trigger_type', $types)
- ->where('rule_triggers.trigger_value', $oldName)
- ->get(['rule_triggers.*']);
- Log::debug(sprintf('Found %d triggers to update.', $triggers->count()));
+ ->where('rules.user_id', $this->user->id)
+ ->whereIn('rule_triggers.trigger_type', $types)
+ ->where('rule_triggers.trigger_value', $oldName)
+ ->get(['rule_triggers.*'])
+ ;
+ app('log')->debug(sprintf('Found %d triggers to update.', $triggers->count()));
+
/** @var RuleTrigger $trigger */
foreach ($triggers as $trigger) {
$trigger->trigger_value = $newName;
$trigger->save();
- Log::debug(sprintf('Updated trigger %d: %s', $trigger->id, $trigger->trigger_value));
+ app('log')->debug(sprintf('Updated trigger %d: %s', $trigger->id, $trigger->trigger_value));
}
}
- /**
- * @param Budget $budget
- * @param string $text
- *
- * @return void
- */
private function setNoteText(Budget $budget, string $text): void
{
$dbNote = $budget->notes()->first();
@@ -396,20 +380,13 @@ class BudgetRepository implements BudgetRepositoryInterface
}
}
- /**
- * @inheritDoc
- */
public function getAutoBudget(Budget $budget): ?AutoBudget
{
return $budget->autoBudgets()->first();
}
/**
- * @param Budget $budget
- * @param array $data
- *
* @throws FireflyException
- * @throws JsonException
*/
private function updateAutoBudget(Budget $budget, array $data): void
{
@@ -417,7 +394,7 @@ class BudgetRepository implements BudgetRepositoryInterface
$autoBudget = $this->getAutoBudget($budget);
// grab default currency:
- $currency = app('amount')->getDefaultCurrencyByUser($this->user);
+ $currency = app('amount')->getDefaultCurrencyByUserGroup($this->user->userGroup);
if (null === $autoBudget) {
// at this point it's a blind assumption auto_budget_type is 1 or 2.
@@ -429,12 +406,13 @@ class BudgetRepository implements BudgetRepositoryInterface
// set or update the currency.
if (array_key_exists('currency_id', $data) || array_key_exists('currency_code', $data)) {
+ /** @var CurrencyRepositoryInterface $repos */
$repos = app(CurrencyRepositoryInterface::class);
$currencyId = (int)($data['currency_id'] ?? 0);
$currencyCode = (string)($data['currency_code'] ?? '');
$currency = $repos->find($currencyId);
if (null === $currency) {
- $currency = $repos->findByCodeNull($currencyCode);
+ $currency = $repos->findByCode($currencyCode);
}
if (null !== $currency) {
$autoBudget->transaction_currency_id = $currency->id;
@@ -458,20 +436,13 @@ class BudgetRepository implements BudgetRepositoryInterface
/**
* Find a budget or return NULL
*
- * @param int|null $budgetId |null
- *
- * @return Budget|null
+ * @param null|int $budgetId |null
*/
public function find(int $budgetId = null): ?Budget
{
return $this->user->budgets()->find($budgetId);
}
- /**
- * @param Budget $budget
- *
- * @return bool
- */
public function destroy(Budget $budget): bool
{
/** @var BudgetDestroyService $service */
@@ -487,28 +458,25 @@ class BudgetRepository implements BudgetRepositoryInterface
public function destroyAll(): void
{
$budgets = $this->getBudgets();
+
/** @var Budget $budget */
foreach ($budgets as $budget) {
- DB::table('budget_transaction')->where('budget_id', (int)$budget->id)->delete();
- DB::table('budget_transaction_journal')->where('budget_id', (int)$budget->id)->delete();
+ \DB::table('budget_transaction')->where('budget_id', $budget->id)->delete();
+ \DB::table('budget_transaction_journal')->where('budget_id', $budget->id)->delete();
RecurrenceTransactionMeta::where('name', 'budget_id')->where('value', (string)$budget->id)->delete();
RuleAction::where('action_type', 'set_budget')->where('action_value', (string)$budget->id)->delete();
$budget->delete();
}
+ Log::channel('audit')->info('Delete all budgets through destroyAll');
}
- /**
- * @return Collection
- */
public function getBudgets(): Collection
{
return $this->user->budgets()->orderBy('order', 'ASC')
- ->orderBy('name', 'ASC')->get();
+ ->orderBy('name', 'ASC')->get()
+ ;
}
- /**
- * @inheritDoc
- */
public function destroyAutoBudget(Budget $budget): void
{
/** @var AutoBudget $autoBudget */
@@ -517,35 +485,25 @@ class BudgetRepository implements BudgetRepositoryInterface
}
}
- /**
- * @param int|null $budgetId
- * @param string|null $budgetName
- *
- * @return Budget|null
- */
public function findBudget(?int $budgetId, ?string $budgetName): ?Budget
{
- Log::debug('Now in findBudget()');
- Log::debug(sprintf('Searching for budget with ID #%d...', $budgetId));
+ app('log')->debug('Now in findBudget()');
+ app('log')->debug(sprintf('Searching for budget with ID #%d...', $budgetId));
$result = $this->find((int)$budgetId);
if (null === $result && null !== $budgetName && '' !== $budgetName) {
- Log::debug(sprintf('Searching for budget with name %s...', $budgetName));
- $result = $this->findByName((string)$budgetName);
+ app('log')->debug(sprintf('Searching for budget with name %s...', $budgetName));
+ $result = $this->findByName($budgetName);
}
if (null !== $result) {
- Log::debug(sprintf('Found budget #%d: %s', $result->id, $result->name));
+ app('log')->debug(sprintf('Found budget #%d: %s', $result->id, $result->name));
}
- Log::debug(sprintf('Found result is null? %s', var_export(null === $result, true)));
+ app('log')->debug(sprintf('Found result is null? %s', var_export(null === $result, true)));
return $result;
}
/**
* Find budget by name.
- *
- * @param string|null $name
- *
- * @return Budget|null
*/
public function findByName(?string $name): ?Budget
{
@@ -560,10 +518,6 @@ class BudgetRepository implements BudgetRepositoryInterface
/**
* This method returns the oldest journal or transaction date known to this budget.
* Will cache result.
- *
- * @param Budget $budget
- *
- * @return Carbon|null
*/
public function firstUseDate(Budget $budget): ?Carbon
{
@@ -575,21 +529,18 @@ class BudgetRepository implements BudgetRepositoryInterface
return null;
}
- /**
- * @inheritDoc
- */
public function getAttachments(Budget $budget): Collection
{
- $set = $budget->attachments()->get();
+ $set = $budget->attachments()->get();
- /** @var Storage $disk */
- $disk = Storage::disk('upload');
+ /** @var \Storage $disk */
+ $disk = \Storage::disk('upload');
return $set->each(
static function (Attachment $attachment) use ($disk) {
$notes = $attachment->notes()->first();
$attachment->file_exists = $disk->exists($attachment->fileName());
- $attachment->notes = $notes ? $notes->text : '';
+ $attachment->notes_text = null !== $notes ? $notes->text : '';
return $attachment;
}
@@ -598,29 +549,20 @@ class BudgetRepository implements BudgetRepositoryInterface
/**
* Get all budgets with these ID's.
- *
- * @param array $budgetIds
- *
- * @return Collection
*/
public function getByIds(array $budgetIds): Collection
{
return $this->user->budgets()->whereIn('id', $budgetIds)->get();
}
- /**
- * @return Collection
- */
public function getInactiveBudgets(): Collection
{
return $this->user->budgets()
- ->orderBy('order', 'ASC')
- ->orderBy('name', 'ASC')->where('active', 0)->get();
+ ->orderBy('order', 'ASC')
+ ->orderBy('name', 'ASC')->where('active', 0)->get()
+ ;
}
- /**
- * @inheritDoc
- */
public function getNoteText(Budget $budget): ?string
{
$note = $budget->notes()->first();
@@ -631,12 +573,6 @@ class BudgetRepository implements BudgetRepositoryInterface
return $note->text;
}
- /**
- * @param string $query
- * @param int $limit
- *
- * @return Collection
- */
public function searchBudget(string $query, int $limit): Collection
{
$search = $this->user->budgets();
@@ -644,35 +580,30 @@ class BudgetRepository implements BudgetRepositoryInterface
$search->where('name', 'LIKE', sprintf('%%%s%%', $query));
}
$search->orderBy('order', 'ASC')
- ->orderBy('name', 'ASC')->where('active', true);
+ ->orderBy('name', 'ASC')->where('active', true)
+ ;
return $search->take($limit)->get();
}
- /**
- * @param Budget $budget
- * @param int $order
- */
public function setBudgetOrder(Budget $budget, int $order): void
{
$budget->order = $order;
$budget->save();
}
- /**
- * @inheritDoc
- */
public function spentInPeriod(Carbon $start, Carbon $end): array
{
- Log::debug(sprintf('Now in %s', __METHOD__));
+ app('log')->debug(sprintf('Now in %s', __METHOD__));
$start->startOfDay();
$end->endOfDay();
// exclude specific liabilities
$repository = app(AccountRepositoryInterface::class);
$repository->setUser($this->user);
- $subset = $repository->getAccountsByType(config('firefly.valid_liabilities'));
- $selection = new Collection();
+ $subset = $repository->getAccountsByType(config('firefly.valid_liabilities'));
+ $selection = new Collection();
+
/** @var Account $account */
foreach ($subset as $account) {
if ('credit' === $repository->getMetaValue($account, 'liability_direction')) {
@@ -682,19 +613,20 @@ class BudgetRepository implements BudgetRepositoryInterface
// start collecting:
/** @var GroupCollectorInterface $collector */
- $collector = app(GroupCollectorInterface::class);
+ $collector = app(GroupCollectorInterface::class);
$collector->setUser($this->user)
- ->setRange($start, $end)
- ->excludeDestinationAccounts($selection)
- ->setTypes([TransactionType::WITHDRAWAL])
- ->setBudgets($this->getActiveBudgets());
+ ->setRange($start, $end)
+ ->excludeDestinationAccounts($selection)
+ ->setTypes([TransactionType::WITHDRAWAL])
+ ->setBudgets($this->getActiveBudgets())
+ ;
- $journals = $collector->getExtractedJournals();
- $array = [];
+ $journals = $collector->getExtractedJournals();
+ $array = [];
foreach ($journals as $journal) {
$currencyId = (int)$journal['currency_id'];
- $array[$currencyId] = $array[$currencyId] ?? [
+ $array[$currencyId] ??= [
'id' => (string)$currencyId,
'name' => $journal['currency_name'],
'symbol' => $journal['currency_symbol'],
@@ -705,9 +637,9 @@ class BudgetRepository implements BudgetRepositoryInterface
$array[$currencyId]['sum'] = bcadd($array[$currencyId]['sum'], app('steam')->negative($journal['amount']));
// also do foreign amount:
- $foreignId = (int)$journal['foreign_currency_id'];
+ $foreignId = (int)$journal['foreign_currency_id'];
if (0 !== $foreignId) {
- $array[$foreignId] = $array[$foreignId] ?? [
+ $array[$foreignId] ??= [
'id' => (string)$foreignId,
'name' => $journal['foreign_currency_name'],
'symbol' => $journal['foreign_currency_symbol'],
@@ -722,20 +654,18 @@ class BudgetRepository implements BudgetRepositoryInterface
return $array;
}
- /**
- * @inheritDoc
- */
public function spentInPeriodForBudget(Budget $budget, Carbon $start, Carbon $end): array
{
- Log::debug(sprintf('Now in %s', __METHOD__));
+ app('log')->debug(sprintf('Now in %s', __METHOD__));
$start->startOfDay();
$end->endOfDay();
// exclude specific liabilities
$repository = app(AccountRepositoryInterface::class);
$repository->setUser($this->user);
- $subset = $repository->getAccountsByType(config('firefly.valid_liabilities'));
- $selection = new Collection();
+ $subset = $repository->getAccountsByType(config('firefly.valid_liabilities'));
+ $selection = new Collection();
+
/** @var Account $account */
foreach ($subset as $account) {
if ('credit' === $repository->getMetaValue($account, 'liability_direction')) {
@@ -745,19 +675,20 @@ class BudgetRepository implements BudgetRepositoryInterface
// start collecting:
/** @var GroupCollectorInterface $collector */
- $collector = app(GroupCollectorInterface::class);
+ $collector = app(GroupCollectorInterface::class);
$collector->setUser($this->user)
- ->setRange($start, $end)
- ->excludeDestinationAccounts($selection)
- ->setTypes([TransactionType::WITHDRAWAL])
- ->setBudget($budget);
+ ->setRange($start, $end)
+ ->excludeDestinationAccounts($selection)
+ ->setTypes([TransactionType::WITHDRAWAL])
+ ->setBudget($budget)
+ ;
- $journals = $collector->getExtractedJournals();
- $array = [];
+ $journals = $collector->getExtractedJournals();
+ $array = [];
foreach ($journals as $journal) {
$currencyId = (int)$journal['currency_id'];
- $array[$currencyId] = $array[$currencyId] ?? [
+ $array[$currencyId] ??= [
'id' => (string)$currencyId,
'name' => $journal['currency_name'],
'symbol' => $journal['currency_symbol'],
@@ -768,9 +699,9 @@ class BudgetRepository implements BudgetRepositoryInterface
$array[$currencyId]['sum'] = bcadd($array[$currencyId]['sum'], app('steam')->negative($journal['amount']));
// also do foreign amount:
- $foreignId = (int)$journal['foreign_currency_id'];
+ $foreignId = (int)$journal['foreign_currency_id'];
if (0 !== $foreignId) {
- $array[$foreignId] = $array[$foreignId] ?? [
+ $array[$foreignId] ??= [
'id' => (string)$foreignId,
'name' => $journal['foreign_currency_name'],
'symbol' => $journal['foreign_currency_symbol'],
@@ -786,15 +717,14 @@ class BudgetRepository implements BudgetRepositoryInterface
}
/**
- * @param array $data
- *
- * @return Budget
* @throws FireflyException
- * @throws JsonException
+ *
+ * @SuppressWarnings(PHPMD.NPathComplexity)
*/
public function store(array $data): Budget
{
- $order = $this->getMaxOrder();
+ $order = $this->getMaxOrder();
+
try {
$newBudget = Budget::create(
[
@@ -806,8 +736,9 @@ class BudgetRepository implements BudgetRepositoryInterface
]
);
} catch (QueryException $e) {
- Log::error($e->getMessage());
- Log::error($e->getTraceAsString());
+ app('log')->error($e->getMessage());
+ app('log')->error($e->getTraceAsString());
+
throw new FireflyException('400002: Could not store budget.', 0, $e);
}
@@ -819,7 +750,7 @@ class BudgetRepository implements BudgetRepositoryInterface
if (!array_key_exists('auto_budget_type', $data) || !array_key_exists('auto_budget_amount', $data) || !array_key_exists('auto_budget_period', $data)) {
return $newBudget;
}
- $type = $data['auto_budget_type'];
+ $type = $data['auto_budget_type'];
if ('none' === $type) {
return $newBudget;
}
@@ -837,8 +768,9 @@ class BudgetRepository implements BudgetRepositoryInterface
$type = AutoBudget::AUTO_BUDGET_ADJUSTED;
}
- $repos = app(CurrencyRepositoryInterface::class);
- $currency = null;
+ /** @var CurrencyRepositoryInterface $repos */
+ $repos = app(CurrencyRepositoryInterface::class);
+ $currency = null;
if (array_key_exists('currency_id', $data)) {
$currency = $repos->find((int)$data['currency_id']);
}
@@ -846,10 +778,10 @@ class BudgetRepository implements BudgetRepositoryInterface
$currency = $repos->findByCode((string)$data['currency_code']);
}
if (null === $currency) {
- $currency = app('amount')->getDefaultCurrencyByUser($this->user);
+ $currency = app('amount')->getDefaultCurrencyByUserGroup($this->user->userGroup);
}
- $autoBudget = new AutoBudget();
+ $autoBudget = new AutoBudget();
$autoBudget->budget()->associate($newBudget);
$autoBudget->transaction_currency_id = $currency->id;
$autoBudget->auto_budget_type = $type;
@@ -858,11 +790,11 @@ class BudgetRepository implements BudgetRepositoryInterface
$autoBudget->save();
// create initial budget limit.
- $today = today(config('app.timezone'));
- $start = app('navigation')->startOfPeriod($today, $autoBudget->period);
- $end = app('navigation')->endOfPeriod($start, $autoBudget->period);
+ $today = today(config('app.timezone'));
+ $start = app('navigation')->startOfPeriod($today, $autoBudget->period);
+ $end = app('navigation')->endOfPeriod($start, $autoBudget->period);
- $limitRepos = app(BudgetLimitRepositoryInterface::class);
+ $limitRepos = app(BudgetLimitRepositoryInterface::class);
$limitRepos->setUser($this->user);
$limitRepos->store(
[
@@ -877,9 +809,6 @@ class BudgetRepository implements BudgetRepositoryInterface
return $newBudget;
}
- /**
- * @return int
- */
public function getMaxOrder(): int
{
return (int)$this->user->budgets()->max('order');
diff --git a/app/Repositories/Budget/BudgetRepositoryInterface.php b/app/Repositories/Budget/BudgetRepositoryInterface.php
index fcfaaed4ba..1f5b1df804 100644
--- a/app/Repositories/Budget/BudgetRepositoryInterface.php
+++ b/app/Repositories/Budget/BudgetRepositoryInterface.php
@@ -36,53 +36,22 @@ use Illuminate\Support\Collection;
*/
interface BudgetRepositoryInterface
{
- /**
- * @param string $query
- * @param int $limit
- *
- * @return Collection
- */
public function budgetEndsWith(string $query, int $limit): Collection;
- /**
- * @param string $query
- * @param int $limit
- *
- * @return Collection
- */
public function budgetStartsWith(string $query, int $limit): Collection;
/**
* Returns the amount that is budgeted in a period.
- *
- * @param Carbon $start
- * @param Carbon $end
- *
- * @return array
*/
public function budgetedInPeriod(Carbon $start, Carbon $end): array;
/**
* Returns the amount that is budgeted in a period.
- *
- * @param Budget $budget
- * @param Carbon $start
- * @param Carbon $end
- *
- * @return array
*/
public function budgetedInPeriodForBudget(Budget $budget, Carbon $start, Carbon $end): array;
- /**
- * @return bool
- */
public function cleanupBudgets(): bool;
- /**
- * @param Budget $budget
- *
- * @return bool
- */
public function destroy(Budget $budget): bool;
/**
@@ -90,145 +59,62 @@ interface BudgetRepositoryInterface
*/
public function destroyAll(): void;
- /**
- * @param Budget $budget
- */
public function destroyAutoBudget(Budget $budget): void;
- /**
- *
- * @param int|null $budgetId
- *
- * @return Budget|null
- */
public function find(int $budgetId = null): ?Budget;
- /**
- * @param int|null $budgetId
- * @param string|null $budgetName
- *
- * @return Budget|null
- */
public function findBudget(?int $budgetId, ?string $budgetName): ?Budget;
/**
* Find budget by name.
- *
- * @param string|null $name
- *
- * @return Budget|null
*/
public function findByName(?string $name): ?Budget;
/**
* This method returns the oldest journal or transaction date known to this budget.
* Will cache result.
- *
- * @param Budget $budget
- *
- * @return Carbon|null
*/
public function firstUseDate(Budget $budget): ?Carbon;
- /**
- * @return Collection
- */
public function getActiveBudgets(): Collection;
- /**
- * @param Budget $budget
- *
- * @return Collection
- */
public function getAttachments(Budget $budget): Collection;
- /**
- * @param Budget $budget
- *
- * @return AutoBudget|null
- */
public function getAutoBudget(Budget $budget): ?AutoBudget;
- /**
- * @return Collection
- */
public function getBudgets(): Collection;
/**
* Get all budgets with these ID's.
- *
- * @param array $budgetIds
- *
- * @return Collection
*/
public function getByIds(array $budgetIds): Collection;
- /**
- * @return Collection
- */
public function getInactiveBudgets(): Collection;
- /**
- * @return int
- */
public function getMaxOrder(): int;
- /**
- * @param Budget $budget
- *
- * @return string|null
- */
public function getNoteText(Budget $budget): ?string;
- /**
- * @param string $query
- * @param int $limit
- *
- * @return Collection
- */
public function searchBudget(string $query, int $limit): Collection;
- /**
- * @param Budget $budget
- * @param int $order
- */
public function setBudgetOrder(Budget $budget, int $order): void;
- /**
- * @param User|Authenticatable|null $user
- */
- public function setUser(User | Authenticatable | null $user): void;
+ public function setUser(null|Authenticatable|User $user): void;
/**
* Used in the v2 API to calculate the amount of money spent in all active budgets.
- *
- * @param Carbon $start
- * @param Carbon $end
- *
- * @return array
*/
public function spentInPeriod(Carbon $start, Carbon $end): array;
/**
* Used in the v2 API to calculate the amount of money spent in a single budget..
- *
- *
*/
public function spentInPeriodForBudget(Budget $budget, Carbon $start, Carbon $end): array;
/**
- * @param array $data
- *
- * @return Budget
* @throws FireflyException
*/
public function store(array $data): Budget;
- /**
- * @param Budget $budget
- * @param array $data
- *
- * @return Budget
- */
public function update(Budget $budget, array $data): Budget;
}
diff --git a/app/Repositories/Budget/NoBudgetRepository.php b/app/Repositories/Budget/NoBudgetRepository.php
index 037a3c3a08..4527e77114 100644
--- a/app/Repositories/Budget/NoBudgetRepository.php
+++ b/app/Repositories/Budget/NoBudgetRepository.php
@@ -32,7 +32,6 @@ use Illuminate\Contracts\Auth\Authenticatable;
use Illuminate\Support\Collection;
/**
- *
* Class NoBudgetRepository
*/
class NoBudgetRepository implements NoBudgetRepositoryInterface
@@ -40,31 +39,24 @@ class NoBudgetRepository implements NoBudgetRepositoryInterface
/** @var User */
private $user;
- /**
- * @param Collection $accounts
- * @param Carbon $start
- * @param Carbon $end
- *
- * @return array
- */
public function getNoBudgetPeriodReport(Collection $accounts, Carbon $start, Carbon $end): array
{
$carbonFormat = app('navigation')->preferredCarbonFormat($start, $end);
/** @var GroupCollectorInterface $collector */
- $collector = app(GroupCollectorInterface::class);
+ $collector = app(GroupCollectorInterface::class);
$collector->setAccounts($accounts)->setRange($start, $end);
$collector->setTypes([TransactionType::WITHDRAWAL]);
$collector->withoutBudget();
- $journals = $collector->getExtractedJournals();
- $data = [];
+ $journals = $collector->getExtractedJournals();
+ $data = [];
/** @var array $journal */
foreach ($journals as $journal) {
- $currencyId = (int)$journal['currency_id'];
+ $currencyId = (int)$journal['currency_id'];
- $data[$currencyId] = $data[$currencyId] ?? [
+ $data[$currencyId] ??= [
'id' => 0,
'name' => sprintf('%s (%s)', trans('firefly.no_budget'), $journal['currency_name']),
'sum' => '0',
@@ -75,7 +67,7 @@ class NoBudgetRepository implements NoBudgetRepositoryInterface
'currency_decimal_places' => $journal['currency_decimal_places'],
'entries' => [],
];
- $date = $journal['date']->format($carbonFormat);
+ $date = $journal['date']->format($carbonFormat);
if (!array_key_exists($date, $data[$currencyId]['entries'])) {
$data[$currencyId]['entries'][$date] = '0';
@@ -87,17 +79,12 @@ class NoBudgetRepository implements NoBudgetRepositoryInterface
}
/**
- * @param Collection $accounts
- * @param Carbon $start
- * @param Carbon $end
- *
- * @return array
* @deprecated
*/
public function spentInPeriodWoBudgetMc(Collection $accounts, Carbon $start, Carbon $end): array
{
/** @var GroupCollectorInterface $collector */
- $collector = app(GroupCollectorInterface::class);
+ $collector = app(GroupCollectorInterface::class);
$collector->setUser($this->user);
$collector->setRange($start, $end)->setTypes([TransactionType::WITHDRAWAL])->withoutBudget();
@@ -109,9 +96,10 @@ class NoBudgetRepository implements NoBudgetRepositoryInterface
$return = [];
$total = [];
$currencies = [];
+
/** @var array $journal */
foreach ($journals as $journal) {
- $code = $journal['currency_code'];
+ $code = $journal['currency_code'];
if (!array_key_exists($code, $currencies)) {
$currencies[$code] = [
'id' => $journal['currency_id'],
@@ -138,12 +126,9 @@ class NoBudgetRepository implements NoBudgetRepositoryInterface
return $return;
}
- /**
- * @param User|Authenticatable|null $user
- */
- public function setUser(User | Authenticatable | null $user): void
+ public function setUser(null|Authenticatable|User $user): void
{
- if (null !== $user) {
+ if ($user instanceof User) {
$this->user = $user;
}
}
@@ -151,13 +136,6 @@ class NoBudgetRepository implements NoBudgetRepositoryInterface
/**
* TODO this method does not include multi currency. It just counts.
* TODO this probably also applies to the other "sumExpenses" methods.
- *
- * @param Carbon $start
- * @param Carbon $end
- * @param Collection|null $accounts
- * @param TransactionCurrency|null $currency
- *
- * @return array
*/
public function sumExpenses(Carbon $start, Carbon $end, ?Collection $accounts = null, ?TransactionCurrency $currency = null): array
{
@@ -173,12 +151,12 @@ class NoBudgetRepository implements NoBudgetRepositoryInterface
}
$collector->withoutBudget();
$collector->withBudgetInformation();
- $journals = $collector->getExtractedJournals();
- $array = [];
+ $journals = $collector->getExtractedJournals();
+ $array = [];
foreach ($journals as $journal) {
$currencyId = (int)$journal['currency_id'];
- $array[$currencyId] = $array[$currencyId] ?? [
+ $array[$currencyId] ??= [
'sum' => '0',
'currency_id' => $currencyId,
'currency_name' => $journal['currency_name'],
diff --git a/app/Repositories/Budget/NoBudgetRepositoryInterface.php b/app/Repositories/Budget/NoBudgetRepositoryInterface.php
index 579d37eec2..79e30d1867 100644
--- a/app/Repositories/Budget/NoBudgetRepositoryInterface.php
+++ b/app/Repositories/Budget/NoBudgetRepositoryInterface.php
@@ -35,37 +35,16 @@ use Illuminate\Support\Collection;
interface NoBudgetRepositoryInterface
{
/**
- * @param Collection $accounts
- * @param Carbon $start
- * @param Carbon $end
- *
- * @return array
* @deprecated
*/
public function getNoBudgetPeriodReport(Collection $accounts, Carbon $start, Carbon $end): array;
- /**
- * @param User|Authenticatable|null $user
- */
- public function setUser(User | Authenticatable | null $user): void;
+ public function setUser(null|Authenticatable|User $user): void;
/**
- * @param Collection $accounts
- * @param Carbon $start
- * @param Carbon $end
- *
- * @return array
* @deprecated
*/
public function spentInPeriodWoBudgetMc(Collection $accounts, Carbon $start, Carbon $end): array;
- /**
- * @param Carbon $start
- * @param Carbon $end
- * @param Collection|null $accounts
- * @param TransactionCurrency|null $currency
- *
- * @return array
- */
public function sumExpenses(Carbon $start, Carbon $end, ?Collection $accounts = null, ?TransactionCurrency $currency = null): array;
}
diff --git a/app/Repositories/Budget/OperationsRepository.php b/app/Repositories/Budget/OperationsRepository.php
index 3289b9e4f6..b33ff50748 100644
--- a/app/Repositories/Budget/OperationsRepository.php
+++ b/app/Repositories/Budget/OperationsRepository.php
@@ -33,10 +33,8 @@ use FireflyIII\Repositories\Account\AccountRepositoryInterface;
use FireflyIII\User;
use Illuminate\Contracts\Auth\Authenticatable;
use Illuminate\Support\Collection;
-use Illuminate\Support\Facades\Log;
/**
- *
* Class OperationsRepository
*/
class OperationsRepository implements OperationsRepositoryInterface
@@ -46,30 +44,26 @@ class OperationsRepository implements OperationsRepositoryInterface
/**
* A method that returns the amount of money budgeted per day for this budget,
* on average.
- *
- * @param Budget $budget
- *
- * @return string
*/
public function budgetedPerDay(Budget $budget): string
{
- Log::debug(sprintf('Now with budget #%d "%s"', $budget->id, $budget->name));
+ app('log')->debug(sprintf('Now with budget #%d "%s"', $budget->id, $budget->name));
$total = '0';
$count = 0;
foreach ($budget->budgetlimits as $limit) {
$diff = $limit->start_date->diffInDays($limit->end_date);
$diff = 0 === $diff ? 1 : $diff;
- $amount = (string)$limit->amount;
+ $amount = $limit->amount;
$perDay = bcdiv($amount, (string)$diff);
$total = bcadd($total, $perDay);
- $count++;
- Log::debug(sprintf('Found %d budget limits. Per day is %s, total is %s', $count, $perDay, $total));
+ ++$count;
+ app('log')->debug(sprintf('Found %d budget limits. Per day is %s, total is %s', $count, $perDay, $total));
}
- $avg = $total;
+ $avg = $total;
if ($count > 0) {
$avg = bcdiv($total, (string)$count);
}
- Log::debug(sprintf('%s / %d = %s = average.', $total, $count, $avg));
+ app('log')->debug(sprintf('%s / %d = %s = average.', $total, $count, $avg));
return $avg;
}
@@ -78,35 +72,30 @@ class OperationsRepository implements OperationsRepositoryInterface
* This method is being used to generate the budget overview in the year/multi-year report. Its used
* in both the year/multi-year budget overview AND in the accompanying chart.
*
- * @param Collection $budgets
- * @param Collection $accounts
- * @param Carbon $start
- * @param Carbon $end
- *
- * @return array
* @deprecated
*/
public function getBudgetPeriodReport(Collection $budgets, Collection $accounts, Carbon $start, Carbon $end): array
{
$carbonFormat = app('navigation')->preferredCarbonFormat($start, $end);
$data = [];
+
// get all transactions:
/** @var GroupCollectorInterface $collector */
- $collector = app(GroupCollectorInterface::class);
+ $collector = app(GroupCollectorInterface::class);
$collector->setAccounts($accounts)->setRange($start, $end);
$collector->setBudgets($budgets);
- $journals = $collector->getExtractedJournals();
+ $journals = $collector->getExtractedJournals();
// loop transactions:
/** @var array $journal */
foreach ($journals as $journal) {
// prep data array for currency:
- $budgetId = (int)$journal['budget_id'];
- $budgetName = $journal['budget_name'];
- $currencyId = (int)$journal['currency_id'];
- $key = sprintf('%d-%d', $budgetId, $currencyId);
+ $budgetId = (int)$journal['budget_id'];
+ $budgetName = $journal['budget_name'];
+ $currencyId = (int)$journal['currency_id'];
+ $key = sprintf('%d-%d', $budgetId, $currencyId);
- $data[$key] = $data[$key] ?? [
+ $data[$key] ??= [
'id' => $budgetId,
'name' => sprintf('%s (%s)', $budgetName, $journal['currency_name']),
'sum' => '0',
@@ -128,13 +117,6 @@ class OperationsRepository implements OperationsRepositoryInterface
* This method returns a list of all the withdrawal transaction journals (as arrays) set in that period
* which have the specified budget set to them. It's grouped per currency, with as few details in the array
* as possible. Amounts are always negative.
- *
- * @param Carbon $start
- * @param Carbon $end
- * @param Collection|null $accounts
- * @param Collection|null $budgets
- *
- * @return array
*/
public function listExpenses(Carbon $start, Carbon $end, ?Collection $accounts = null, ?Collection $budgets = null): array
{
@@ -147,17 +129,17 @@ class OperationsRepository implements OperationsRepositoryInterface
if (null !== $budgets && $budgets->count() > 0) {
$collector->setBudgets($budgets);
}
- if (null === $budgets || (null !== $budgets && 0 === $budgets->count())) {
+ if (null === $budgets || 0 === $budgets->count()) {
$collector->setBudgets($this->getBudgets());
}
$collector->withBudgetInformation()->withAccountInformation()->withCategoryInformation();
- $journals = $collector->getExtractedJournals();
- $array = [];
+ $journals = $collector->getExtractedJournals();
+ $array = [];
foreach ($journals as $journal) {
- $currencyId = (int)$journal['currency_id'];
- $budgetId = (int)$journal['budget_id'];
- $budgetName = (string)$journal['budget_name'];
+ $currencyId = (int)$journal['currency_id'];
+ $budgetId = (int)$journal['budget_id'];
+ $budgetName = (string)$journal['budget_name'];
// catch "no category" entries.
if (0 === $budgetId) {
@@ -165,7 +147,7 @@ class OperationsRepository implements OperationsRepositoryInterface
}
// info about the currency:
- $array[$currencyId] = $array[$currencyId] ?? [
+ $array[$currencyId] ??= [
'budgets' => [],
'currency_id' => $currencyId,
'currency_name' => $journal['currency_name'],
@@ -175,7 +157,7 @@ class OperationsRepository implements OperationsRepositoryInterface
];
// info about the categories:
- $array[$currencyId]['budgets'][$budgetId] = $array[$currencyId]['budgets'][$budgetId] ?? [
+ $array[$currencyId]['budgets'][$budgetId] ??= [
'id' => $budgetId,
'name' => $budgetName,
'transaction_journals' => [],
@@ -200,19 +182,13 @@ class OperationsRepository implements OperationsRepositoryInterface
return $array;
}
- /**
- * @param User|Authenticatable|null $user
- */
- public function setUser(User | Authenticatable | null $user): void
+ public function setUser(null|Authenticatable|User $user): void
{
- if (null !== $user) {
+ if ($user instanceof User) {
$this->user = $user;
}
}
- /**
- * @return Collection
- */
private function getBudgets(): Collection
{
/** @var BudgetRepositoryInterface $repos */
@@ -222,75 +198,7 @@ class OperationsRepository implements OperationsRepositoryInterface
}
/**
- * @param Collection $budgets
- * @param Collection $accounts
- * @param Carbon $start
- * @param Carbon $end
- *
- * @return array
- * @deprecated
- */
- public function spentInPeriodMc(Collection $budgets, Collection $accounts, Carbon $start, Carbon $end): array
- {
- /** @var GroupCollectorInterface $collector */
- $collector = app(GroupCollectorInterface::class);
- $collector->setUser($this->user);
- $collector->setRange($start, $end)->setBudgets($budgets)->withBudgetInformation();
-
- if ($accounts->count() > 0) {
- $collector->setAccounts($accounts);
- }
- // TODO possible candidate for "get extracted groups" method.
- $set = $collector->getGroups();
- $return = [];
- $total = [];
- $currencies = [];
- /** @var array $group */
- foreach ($set as $group) {
- /** @var array $transaction */
- foreach ($group['transactions'] as $transaction) {
- $code = $transaction['currency_code'];
- if (!array_key_exists($code, $currencies)) {
- $currencies[$code] = [
- 'id' => $transaction['currency_id'],
- 'decimal_places' => $transaction['currency_decimal_places'],
- 'code' => $transaction['currency_code'],
- 'name' => $transaction['currency_name'],
- 'symbol' => $transaction['currency_symbol'],
- ];
- }
- $total[$code] = array_key_exists($code, $total) ? bcadd($total[$code], $transaction['amount']) : $transaction['amount'];
- }
- }
- /**
- * @var string $code
- * @var string $spent
- */
- foreach ($total as $code => $spent) {
- /** @var TransactionCurrency $currency */
- $currency = $currencies[$code];
- $return[] = [
- 'currency_id' => (string)$currency['id'],
- 'currency_code' => $code,
- 'currency_name' => $currency['name'],
- 'currency_symbol' => $currency['symbol'],
- 'currency_decimal_places' => $currency['decimal_places'],
- 'amount' => app('steam')->bcround($spent, $currency['decimal_places']),
- ];
- }
-
- return $return;
- }
-
- /**
- * @param Carbon $start
- * @param Carbon $end
- * @param Collection|null $accounts
- * @param Collection|null $budgets
- * @param TransactionCurrency|null $currency
- *
- * @return array
- * @deprecated
+ * @SuppressWarnings(PHPMD.ExcessiveParameterList)
*/
public function sumExpenses(
Carbon $start,
@@ -299,7 +207,7 @@ class OperationsRepository implements OperationsRepositoryInterface
?Collection $budgets = null,
?TransactionCurrency $currency = null
): array {
- //Log::debug(sprintf('Now in %s', __METHOD__));
+ // app('log')->debug(sprintf('Now in %s', __METHOD__));
$start->startOfDay();
$end->endOfDay();
@@ -310,8 +218,9 @@ class OperationsRepository implements OperationsRepositoryInterface
// TODO this filter must be somewhere in AccountRepositoryInterface because I suspect its needed more often (A113)
$repository = app(AccountRepositoryInterface::class);
$repository->setUser($this->user);
- $subset = $repository->getAccountsByType(config('firefly.valid_liabilities'));
- $selection = new Collection();
+ $subset = $repository->getAccountsByType(config('firefly.valid_liabilities'));
+ $selection = new Collection();
+
/** @var Account $account */
foreach ($subset as $account) {
if ('credit' === $repository->getMetaValue($account, 'liability_direction')) {
@@ -319,13 +228,13 @@ class OperationsRepository implements OperationsRepositoryInterface
}
}
-
/** @var GroupCollectorInterface $collector */
- $collector = app(GroupCollectorInterface::class);
+ $collector = app(GroupCollectorInterface::class);
$collector->setUser($this->user)
- ->setRange($start, $end)
- ->excludeDestinationAccounts($selection)
- ->setTypes([TransactionType::WITHDRAWAL]);
+ ->setRange($start, $end)
+ ->excludeDestinationAccounts($selection)
+ ->setTypes([TransactionType::WITHDRAWAL])
+ ;
if (null !== $accounts) {
$collector->setAccounts($accounts);
@@ -337,29 +246,30 @@ class OperationsRepository implements OperationsRepositoryInterface
$collector->setCurrency($currency);
}
$collector->setBudgets($budgets);
- $journals = $collector->getExtractedJournals();
+ $journals = $collector->getExtractedJournals();
// same but for foreign currencies:
if (null !== $currency) {
- //Log::debug(sprintf('Currency is "%s".', $currency->name));
+ // app('log')->debug(sprintf('Currency is "%s".', $currency->name));
/** @var GroupCollectorInterface $collector */
$collector = app(GroupCollectorInterface::class);
$collector->setUser($this->user)->setRange($start, $end)->setTypes([TransactionType::WITHDRAWAL])
- ->setForeignCurrency($currency)->setBudgets($budgets);
+ ->setForeignCurrency($currency)->setBudgets($budgets)
+ ;
if (null !== $accounts) {
$collector->setAccounts($accounts);
}
- $result = $collector->getExtractedJournals();
- //Log::debug(sprintf('Found %d journals with currency %s.', count($result), $currency->code));
+ $result = $collector->getExtractedJournals();
+ // app('log')->debug(sprintf('Found %d journals with currency %s.', count($result), $currency->code));
// do not use array_merge because you want keys to overwrite (otherwise you get double results):
- $journals = $result + $journals;
+ $journals = $result + $journals;
}
- $array = [];
+ $array = [];
foreach ($journals as $journal) {
$currencyId = (int)$journal['currency_id'];
- $array[$currencyId] = $array[$currencyId] ?? [
+ $array[$currencyId] ??= [
'sum' => '0',
'currency_id' => $currencyId,
'currency_name' => $journal['currency_name'],
@@ -370,9 +280,9 @@ class OperationsRepository implements OperationsRepositoryInterface
$array[$currencyId]['sum'] = bcadd($array[$currencyId]['sum'], app('steam')->negative($journal['amount']));
// also do foreign amount:
- $foreignId = (int)$journal['foreign_currency_id'];
+ $foreignId = (int)$journal['foreign_currency_id'];
if (0 !== $foreignId) {
- $array[$foreignId] = $array[$foreignId] ?? [
+ $array[$foreignId] ??= [
'sum' => '0',
'currency_id' => $foreignId,
'currency_name' => $journal['foreign_currency_name'],
@@ -386,22 +296,4 @@ class OperationsRepository implements OperationsRepositoryInterface
return $array;
}
-
- /**
- * For now, simply refer to whichever repository holds this function.
- * TODO perhaps better in the future.
- *
- * @param Budget $budget
- * @param Carbon|null $start
- * @param Carbon|null $end
- *
- * @return Collection
- */
- private function getBudgetLimits(Budget $budget, Carbon $start = null, Carbon $end = null): Collection
- {
- /** @var BudgetLimitRepositoryInterface $blRepository */
- $blRepository = app(BudgetLimitRepositoryInterface::class);
-
- return $blRepository->getBudgetLimits($budget, $start, $end);
- }
}
diff --git a/app/Repositories/Budget/OperationsRepositoryInterface.php b/app/Repositories/Budget/OperationsRepositoryInterface.php
index 1e2ab042f8..01c5da7560 100644
--- a/app/Repositories/Budget/OperationsRepositoryInterface.php
+++ b/app/Repositories/Budget/OperationsRepositoryInterface.php
@@ -38,20 +38,10 @@ interface OperationsRepositoryInterface
/**
* A method that returns the amount of money budgeted per day for this budget,
* on average.
- *
- * @param Budget $budget
- *
- * @return string
*/
public function budgetedPerDay(Budget $budget): string;
/**
- * @param Collection $budgets
- * @param Collection $accounts
- * @param Carbon $start
- * @param Carbon $end
- *
- * @return array
* @deprecated
*/
public function getBudgetPeriodReport(Collection $budgets, Collection $accounts, Carbon $start, Carbon $end): array;
@@ -60,46 +50,13 @@ interface OperationsRepositoryInterface
* This method returns a list of all the withdrawal transaction journals (as arrays) set in that period
* which have the specified budget set to them. It's grouped per currency, with as few details in the array
* as possible. Amounts are always negative.
- *
- * @param Carbon $start
- * @param Carbon $end
- * @param Collection|null $accounts
- * @param Collection|null $budgets
- *
- * @return array
*/
public function listExpenses(Carbon $start, Carbon $end, ?Collection $accounts = null, ?Collection $budgets = null): array;
- /**
- * @param User|Authenticatable|null $user
- */
- public function setUser(User | Authenticatable | null $user): void;
-
+ public function setUser(null|Authenticatable|User $user): void;
/**
- * Return multi-currency spent information.
- *
- * @param Collection $budgets
- * @param Collection $accounts
- * @param Carbon $start
- * @param Carbon $end
- *
- * @return array
- * @deprecated
- */
- public function spentInPeriodMc(Collection $budgets, Collection $accounts, Carbon $start, Carbon $end): array;
-
- /**
- * TODO this method was marked as deprecated but I'm not sure why.
- *
- * @param Carbon $start
- * @param Carbon $end
- * @param Collection|null $accounts
- * @param Collection|null $budgets
- * @param TransactionCurrency|null $currency
- *
- * @return array
- *
+ * @SuppressWarnings(PHPMD.ExcessiveParameterList)
*/
public function sumExpenses(
Carbon $start,
diff --git a/app/Repositories/Category/CategoryRepository.php b/app/Repositories/Category/CategoryRepository.php
index d922fe3658..c4312c833c 100644
--- a/app/Repositories/Category/CategoryRepository.php
+++ b/app/Repositories/Category/CategoryRepository.php
@@ -24,8 +24,6 @@ declare(strict_types=1);
namespace FireflyIII\Repositories\Category;
use Carbon\Carbon;
-use DB;
-use Exception;
use FireflyIII\Exceptions\FireflyException;
use FireflyIII\Factory\CategoryFactory;
use FireflyIII\Models\Attachment;
@@ -39,7 +37,6 @@ use FireflyIII\User;
use Illuminate\Contracts\Auth\Authenticatable;
use Illuminate\Support\Collection;
use Illuminate\Support\Facades\Log;
-use Storage;
/**
* Class CategoryRepository.
@@ -48,9 +45,6 @@ class CategoryRepository implements CategoryRepositoryInterface
{
private User $user;
- /**
- * @inheritDoc
- */
public function categoryEndsWith(string $query, int $limit): Collection
{
$search = $this->user->categories();
@@ -61,9 +55,6 @@ class CategoryRepository implements CategoryRepositoryInterface
return $search->take($limit)->get();
}
- /**
- * @inheritDoc
- */
public function categoryStartsWith(string $query, int $limit): Collection
{
$search = $this->user->categories();
@@ -74,13 +65,6 @@ class CategoryRepository implements CategoryRepositoryInterface
return $search->take($limit)->get();
}
- /**
- * @param Category $category
- *
- * @return bool
- *
-
- */
public function destroy(Category $category): bool
{
/** @var CategoryDestroyService $service */
@@ -96,20 +80,20 @@ class CategoryRepository implements CategoryRepositoryInterface
public function destroyAll(): void
{
$categories = $this->getCategories();
+
/** @var Category $category */
foreach ($categories as $category) {
- DB::table('category_transaction')->where('category_id', $category->id)->delete();
- DB::table('category_transaction_journal')->where('category_id', $category->id)->delete();
+ \DB::table('category_transaction')->where('category_id', $category->id)->delete();
+ \DB::table('category_transaction_journal')->where('category_id', $category->id)->delete();
RecurrenceTransactionMeta::where('name', 'category_id')->where('value', $category->id)->delete();
RuleAction::where('action_type', 'set_category')->where('action_value', $category->name)->delete();
$category->delete();
}
+ Log::channel('audit')->info('Delete all categories through destroyAll');
}
/**
* Returns a list of all the categories belonging to a user.
- *
- * @return Collection
*/
public function getCategories(): Collection
{
@@ -117,19 +101,15 @@ class CategoryRepository implements CategoryRepositoryInterface
}
/**
- * @param int|null $categoryId
- * @param string|null $categoryName
- *
- * @return Category|null
* @throws FireflyException
*/
public function findCategory(?int $categoryId, ?string $categoryName): ?Category
{
- Log::debug('Now in findCategory()');
- Log::debug(sprintf('Searching for category with ID #%d...', $categoryId));
+ app('log')->debug('Now in findCategory()');
+ app('log')->debug(sprintf('Searching for category with ID #%d...', $categoryId));
$result = $this->find((int)$categoryId);
if (null === $result) {
- Log::debug(sprintf('Searching for category with name %s...', $categoryName));
+ app('log')->debug(sprintf('Searching for category with name %s...', $categoryName));
$result = $this->findByName((string)$categoryName);
if (null === $result && '' !== (string)$categoryName) {
// create it!
@@ -137,19 +117,15 @@ class CategoryRepository implements CategoryRepositoryInterface
}
}
if (null !== $result) {
- Log::debug(sprintf('Found category #%d: %s', $result->id, $result->name));
+ app('log')->debug(sprintf('Found category #%d: %s', $result->id, $result->name));
}
- Log::debug(sprintf('Found category result is null? %s', var_export(null === $result, true)));
+ app('log')->debug(sprintf('Found category result is null? %s', var_export(null === $result, true)));
return $result;
}
/**
* Find a category or return NULL
- *
- * @param int $categoryId
- *
- * @return Category|null
*/
public function find(int $categoryId): ?Category
{
@@ -158,10 +134,6 @@ class CategoryRepository implements CategoryRepositoryInterface
/**
* Find a category.
- *
- * @param string $name
- *
- * @return Category|null
*/
public function findByName(string $name): ?Category
{
@@ -169,15 +141,12 @@ class CategoryRepository implements CategoryRepositoryInterface
}
/**
- * @param array $data
- *
- * @return Category
* @throws FireflyException
*/
public function store(array $data): Category
{
/** @var CategoryFactory $factory */
- $factory = app(CategoryFactory::class);
+ $factory = app(CategoryFactory::class);
$factory->setUser($this->user);
$category = $factory->findOrCreate(null, $data['name']);
@@ -196,30 +165,21 @@ class CategoryRepository implements CategoryRepositoryInterface
return $category;
}
- /**
- * @param User|Authenticatable|null $user
- */
- public function setUser(User | Authenticatable | null $user): void
+ public function setUser(null|Authenticatable|User $user): void
{
- if (null !== $user) {
+ if ($user instanceof User) {
$this->user = $user;
}
}
- /**
- * @param Category $category
- */
public function removeNotes(Category $category): void
{
$category->notes()->delete();
}
- /**
- * @inheritDoc
- */
public function updateNotes(Category $category, string $notes): void
{
- $dbNote = $category->notes()->first();
+ $dbNote = $category->notes()->first();
if (null === $dbNote) {
$dbNote = new Note();
$dbNote->noteable()->associate($category);
@@ -228,12 +188,6 @@ class CategoryRepository implements CategoryRepositoryInterface
$dbNote->save();
}
- /**
- * @param Category $category
- *
- * @return Carbon|null
- *
- */
public function firstUseDate(Category $category): ?Carbon
{
$firstJournalDate = $this->getFirstJournalDate($category);
@@ -256,11 +210,6 @@ class CategoryRepository implements CategoryRepositoryInterface
return $firstJournalDate;
}
- /**
- * @param Category $category
- *
- * @return Carbon|null
- */
private function getFirstJournalDate(Category $category): ?Carbon
{
$query = $category->transactionJournals()->orderBy('date', 'ASC');
@@ -273,17 +222,13 @@ class CategoryRepository implements CategoryRepositoryInterface
return null;
}
- /**
- * @param Category $category
- *
- * @return Carbon|null
- */
private function getFirstTransactionDate(Category $category): ?Carbon
{
// check transactions:
- $query = $category->transactions()
- ->leftJoin('transaction_journals', 'transaction_journals.id', '=', 'transactions.transaction_journal_id')
- ->orderBy('transaction_journals.date', 'ASC');
+ $query = $category->transactions()
+ ->leftJoin('transaction_journals', 'transaction_journals.id', '=', 'transactions.transaction_journal_id')
+ ->orderBy('transaction_journals.date', 'ASC')
+ ;
$lastTransaction = $query->first(['transaction_journals.*']);
if (null !== $lastTransaction) {
@@ -293,21 +238,18 @@ class CategoryRepository implements CategoryRepositoryInterface
return null;
}
- /**
- * @inheritDoc
- */
public function getAttachments(Category $category): Collection
{
- $set = $category->attachments()->get();
+ $set = $category->attachments()->get();
- /** @var Storage $disk */
- $disk = Storage::disk('upload');
+ /** @var \Storage $disk */
+ $disk = \Storage::disk('upload');
return $set->each(
static function (Attachment $attachment) use ($disk) {
$notes = $attachment->notes()->first();
$attachment->file_exists = $disk->exists($attachment->fileName());
- $attachment->notes = $notes ? $notes->text : '';
+ $attachment->notes_text = null !== $notes ? $notes->text : '';
return $attachment;
}
@@ -316,19 +258,12 @@ class CategoryRepository implements CategoryRepositoryInterface
/**
* Get all categories with ID's.
- *
- * @param array $categoryIds
- *
- * @return Collection
*/
public function getByIds(array $categoryIds): Collection
{
return $this->user->categories()->whereIn('id', $categoryIds)->get();
}
- /**
- * @inheritDoc
- */
public function getNoteText(Category $category): ?string
{
$dbNote = $category->notes()->first();
@@ -340,11 +275,7 @@ class CategoryRepository implements CategoryRepositoryInterface
}
/**
- * @param Category $category
- * @param Collection $accounts
- *
- * @return Carbon|null
- * @throws Exception
+ * @throws \Exception
*/
public function lastUseDate(Category $category, Collection $accounts): ?Carbon
{
@@ -368,15 +299,9 @@ class CategoryRepository implements CategoryRepositoryInterface
return $lastJournalDate;
}
- /**
- * @param Category $category
- * @param Collection $accounts
- *
- * @return Carbon|null
- */
private function getLastJournalDate(Category $category, Collection $accounts): ?Carbon
{
- $query = $category->transactionJournals()->orderBy('date', 'DESC');
+ $query = $category->transactionJournals()->orderBy('date', 'DESC');
if ($accounts->count() > 0) {
$query->leftJoin('transactions as t', 't.transaction_journal_id', '=', 'transaction_journals.id');
@@ -393,18 +318,15 @@ class CategoryRepository implements CategoryRepositoryInterface
}
/**
- * @param Category $category
- * @param Collection $accounts
- *
- * @return Carbon|null
- * @throws Exception
+ * @throws \Exception
*/
private function getLastTransactionDate(Category $category, Collection $accounts): ?Carbon
{
// check transactions:
- $query = $category->transactions()
- ->leftJoin('transaction_journals', 'transaction_journals.id', '=', 'transactions.transaction_journal_id')
- ->orderBy('transaction_journals.date', 'DESC');
+ $query = $category->transactions()
+ ->leftJoin('transaction_journals', 'transaction_journals.id', '=', 'transactions.transaction_journal_id')
+ ->orderBy('transaction_journals.date', 'DESC')
+ ;
if ($accounts->count() > 0) {
// filter journals:
$query->whereIn('transactions.account_id', $accounts->pluck('id')->toArray());
@@ -418,12 +340,6 @@ class CategoryRepository implements CategoryRepositoryInterface
return null;
}
- /**
- * @param string $query
- * @param int $limit
- *
- * @return Collection
- */
public function searchCategory(string $query, int $limit): Collection
{
$search = $this->user->categories();
@@ -435,11 +351,7 @@ class CategoryRepository implements CategoryRepositoryInterface
}
/**
- * @param Category $category
- * @param array $data
- *
- * @return Category
- * @throws Exception
+ * @throws \Exception
*/
public function update(Category $category, array $data): Category
{
diff --git a/app/Repositories/Category/CategoryRepositoryInterface.php b/app/Repositories/Category/CategoryRepositoryInterface.php
index 4f4d2e0afe..94e7bd7c48 100644
--- a/app/Repositories/Category/CategoryRepositoryInterface.php
+++ b/app/Repositories/Category/CategoryRepositoryInterface.php
@@ -35,27 +35,10 @@ use Illuminate\Support\Collection;
*/
interface CategoryRepositoryInterface
{
- /**
- * @param string $query
- * @param int $limit
- *
- * @return Collection
- */
public function categoryEndsWith(string $query, int $limit): Collection;
- /**
- * @param string $query
- * @param int $limit
- *
- * @return Collection
- */
public function categoryStartsWith(string $query, int $limit): Collection;
- /**
- * @param Category $category
- *
- * @return bool
- */
public function destroy(Category $category): bool;
/**
@@ -65,116 +48,52 @@ interface CategoryRepositoryInterface
/**
* Find a category or return NULL
- *
- * @param int $categoryId
- *
- * @return Category|null
*/
public function find(int $categoryId): ?Category;
/**
* Find a category.
- *
- * @param string $name
- *
- * @return Category|null
*/
public function findByName(string $name): ?Category;
- /**
- * @param int|null $categoryId
- * @param string|null $categoryName
- *
- * @return Category|null
- */
public function findCategory(?int $categoryId, ?string $categoryName): ?Category;
- /**
- * @param Category $category
- *
- * @return Carbon|null
- */
public function firstUseDate(Category $category): ?Carbon;
- /**
- * @param Category $category
- *
- * @return Collection
- */
public function getAttachments(Category $category): Collection;
/**
* Get all categories with ID's.
- *
- * @param array $categoryIds
- *
- * @return Collection
*/
public function getByIds(array $categoryIds): Collection;
/**
* Returns a list of all the categories belonging to a user.
- *
- * @return Collection
*/
public function getCategories(): Collection;
- /**
- * @param Category $category
- *
- * @return string|null
- */
public function getNoteText(Category $category): ?string;
/**
* Return most recent transaction(journal) date or null when never used before.
- *
- * @param Category $category
- * @param Collection $accounts
- *
- * @return Carbon|null
*/
public function lastUseDate(Category $category, Collection $accounts): ?Carbon;
/**
* Remove notes.
- *
- * @param Category $category
*/
public function removeNotes(Category $category): void;
- /**
- * @param string $query
- * @param int $limit
- *
- * @return Collection
- */
public function searchCategory(string $query, int $limit): Collection;
- /**
- * @param User|Authenticatable|null $user
- */
- public function setUser(User | Authenticatable | null $user): void;
+ public function setUser(null|Authenticatable|User $user): void;
/**
- * @param array $data
- *
- * @return Category
* @throws FireflyException
*/
public function store(array $data): Category;
- /**
- * @param Category $category
- * @param array $data
- *
- * @return Category
- */
public function update(Category $category, array $data): Category;
- /**
- * @param Category $category
- * @param string $notes
- */
public function updateNotes(Category $category, string $notes): void;
}
diff --git a/app/Repositories/Category/NoCategoryRepository.php b/app/Repositories/Category/NoCategoryRepository.php
index f43f674c87..1da423c8b0 100644
--- a/app/Repositories/Category/NoCategoryRepository.php
+++ b/app/Repositories/Category/NoCategoryRepository.php
@@ -31,7 +31,6 @@ use Illuminate\Contracts\Auth\Authenticatable;
use Illuminate\Support\Collection;
/**
- *
* Class NoCategoryRepository
*/
class NoCategoryRepository implements NoCategoryRepositoryInterface
@@ -42,12 +41,6 @@ class NoCategoryRepository implements NoCategoryRepositoryInterface
* This method returns a list of all the withdrawal transaction journals (as arrays) set in that period
* which have no category set to them. It's grouped per currency, with as few details in the array
* as possible. Amounts are always negative.
- *
- * @param Carbon $start
- * @param Carbon $end
- * @param Collection|null $accounts
- *
- * @return array
*/
public function listExpenses(Carbon $start, Carbon $end, ?Collection $accounts = null): array
{
@@ -57,12 +50,12 @@ class NoCategoryRepository implements NoCategoryRepositoryInterface
if (null !== $accounts && $accounts->count() > 0) {
$collector->setAccounts($accounts);
}
- $journals = $collector->getExtractedJournals();
- $array = [];
+ $journals = $collector->getExtractedJournals();
+ $array = [];
foreach ($journals as $journal) {
- $currencyId = (int)$journal['currency_id'];
- $array[$currencyId] = $array[$currencyId] ?? [
+ $currencyId = (int)$journal['currency_id'];
+ $array[$currencyId] ??= [
'categories' => [],
'currency_id' => $currencyId,
'currency_name' => $journal['currency_name'],
@@ -71,7 +64,7 @@ class NoCategoryRepository implements NoCategoryRepositoryInterface
'currency_decimal_places' => $journal['currency_decimal_places'],
];
// info about the non-existent category:
- $array[$currencyId]['categories'][0] = $array[$currencyId]['categories'][0] ?? [
+ $array[$currencyId]['categories'][0] ??= [
'id' => 0,
'name' => (string)trans('firefly.noCategory'),
'transaction_journals' => [],
@@ -79,23 +72,20 @@ class NoCategoryRepository implements NoCategoryRepositoryInterface
// add journal to array:
// only a subset of the fields.
- $journalId = (int)$journal['transaction_journal_id'];
+ $journalId = (int)$journal['transaction_journal_id'];
$array[$currencyId]['categories'][0]['transaction_journals'][$journalId]
- = [
- 'amount' => app('steam')->negative($journal['amount']),
- 'date' => $journal['date'],
- ];
+ = [
+ 'amount' => app('steam')->negative($journal['amount']),
+ 'date' => $journal['date'],
+ ];
}
return $array;
}
- /**
- * @param User|Authenticatable|null $user
- */
- public function setUser(User | Authenticatable | null $user): void
+ public function setUser(null|Authenticatable|User $user): void
{
- if (null !== $user) {
+ if ($user instanceof User) {
$this->user = $user;
}
}
@@ -104,12 +94,6 @@ class NoCategoryRepository implements NoCategoryRepositoryInterface
* This method returns a list of all the deposit transaction journals (as arrays) set in that period
* which have no category set to them. It's grouped per currency, with as few details in the array
* as possible. Amounts are always positive.
- *
- * @param Carbon $start
- * @param Carbon $end
- * @param Collection|null $accounts
- *
- * @return array
*/
public function listIncome(Carbon $start, Carbon $end, ?Collection $accounts = null): array
{
@@ -119,12 +103,12 @@ class NoCategoryRepository implements NoCategoryRepositoryInterface
if (null !== $accounts && $accounts->count() > 0) {
$collector->setAccounts($accounts);
}
- $journals = $collector->getExtractedJournals();
- $array = [];
+ $journals = $collector->getExtractedJournals();
+ $array = [];
foreach ($journals as $journal) {
- $currencyId = (int)$journal['currency_id'];
- $array[$currencyId] = $array[$currencyId] ?? [
+ $currencyId = (int)$journal['currency_id'];
+ $array[$currencyId] ??= [
'categories' => [],
'currency_id' => $currencyId,
'currency_name' => $journal['currency_name'],
@@ -134,19 +118,19 @@ class NoCategoryRepository implements NoCategoryRepositoryInterface
];
// info about the non-existent category:
- $array[$currencyId]['categories'][0] = $array[$currencyId]['categories'][0] ?? [
+ $array[$currencyId]['categories'][0] ??= [
'id' => 0,
'name' => (string)trans('firefly.noCategory'),
'transaction_journals' => [],
];
// add journal to array:
// only a subset of the fields.
- $journalId = (int)$journal['transaction_journal_id'];
+ $journalId = (int)$journal['transaction_journal_id'];
$array[$currencyId]['categories'][0]['transaction_journals'][$journalId]
- = [
- 'amount' => app('steam')->positive($journal['amount']),
- 'date' => $journal['date'],
- ];
+ = [
+ 'amount' => app('steam')->positive($journal['amount']),
+ 'date' => $journal['date'],
+ ];
}
return $array;
@@ -154,12 +138,6 @@ class NoCategoryRepository implements NoCategoryRepositoryInterface
/**
* Sum of withdrawal journals in period without a category, grouped per currency. Amounts are always negative.
- *
- * @param Carbon $start
- * @param Carbon $end
- * @param Collection|null $accounts
- *
- * @return array
*/
public function sumExpenses(Carbon $start, Carbon $end, ?Collection $accounts = null): array
{
@@ -170,12 +148,12 @@ class NoCategoryRepository implements NoCategoryRepositoryInterface
if (null !== $accounts && $accounts->count() > 0) {
$collector->setAccounts($accounts);
}
- $journals = $collector->getExtractedJournals();
- $array = [];
+ $journals = $collector->getExtractedJournals();
+ $array = [];
foreach ($journals as $journal) {
$currencyId = (int)$journal['currency_id'];
- $array[$currencyId] = $array[$currencyId] ?? [
+ $array[$currencyId] ??= [
'sum' => '0',
'currency_id' => $currencyId,
'currency_name' => $journal['currency_name'],
@@ -191,12 +169,6 @@ class NoCategoryRepository implements NoCategoryRepositoryInterface
/**
* Sum of income journals in period without a category, grouped per currency. Amounts are always positive.
- *
- * @param Carbon $start
- * @param Carbon $end
- * @param Collection|null $accounts
- *
- * @return array
*/
public function sumIncome(Carbon $start, Carbon $end, ?Collection $accounts = null): array
{
@@ -207,12 +179,12 @@ class NoCategoryRepository implements NoCategoryRepositoryInterface
if (null !== $accounts && $accounts->count() > 0) {
$collector->setAccounts($accounts);
}
- $journals = $collector->getExtractedJournals();
- $array = [];
+ $journals = $collector->getExtractedJournals();
+ $array = [];
foreach ($journals as $journal) {
$currencyId = (int)$journal['currency_id'];
- $array[$currencyId] = $array[$currencyId] ?? [
+ $array[$currencyId] ??= [
'sum' => '0',
'currency_id' => $currencyId,
'currency_name' => $journal['currency_name'],
@@ -226,9 +198,6 @@ class NoCategoryRepository implements NoCategoryRepositoryInterface
return $array;
}
- /**
- * @inheritDoc
- */
public function sumTransfers(Carbon $start, Carbon $end, ?Collection $accounts = null): array
{
/** @var GroupCollectorInterface $collector */
@@ -238,12 +207,12 @@ class NoCategoryRepository implements NoCategoryRepositoryInterface
if (null !== $accounts && $accounts->count() > 0) {
$collector->setAccounts($accounts);
}
- $journals = $collector->getExtractedJournals();
- $array = [];
+ $journals = $collector->getExtractedJournals();
+ $array = [];
foreach ($journals as $journal) {
$currencyId = (int)$journal['currency_id'];
- $array[$currencyId] = $array[$currencyId] ?? [
+ $array[$currencyId] ??= [
'sum' => '0',
'currency_id' => $currencyId,
'currency_name' => $journal['currency_name'],
diff --git a/app/Repositories/Category/NoCategoryRepositoryInterface.php b/app/Repositories/Category/NoCategoryRepositoryInterface.php
index a227c8262a..58bc06446f 100644
--- a/app/Repositories/Category/NoCategoryRepositoryInterface.php
+++ b/app/Repositories/Category/NoCategoryRepositoryInterface.php
@@ -30,7 +30,6 @@ use Illuminate\Support\Collection;
/**
* Interface NoCategoryRepositoryInterface
- *
*/
interface NoCategoryRepositoryInterface
{
@@ -38,12 +37,6 @@ interface NoCategoryRepositoryInterface
* This method returns a list of all the withdrawal transaction journals (as arrays) set in that period
* which have no category set to them. It's grouped per currency, with as few details in the array
* as possible. Amounts are always negative.
- *
- * @param Carbon $start
- * @param Carbon $end
- * @param Collection|null $accounts
- *
- * @return array
*/
public function listExpenses(Carbon $start, Carbon $end, ?Collection $accounts = null): array;
@@ -51,50 +44,23 @@ interface NoCategoryRepositoryInterface
* This method returns a list of all the deposit transaction journals (as arrays) set in that period
* which have no category set to them. It's grouped per currency, with as few details in the array
* as possible. Amounts are always positive.
- *
- * @param Carbon $start
- * @param Carbon $end
- * @param Collection|null $accounts
- *
- * @return array
*/
public function listIncome(Carbon $start, Carbon $end, ?Collection $accounts = null): array;
- /**
- * @param User|Authenticatable|null $user
- */
- public function setUser(User | Authenticatable | null $user): void;
+ public function setUser(null|Authenticatable|User $user): void;
/**
* Sum of withdrawal journals in period without a category, grouped per currency. Amounts are always negative.
- *
- * @param Carbon $start
- * @param Carbon $end
- * @param Collection|null $accounts
- *
- * @return array
*/
public function sumExpenses(Carbon $start, Carbon $end, ?Collection $accounts = null): array;
/**
* Sum of income journals in period without a category, grouped per currency. Amounts are always positive.
- *
- * @param Carbon $start
- * @param Carbon $end
- * @param Collection|null $accounts
- *
- * @return array
*/
public function sumIncome(Carbon $start, Carbon $end, ?Collection $accounts = null): array;
/**
* Sum of transfers in period without a category, grouped per currency. Amounts are always positive.
- *
- * @param Carbon $start
- * @param Carbon $end
- * @param Collection|null $accounts
- *
- * @return array
*/
public function sumTransfers(Carbon $start, Carbon $end, ?Collection $accounts = null): array;
}
diff --git a/app/Repositories/Category/OperationsRepository.php b/app/Repositories/Category/OperationsRepository.php
index 9211a0d060..b1f17d184f 100644
--- a/app/Repositories/Category/OperationsRepository.php
+++ b/app/Repositories/Category/OperationsRepository.php
@@ -31,7 +31,6 @@ use Illuminate\Contracts\Auth\Authenticatable;
use Illuminate\Support\Collection;
/**
- *
* Class OperationsRepository
*/
class OperationsRepository implements OperationsRepositoryInterface
@@ -44,13 +43,6 @@ class OperationsRepository implements OperationsRepositoryInterface
* as possible. Amounts are always negative.
*
* First currency, then categories.
- *
- * @param Carbon $start
- * @param Carbon $end
- * @param Collection|null $accounts
- * @param Collection|null $categories
- *
- * @return array
*/
public function listExpenses(Carbon $start, Carbon $end, ?Collection $accounts = null, ?Collection $categories = null): array
{
@@ -63,17 +55,17 @@ class OperationsRepository implements OperationsRepositoryInterface
if (null !== $categories && $categories->count() > 0) {
$collector->setCategories($categories);
}
- if (null === $categories || (null !== $categories && 0 === $categories->count())) {
+ if (null === $categories || 0 === $categories->count()) {
$collector->setCategories($this->getCategories());
}
$collector->withCategoryInformation()->withAccountInformation()->withBudgetInformation();
- $journals = $collector->getExtractedJournals();
- $array = [];
+ $journals = $collector->getExtractedJournals();
+ $array = [];
foreach ($journals as $journal) {
- $currencyId = (int)$journal['currency_id'];
- $categoryId = (int)$journal['category_id'];
- $categoryName = (string)$journal['category_name'];
+ $currencyId = (int)$journal['currency_id'];
+ $categoryId = (int)$journal['category_id'];
+ $categoryName = (string)$journal['category_name'];
// catch "no category" entries.
if (0 === $categoryId) {
@@ -81,7 +73,7 @@ class OperationsRepository implements OperationsRepositoryInterface
}
// info about the currency:
- $array[$currencyId] = $array[$currencyId] ?? [
+ $array[$currencyId] ??= [
'categories' => [],
'currency_id' => (string)$currencyId,
'currency_name' => $journal['currency_name'],
@@ -91,7 +83,7 @@ class OperationsRepository implements OperationsRepositoryInterface
];
// info about the categories:
- $array[$currencyId]['categories'][$categoryId] = $array[$currencyId]['categories'][$categoryId] ?? [
+ $array[$currencyId]['categories'][$categoryId] ??= [
'id' => (string)$categoryId,
'name' => $categoryName,
'transaction_journals' => [],
@@ -116,20 +108,15 @@ class OperationsRepository implements OperationsRepositoryInterface
return $array;
}
- /**
- * @param User|Authenticatable|null $user
- */
- public function setUser(User | Authenticatable | null $user): void
+ public function setUser(null|Authenticatable|User $user): void
{
- if (null !== $user) {
+ if ($user instanceof User) {
$this->user = $user;
}
}
/**
* Returns a list of all the categories belonging to a user.
- *
- * @return Collection
*/
private function getCategories(): Collection
{
@@ -140,13 +127,6 @@ class OperationsRepository implements OperationsRepositoryInterface
* This method returns a list of all the deposit transaction journals (as arrays) set in that period
* which have the specified category set to them. It's grouped per currency, with as few details in the array
* as possible. Amounts are always positive.
- *
- * @param Carbon $start
- * @param Carbon $end
- * @param Collection|null $accounts
- * @param Collection|null $categories
- *
- * @return array
*/
public function listIncome(Carbon $start, Carbon $end, ?Collection $accounts = null, ?Collection $categories = null): array
{
@@ -159,17 +139,17 @@ class OperationsRepository implements OperationsRepositoryInterface
if (null !== $categories && $categories->count() > 0) {
$collector->setCategories($categories);
}
- if (null === $categories || (null !== $categories && 0 === $categories->count())) {
+ if (null === $categories || 0 === $categories->count()) {
$collector->setCategories($this->getCategories());
}
$collector->withCategoryInformation()->withAccountInformation();
- $journals = $collector->getExtractedJournals();
- $array = [];
+ $journals = $collector->getExtractedJournals();
+ $array = [];
foreach ($journals as $journal) {
- $currencyId = (int)$journal['currency_id'];
- $categoryId = (int)$journal['category_id'];
- $categoryName = (string)$journal['category_name'];
+ $currencyId = (int)$journal['currency_id'];
+ $categoryId = (int)$journal['category_id'];
+ $categoryName = (string)$journal['category_name'];
// catch "no category" entries.
if (0 === $categoryId) {
@@ -177,7 +157,7 @@ class OperationsRepository implements OperationsRepositoryInterface
}
// info about the currency:
- $array[$currencyId] = $array[$currencyId] ?? [
+ $array[$currencyId] ??= [
'categories' => [],
'currency_id' => (string)$currencyId,
'currency_name' => $journal['currency_name'],
@@ -187,7 +167,7 @@ class OperationsRepository implements OperationsRepositoryInterface
];
// info about the categories:
- $array[$currencyId]['categories'][$categoryId] = $array[$currencyId]['categories'][$categoryId] ?? [
+ $array[$currencyId]['categories'][$categoryId] ??= [
'id' => (string)$categoryId,
'name' => $categoryName,
'transaction_journals' => [],
@@ -211,29 +191,27 @@ class OperationsRepository implements OperationsRepositoryInterface
return $array;
}
- /**
- * @inheritDoc
- */
public function listTransferredIn(Carbon $start, Carbon $end, Collection $accounts, ?Collection $categories = null): array
{
/** @var GroupCollectorInterface $collector */
$collector = app(GroupCollectorInterface::class);
$collector->setUser($this->user)->setRange($start, $end)->setTypes([TransactionType::TRANSFER])
- ->setDestinationAccounts($accounts)->excludeSourceAccounts($accounts);
+ ->setDestinationAccounts($accounts)->excludeSourceAccounts($accounts)
+ ;
if (null !== $categories && $categories->count() > 0) {
$collector->setCategories($categories);
}
- if (null === $categories || (null !== $categories && 0 === $categories->count())) {
+ if (null === $categories || 0 === $categories->count()) {
$collector->setCategories($this->getCategories());
}
$collector->withCategoryInformation()->withAccountInformation()->withBudgetInformation();
- $journals = $collector->getExtractedJournals();
- $array = [];
+ $journals = $collector->getExtractedJournals();
+ $array = [];
foreach ($journals as $journal) {
- $currencyId = (int)$journal['currency_id'];
- $categoryId = (int)$journal['category_id'];
- $categoryName = (string)$journal['category_name'];
+ $currencyId = (int)$journal['currency_id'];
+ $categoryId = (int)$journal['category_id'];
+ $categoryName = (string)$journal['category_name'];
// catch "no category" entries.
if (0 === $categoryId) {
@@ -241,7 +219,7 @@ class OperationsRepository implements OperationsRepositoryInterface
}
// info about the currency:
- $array[$currencyId] = $array[$currencyId] ?? [
+ $array[$currencyId] ??= [
'categories' => [],
'currency_id' => (string)$currencyId,
'currency_name' => $journal['currency_name'],
@@ -251,7 +229,7 @@ class OperationsRepository implements OperationsRepositoryInterface
];
// info about the categories:
- $array[$currencyId]['categories'][$categoryId] = $array[$currencyId]['categories'][$categoryId] ?? [
+ $array[$currencyId]['categories'][$categoryId] ??= [
'id' => (string)$categoryId,
'name' => $categoryName,
'transaction_journals' => [],
@@ -276,29 +254,27 @@ class OperationsRepository implements OperationsRepositoryInterface
return $array;
}
- /**
- * @inheritDoc
- */
public function listTransferredOut(Carbon $start, Carbon $end, Collection $accounts, ?Collection $categories = null): array
{
/** @var GroupCollectorInterface $collector */
$collector = app(GroupCollectorInterface::class);
$collector->setUser($this->user)->setRange($start, $end)->setTypes([TransactionType::TRANSFER])
- ->setSourceAccounts($accounts)->excludeDestinationAccounts($accounts);
+ ->setSourceAccounts($accounts)->excludeDestinationAccounts($accounts)
+ ;
if (null !== $categories && $categories->count() > 0) {
$collector->setCategories($categories);
}
- if (null === $categories || (null !== $categories && 0 === $categories->count())) {
+ if (null === $categories || 0 === $categories->count()) {
$collector->setCategories($this->getCategories());
}
$collector->withCategoryInformation()->withAccountInformation()->withBudgetInformation();
- $journals = $collector->getExtractedJournals();
- $array = [];
+ $journals = $collector->getExtractedJournals();
+ $array = [];
foreach ($journals as $journal) {
- $currencyId = (int)$journal['currency_id'];
- $categoryId = (int)$journal['category_id'];
- $categoryName = (string)$journal['category_name'];
+ $currencyId = (int)$journal['currency_id'];
+ $categoryId = (int)$journal['category_id'];
+ $categoryName = (string)$journal['category_name'];
// catch "no category" entries.
if (0 === $categoryId) {
@@ -306,7 +282,7 @@ class OperationsRepository implements OperationsRepositoryInterface
}
// info about the currency:
- $array[$currencyId] = $array[$currencyId] ?? [
+ $array[$currencyId] ??= [
'categories' => [],
'currency_id' => (string)$currencyId,
'currency_name' => $journal['currency_name'],
@@ -316,7 +292,7 @@ class OperationsRepository implements OperationsRepositoryInterface
];
// info about the categories:
- $array[$currencyId]['categories'][$categoryId] = $array[$currencyId]['categories'][$categoryId] ?? [
+ $array[$currencyId]['categories'][$categoryId] ??= [
'id' => (string)$categoryId,
'name' => $categoryName,
'transaction_journals' => [],
@@ -343,35 +319,29 @@ class OperationsRepository implements OperationsRepositoryInterface
/**
* Sum of withdrawal journals in period for a set of categories, grouped per currency. Amounts are always negative.
- *
- * @param Carbon $start
- * @param Carbon $end
- * @param Collection|null $accounts
- * @param Collection|null $categories
- *
- * @return array
*/
public function sumExpenses(Carbon $start, Carbon $end, ?Collection $accounts = null, ?Collection $categories = null): array
{
/** @var GroupCollectorInterface $collector */
$collector = app(GroupCollectorInterface::class);
$collector->setUser($this->user)->setRange($start, $end)
- ->setTypes([TransactionType::WITHDRAWAL]);
+ ->setTypes([TransactionType::WITHDRAWAL])
+ ;
if (null !== $accounts && $accounts->count() > 0) {
$collector->setAccounts($accounts);
}
- if (null === $categories || (null !== $categories && 0 === $categories->count())) {
+ if (null === $categories || 0 === $categories->count()) {
$categories = $this->getCategories();
}
$collector->setCategories($categories);
$collector->withCategoryInformation();
- $journals = $collector->getExtractedJournals();
- $array = [];
+ $journals = $collector->getExtractedJournals();
+ $array = [];
foreach ($journals as $journal) {
$currencyId = (int)$journal['currency_id'];
- $array[$currencyId] = $array[$currencyId] ?? [
+ $array[$currencyId] ??= [
'sum' => '0',
'currency_id' => (string)$currencyId,
'currency_name' => $journal['currency_name'],
@@ -387,34 +357,28 @@ class OperationsRepository implements OperationsRepositoryInterface
/**
* Sum of income journals in period for a set of categories, grouped per currency. Amounts are always positive.
- *
- * @param Carbon $start
- * @param Carbon $end
- * @param Collection|null $accounts
- * @param Collection|null $categories
- *
- * @return array
*/
public function sumIncome(Carbon $start, Carbon $end, ?Collection $accounts = null, ?Collection $categories = null): array
{
/** @var GroupCollectorInterface $collector */
$collector = app(GroupCollectorInterface::class);
$collector->setUser($this->user)->setRange($start, $end)
- ->setTypes([TransactionType::DEPOSIT]);
+ ->setTypes([TransactionType::DEPOSIT])
+ ;
if (null !== $accounts && $accounts->count() > 0) {
$collector->setAccounts($accounts);
}
- if (null === $categories || (null !== $categories && 0 === $categories->count())) {
+ if (null === $categories || 0 === $categories->count()) {
$categories = $this->getCategories();
}
$collector->setCategories($categories);
- $journals = $collector->getExtractedJournals();
- $array = [];
+ $journals = $collector->getExtractedJournals();
+ $array = [];
foreach ($journals as $journal) {
$currencyId = (int)$journal['currency_id'];
- $array[$currencyId] = $array[$currencyId] ?? [
+ $array[$currencyId] ??= [
'sum' => '0',
'currency_id' => (string)$currencyId,
'currency_name' => $journal['currency_name'],
@@ -430,34 +394,28 @@ class OperationsRepository implements OperationsRepositoryInterface
/**
* Sum of income journals in period for a set of categories, grouped per currency. Amounts are always positive.
- *
- * @param Carbon $start
- * @param Carbon $end
- * @param Collection|null $accounts
- * @param Collection|null $categories
- *
- * @return array
*/
public function sumTransfers(Carbon $start, Carbon $end, ?Collection $accounts = null, ?Collection $categories = null): array
{
/** @var GroupCollectorInterface $collector */
$collector = app(GroupCollectorInterface::class);
$collector->setUser($this->user)->setRange($start, $end)
- ->setTypes([TransactionType::TRANSFER]);
+ ->setTypes([TransactionType::TRANSFER])
+ ;
if (null !== $accounts && $accounts->count() > 0) {
$collector->setAccounts($accounts);
}
- if (null === $categories || (null !== $categories && 0 === $categories->count())) {
+ if (null === $categories || 0 === $categories->count()) {
$categories = $this->getCategories();
}
$collector->setCategories($categories);
- $journals = $collector->getExtractedJournals();
- $array = [];
+ $journals = $collector->getExtractedJournals();
+ $array = [];
foreach ($journals as $journal) {
$currencyId = (int)$journal['currency_id'];
- $array[$currencyId] = $array[$currencyId] ?? [
+ $array[$currencyId] ??= [
'sum' => '0',
'currency_id' => (string)$currencyId,
'currency_name' => $journal['currency_name'],
diff --git a/app/Repositories/Category/OperationsRepositoryInterface.php b/app/Repositories/Category/OperationsRepositoryInterface.php
index 2738df0d6a..3eb38cc3c3 100644
--- a/app/Repositories/Category/OperationsRepositoryInterface.php
+++ b/app/Repositories/Category/OperationsRepositoryInterface.php
@@ -30,7 +30,6 @@ use Illuminate\Support\Collection;
/**
* Interface OperationsRepositoryInterface
- *
*/
interface OperationsRepositoryInterface
{
@@ -38,13 +37,6 @@ interface OperationsRepositoryInterface
* This method returns a list of all the withdrawal transaction journals (as arrays) set in that period
* which have the specified category set to them. It's grouped per currency, with as few details in the array
* as possible. Amounts are always negative.
- *
- * @param Carbon $start
- * @param Carbon $end
- * @param Collection|null $accounts
- * @param Collection|null $categories
- *
- * @return array
*/
public function listExpenses(Carbon $start, Carbon $end, ?Collection $accounts = null, ?Collection $categories = null): array;
@@ -52,13 +44,6 @@ interface OperationsRepositoryInterface
* This method returns a list of all the deposit transaction journals (as arrays) set in that period
* which have the specified category set to them. It's grouped per currency, with as few details in the array
* as possible. Amounts are always positive.
- *
- * @param Carbon $start
- * @param Carbon $end
- * @param Collection|null $accounts
- * @param Collection|null $categories
- *
- * @return array
*/
public function listIncome(Carbon $start, Carbon $end, ?Collection $accounts = null, ?Collection $categories = null): array;
@@ -67,13 +52,6 @@ interface OperationsRepositoryInterface
* which have the specified category set to them, transferred INTO the listed accounts.
* It excludes any transfers between the listed accounts.
* It's grouped per currency, with as few details in the array as possible. Amounts are always negative.
- *
- * @param Carbon $start
- * @param Carbon $end
- * @param Collection $accounts
- * @param Collection|null $categories
- *
- * @return array
*/
public function listTransferredIn(Carbon $start, Carbon $end, Collection $accounts, ?Collection $categories = null): array;
@@ -82,54 +60,23 @@ interface OperationsRepositoryInterface
* which have the specified category set to them, transferred FROM the listed accounts.
* It excludes any transfers between the listed accounts.
* It's grouped per currency, with as few details in the array as possible. Amounts are always negative.
- *
- * @param Carbon $start
- * @param Carbon $end
- * @param Collection $accounts
- * @param Collection|null $categories
- *
- * @return array
*/
public function listTransferredOut(Carbon $start, Carbon $end, Collection $accounts, ?Collection $categories = null): array;
- /**
- * @param User|Authenticatable|null $user
- */
- public function setUser(User | Authenticatable | null $user): void;
+ public function setUser(null|Authenticatable|User $user): void;
/**
* Sum of withdrawal journals in period for a set of categories, grouped per currency. Amounts are always negative.
- *
- * @param Carbon $start
- * @param Carbon $end
- * @param Collection|null $accounts
- * @param Collection|null $categories
- *
- * @return array
*/
public function sumExpenses(Carbon $start, Carbon $end, ?Collection $accounts = null, ?Collection $categories = null): array;
/**
* Sum of income journals in period for a set of categories, grouped per currency. Amounts are always positive.
- *
- * @param Carbon $start
- * @param Carbon $end
- * @param Collection|null $accounts
- * @param Collection|null $categories
- *
- * @return array
*/
public function sumIncome(Carbon $start, Carbon $end, ?Collection $accounts = null, ?Collection $categories = null): array;
/**
* Sum of transfers in period for a set of categories, grouped per currency. Amounts are always positive.
- *
- * @param Carbon $start
- * @param Carbon $end
- * @param Collection|null $accounts
- * @param Collection|null $categories
- *
- * @return array
*/
public function sumTransfers(Carbon $start, Carbon $end, ?Collection $accounts = null, ?Collection $categories = null): array;
}
diff --git a/app/Repositories/Currency/CurrencyRepository.php b/app/Repositories/Currency/CurrencyRepository.php
index c977e730b0..725a5741ad 100644
--- a/app/Repositories/Currency/CurrencyRepository.php
+++ b/app/Repositories/Currency/CurrencyRepository.php
@@ -24,25 +24,11 @@ declare(strict_types=1);
namespace FireflyIII\Repositories\Currency;
use Carbon\Carbon;
-use FireflyIII\Exceptions\FireflyException;
-use FireflyIII\Factory\TransactionCurrencyFactory;
-use FireflyIII\Models\AccountMeta;
-use FireflyIII\Models\AvailableBudget;
-use FireflyIII\Models\Bill;
-use FireflyIII\Models\BudgetLimit;
use FireflyIII\Models\CurrencyExchangeRate;
-use FireflyIII\Models\Preference;
-use FireflyIII\Models\RecurrenceTransaction;
-use FireflyIII\Models\Transaction;
use FireflyIII\Models\TransactionCurrency;
-use FireflyIII\Repositories\User\UserRepositoryInterface;
-use FireflyIII\Services\Internal\Destroy\CurrencyDestroyService;
-use FireflyIII\Services\Internal\Update\CurrencyUpdateService;
use FireflyIII\User;
use Illuminate\Contracts\Auth\Authenticatable;
use Illuminate\Support\Collection;
-use Illuminate\Support\Facades\Log;
-use JsonException;
/**
* Class CurrencyRepository.
@@ -51,334 +37,8 @@ class CurrencyRepository implements CurrencyRepositoryInterface
{
private User $user;
- /**
- * @param TransactionCurrency $currency
- *
- * @return bool
- * @throws FireflyException
- */
- public function currencyInUse(TransactionCurrency $currency): bool
- {
- $result = $this->currencyInUseAt($currency);
-
- return null !== $result;
- }
-
- /**
- * @param TransactionCurrency $currency
- *
- * @return string|null
- * @throws FireflyException
- */
- public function currencyInUseAt(TransactionCurrency $currency): ?string
- {
- Log::debug(sprintf('Now in currencyInUse() for #%d ("%s")', $currency->id, $currency->code));
- $countJournals = $this->countJournals($currency);
- if ($countJournals > 0) {
- Log::info(sprintf('Count journals is %d, return true.', $countJournals));
-
- return 'journals';
- }
-
- // is the only currency left
- if (1 === $this->getAll()->count()) {
- Log::info('Is the last currency in the system, return true. ');
-
- return 'last_left';
- }
-
- // is being used in accounts:
- $meta = AccountMeta::where('name', 'currency_id')->where('data', json_encode((string)$currency->id))->count();
- if ($meta > 0) {
- Log::info(sprintf('Used in %d accounts as currency_id, return true. ', $meta));
-
- return 'account_meta';
- }
-
- // is being used in bills:
- $bills = Bill::where('transaction_currency_id', $currency->id)->count();
- if ($bills > 0) {
- Log::info(sprintf('Used in %d bills as currency, return true. ', $bills));
-
- return 'bills';
- }
-
- // is being used in recurring transactions
- $recurringAmount = RecurrenceTransaction::where('transaction_currency_id', $currency->id)->count();
- $recurringForeign = RecurrenceTransaction::where('foreign_currency_id', $currency->id)->count();
-
- if ($recurringAmount > 0 || $recurringForeign > 0) {
- Log::info(sprintf('Used in %d recurring transactions as (foreign) currency id, return true. ', $recurringAmount + $recurringForeign));
-
- return 'recurring';
- }
-
- // is being used in accounts (as integer)
- $meta = AccountMeta::leftJoin('accounts', 'accounts.id', '=', 'account_meta.account_id')
- ->whereNull('accounts.deleted_at')
- ->where('account_meta.name', 'currency_id')->where('account_meta.data', json_encode((int)$currency->id))->count();
- if ($meta > 0) {
- Log::info(sprintf('Used in %d accounts as currency_id, return true. ', $meta));
-
- return 'account_meta';
- }
-
- // is being used in available budgets
- $availableBudgets = AvailableBudget::where('transaction_currency_id', $currency->id)->count();
- if ($availableBudgets > 0) {
- Log::info(sprintf('Used in %d available budgets as currency, return true. ', $availableBudgets));
-
- return 'available_budgets';
- }
-
- // is being used in budget limits
- $budgetLimit = BudgetLimit::where('transaction_currency_id', $currency->id)->count();
- if ($budgetLimit > 0) {
- Log::info(sprintf('Used in %d budget limits as currency, return true. ', $budgetLimit));
-
- return 'budget_limits';
- }
-
- // is the default currency for the user or the system
- $defaultCode = app('preferences')->getForUser($this->user, 'currencyPreference', config('firefly.default_currency', 'EUR'))->data;
- if ($currency->code === $defaultCode) {
- Log::info('Is the default currency of the user, return true.');
-
- return 'current_default';
- }
-
- Log::debug('Currency is not used, return false.');
-
- return null;
- }
-
- /**
- * @param TransactionCurrency $currency
- *
- * @return int
- */
- public function countJournals(TransactionCurrency $currency): int
- {
- $count = $currency->transactions()->whereNull('deleted_at')->count() + $currency->transactionJournals()->whereNull('deleted_at')->count();
-
- // also count foreign:
- return $count + Transaction::where('foreign_currency_id', $currency->id)->count();
- }
-
- /**
- * @return Collection
- */
- public function getAll(): Collection
- {
- return TransactionCurrency::orderBy('code', 'ASC')->get();
- }
-
- /**
- * @return Collection
- */
- public function get(): Collection
- {
- return TransactionCurrency::where('enabled', true)->orderBy('code', 'ASC')->get();
- }
-
- /**
- * @param TransactionCurrency $currency
- *
- * @return bool
- */
- public function destroy(TransactionCurrency $currency): bool
- {
- /** @var UserRepositoryInterface $repository */
- $repository = app(UserRepositoryInterface::class);
- if ($repository->hasRole($this->user, 'owner')) {
- /** @var CurrencyDestroyService $service */
- $service = app(CurrencyDestroyService::class);
- $service->destroy($currency);
- }
-
- return true;
- }
-
- /**
- * Disables a currency
- *
- * @param TransactionCurrency $currency
- */
- public function disable(TransactionCurrency $currency): void
- {
- $currency->enabled = false;
- $currency->save();
- }
-
- /**
- * @inheritDoc
- */
- public function ensureMinimalEnabledCurrencies(): void
- {
- // if no currencies are enabled, enable the first one in the DB (usually the EUR)
- if (0 === $this->get()->count()) {
- /** @var TransactionCurrency $first */
- $first = $this->getAll()->first();
- if (null === $first) {
- throw new FireflyException('No currencies found. You broke Firefly III');
- }
- Log::channel('audit')->info(sprintf('Auto-enabled currency %s.', $first->code));
- $this->enable($first);
- app('preferences')->set('currencyPreference', $first->code);
- app('preferences')->mark();
- }
- }
-
- /**
- * @param TransactionCurrency $currency
- * Enables a currency
- */
- public function enable(TransactionCurrency $currency): void
- {
- $currency->enabled = true;
- $currency->save();
- }
-
/**
* Find by currency code, return NULL if unfound.
- * Used in Import Currency!
- *
- * @param string $currencyCode
- *
- * @return TransactionCurrency|null
- * @deprecated
- */
- public function findByCodeNull(string $currencyCode): ?TransactionCurrency
- {
- return TransactionCurrency::where('code', $currencyCode)->first();
- }
-
- /**
- * Find by currency name.
- *
- * @param string $currencyName
- *
- * @return TransactionCurrency|null
- */
- public function findByName(string $currencyName): ?TransactionCurrency
- {
- return TransactionCurrency::whereName($currencyName)->first();
- }
-
- /**
- * Find by currency name or return null.
- * Used in Import Currency!
- *
- * @param string $currencyName
- *
- * @return TransactionCurrency|null
- * @deprecated
- */
- public function findByNameNull(string $currencyName): ?TransactionCurrency
- {
- return TransactionCurrency::whereName($currencyName)->first();
- }
-
- /**
- * Find by currency symbol.
- *
- * @param string $currencySymbol
- *
- * @return TransactionCurrency|null
- */
- public function findBySymbol(string $currencySymbol): ?TransactionCurrency
- {
- return TransactionCurrency::whereSymbol($currencySymbol)->first();
- }
-
- /**
- * Find by currency symbol or return NULL
- * Used in Import Currency!
- *
- * @param string $currencySymbol
- *
- * @return TransactionCurrency|null
- * @deprecated
- */
- public function findBySymbolNull(string $currencySymbol): ?TransactionCurrency
- {
- return TransactionCurrency::whereSymbol($currencySymbol)->first();
- }
-
- /**
- * Find by object, ID or code. Returns user default or system default.
- *
- * @param int|null $currencyId
- * @param string|null $currencyCode
- *
- * @return TransactionCurrency
- * @throws FireflyException
- * @throws JsonException
- */
- public function findCurrency(?int $currencyId, ?string $currencyCode): TransactionCurrency
- {
- $result = $this->findCurrencyNull($currencyId, $currencyCode);
-
- if (null === $result) {
- Log::debug('Grabbing default currency for this user...');
- $result = app('amount')->getDefaultCurrencyByUser($this->user);
- }
-
- if (null === $result) {
- Log::debug('Grabbing EUR as fallback.');
- $result = $this->findByCode('EUR');
- }
- Log::debug(sprintf('Final result: %s', $result->code));
- if (false === $result->enabled) {
- Log::debug(sprintf('Also enabled currency %s', $result->code));
- $this->enable($result);
- }
-
- return $result;
- }
-
- /**
- * Find by object, ID or code. Returns NULL if nothing found.
- *
- * @param int|null $currencyId
- * @param string|null $currencyCode
- *
- * @return TransactionCurrency|null
- */
- public function findCurrencyNull(?int $currencyId, ?string $currencyCode): ?TransactionCurrency
- {
- Log::debug('Now in findCurrencyNull()');
- $result = $this->find((int)$currencyId);
- if (null === $result) {
- Log::debug(sprintf('Searching for currency with code %s...', $currencyCode));
- $result = $this->findByCode((string)$currencyCode);
- }
- if (null !== $result && false === $result->enabled) {
- Log::debug(sprintf('Also enabled currency %s', $result->code));
- $this->enable($result);
- }
-
- return $result;
- }
-
- /**
- * Find by ID, return NULL if not found.
- *
- * @param int $currencyId
- *
- * @return TransactionCurrency|null
- */
- public function find(int $currencyId): ?TransactionCurrency
- {
- return TransactionCurrency::find($currencyId);
- }
-
- /**
- * Find by currency code, return NULL if unfound.
- *
- * @param string $currencyCode
- *
- * @return TransactionCurrency|null
*/
public function findByCode(string $currencyCode): ?TransactionCurrency
{
@@ -386,55 +46,35 @@ class CurrencyRepository implements CurrencyRepositoryInterface
}
/**
- * @param array $ids
- *
- * @return Collection
+ * Returns the complete set of transactions but needs
+ * no user object.
*/
- public function getByIds(array $ids): Collection
+ public function getCompleteSet(): Collection
{
- return TransactionCurrency::orderBy('code', 'ASC')->whereIn('id', $ids)->get();
- }
-
- /**
- * @param Preference $preference
- *
- * @return TransactionCurrency
- */
- public function getCurrencyByPreference(Preference $preference): TransactionCurrency
- {
- $preferred = TransactionCurrency::where('code', $preference->data)->first();
- if (null === $preferred) {
- $preferred = TransactionCurrency::first();
- }
-
- return $preferred;
+ return TransactionCurrency::orderBy('code', 'ASC')->get();
}
/**
* Get currency exchange rate.
- *
- * @param TransactionCurrency $fromCurrency
- * @param TransactionCurrency $toCurrency
- * @param Carbon $date
- *
- * @return CurrencyExchangeRate|null
*/
public function getExchangeRate(TransactionCurrency $fromCurrency, TransactionCurrency $toCurrency, Carbon $date): ?CurrencyExchangeRate
{
if ($fromCurrency->id === $toCurrency->id) {
$rate = new CurrencyExchangeRate();
- $rate->rate = 1;
+ $rate->rate = '1';
$rate->id = 0;
return $rate;
}
- /** @var CurrencyExchangeRate $rate */
+
+ /** @var null|CurrencyExchangeRate $rate */
$rate = $this->user->currencyExchangeRates()
- ->where('from_currency_id', $fromCurrency->id)
- ->where('to_currency_id', $toCurrency->id)
- ->where('date', $date->format('Y-m-d'))->first();
+ ->where('from_currency_id', $fromCurrency->id)
+ ->where('to_currency_id', $toCurrency->id)
+ ->where('date', $date->format('Y-m-d'))->first()
+ ;
if (null !== $rate) {
- Log::debug(sprintf('Found cached exchange rate in database for %s to %s on %s', $fromCurrency->code, $toCurrency->code, $date->format('Y-m-d')));
+ app('log')->debug(sprintf('Found cached exchange rate in database for %s to %s on %s', $fromCurrency->code, $toCurrency->code, $date->format('Y-m-d')));
return $rate;
}
@@ -442,39 +82,8 @@ class CurrencyRepository implements CurrencyRepositoryInterface
return null;
}
- /**
- * @inheritDoc
- */
- public function isFallbackCurrency(TransactionCurrency $currency): bool
- {
- return $currency->code === config('firefly.default_currency', 'EUR');
- }
-
- /**
- * @param string $search
- * @param int $limit
- *
- * @return Collection
- */
- public function searchCurrency(string $search, int $limit): Collection
- {
- $query = TransactionCurrency::where('enabled', true);
- if ('' !== $search) {
- $query->where('name', 'LIKE', sprintf('%%%s%%', $search));
- }
-
- return $query->take($limit)->get();
- }
-
/**
* TODO must be a factory
- *
- * @param TransactionCurrency $fromCurrency
- * @param TransactionCurrency $toCurrency
- * @param Carbon $date
- * @param float $rate
- *
- * @return CurrencyExchangeRate
*/
public function setExchangeRate(TransactionCurrency $fromCurrency, TransactionCurrency $toCurrency, Carbon $date, float $rate): CurrencyExchangeRate
{
@@ -489,46 +98,10 @@ class CurrencyRepository implements CurrencyRepositoryInterface
);
}
- /**
- * @param User|Authenticatable|null $user
- */
- public function setUser(User | Authenticatable | null $user): void
+ public function setUser(null|Authenticatable|User $user): void
{
- if (null !== $user) {
+ if ($user instanceof User) {
$this->user = $user;
}
}
-
- /**
- * @param array $data
- *
- * @return TransactionCurrency
- * @throws FireflyException
- */
- public function store(array $data): TransactionCurrency
- {
- /** @var TransactionCurrencyFactory $factory */
- $factory = app(TransactionCurrencyFactory::class);
- $result = $factory->create($data);
-
- if (null === $result) {
- throw new FireflyException('400004: Could not store new currency.');
- }
-
- return $result;
- }
-
- /**
- * @param TransactionCurrency $currency
- * @param array $data
- *
- * @return TransactionCurrency
- */
- public function update(TransactionCurrency $currency, array $data): TransactionCurrency
- {
- /** @var CurrencyUpdateService $service */
- $service = app(CurrencyUpdateService::class);
-
- return $service->update($currency, $data);
- }
}
diff --git a/app/Repositories/Currency/CurrencyRepositoryInterface.php b/app/Repositories/Currency/CurrencyRepositoryInterface.php
index 3ef07f66f4..e714977abb 100644
--- a/app/Repositories/Currency/CurrencyRepositoryInterface.php
+++ b/app/Repositories/Currency/CurrencyRepositoryInterface.php
@@ -24,9 +24,7 @@ declare(strict_types=1);
namespace FireflyIII\Repositories\Currency;
use Carbon\Carbon;
-use FireflyIII\Exceptions\FireflyException;
use FireflyIII\Models\CurrencyExchangeRate;
-use FireflyIII\Models\Preference;
use FireflyIII\Models\TransactionCurrency;
use FireflyIII\User;
use Illuminate\Contracts\Auth\Authenticatable;
@@ -37,218 +35,34 @@ use Illuminate\Support\Collection;
*/
interface CurrencyRepositoryInterface
{
- /**
- * @param TransactionCurrency $currency
- *
- * @return int
- */
- public function countJournals(TransactionCurrency $currency): int;
-
- /**
- * @param TransactionCurrency $currency
- *
- * @return bool
- */
- public function currencyInUse(TransactionCurrency $currency): bool;
-
- /**
- * Currency is in use where exactly.
- *
- * @param TransactionCurrency $currency
- *
- * @return string|null
- */
- public function currencyInUseAt(TransactionCurrency $currency): ?string;
-
- /**
- * @param TransactionCurrency $currency
- *
- * @return bool
- */
- public function destroy(TransactionCurrency $currency): bool;
-
- /**
- * Disables a currency
- *
- * @param TransactionCurrency $currency
- */
- public function disable(TransactionCurrency $currency): void;
-
- /**
- * Enables a currency
- *
- * @param TransactionCurrency $currency
- */
- public function enable(TransactionCurrency $currency): void;
-
- /**
- * @return void
- */
- public function ensureMinimalEnabledCurrencies(): void;
-
- /**
- * Find by ID, return NULL if not found.
- *
- * @param int $currencyId
- *
- * @return TransactionCurrency|null
- */
- public function find(int $currencyId): ?TransactionCurrency;
-
/**
* Find by currency code, return NULL if unfound.
*
- * @param string $currencyCode
- *
- * @return TransactionCurrency|null
+ * Used in the download exchange rates cron job. Does not require user object.
*/
public function findByCode(string $currencyCode): ?TransactionCurrency;
/**
- * Find by currency code, return NULL if unfound.
+ * Returns the complete set of transactions but needs
+ * no user object.
*
- * @param string $currencyCode
- *
- * @return TransactionCurrency|null
+ * Used by the download exchange rate cron job.
*/
- public function findByCodeNull(string $currencyCode): ?TransactionCurrency;
-
- /**
- * Find by currency name.
- *
- * @param string $currencyName
- *
- * @return TransactionCurrency|null
- */
- public function findByName(string $currencyName): ?TransactionCurrency;
-
- /**
- * Find by currency name.
- *
- * @param string $currencyName
- *
- * @return TransactionCurrency|null
- */
- public function findByNameNull(string $currencyName): ?TransactionCurrency;
-
- /**
- * Find by currency symbol.
- *
- * @param string $currencySymbol
- *
- * @return TransactionCurrency|null
- */
- public function findBySymbol(string $currencySymbol): ?TransactionCurrency;
-
- /**
- * Find by currency symbol.
- *
- * @param string $currencySymbol
- *
- * @return TransactionCurrency|null
- */
- public function findBySymbolNull(string $currencySymbol): ?TransactionCurrency;
-
- /**
- * Find by object, ID or code. Returns user default or system default.
- *
- * @param int|null $currencyId
- * @param string|null $currencyCode
- *
- * @return TransactionCurrency
- */
- public function findCurrency(?int $currencyId, ?string $currencyCode): TransactionCurrency;
-
- /**
- * Find by object, ID or code. Returns NULL if nothing found.
- *
- * @param int|null $currencyId
- * @param string|null $currencyCode
- *
- * @return TransactionCurrency|null
- */
- public function findCurrencyNull(?int $currencyId, ?string $currencyCode): ?TransactionCurrency;
-
- /**
- * @return Collection
- */
- public function get(): Collection;
-
- /**
- * @return Collection
- */
- public function getAll(): Collection;
-
- /**
- * @param array $ids
- *
- * @return Collection
- */
- public function getByIds(array $ids): Collection;
-
- /**
- * @param Preference $preference
- *
- * @return TransactionCurrency
- */
- public function getCurrencyByPreference(Preference $preference): TransactionCurrency;
+ public function getCompleteSet(): Collection;
/**
* Get currency exchange rate.
*
- * @param TransactionCurrency $fromCurrency
- * @param TransactionCurrency $toCurrency
- * @param Carbon $date
- *
- * @return CurrencyExchangeRate|null
+ * Used in the download exchange rate cron job. Needs the user object!
*/
public function getExchangeRate(TransactionCurrency $fromCurrency, TransactionCurrency $toCurrency, Carbon $date): ?CurrencyExchangeRate;
/**
- * @param TransactionCurrency $currency
+ * Set currency exchange rate.
*
- * @return bool
- */
- public function isFallbackCurrency(TransactionCurrency $currency): bool;
-
- /**
- * @param string $search
- * @param int $limit
- *
- * @return Collection
- */
- public function searchCurrency(string $search, int $limit): Collection;
-
- /**
- * TODO must be a factory
- *
- * @param TransactionCurrency $fromCurrency
- * @param TransactionCurrency $toCurrency
- * @param Carbon $date
- * @param float $rate
- *
- * @return CurrencyExchangeRate
+ * Used in download exchange rate cron job. Needs the user object!
*/
public function setExchangeRate(TransactionCurrency $fromCurrency, TransactionCurrency $toCurrency, Carbon $date, float $rate): CurrencyExchangeRate;
- /**
- * @param User|Authenticatable|null $user
- */
- public function setUser(User | Authenticatable | null $user): void;
-
- /**
- * @param array $data
- *
- * @return TransactionCurrency
- * @throws FireflyException
- */
- public function store(array $data): TransactionCurrency;
-
- /**
- * @param TransactionCurrency $currency
- * @param array $data
- *
- * @return TransactionCurrency
- */
- public function update(TransactionCurrency $currency, array $data): TransactionCurrency;
+ public function setUser(null|Authenticatable|User $user): void;
}
diff --git a/app/Repositories/Journal/JournalAPIRepository.php b/app/Repositories/Journal/JournalAPIRepository.php
index 6eb5f743a1..68daaf8f8a 100644
--- a/app/Repositories/Journal/JournalAPIRepository.php
+++ b/app/Repositories/Journal/JournalAPIRepository.php
@@ -30,7 +30,6 @@ use FireflyIII\Models\TransactionJournal;
use FireflyIII\User;
use Illuminate\Contracts\Auth\Authenticatable;
use Illuminate\Support\Collection;
-use Storage;
/**
* Class JournalAPIRepository
@@ -41,49 +40,39 @@ class JournalAPIRepository implements JournalAPIRepositoryInterface
/**
* Returns transaction by ID. Used to validate attachments.
- *
- * @param int $transactionId
- *
- * @return Transaction|null
*/
public function findTransaction(int $transactionId): ?Transaction
{
return Transaction::leftJoin('transaction_journals', 'transaction_journals.id', '=', 'transactions.transaction_journal_id')
- ->where('transaction_journals.user_id', $this->user->id)
- ->where('transactions.id', $transactionId)
- ->first(['transactions.*']);
+ ->where('transaction_journals.user_id', $this->user->id)
+ ->where('transactions.id', $transactionId)
+ ->first(['transactions.*'])
+ ;
}
/**
* TODO pretty sure method duplicated.
*
* Return all attachments for journal.
- *
- * @param TransactionJournal $journal
- *
- * @return Collection
*/
public function getAttachments(TransactionJournal $journal): Collection
{
- $set = $journal->attachments;
+ $set = $journal->attachments;
- /** @var Storage $disk */
- $disk = Storage::disk('upload');
+ /** @var \Storage $disk */
+ $disk = \Storage::disk('upload');
return $set->each(
static function (Attachment $attachment) use ($disk) {
$notes = $attachment->notes()->first();
$attachment->file_exists = $disk->exists($attachment->fileName());
- $attachment->notes = $notes ? $notes->text : ''; // TODO should not set notes like this.
+ $attachment->notes_text = null !== $notes ? $notes->text : ''; // TODO should not set notes like this.
return $attachment;
}
);
}
- /**
- * @inheritDoc
- */
public function getJournalLinks(TransactionJournal $journal): Collection
{
$collection = $journal->destJournalLinks()->get();
@@ -93,16 +82,12 @@ class JournalAPIRepository implements JournalAPIRepositoryInterface
/**
* Get all piggy bank events for a journal.
- *
- * @param TransactionJournal $journal
- *
- * @return Collection
*/
public function getPiggyBankEvents(TransactionJournal $journal): Collection
{
$events = $journal->piggyBankEvents()->get();
$events->each(
- function (PiggyBankEvent $event) {
+ static function (PiggyBankEvent $event): void {
$event->piggyBank = $event->piggyBank()->withTrashed()->first();
}
);
@@ -110,12 +95,9 @@ class JournalAPIRepository implements JournalAPIRepositoryInterface
return $events;
}
- /**
- * @param User|Authenticatable|null $user
- */
- public function setUser(User | Authenticatable | null $user): void
+ public function setUser(null|Authenticatable|User $user): void
{
- if (null !== $user) {
+ if ($user instanceof User) {
$this->user = $user;
}
}
diff --git a/app/Repositories/Journal/JournalAPIRepositoryInterface.php b/app/Repositories/Journal/JournalAPIRepositoryInterface.php
index 30a1f0b3fd..66dae77d0c 100644
--- a/app/Repositories/Journal/JournalAPIRepositoryInterface.php
+++ b/app/Repositories/Journal/JournalAPIRepositoryInterface.php
@@ -36,42 +36,23 @@ interface JournalAPIRepositoryInterface
{
/**
* Returns transaction by ID. Used to validate attachments.
- *
- * @param int $transactionId
- *
- * @return Transaction|null
*/
public function findTransaction(int $transactionId): ?Transaction;
/**
* Return all attachments for journal.
- *
- * @param TransactionJournal $journal
- *
- * @return Collection
*/
public function getAttachments(TransactionJournal $journal): Collection;
/**
* Return all journal links for journal.
- *
- * @param TransactionJournal $journal
- *
- * @return Collection
*/
public function getJournalLinks(TransactionJournal $journal): Collection;
/**
* Get all piggy bank events for a journal.
- *
- * @param TransactionJournal $journal
- *
- * @return Collection
*/
public function getPiggyBankEvents(TransactionJournal $journal): Collection;
- /**
- * @param User|Authenticatable|null $user
- */
- public function setUser(User | Authenticatable | null $user): void;
+ public function setUser(null|Authenticatable|User $user): void;
}
diff --git a/app/Repositories/Journal/JournalCLIRepository.php b/app/Repositories/Journal/JournalCLIRepository.php
index 8f37b8f1fd..caa152c818 100644
--- a/app/Repositories/Journal/JournalCLIRepository.php
+++ b/app/Repositories/Journal/JournalCLIRepository.php
@@ -24,13 +24,11 @@ declare(strict_types=1);
namespace FireflyIII\Repositories\Journal;
use Carbon\Carbon;
-use DB;
use FireflyIII\Models\TransactionJournal;
use FireflyIII\Support\CacheProperties;
use FireflyIII\User;
use Illuminate\Contracts\Auth\Authenticatable;
use Illuminate\Support\Collection;
-use stdClass;
/**
* Class JournalCLIRepository
@@ -39,25 +37,18 @@ class JournalCLIRepository implements JournalCLIRepositoryInterface
{
/**
* Get all transaction journals with a specific type, regardless of user.
- *
- * @param array $types
- *
- * @return Collection
*/
public function getAllJournals(array $types): Collection
{
return TransactionJournal::leftJoin('transaction_types', 'transaction_types.id', '=', 'transaction_journals.transaction_type_id')
- ->whereIn('transaction_types.type', $types)
- ->with(['user', 'transactionType', 'transactionCurrency', 'transactions', 'transactions.account'])
- ->get(['transaction_journals.*']);
+ ->whereIn('transaction_types.type', $types)
+ ->with(['user', 'transactionType', 'transactionCurrency', 'transactions', 'transactions.account'])
+ ->get(['transaction_journals.*'])
+ ;
}
/**
* Return the ID of the budget linked to the journal (if any) or the transactions (if any).
- *
- * @param TransactionJournal $journal
- *
- * @return int
*/
public function getJournalBudgetId(TransactionJournal $journal): int
{
@@ -75,10 +66,6 @@ class JournalCLIRepository implements JournalCLIRepositoryInterface
/**
* Return the ID of the category linked to the journal (if any) or to the transactions (if any).
- *
- * @param TransactionJournal $journal
- *
- * @return int
*/
public function getJournalCategoryId(TransactionJournal $journal): int
{
@@ -96,8 +83,6 @@ class JournalCLIRepository implements JournalCLIRepositoryInterface
/**
* Return all journals without a group, used in an upgrade routine.
- *
- * @return array
*/
public function getJournalsWithoutGroup(): array
{
@@ -106,11 +91,6 @@ class JournalCLIRepository implements JournalCLIRepositoryInterface
/**
* Return Carbon value of a meta field (or NULL).
- *
- * @param TransactionJournal $journal
- * @param string $field
- *
- * @return null|Carbon
*/
public function getMetaDate(TransactionJournal $journal, string $field): ?Carbon
{
@@ -120,7 +100,6 @@ class JournalCLIRepository implements JournalCLIRepositoryInterface
$cache->addProperty($field);
if ($cache->has()) {
- $result = null;
return new Carbon($cache->get());
}
@@ -136,15 +115,10 @@ class JournalCLIRepository implements JournalCLIRepositoryInterface
/**
* Return value of a meta field (or NULL) as a string.
- *
- * @param TransactionJournal $journal
- * @param string $field
- *
- * @return null|string
*/
public function getMetaField(TransactionJournal $journal, string $field): ?string
{
- $cache = new CacheProperties();
+ $cache = new CacheProperties();
$cache->addProperty('journal-meta-updated');
$cache->addProperty($journal->id);
$cache->addProperty($field);
@@ -153,12 +127,12 @@ class JournalCLIRepository implements JournalCLIRepositoryInterface
return $cache->get();
}
- $entry = $journal->transactionJournalMeta()->where('name', $field)->first();
+ $entry = $journal->transactionJournalMeta()->where('name', $field)->first();
if (null === $entry) {
return null;
}
- $value = $entry->data;
+ $value = $entry->data;
if (is_array($value)) {
$return = implode(',', $value);
@@ -176,10 +150,6 @@ class JournalCLIRepository implements JournalCLIRepositoryInterface
/**
* Return text of a note attached to journal, or NULL
- *
- * @param TransactionJournal $journal
- *
- * @return string|null
*/
public function getNoteText(TransactionJournal $journal): ?string
{
@@ -194,16 +164,16 @@ class JournalCLIRepository implements JournalCLIRepositoryInterface
/**
* Returns all journals with more than 2 transactions. Should only return empty collections
* in Firefly III > v4.8,0.
- *
- * @return Collection
*/
public function getSplitJournals(): Collection
{
$query = TransactionJournal::leftJoin('transactions', 'transaction_journals.id', '=', 'transactions.transaction_journal_id')
- ->groupBy('transaction_journals.id');
- $result = $query->get(['transaction_journals.id as id', DB::raw('count(transactions.id) as transaction_count')]);
+ ->groupBy('transaction_journals.id')
+ ;
+ $result = $query->get(['transaction_journals.id as id', \DB::raw('count(transactions.id) as transaction_count')]); // @phpstan-ignore-line
$journalIds = [];
- /** @var stdClass $row */
+
+ /** @var \stdClass $row */
foreach ($result as $row) {
if ((int)$row->transaction_count > 2) {
$journalIds[] = (int)$row->id;
@@ -212,25 +182,19 @@ class JournalCLIRepository implements JournalCLIRepositoryInterface
$journalIds = array_unique($journalIds);
return TransactionJournal::with(['transactions'])
- ->whereIn('id', $journalIds)->get();
+ ->whereIn('id', $journalIds)->get()
+ ;
}
/**
* Return all tags as strings in an array.
- *
- * @param TransactionJournal $journal
- *
- * @return array
*/
public function getTags(TransactionJournal $journal): array
{
return $journal->tags()->get()->pluck('tag')->toArray();
}
- /**
- * @param User|Authenticatable|null $user
- */
- public function setUser(User | Authenticatable | null $user): void
+ public function setUser(null|Authenticatable|User $user): void
{
// empty
}
diff --git a/app/Repositories/Journal/JournalCLIRepositoryInterface.php b/app/Repositories/Journal/JournalCLIRepositoryInterface.php
index ca43bb908e..c0dc10fd54 100644
--- a/app/Repositories/Journal/JournalCLIRepositoryInterface.php
+++ b/app/Repositories/Journal/JournalCLIRepositoryInterface.php
@@ -36,86 +36,49 @@ interface JournalCLIRepositoryInterface
{
/**
* Get all transaction journals with a specific type, regardless of user.
- *
- * @param array $types
- *
- * @return Collection
*/
public function getAllJournals(array $types): Collection;
/**
* Return the ID of the budget linked to the journal (if any) or the transactions (if any).
- *
- * @param TransactionJournal $journal
- *
- * @return int
*/
public function getJournalBudgetId(TransactionJournal $journal): int;
/**
* Return the ID of the category linked to the journal (if any) or to the transactions (if any).
- *
- * @param TransactionJournal $journal
- *
- * @return int
*/
public function getJournalCategoryId(TransactionJournal $journal): int;
/**
* Return all journals without a group, used in an upgrade routine.
- *
- * @return array
*/
public function getJournalsWithoutGroup(): array;
/**
* Return Carbon value of a meta field (or NULL).
- *
- * @param TransactionJournal $journal
- * @param string $field
- *
- * @return null|Carbon
*/
public function getMetaDate(TransactionJournal $journal, string $field): ?Carbon;
/**
* Return value of a meta field (or NULL).
- *
- * @param TransactionJournal $journal
- * @param string $field
- *
- * @return null|string
*/
public function getMetaField(TransactionJournal $journal, string $field): ?string;
/**
* Return text of a note attached to journal, or NULL
- *
- * @param TransactionJournal $journal
- *
- * @return string|null
*/
public function getNoteText(TransactionJournal $journal): ?string;
/**
* Returns all journals with more than 2 transactions. Should only return empty collections
* in Firefly III > v4.8,0.
- *
- * @return Collection
*/
public function getSplitJournals(): Collection;
/**
* Return all tags as strings in an array.
- *
- * @param TransactionJournal $journal
- *
- * @return array
*/
public function getTags(TransactionJournal $journal): array;
- /**
- * @param User|Authenticatable|null $user
- */
- public function setUser(User | Authenticatable | null $user): void;
+ public function setUser(null|Authenticatable|User $user): void;
}
diff --git a/app/Repositories/Journal/JournalRepository.php b/app/Repositories/Journal/JournalRepository.php
index 859c8f953e..ea80eed79b 100644
--- a/app/Repositories/Journal/JournalRepository.php
+++ b/app/Repositories/Journal/JournalRepository.php
@@ -45,13 +45,8 @@ use Illuminate\Support\Collection;
*/
class JournalRepository implements JournalRepositoryInterface
{
- /** @var User */
- private $user;
+ private User $user;
- /**
- * @param TransactionGroup $transactionGroup
- *
- */
public function destroyGroup(TransactionGroup $transactionGroup): void
{
/** @var TransactionGroupDestroyService $service */
@@ -59,10 +54,6 @@ class JournalRepository implements JournalRepositoryInterface
$service->destroy($transactionGroup);
}
- /**
- * @param TransactionJournal $journal
- *
- */
public function destroyJournal(TransactionJournal $journal): void
{
/** @var JournalDestroyService $service */
@@ -70,26 +61,22 @@ class JournalRepository implements JournalRepositoryInterface
$service->destroy($journal);
}
- /**
- * @inheritDoc
- */
public function findByType(array $types): Collection
{
return $this->user
->transactionJournals()
->leftJoin('transaction_types', 'transaction_types.id', '=', 'transaction_journals.transaction_type_id')
->whereIn('transaction_types.type', $types)
- ->get(['transaction_journals.*']);
+ ->get(['transaction_journals.*'])
+ ;
}
/**
* Get users first transaction journal or NULL.
- *
- * @return TransactionJournal|null
*/
public function firstNull(): ?TransactionJournal
{
- /** @var TransactionJournal $entry */
+ /** @var null|TransactionJournal $entry */
$entry = $this->user->transactionJournals()->orderBy('date', 'ASC')->first(['transaction_journals.*']);
$result = null;
if (null !== $entry) {
@@ -99,12 +86,9 @@ class JournalRepository implements JournalRepositoryInterface
return $result;
}
- /**
- * @inheritDoc
- */
public function getDestinationAccount(TransactionJournal $journal): Account
{
- /** @var Transaction $transaction */
+ /** @var null|Transaction $transaction */
$transaction = $journal->transactions()->with('account')->where('amount', '>', 0)->first();
if (null === $transaction) {
throw new FireflyException(sprintf('Your administration is broken. Transaction journal #%d has no destination transaction.', $journal->id));
@@ -115,14 +99,10 @@ class JournalRepository implements JournalRepositoryInterface
/**
* Return total amount of journal. Is always positive.
- *
- * @param TransactionJournal $journal
- *
- * @return string
*/
public function getJournalTotal(TransactionJournal $journal): string
{
- $cache = new CacheProperties();
+ $cache = new CacheProperties();
$cache->addProperty($journal->id);
$cache->addProperty('amount-positive');
if ($cache->has()) {
@@ -137,12 +117,9 @@ class JournalRepository implements JournalRepositoryInterface
return $amount;
}
- /**
- * @return TransactionJournal|null
- */
public function getLast(): ?TransactionJournal
{
- /** @var TransactionJournal $entry */
+ /** @var null|TransactionJournal $entry */
$entry = $this->user->transactionJournals()->orderBy('date', 'DESC')->first(['transaction_journals.*']);
$result = null;
if (null !== $entry) {
@@ -152,29 +129,16 @@ class JournalRepository implements JournalRepositoryInterface
return $result;
}
- /**
- * @param TransactionJournalLink $link
- *
- * @return string
- */
public function getLinkNoteText(TransactionJournalLink $link): string
{
- /** @var Note $note */
+ /** @var null|Note $note */
$note = $link->notes()->first();
- if (null !== $note) {
- return $note->text ?? '';
- }
- return '';
+ return (string)$note?->text;
}
/**
* Return Carbon value of a meta field (or NULL).
- *
- * @param int $journalId
- * @param string $field
- *
- * @return null|Carbon
*/
public function getMetaDateById(int $journalId, string $field): ?Carbon
{
@@ -187,7 +151,8 @@ class JournalRepository implements JournalRepositoryInterface
return new Carbon($cache->get());
}
$entry = TransactionJournalMeta::where('transaction_journal_id', $journalId)
- ->where('name', $field)->first();
+ ->where('name', $field)->first()
+ ;
if (null === $entry) {
return null;
}
@@ -197,12 +162,9 @@ class JournalRepository implements JournalRepositoryInterface
return $value;
}
- /**
- * @inheritDoc
- */
public function getSourceAccount(TransactionJournal $journal): Account
{
- /** @var Transaction $transaction */
+ /** @var null|Transaction $transaction */
$transaction = $journal->transactions()->with('account')->where('amount', '<', 0)->first();
if (null === $transaction) {
throw new FireflyException(sprintf('Your administration is broken. Transaction journal #%d has no source transaction.', $journal->id));
@@ -211,22 +173,15 @@ class JournalRepository implements JournalRepositoryInterface
return $transaction->account;
}
- /**
- * @param int $journalId
- */
public function reconcileById(int $journalId): void
{
- /** @var TransactionJournal $journal */
+ /** @var null|TransactionJournal $journal */
$journal = $this->user->transactionJournals()->find($journalId);
$journal?->transactions()->update(['reconciled' => true]);
}
/**
* Find a specific journal.
- *
- * @param int $journalId
- *
- * @return TransactionJournal|null
*/
public function find(int $journalId): ?TransactionJournal
{
@@ -235,16 +190,12 @@ class JournalRepository implements JournalRepositoryInterface
/**
* Search in journal descriptions.
- *
- * @param string $search
- * @param int $limit
- *
- * @return Collection
*/
public function searchJournalDescriptions(string $search, int $limit): Collection
{
$query = $this->user->transactionJournals()
- ->orderBy('date', 'DESC');
+ ->orderBy('date', 'DESC')
+ ;
if ('' !== $search) {
$query->where('description', 'LIKE', sprintf('%%%s%%', $search));
}
@@ -252,23 +203,22 @@ class JournalRepository implements JournalRepositoryInterface
return $query->take($limit)->get();
}
- /**
- * @param User|Authenticatable|null $user
- */
- public function setUser(User | Authenticatable | null $user): void
+ public function setUser(null|Authenticatable|User $user): void
{
- if (null !== $user) {
+ if ($user instanceof User) {
$this->user = $user;
}
}
+ public function unreconcileById(int $journalId): void
+ {
+ /** @var null|TransactionJournal $journal */
+ $journal = $this->user->transactionJournals()->find($journalId);
+ $journal?->transactions()->update(['reconciled' => false]);
+ }
+
/**
* Update budget for a journal.
- *
- * @param TransactionJournal $journal
- * @param int $budgetId
- *
- * @return TransactionJournal
*/
public function updateBudget(TransactionJournal $journal, int $budgetId): TransactionJournal
{
@@ -289,11 +239,6 @@ class JournalRepository implements JournalRepositoryInterface
/**
* Update category for a journal.
- *
- * @param TransactionJournal $journal
- * @param string $category
- *
- * @return TransactionJournal
*/
public function updateCategory(TransactionJournal $journal, string $category): TransactionJournal
{
@@ -313,11 +258,6 @@ class JournalRepository implements JournalRepositoryInterface
/**
* Update tag(s) for a journal.
- *
- * @param TransactionJournal $journal
- * @param array $tags
- *
- * @return TransactionJournal
*/
public function updateTags(TransactionJournal $journal, array $tags): TransactionJournal
{
diff --git a/app/Repositories/Journal/JournalRepositoryInterface.php b/app/Repositories/Journal/JournalRepositoryInterface.php
index 8133d5d02f..055af9b5f5 100644
--- a/app/Repositories/Journal/JournalRepositoryInterface.php
+++ b/app/Repositories/Journal/JournalRepositoryInterface.php
@@ -40,141 +40,83 @@ interface JournalRepositoryInterface
{
/**
* Deletes a transaction group.
- *
- * @param TransactionGroup $transactionGroup
*/
public function destroyGroup(TransactionGroup $transactionGroup): void;
/**
* Deletes a journal.
- *
- * @param TransactionJournal $journal
*/
public function destroyJournal(TransactionJournal $journal): void;
/**
* Find a specific journal.
- *
- * @param int $journalId
- *
- * @return TransactionJournal|null
*/
public function find(int $journalId): ?TransactionJournal;
- /**
- * @param array $types
- *
- * @return Collection
- */
public function findByType(array $types): Collection;
/**
* Get users very first transaction journal.
- *
- * @return TransactionJournal|null
*/
public function firstNull(): ?TransactionJournal;
/**
* Returns the destination account of the journal.
*
- * @param TransactionJournal $journal
- *
- * @return Account
* @throws FireflyException
*/
public function getDestinationAccount(TransactionJournal $journal): Account;
/**
* Return total amount of journal. Is always positive.
- *
- * @param TransactionJournal $journal
- *
- * @return string
*/
public function getJournalTotal(TransactionJournal $journal): string;
- /**
- * @return TransactionJournal|null
- */
public function getLast(): ?TransactionJournal;
- /**
- * @param TransactionJournalLink $link
- *
- * @return string
- */
public function getLinkNoteText(TransactionJournalLink $link): string;
/**
* Return Carbon value of a meta field (or NULL).
- *
- * @param int $journalId
- * @param string $field
- *
- * @return null|Carbon
*/
public function getMetaDateById(int $journalId, string $field): ?Carbon;
/**
* Returns the source account of the journal.
*
- * @param TransactionJournal $journal
- *
- * @return Account
* @throws FireflyException
*/
public function getSourceAccount(TransactionJournal $journal): Account;
/**
* TODO Maybe to account repository? Do this wen reconcile is API only.
- *
- * @param int $journalId
*/
public function reconcileById(int $journalId): void;
/**
* Search in journal descriptions.
- *
- * @param string $search
- * @param int $limit
- *
- * @return Collection
*/
public function searchJournalDescriptions(string $search, int $limit): Collection;
+ public function setUser(null|Authenticatable|User $user): void;
+
/**
- * @param User|Authenticatable|null $user
+ * TODO Maybe to account repository? Do this wen reconcile is API only.
*/
- public function setUser(User | Authenticatable | null $user): void;
+ public function unreconcileById(int $journalId): void;
/**
* Update budget for a journal.
- *
- * @param TransactionJournal $journal
- * @param int $budgetId
- *
- * @return TransactionJournal
*/
public function updateBudget(TransactionJournal $journal, int $budgetId): TransactionJournal;
/**
* Update category for a journal.
- *
- * @param TransactionJournal $journal
- * @param string $category
- *
- * @return TransactionJournal
*/
public function updateCategory(TransactionJournal $journal, string $category): TransactionJournal;
/**
* Update tag(s) for a journal.
- *
- * @param TransactionJournal $journal
- * @param array $tags
- *
- * @return TransactionJournal
*/
public function updateTags(TransactionJournal $journal, array $tags): TransactionJournal;
}
diff --git a/app/Repositories/LinkType/LinkTypeRepository.php b/app/Repositories/LinkType/LinkTypeRepository.php
index d6c841ff02..7a438ee7fd 100644
--- a/app/Repositories/LinkType/LinkTypeRepository.php
+++ b/app/Repositories/LinkType/LinkTypeRepository.php
@@ -23,7 +23,6 @@ declare(strict_types=1);
namespace FireflyIII\Repositories\LinkType;
-use Exception;
use FireflyIII\Events\DestroyedTransactionLink;
use FireflyIII\Models\LinkType;
use FireflyIII\Models\Note;
@@ -32,32 +31,19 @@ use FireflyIII\Models\TransactionJournalLink;
use FireflyIII\User;
use Illuminate\Contracts\Auth\Authenticatable;
use Illuminate\Support\Collection;
-use Illuminate\Support\Facades\Log;
/**
* Class LinkTypeRepository.
- *
*/
class LinkTypeRepository implements LinkTypeRepositoryInterface
{
private User $user;
- /**
- * @param LinkType $linkType
- *
- * @return int
- */
public function countJournals(LinkType $linkType): int
{
return $linkType->transactionJournalLinks()->count();
}
- /**
- * @param LinkType $linkType
- * @param LinkType|null $moveTo
- *
- * @return bool
- */
public function destroy(LinkType $linkType, LinkType $moveTo = null): bool
{
if (null !== $moveTo) {
@@ -68,12 +54,6 @@ class LinkTypeRepository implements LinkTypeRepositoryInterface
return true;
}
- /**
- * @param LinkType $linkType
- * @param array $data
- *
- * @return LinkType
- */
public function update(LinkType $linkType, array $data): LinkType
{
if (array_key_exists('name', $data) && '' !== (string)$data['name']) {
@@ -91,10 +71,7 @@ class LinkTypeRepository implements LinkTypeRepositoryInterface
}
/**
- * @param TransactionJournalLink $link
- *
- * @return bool
- * @throws Exception
+ * @throws \Exception
*/
public function destroyLink(TransactionJournalLink $link): bool
{
@@ -106,15 +83,10 @@ class LinkTypeRepository implements LinkTypeRepositoryInterface
/**
* Check if link exists between journals.
- *
- * @param TransactionJournal $one
- * @param TransactionJournal $two
- *
- * @return bool
*/
public function findLink(TransactionJournal $one, TransactionJournal $two): bool
{
- Log::debug(sprintf('Now in findLink(%d, %d)', $one->id, $two->id));
+ app('log')->debug(sprintf('Now in findLink(%d, %d)', $one->id, $two->id));
$count = TransactionJournalLink::whereDestinationId($one->id)->whereSourceId($two->id)->count();
$opposingCount = TransactionJournalLink::whereDestinationId($two->id)->whereSourceId($one->id)->count();
@@ -123,10 +95,6 @@ class LinkTypeRepository implements LinkTypeRepositoryInterface
/**
* Return array of all journal ID's for this type of link.
- *
- * @param LinkType $linkType
- *
- * @return array
*/
public function getJournalIds(LinkType $linkType): array
{
@@ -137,9 +105,6 @@ class LinkTypeRepository implements LinkTypeRepositoryInterface
return array_unique(array_merge($sources, $destinations));
}
- /**
- * @return Collection
- */
public function get(): Collection
{
return LinkType::orderBy('name', 'ASC')->get();
@@ -147,20 +112,17 @@ class LinkTypeRepository implements LinkTypeRepositoryInterface
/**
* Returns all the journal links (of a specific type).
- *
- * @param LinkType|null $linkType
- *
- * @return Collection
*/
public function getJournalLinks(LinkType $linkType = null): Collection
{
$query = TransactionJournalLink::with(['source', 'destination'])
- ->leftJoin('transaction_journals as source_journals', 'journal_links.source_id', '=', 'source_journals.id')
- ->leftJoin('transaction_journals as dest_journals', 'journal_links.destination_id', '=', 'dest_journals.id')
- ->where('source_journals.user_id', $this->user->id)
- ->where('dest_journals.user_id', $this->user->id)
- ->whereNull('source_journals.deleted_at')
- ->whereNull('dest_journals.deleted_at');
+ ->leftJoin('transaction_journals as source_journals', 'journal_links.source_id', '=', 'source_journals.id')
+ ->leftJoin('transaction_journals as dest_journals', 'journal_links.destination_id', '=', 'dest_journals.id')
+ ->where('source_journals.user_id', $this->user->id)
+ ->where('dest_journals.user_id', $this->user->id)
+ ->whereNull('source_journals.deleted_at')
+ ->whereNull('dest_journals.deleted_at')
+ ;
if (null !== $linkType) {
$query->where('journal_links.link_type_id', $linkType->id);
@@ -169,12 +131,6 @@ class LinkTypeRepository implements LinkTypeRepositoryInterface
return $query->get(['journal_links.*']);
}
- /**
- * @param TransactionJournal $one
- * @param TransactionJournal $two
- *
- * @return TransactionJournalLink|null
- */
public function getLink(TransactionJournal $one, TransactionJournal $two): ?TransactionJournalLink
{
$left = TransactionJournalLink::whereDestinationId($one->id)->whereSourceId($two->id)->first();
@@ -187,10 +143,6 @@ class LinkTypeRepository implements LinkTypeRepositoryInterface
/**
* Return list of existing connections.
- *
- * @param TransactionJournal $journal
- *
- * @return Collection
*/
public function getLinks(TransactionJournal $journal): Collection
{
@@ -199,27 +151,19 @@ class LinkTypeRepository implements LinkTypeRepositoryInterface
$merged = $outward->merge($inward);
return $merged->filter(
- function (TransactionJournalLink $link) {
+ static function (TransactionJournalLink $link) {
return null !== $link->source && null !== $link->destination;
}
);
}
- /**
- * @param User|Authenticatable|null $user
- */
- public function setUser(User | Authenticatable | null $user): void
+ public function setUser(null|Authenticatable|User $user): void
{
- if (null !== $user) {
+ if ($user instanceof User) {
$this->user = $user;
}
}
- /**
- * @param array $data
- *
- * @return LinkType
- */
public function store(array $data): LinkType
{
$linkType = new LinkType();
@@ -235,12 +179,7 @@ class LinkTypeRepository implements LinkTypeRepositoryInterface
/**
* Store link between two journals.
*
- * @param array $information
- * @param TransactionJournal $inward
- * @param TransactionJournal $outward
- *
- * @return TransactionJournalLink|null
- * @throws Exception
+ * @throws \Exception
*/
public function storeLink(array $information, TransactionJournal $inward, TransactionJournal $outward): ?TransactionJournalLink
{
@@ -260,16 +199,16 @@ class LinkTypeRepository implements LinkTypeRepositoryInterface
return $existing;
}
- $link = new TransactionJournalLink();
+ $link = new TransactionJournalLink();
$link->linkType()->associate($linkType);
if ('inward' === $information['direction']) {
- Log::debug(sprintf('Link type is inwards ("%s"), so %d is source and %d is destination.', $linkType->inward, $inward->id, $outward->id));
+ app('log')->debug(sprintf('Link type is inwards ("%s"), so %d is source and %d is destination.', $linkType->inward, $inward->id, $outward->id));
$link->source()->associate($inward);
$link->destination()->associate($outward);
}
if ('outward' === $information['direction']) {
- Log::debug(sprintf('Link type is inwards ("%s"), so %d is source and %d is destination.', $linkType->outward, $outward->id, $inward->id));
+ app('log')->debug(sprintf('Link type is inwards ("%s"), so %d is source and %d is destination.', $linkType->outward, $outward->id, $inward->id));
$link->source()->associate($outward);
$link->destination()->associate($inward);
}
@@ -281,21 +220,11 @@ class LinkTypeRepository implements LinkTypeRepositoryInterface
return $link;
}
- /**
- * @param int $linkTypeId
- *
- * @return LinkType|null
- */
public function find(int $linkTypeId): ?LinkType
{
return LinkType::find($linkTypeId);
}
- /**
- * @param string|null $name
- *
- * @return LinkType|null
- */
public function findByName(string $name = null): ?LinkType
{
if (null === $name) {
@@ -307,25 +236,17 @@ class LinkTypeRepository implements LinkTypeRepositoryInterface
/**
* See if such a link already exists (and get it).
- *
- * @param LinkType $linkType
- * @param TransactionJournal $inward
- * @param TransactionJournal $outward
- *
- * @return TransactionJournalLink|null
*/
public function findSpecificLink(LinkType $linkType, TransactionJournal $inward, TransactionJournal $outward): ?TransactionJournalLink
{
return TransactionJournalLink::where('link_type_id', $linkType->id)
- ->where('source_id', $inward->id)
- ->where('destination_id', $outward->id)->first();
+ ->where('source_id', $inward->id)
+ ->where('destination_id', $outward->id)->first()
+ ;
}
/**
- * @param TransactionJournalLink $link
- * @param string $text
- *
- * @throws Exception
+ * @throws \Exception
*/
private function setNoteText(TransactionJournalLink $link, string $text): void
{
@@ -343,12 +264,9 @@ class LinkTypeRepository implements LinkTypeRepositoryInterface
$dbNote?->delete();
}
- /**
- * @inheritDoc
- */
public function switchLinkById(int $linkId): bool
{
- /** @var TransactionJournalLink $link */
+ /** @var null|TransactionJournalLink $link */
$link = TransactionJournalLink::find($linkId);
if (null !== $link && $link->source->user->id === $this->user->id) {
$this->switchLink($link);
@@ -357,11 +275,6 @@ class LinkTypeRepository implements LinkTypeRepositoryInterface
return true;
}
- /**
- * @param TransactionJournalLink $link
- *
- * @return bool
- */
public function switchLink(TransactionJournalLink $link): bool
{
$source = $link->source_id;
@@ -375,16 +288,12 @@ class LinkTypeRepository implements LinkTypeRepositoryInterface
/**
* Update an existing transaction journal link.
*
- * @param TransactionJournalLink $journalLink
- * @param array $data
- *
- * @return TransactionJournalLink
- * @throws Exception
+ * @throws \Exception
*/
public function updateLink(TransactionJournalLink $journalLink, array $data): TransactionJournalLink
{
- $journalLink->source_id = $data['inward_id'] ?: $journalLink->source_id;
- $journalLink->destination_id = $data['outward_id'] ?: $journalLink->destination_id;
+ $journalLink->source_id = null === $data['inward_id'] ? $journalLink->source_id : $data['inward_id'];
+ $journalLink->destination_id = null === $data['outward_id'] ? $journalLink->destination_id : $data['outward_id'];
$journalLink->save();
if (array_key_exists('link_type_name', $data)) {
$linkType = LinkType::whereName($data['link_type_name'])->first();
@@ -395,7 +304,7 @@ class LinkTypeRepository implements LinkTypeRepositoryInterface
$journalLink->refresh();
}
- $journalLink->link_type_id = $data['link_type_id'] ?: $journalLink->link_type_id;
+ $journalLink->link_type_id = null === $data['link_type_id'] ? $journalLink->link_type_id : $data['link_type_id'];
$journalLink->save();
if (array_key_exists('notes', $data) && null !== $data['notes']) {
$this->setNoteText($journalLink, $data['notes']);
diff --git a/app/Repositories/LinkType/LinkTypeRepositoryInterface.php b/app/Repositories/LinkType/LinkTypeRepositoryInterface.php
index b2941331f8..a8741f607c 100644
--- a/app/Repositories/LinkType/LinkTypeRepositoryInterface.php
+++ b/app/Repositories/LinkType/LinkTypeRepositoryInterface.php
@@ -35,147 +35,60 @@ use Illuminate\Support\Collection;
*/
interface LinkTypeRepositoryInterface
{
- /**
- * @param LinkType $linkType
- *
- * @return int
- */
public function countJournals(LinkType $linkType): int;
- /**
- * @param LinkType $linkType
- * @param LinkType|null $moveTo
- *
- * @return bool
- */
public function destroy(LinkType $linkType, LinkType $moveTo = null): bool;
- /**
- * @param TransactionJournalLink $link
- *
- * @return bool
- */
public function destroyLink(TransactionJournalLink $link): bool;
- /**
- * @param int $linkTypeId
- *
- * @return LinkType|null
- */
public function find(int $linkTypeId): ?LinkType;
/**
* Find link type by name.
- *
- * @param string|null $name
- *
- * @return LinkType|null
*/
public function findByName(string $name = null): ?LinkType;
/**
* Check if link exists between journals.
- *
- * @param TransactionJournal $one
- * @param TransactionJournal $two
- *
- * @return bool
*/
public function findLink(TransactionJournal $one, TransactionJournal $two): bool;
/**
* See if such a link already exists (and get it).
- *
- * @param LinkType $linkType
- * @param TransactionJournal $inward
- * @param TransactionJournal $outward
- *
- * @return TransactionJournalLink|null
*/
public function findSpecificLink(LinkType $linkType, TransactionJournal $inward, TransactionJournal $outward): ?TransactionJournalLink;
- /**
- * @return Collection
- */
public function get(): Collection;
/**
* Return array of all journal ID's for this type of link.
- *
- * @param LinkType $linkType
- *
- * @return array
*/
public function getJournalIds(LinkType $linkType): array;
- /**
- * @param LinkType|null $linkType
- *
- * @return Collection
- */
public function getJournalLinks(LinkType $linkType = null): Collection;
/**
* Return list of existing connections.
- *
- * @param TransactionJournal $journal
- *
- * @return Collection
*/
public function getLinks(TransactionJournal $journal): Collection;
- /**
- * @param User|Authenticatable|null $user
- */
- public function setUser(User | Authenticatable | null $user): void;
+ public function setUser(null|Authenticatable|User $user): void;
- /**
- * @param array $data
- *
- * @return LinkType
- */
public function store(array $data): LinkType;
/**
* Store link between two journals.
- *
- * @param array $information
- * @param TransactionJournal $inward
- * @param TransactionJournal $outward
- *
- * @return TransactionJournalLink|null
*/
public function storeLink(array $information, TransactionJournal $inward, TransactionJournal $outward): ?TransactionJournalLink;
- /**
- * @param TransactionJournalLink $link
- *
- * @return bool
- */
public function switchLink(TransactionJournalLink $link): bool;
- /**
- * @param int $linkId
- *
- * @return bool
- */
public function switchLinkById(int $linkId): bool;
- /**
- * @param LinkType $linkType
- * @param array $data
- *
- * @return LinkType
- */
public function update(LinkType $linkType, array $data): LinkType;
/**
* Update an existing transaction journal link.
- *
- * @param TransactionJournalLink $journalLink
- * @param array $data
- *
- * @return TransactionJournalLink
*/
public function updateLink(TransactionJournalLink $journalLink, array $data): TransactionJournalLink;
}
diff --git a/app/Repositories/ObjectGroup/CreatesObjectGroups.php b/app/Repositories/ObjectGroup/CreatesObjectGroups.php
index 5258479fbf..dc843cc2c2 100644
--- a/app/Repositories/ObjectGroup/CreatesObjectGroups.php
+++ b/app/Repositories/ObjectGroup/CreatesObjectGroups.php
@@ -31,21 +31,11 @@ use FireflyIII\Models\ObjectGroup;
*/
trait CreatesObjectGroups
{
- /**
- * @param int $groupId
- *
- * @return ObjectGroup|null
- */
protected function findObjectGroupById(int $groupId): ?ObjectGroup
{
return $this->user->objectGroups()->where('id', $groupId)->first();
}
- /**
- * @param string $title
- *
- * @return ObjectGroup|null
- */
protected function findOrCreateObjectGroup(string $title): ?ObjectGroup
{
$title = substr($title, 0, 255);
@@ -64,29 +54,16 @@ trait CreatesObjectGroups
return $this->findObjectGroup($title);
}
- /**
- * @return int
- */
protected function getObjectGroupMaxOrder(): int
{
return (int)$this->user->objectGroups()->max('order');
}
- /**
- * @param string $title
- *
- * @return bool
- */
protected function hasObjectGroup(string $title): bool
{
return 1 === $this->user->objectGroups()->where('title', $title)->count();
}
- /**
- * @param string $title
- *
- * @return null|ObjectGroup
- */
protected function findObjectGroup(string $title): ?ObjectGroup
{
return $this->user->objectGroups()->where('title', $title)->first();
diff --git a/app/Repositories/ObjectGroup/ObjectGroupRepository.php b/app/Repositories/ObjectGroup/ObjectGroupRepository.php
index a82c9b7f9d..2d60e7eace 100644
--- a/app/Repositories/ObjectGroup/ObjectGroupRepository.php
+++ b/app/Repositories/ObjectGroup/ObjectGroupRepository.php
@@ -24,13 +24,11 @@ declare(strict_types=1);
namespace FireflyIII\Repositories\ObjectGroup;
-use DB;
use FireflyIII\Models\ObjectGroup;
use FireflyIII\Models\PiggyBank;
use FireflyIII\User;
use Illuminate\Contracts\Auth\Authenticatable;
use Illuminate\Support\Collection;
-use Illuminate\Support\Facades\Log;
/**
* Class ObjectGroupRepository
@@ -39,12 +37,10 @@ class ObjectGroupRepository implements ObjectGroupRepositoryInterface
{
private User $user;
- /**
- * @inheritDoc
- */
public function deleteAll(): void
{
$all = $this->get();
+
/** @var ObjectGroup $group */
foreach ($all as $group) {
$group->piggyBanks()->sync([]);
@@ -53,38 +49,32 @@ class ObjectGroupRepository implements ObjectGroupRepositoryInterface
}
}
- /**
- * @inheritDoc
- */
public function get(): Collection
{
return $this->user->objectGroups()
- ->with(['piggyBanks', 'bills'])
- ->orderBy('order', 'ASC')
- ->orderBy('title', 'ASC')->get();
+ ->with(['piggyBanks', 'bills'])
+ ->orderBy('order', 'ASC')
+ ->orderBy('title', 'ASC')->get()
+ ;
}
- /**
- * @inheritDoc
- */
public function deleteEmpty(): void
{
$all = $this->get();
+
/** @var ObjectGroup $group */
foreach ($all as $group) {
- $count = DB::table('object_groupables')->where('object_groupables.object_group_id', $group->id)->count();
+ $count = \DB::table('object_groupables')->where('object_groupables.object_group_id', $group->id)->count();
if (0 === $count) {
$group->delete();
}
}
}
- /**
- * @inheritDoc
- */
public function destroy(ObjectGroup $objectGroup): void
{
$list = $objectGroup->piggyBanks;
+
/** @var PiggyBank $piggy */
foreach ($list as $piggy) {
$piggy->objectGroups()->sync([]);
@@ -93,49 +83,35 @@ class ObjectGroupRepository implements ObjectGroupRepositoryInterface
$objectGroup->delete();
}
- /**
- * @inheritDoc
- */
public function getBills(ObjectGroup $objectGroup): Collection
{
return $objectGroup->bills;
}
- /**
- * @inheritDoc
- */
public function getPiggyBanks(ObjectGroup $objectGroup): Collection
{
return $objectGroup->piggyBanks;
}
- /**
- * @inheritDoc
- */
public function resetOrder(): void
{
- Log::debug('Now in resetOrder');
+ app('log')->debug('Now in resetOrder');
$list = $this->get();
$index = 1;
+
/** @var ObjectGroup $objectGroup */
foreach ($list as $objectGroup) {
- if ($index !== (int)$objectGroup->order) {
- Log::debug(
+ if ($index !== $objectGroup->order) {
+ app('log')->debug(
sprintf('objectGroup #%d ("%s"): order should %d be but is %d.', $objectGroup->id, $objectGroup->title, $index, $objectGroup->order)
);
$objectGroup->order = $index;
$objectGroup->save();
}
- $index++;
+ ++$index;
}
}
- /**
- * @param string $query
- * @param int $limit
- *
- * @return Collection
- */
public function search(string $query, int $limit): Collection
{
$dbQuery = $this->user->objectGroups()->orderBy('order', 'ASC')->orderBy('title', 'ASC');
@@ -151,19 +127,13 @@ class ObjectGroupRepository implements ObjectGroupRepositoryInterface
return $dbQuery->take($limit)->get(['object_groups.*']);
}
- /**
- * @param User|Authenticatable|null $user
- */
- public function setUser(User | Authenticatable | null $user): void
+ public function setUser(null|Authenticatable|User $user): void
{
- if (null !== $user) {
+ if ($user instanceof User) {
$this->user = $user;
}
}
- /**
- * @inheritDoc
- */
public function update(ObjectGroup $objectGroup, array $data): ObjectGroup
{
if (array_key_exists('title', $data)) {
@@ -179,31 +149,30 @@ class ObjectGroupRepository implements ObjectGroupRepositoryInterface
return $objectGroup;
}
- /**
- * @inheritDoc
- */
public function setOrder(ObjectGroup $objectGroup, int $newOrder): ObjectGroup
{
- $oldOrder = (int)$objectGroup->order;
+ $oldOrder = $objectGroup->order;
if ($newOrder > $oldOrder) {
$this->user->objectGroups()->where('object_groups.order', '<=', $newOrder)->where('object_groups.order', '>', $oldOrder)
- ->where('object_groups.id', '!=', $objectGroup->id)
- ->decrement('object_groups.order');
+ ->where('object_groups.id', '!=', $objectGroup->id)
+ ->decrement('object_groups.order')
+ ;
$objectGroup->order = $newOrder;
$objectGroup->save();
}
if ($newOrder < $oldOrder) {
$this->user->objectGroups()->where('object_groups.order', '>=', $newOrder)->where('object_groups.order', '<', $oldOrder)
- ->where('object_groups.id', '!=', $objectGroup->id)
- ->increment('object_groups.order');
+ ->where('object_groups.id', '!=', $objectGroup->id)
+ ->increment('object_groups.order')
+ ;
$objectGroup->order = $newOrder;
$objectGroup->save();
}
- Log::debug(sprintf('Objectgroup #%d order is now %d', $objectGroup->id, $newOrder));
+ app('log')->debug(sprintf('Objectgroup #%d order is now %d', $objectGroup->id, $newOrder));
return $objectGroup;
}
diff --git a/app/Repositories/ObjectGroup/ObjectGroupRepositoryInterface.php b/app/Repositories/ObjectGroup/ObjectGroupRepositoryInterface.php
index 6f0c2382c0..0232de5ef6 100644
--- a/app/Repositories/ObjectGroup/ObjectGroupRepositoryInterface.php
+++ b/app/Repositories/ObjectGroup/ObjectGroupRepositoryInterface.php
@@ -44,28 +44,12 @@ interface ObjectGroupRepositoryInterface
*/
public function deleteEmpty(): void;
- /**
- * @param ObjectGroup $objectGroup
- */
public function destroy(ObjectGroup $objectGroup): void;
- /**
- * @return Collection
- */
public function get(): Collection;
- /**
- * @param ObjectGroup $objectGroup
- *
- * @return Collection
- */
public function getBills(ObjectGroup $objectGroup): Collection;
- /**
- * @param ObjectGroup $objectGroup
- *
- * @return Collection
- */
public function getPiggyBanks(ObjectGroup $objectGroup): Collection;
/**
@@ -73,32 +57,11 @@ interface ObjectGroupRepositoryInterface
*/
public function resetOrder(): void;
- /**
- * @param string $query
- * @param int $limit
- *
- * @return Collection
- */
public function search(string $query, int $limit): Collection;
- /**
- * @param ObjectGroup $objectGroup
- * @param int $newOrder
- *
- * @return ObjectGroup
- */
public function setOrder(ObjectGroup $objectGroup, int $newOrder): ObjectGroup;
- /**
- * @param User|Authenticatable|null $user
- */
- public function setUser(User | Authenticatable | null $user): void;
+ public function setUser(null|Authenticatable|User $user): void;
- /**
- * @param ObjectGroup $objectGroup
- * @param array $data
- *
- * @return ObjectGroup
- */
public function update(ObjectGroup $objectGroup, array $data): ObjectGroup;
}
diff --git a/app/Repositories/ObjectGroup/OrganisesObjectGroups.php b/app/Repositories/ObjectGroup/OrganisesObjectGroups.php
index 1b1e53aaa7..4f23af15a5 100644
--- a/app/Repositories/ObjectGroup/OrganisesObjectGroups.php
+++ b/app/Repositories/ObjectGroup/OrganisesObjectGroups.php
@@ -29,27 +29,18 @@ namespace FireflyIII\Repositories\ObjectGroup;
*/
trait OrganisesObjectGroups
{
- /**
- *
- */
protected function cleanupObjectGroups(): void
{
$this->deleteEmptyObjectGroups();
$this->sortObjectGroups();
}
- /**
- *
- */
private function deleteEmptyObjectGroups(): void
{
$repository = app(ObjectGroupRepositoryInterface::class);
$repository->deleteEmpty();
}
- /**
- *
- */
private function sortObjectGroups(): void
{
$repository = app(ObjectGroupRepositoryInterface::class);
diff --git a/app/Repositories/PiggyBank/ModifiesPiggyBanks.php b/app/Repositories/PiggyBank/ModifiesPiggyBanks.php
index b8e8392e26..0fbf31de71 100644
--- a/app/Repositories/PiggyBank/ModifiesPiggyBanks.php
+++ b/app/Repositories/PiggyBank/ModifiesPiggyBanks.php
@@ -24,9 +24,7 @@ declare(strict_types=1);
namespace FireflyIII\Repositories\PiggyBank;
-use Exception;
use FireflyIII\Events\Model\PiggyBank\ChangedAmount;
-use FireflyIII\Events\Model\PiggyBank\ChangedPiggyBankAmount;
use FireflyIII\Exceptions\FireflyException;
use FireflyIII\Models\Note;
use FireflyIII\Models\PiggyBank;
@@ -34,8 +32,6 @@ use FireflyIII\Models\PiggyBankRepetition;
use FireflyIII\Models\TransactionJournal;
use FireflyIII\Repositories\ObjectGroup\CreatesObjectGroups;
use Illuminate\Database\QueryException;
-use Illuminate\Support\Facades\Log;
-use JsonException;
/**
* Trait ModifiesPiggyBanks
@@ -44,58 +40,37 @@ trait ModifiesPiggyBanks
{
use CreatesObjectGroups;
- /**
- * @param PiggyBankRepetition $repetition
- * @param string $amount
- * @param TransactionJournal $journal
- *
- * @return void
- */
public function addAmountToRepetition(PiggyBankRepetition $repetition, string $amount, TransactionJournal $journal): void
{
- Log::debug(sprintf('addAmountToRepetition: %s', $amount));
+ app('log')->debug(sprintf('addAmountToRepetition: %s', $amount));
if (-1 === bccomp($amount, '0')) {
- Log::debug('Remove amount.');
+ app('log')->debug('Remove amount.');
$this->removeAmount($repetition->piggyBank, bcmul($amount, '-1'), $journal);
}
if (1 === bccomp($amount, '0')) {
- Log::debug('Add amount.');
+ app('log')->debug('Add amount.');
$this->addAmount($repetition->piggyBank, $amount, $journal);
}
}
- /**
- * @param PiggyBank $piggyBank
- * @param string $amount
- * @param TransactionJournal|null $journal
- *
- * @return bool
- */
public function removeAmount(PiggyBank $piggyBank, string $amount, ?TransactionJournal $journal = null): bool
{
- $repetition = $this->getRepetition($piggyBank);
+ $repetition = $this->getRepetition($piggyBank);
if (null === $repetition) {
return false;
}
$repetition->currentamount = bcsub($repetition->currentamount, $amount);
$repetition->save();
- Log::debug('addAmount [a]: Trigger change for negative amount.');
+ app('log')->debug('addAmount [a]: Trigger change for negative amount.');
event(new ChangedAmount($piggyBank, bcmul($amount, '-1'), $journal, null));
return true;
}
- /**
- * @param PiggyBank $piggyBank
- * @param string $amount
- * @param TransactionJournal|null $journal
- *
- * @return bool
- */
public function addAmount(PiggyBank $piggyBank, string $amount, ?TransactionJournal $journal = null): bool
{
- $repetition = $this->getRepetition($piggyBank);
+ $repetition = $this->getRepetition($piggyBank);
if (null === $repetition) {
return false;
}
@@ -103,24 +78,17 @@ trait ModifiesPiggyBanks
$repetition->currentamount = bcadd($currentAmount, $amount);
$repetition->save();
- Log::debug('addAmount [b]: Trigger change for positive amount.');
+ app('log')->debug('addAmount [b]: Trigger change for positive amount.');
event(new ChangedAmount($piggyBank, $amount, $journal, null));
return true;
}
- /**
- * @param PiggyBank $piggyBank
- * @param string $amount
- *
- * @return bool
- * @throws JsonException
- */
public function canAddAmount(PiggyBank $piggyBank, string $amount): bool
{
$today = today(config('app.timezone'));
$leftOnAccount = $this->leftOnAccount($piggyBank, $today);
- $savedSoFar = (string)$this->getRepetition($piggyBank)->currentamount;
+ $savedSoFar = $this->getRepetition($piggyBank)->currentamount;
$maxAmount = $leftOnAccount;
$leftToSave = null;
if (0 !== bccomp($piggyBank->targetamount, '0')) {
@@ -128,24 +96,18 @@ trait ModifiesPiggyBanks
$maxAmount = 1 === bccomp($leftOnAccount, $leftToSave) ? $leftToSave : $leftOnAccount;
}
- $compare = bccomp($amount, $maxAmount);
- $result = $compare <= 0;
+ $compare = bccomp($amount, $maxAmount);
+ $result = $compare <= 0;
- Log::debug(sprintf('Left on account: %s on %s', $leftOnAccount, $today->format('Y-m-d')));
- Log::debug(sprintf('Saved so far: %s', $savedSoFar));
- Log::debug(sprintf('Left to save: %s', $leftToSave));
- Log::debug(sprintf('Maximum amount: %s', $maxAmount));
- Log::debug(sprintf('Compare <= 0? %d, so %s', $compare, var_export($result, true)));
+ app('log')->debug(sprintf('Left on account: %s on %s', $leftOnAccount, $today->format('Y-m-d')));
+ app('log')->debug(sprintf('Saved so far: %s', $savedSoFar));
+ app('log')->debug(sprintf('Left to save: %s', $leftToSave));
+ app('log')->debug(sprintf('Maximum amount: %s', $maxAmount));
+ app('log')->debug(sprintf('Compare <= 0? %d, so %s', $compare, var_export($result, true)));
return $result;
}
- /**
- * @param PiggyBank $piggyBank
- * @param string $amount
- *
- * @return bool
- */
public function canRemoveAmount(PiggyBank $piggyBank, string $amount): bool
{
$repetition = $this->getRepetition($piggyBank);
@@ -158,10 +120,7 @@ trait ModifiesPiggyBanks
}
/**
- * @param PiggyBank $piggyBank
- *
- * @return bool
- * @throws Exception
+ * @throws \Exception
*/
public function destroy(PiggyBank $piggyBank): bool
{
@@ -171,9 +130,6 @@ trait ModifiesPiggyBanks
return true;
}
- /**
- * @inheritDoc
- */
public function removeObjectGroup(PiggyBank $piggyBank): PiggyBank
{
$piggyBank->objectGroups()->sync([]);
@@ -181,19 +137,13 @@ trait ModifiesPiggyBanks
return $piggyBank;
}
- /**
- * @param PiggyBank $piggyBank
- * @param string $amount
- *
- * @return PiggyBank
- */
public function setCurrentAmount(PiggyBank $piggyBank, string $amount): PiggyBank
{
- $repetition = $this->getRepetition($piggyBank);
+ $repetition = $this->getRepetition($piggyBank);
if (null === $repetition) {
return $piggyBank;
}
- $max = $piggyBank->targetamount;
+ $max = $piggyBank->targetamount;
if (1 === bccomp($amount, $max) && 0 !== bccomp($piggyBank->targetamount, '0')) {
$amount = $max;
}
@@ -202,20 +152,17 @@ trait ModifiesPiggyBanks
$repetition->save();
if (-1 === bccomp($difference, '0')) {
- Log::debug('addAmount [c]: Trigger change for negative amount.');
+ app('log')->debug('addAmount [c]: Trigger change for negative amount.');
event(new ChangedAmount($piggyBank, $difference, null, null));
}
if (1 === bccomp($difference, '0')) {
- Log::debug('addAmount [d]: Trigger change for positive amount.');
+ app('log')->debug('addAmount [d]: Trigger change for positive amount.');
event(new ChangedAmount($piggyBank, $difference, null, null));
}
return $piggyBank;
}
- /**
- * @inheritDoc
- */
public function setObjectGroup(PiggyBank $piggyBank, string $objectGroupTitle): PiggyBank
{
$objectGroup = $this->findOrCreateObjectGroup($objectGroupTitle);
@@ -227,19 +174,16 @@ trait ModifiesPiggyBanks
}
/**
- * @param array $data
- *
- * @return PiggyBank
* @throws FireflyException
*/
public function store(array $data): PiggyBank
{
- $order = $this->getMaxOrder() + 1;
+ $order = $this->getMaxOrder() + 1;
if (array_key_exists('order', $data)) {
$order = $data['order'];
}
- $data['order'] = 31337; // very high when creating.
- $piggyData = $data;
+ $data['order'] = 31337; // very high when creating.
+ $piggyData = $data;
// unset fields just in case.
unset($piggyData['object_group_title'], $piggyData['object_group_id'], $piggyData['notes'], $piggyData['current_amount']);
@@ -252,7 +196,8 @@ trait ModifiesPiggyBanks
/** @var PiggyBank $piggyBank */
$piggyBank = PiggyBank::create($piggyData);
} catch (QueryException $e) {
- Log::error(sprintf('Could not store piggy bank: %s', $e->getMessage()), $piggyData);
+ app('log')->error(sprintf('Could not store piggy bank: %s', $e->getMessage()), $piggyData);
+
throw new FireflyException('400005: Could not store new piggy bank.', 0, $e);
}
@@ -263,7 +208,7 @@ trait ModifiesPiggyBanks
$this->updateNote($piggyBank, $data['notes']);
// repetition is auto created.
- $repetition = $this->getRepetition($piggyBank);
+ $repetition = $this->getRepetition($piggyBank);
if (null !== $repetition && array_key_exists('current_amount', $data) && '' !== $data['current_amount']) {
$repetition->currentamount = $data['current_amount'];
$repetition->save();
@@ -278,7 +223,7 @@ trait ModifiesPiggyBanks
}
}
// try also with ID
- $objectGroupId = (int)($data['object_group_id'] ?? 0);
+ $objectGroupId = (int)($data['object_group_id'] ?? 0);
if (0 !== $objectGroupId) {
$objectGroup = $this->findObjectGroupById($objectGroupId);
if (null !== $objectGroup) {
@@ -298,49 +243,42 @@ trait ModifiesPiggyBanks
$set = $this->user->piggyBanks()->orderBy('piggy_banks.order', 'ASC')->get(['piggy_banks.*']);
$current = 1;
foreach ($set as $piggyBank) {
- if ((int)$piggyBank->order !== $current) {
- Log::debug(sprintf('Piggy bank #%d ("%s") was at place %d but should be on %d', $piggyBank->id, $piggyBank->name, $piggyBank->order, $current));
+ if ($piggyBank->order !== $current) {
+ app('log')->debug(sprintf('Piggy bank #%d ("%s") was at place %d but should be on %d', $piggyBank->id, $piggyBank->name, $piggyBank->order, $current));
$piggyBank->order = $current;
$piggyBank->save();
}
- $current++;
+ ++$current;
}
}
- /**
- * @inheritDoc
- */
public function setOrder(PiggyBank $piggyBank, int $newOrder): bool
{
- $oldOrder = (int)$piggyBank->order;
- Log::debug(sprintf('Will move piggy bank #%d ("%s") from %d to %d', $piggyBank->id, $piggyBank->name, $oldOrder, $newOrder));
+ $oldOrder = $piggyBank->order;
+ // app('log')->debug(sprintf('Will move piggy bank #%d ("%s") from %d to %d', $piggyBank->id, $piggyBank->name, $oldOrder, $newOrder));
if ($newOrder > $oldOrder) {
$this->user->piggyBanks()->where('piggy_banks.order', '<=', $newOrder)->where('piggy_banks.order', '>', $oldOrder)
- ->where('piggy_banks.id', '!=', $piggyBank->id)
- ->decrement('piggy_banks.order');
+ ->where('piggy_banks.id', '!=', $piggyBank->id)
+ ->decrement('piggy_banks.order')
+ ;
$piggyBank->order = $newOrder;
- Log::debug(sprintf('Order of piggy #%d ("%s") is now %d', $piggyBank->id, $piggyBank->name, $newOrder));
+ app('log')->debug(sprintf('[1] Order of piggy #%d ("%s") from %d to %d', $piggyBank->id, $piggyBank->name, $oldOrder, $newOrder));
$piggyBank->save();
return true;
}
$this->user->piggyBanks()->where('piggy_banks.order', '>=', $newOrder)->where('piggy_banks.order', '<', $oldOrder)
- ->where('piggy_banks.id', '!=', $piggyBank->id)
- ->increment('piggy_banks.order');
+ ->where('piggy_banks.id', '!=', $piggyBank->id)
+ ->increment('piggy_banks.order')
+ ;
$piggyBank->order = $newOrder;
- Log::debug(sprintf('Order of piggy #%d ("%s") is now %d', $piggyBank->id, $piggyBank->name, $newOrder));
+ app('log')->debug(sprintf('[2] Order of piggy #%d ("%s") from %d to %d', $piggyBank->id, $piggyBank->name, $oldOrder, $newOrder));
$piggyBank->save();
return true;
}
- /**
- * @param PiggyBank $piggyBank
- * @param string $note
- *
- * @return bool
- */
private function updateNote(PiggyBank $piggyBank, string $note): bool
{
if ('' === $note) {
@@ -349,7 +287,7 @@ trait ModifiesPiggyBanks
return true;
}
- $dbNote = $piggyBank->notes()->first();
+ $dbNote = $piggyBank->notes()->first();
if (null === $dbNote) {
$dbNote = new Note();
$dbNote->noteable()->associate($piggyBank);
@@ -360,22 +298,16 @@ trait ModifiesPiggyBanks
return true;
}
- /**
- * @param PiggyBank $piggyBank
- * @param array $data
- *
- * @return PiggyBank
- */
public function update(PiggyBank $piggyBank, array $data): PiggyBank
{
- $piggyBank = $this->updateProperties($piggyBank, $data);
+ $piggyBank = $this->updateProperties($piggyBank, $data);
if (array_key_exists('notes', $data)) {
$this->updateNote($piggyBank, (string)$data['notes']);
}
// update the order of the piggy bank:
- $oldOrder = (int)$piggyBank->order;
- $newOrder = (int)($data['order'] ?? $oldOrder);
+ $oldOrder = $piggyBank->order;
+ $newOrder = (int)($data['order'] ?? $oldOrder);
if ($oldOrder !== $newOrder) {
$this->setOrder($piggyBank, $newOrder);
}
@@ -384,7 +316,7 @@ trait ModifiesPiggyBanks
// remove money from the rep.
$repetition = $this->getRepetition($piggyBank);
if (null !== $repetition && $repetition->currentamount > $piggyBank->targetamount && 0 !== bccomp($piggyBank->targetamount, '0')) {
- $difference = bcsub($piggyBank->targetamount, $repetition->currentamount);
+ $difference = bcsub($piggyBank->targetamount, $repetition->currentamount);
// an amount will be removed, create "negative" event:
event(new ChangedAmount($piggyBank, $difference, null, null));
@@ -405,11 +337,8 @@ trait ModifiesPiggyBanks
return $piggyBank;
}
- // remove if name is empty. Should be overruled by ID.
- if ('' === $objectGroupTitle) {
- $piggyBank->objectGroups()->sync([]);
- $piggyBank->save();
- }
+ $piggyBank->objectGroups()->sync([]);
+ $piggyBank->save();
}
// try also with ID:
@@ -429,12 +358,6 @@ trait ModifiesPiggyBanks
return $piggyBank;
}
- /**
- * @param PiggyBank $piggyBank
- * @param array $data
- *
- * @return PiggyBank
- */
private function updateProperties(PiggyBank $piggyBank, array $data): PiggyBank
{
if (array_key_exists('name', $data) && '' !== $data['name']) {
diff --git a/app/Repositories/PiggyBank/PiggyBankRepository.php b/app/Repositories/PiggyBank/PiggyBankRepository.php
index 95288dd956..0e55fc4265 100644
--- a/app/Repositories/PiggyBank/PiggyBankRepository.php
+++ b/app/Repositories/PiggyBank/PiggyBankRepository.php
@@ -37,12 +37,9 @@ use FireflyIII\User;
use Illuminate\Contracts\Auth\Authenticatable;
use Illuminate\Support\Collection;
use Illuminate\Support\Facades\Log;
-use JsonException;
-use Storage;
/**
* Class PiggyBankRepository.
- *
*/
class PiggyBankRepository implements PiggyBankRepositoryInterface
{
@@ -50,50 +47,37 @@ class PiggyBankRepository implements PiggyBankRepositoryInterface
private User $user;
- /**
- * @inheritDoc
- */
public function destroyAll(): void
{
+ Log::channel('audit')->info('Delete all piggy banks through destroyAll');
$this->user->piggyBanks()->delete();
}
- /**
- * @param int|null $piggyBankId
- * @param string|null $piggyBankName
- *
- * @return PiggyBank|null
- */
public function findPiggyBank(?int $piggyBankId, ?string $piggyBankName): ?PiggyBank
{
- Log::debug('Searching for piggy information.');
+ app('log')->debug('Searching for piggy information.');
if (null !== $piggyBankId) {
- $searchResult = $this->find((int)$piggyBankId);
+ $searchResult = $this->find($piggyBankId);
if (null !== $searchResult) {
- Log::debug(sprintf('Found piggy based on #%d, will return it.', $piggyBankId));
+ app('log')->debug(sprintf('Found piggy based on #%d, will return it.', $piggyBankId));
return $searchResult;
}
}
if (null !== $piggyBankName) {
- $searchResult = $this->findByName((string)$piggyBankName);
+ $searchResult = $this->findByName($piggyBankName);
if (null !== $searchResult) {
- Log::debug(sprintf('Found piggy based on "%s", will return it.', $piggyBankName));
+ app('log')->debug(sprintf('Found piggy based on "%s", will return it.', $piggyBankName));
return $searchResult;
}
}
- Log::debug('Found nothing');
+ app('log')->debug('Found nothing');
return null;
}
- /**
- * @param int $piggyBankId
- *
- * @return PiggyBank|null
- */
public function find(int $piggyBankId): ?PiggyBank
{
// phpstan doesn't get the Model.
@@ -102,31 +86,24 @@ class PiggyBankRepository implements PiggyBankRepositoryInterface
/**
* Find by name or return NULL.
- *
- * @param string $name
- *
- * @return PiggyBank|null
*/
public function findByName(string $name): ?PiggyBank
{
return $this->user->piggyBanks()->where('piggy_banks.name', $name)->first(['piggy_banks.*']);
}
- /**
- * @inheritDoc
- */
public function getAttachments(PiggyBank $piggyBank): Collection
{
- $set = $piggyBank->attachments()->get();
+ $set = $piggyBank->attachments()->get();
- /** @var Storage $disk */
- $disk = Storage::disk('upload');
+ /** @var \Storage $disk */
+ $disk = \Storage::disk('upload');
return $set->each(
static function (Attachment $attachment) use ($disk) {
$notes = $attachment->notes()->first();
$attachment->file_exists = $disk->exists($attachment->fileName());
- $attachment->notes = $notes ? $notes->text : ''; // TODO setting the text to the 'notes' field doesn't work.
+ $attachment->notes_text = null !== $notes ? $notes->text : '';
return $attachment;
}
@@ -135,10 +112,6 @@ class PiggyBankRepository implements PiggyBankRepositoryInterface
/**
* Get current amount saved in piggy bank.
- *
- * @param PiggyBank $piggyBank
- *
- * @return string
*/
public function getCurrentAmount(PiggyBank $piggyBank): string
{
@@ -147,24 +120,14 @@ class PiggyBankRepository implements PiggyBankRepositoryInterface
return '0';
}
- return (string)$rep->currentamount;
+ return $rep->currentamount;
}
- /**
- * @param PiggyBank $piggyBank
- *
- * @return PiggyBankRepetition|null
- */
public function getRepetition(PiggyBank $piggyBank): ?PiggyBankRepetition
{
return $piggyBank->piggyBankRepetitions()->first();
}
- /**
- * @param PiggyBank $piggyBank
- *
- * @return Collection
- */
public function getEvents(PiggyBank $piggyBank): Collection
{
return $piggyBank->piggyBankEvents()->orderBy('date', 'DESC')->orderBy('id', 'DESC')->get();
@@ -173,100 +136,96 @@ class PiggyBankRepository implements PiggyBankRepositoryInterface
/**
* Used for connecting to a piggy bank.
*
- * @param PiggyBank $piggyBank
- * @param PiggyBankRepetition $repetition
- * @param TransactionJournal $journal
- *
- * @return string
* @throws FireflyException
- * @throws JsonException
*/
public function getExactAmount(PiggyBank $piggyBank, PiggyBankRepetition $repetition, TransactionJournal $journal): string
{
- Log::debug(sprintf('Now in getExactAmount(%d, %d, %d)', $piggyBank->id, $repetition->id, $journal->id));
+ app('log')->debug(sprintf('Now in getExactAmount(%d, %d, %d)', $piggyBank->id, $repetition->id, $journal->id));
+
+ $operator = null;
+ $currency = null;
- $operator = null;
- $currency = null;
/** @var JournalRepositoryInterface $journalRepost */
- $journalRepost = app(JournalRepositoryInterface::class);
+ $journalRepost = app(JournalRepositoryInterface::class);
$journalRepost->setUser($this->user);
/** @var AccountRepositoryInterface $accountRepos */
- $accountRepos = app(AccountRepositoryInterface::class);
+ $accountRepos = app(AccountRepositoryInterface::class);
$accountRepos->setUser($this->user);
- $defaultCurrency = app('amount')->getDefaultCurrencyByUser($this->user);
+ $defaultCurrency = app('amount')->getDefaultCurrencyByUserGroup($this->user->userGroup);
$piggyBankCurrency = $accountRepos->getAccountCurrency($piggyBank->account) ?? $defaultCurrency;
- Log::debug(sprintf('Piggy bank #%d currency is %s', $piggyBank->id, $piggyBankCurrency->code));
+ app('log')->debug(sprintf('Piggy bank #%d currency is %s', $piggyBank->id, $piggyBankCurrency->code));
/** @var Transaction $source */
- $source = $journal->transactions()->with(['account'])->where('amount', '<', 0)->first();
+ $source = $journal->transactions()->with(['account'])->where('amount', '<', 0)->first();
+
/** @var Transaction $destination */
- $destination = $journal->transactions()->with(['account'])->where('amount', '>', 0)->first();
+ $destination = $journal->transactions()->with(['account'])->where('amount', '>', 0)->first();
// matches source, which means amount will be removed from piggy:
if ($source->account_id === $piggyBank->account_id) {
$operator = 'negative';
$currency = $accountRepos->getAccountCurrency($source->account) ?? $defaultCurrency;
- Log::debug(sprintf('Currency will draw money out of piggy bank. Source currency is %s', $currency->code));
+ app('log')->debug(sprintf('Currency will draw money out of piggy bank. Source currency is %s', $currency->code));
}
// matches destination, which means amount will be added to piggy.
if ($destination->account_id === $piggyBank->account_id) {
$operator = 'positive';
$currency = $accountRepos->getAccountCurrency($destination->account) ?? $defaultCurrency;
- Log::debug(sprintf('Currency will add money to piggy bank. Destination currency is %s', $currency->code));
+ app('log')->debug(sprintf('Currency will add money to piggy bank. Destination currency is %s', $currency->code));
}
if (null === $operator || null === $currency) {
- Log::debug('Currency is NULL and operator is NULL, return "0".');
+ app('log')->debug('Currency is NULL and operator is NULL, return "0".');
return '0';
}
// currency of the account + the piggy bank currency are almost the same.
// which amount from the transaction matches?
- $amount = null;
- if ((int)$source->transaction_currency_id === (int)$currency->id) {
- Log::debug('Use normal amount');
- $amount = app('steam')->$operator($source->amount);
+ $amount = null;
+ if ((int)$source->transaction_currency_id === $currency->id) {
+ app('log')->debug('Use normal amount');
+ $amount = app('steam')->{$operator}($source->amount); // @phpstan-ignore-line
}
- if ((int)$source->foreign_currency_id === (int)$currency->id) {
- Log::debug('Use foreign amount');
- $amount = app('steam')->$operator($source->foreign_amount);
+ if ((int)$source->foreign_currency_id === $currency->id) {
+ app('log')->debug('Use foreign amount');
+ $amount = app('steam')->{$operator}($source->foreign_amount); // @phpstan-ignore-line
}
if (null === $amount) {
- Log::debug('No match on currency, so amount remains null, return "0".');
+ app('log')->debug('No match on currency, so amount remains null, return "0".');
return '0';
}
- Log::debug(sprintf('The currency is %s and the amount is %s', $currency->code, $amount));
- $room = bcsub((string)$piggyBank->targetamount, (string)$repetition->currentamount);
- $compare = bcmul($repetition->currentamount, '-1');
+ app('log')->debug(sprintf('The currency is %s and the amount is %s', $currency->code, $amount));
+ $room = bcsub($piggyBank->targetamount, $repetition->currentamount);
+ $compare = bcmul($repetition->currentamount, '-1');
- if (bccomp((string)$piggyBank->targetamount, '0') === 0) {
+ if (0 === bccomp($piggyBank->targetamount, '0')) {
// amount is zero? then the "room" is positive amount of we wish to add or remove.
$room = app('steam')->positive($amount);
- Log::debug(sprintf('Room is now %s', $room));
+ app('log')->debug(sprintf('Room is now %s', $room));
}
- Log::debug(sprintf('Will add/remove %f to piggy bank #%d ("%s")', $amount, $piggyBank->id, $piggyBank->name));
+ app('log')->debug(sprintf('Will add/remove %f to piggy bank #%d ("%s")', $amount, $piggyBank->id, $piggyBank->name));
// if the amount is positive, make sure it fits in piggy bank:
- if (1 === bccomp($amount, '0') && bccomp($room, $amount) === -1) {
+ if (1 === bccomp($amount, '0') && -1 === bccomp($room, $amount)) {
// amount is positive and $room is smaller than $amount
- Log::debug(sprintf('Room in piggy bank for extra money is %f', $room));
- Log::debug(sprintf('There is NO room to add %f to piggy bank #%d ("%s")', $amount, $piggyBank->id, $piggyBank->name));
- Log::debug(sprintf('New amount is %f', $room));
+ app('log')->debug(sprintf('Room in piggy bank for extra money is %f', $room));
+ app('log')->debug(sprintf('There is NO room to add %f to piggy bank #%d ("%s")', $amount, $piggyBank->id, $piggyBank->name));
+ app('log')->debug(sprintf('New amount is %f', $room));
return $room;
}
// amount is negative and $currentamount is smaller than $amount
- if (bccomp($amount, '0') === -1 && 1 === bccomp($compare, $amount)) {
- Log::debug(sprintf('Max amount to remove is %f', $repetition->currentamount));
- Log::debug(sprintf('Cannot remove %f from piggy bank #%d ("%s")', $amount, $piggyBank->id, $piggyBank->name));
- Log::debug(sprintf('New amount is %f', $compare));
+ if (-1 === bccomp($amount, '0') && 1 === bccomp($compare, $amount)) {
+ app('log')->debug(sprintf('Max amount to remove is %f', $repetition->currentamount));
+ app('log')->debug(sprintf('Cannot remove %f from piggy bank #%d ("%s")', $amount, $piggyBank->id, $piggyBank->name));
+ app('log')->debug(sprintf('New amount is %f', $compare));
return $compare;
}
@@ -274,19 +233,13 @@ class PiggyBankRepository implements PiggyBankRepositoryInterface
return (string)$amount;
}
- /**
- * @param User|Authenticatable|null $user
- */
- public function setUser(User | Authenticatable | null $user): void
+ public function setUser(null|Authenticatable|User $user): void
{
- if (null !== $user) {
+ if ($user instanceof User) {
$this->user = $user;
}
}
- /**
- * @return int
- */
public function getMaxOrder(): int
{
return (int)$this->user->piggyBanks()->max('piggy_banks.order');
@@ -294,65 +247,49 @@ class PiggyBankRepository implements PiggyBankRepositoryInterface
/**
* Return note for piggy bank.
- *
- * @param PiggyBank $piggyBank
- *
- * @return string
*/
public function getNoteText(PiggyBank $piggyBank): string
{
- /** @var Note $note */
+ /** @var null|Note $note */
$note = $piggyBank->notes()->first();
- if (null === $note) {
- return '';
- }
- return $note->text;
+ return (string)$note?->text;
}
/**
* Also add amount in name.
- *
- * @return Collection
*/
public function getPiggyBanksWithAmount(): Collection
{
$currency = app('amount')->getDefaultCurrency();
- $set = $this->getPiggyBanks();
+ $set = $this->getPiggyBanks();
/** @var PiggyBank $piggy */
foreach ($set as $piggy) {
$currentAmount = $this->getRepetition($piggy)->currentamount ?? '0';
- $piggy->name = $piggy->name . ' (' . app('amount')->formatAnything($currency, $currentAmount, false) . ')';
+ $piggy->name = $piggy->name.' ('.app('amount')->formatAnything($currency, $currentAmount, false).')';
}
return $set;
}
- /**
- * @return Collection
- */
public function getPiggyBanks(): Collection
{
return $this->user // @phpstan-ignore-line (phpstan does not recognize objectGroups)
- ->piggyBanks()
- ->with(
- [
- 'account',
- 'objectGroups',
- ]
- )
- ->orderBy('order', 'ASC')->get();
+ ->piggyBanks()
+ ->with(
+ [
+ 'account',
+ 'objectGroups',
+ ]
+ )
+ ->orderBy('order', 'ASC')->get()
+ ;
}
/**
* Returns the suggested amount the user should save per month, or "".
- *
- * @param PiggyBank $piggyBank
- *
- * @return string
- *
*/
public function getSuggestedMonthlyAmount(PiggyBank $piggyBank): string
{
@@ -383,12 +320,6 @@ class PiggyBankRepository implements PiggyBankRepositoryInterface
/**
* Get for piggy account what is left to put in piggies.
- *
- * @param PiggyBank $piggyBank
- * @param Carbon $date
- *
- * @return string
- * @throws JsonException
*/
public function leftOnAccount(PiggyBank $piggyBank, Carbon $date): string
{
@@ -408,9 +339,6 @@ class PiggyBankRepository implements PiggyBankRepositoryInterface
return $balance;
}
- /**
- * @inheritDoc
- */
public function searchPiggyBank(string $query, int $limit): Collection
{
$search = $this->user->piggyBanks();
@@ -418,7 +346,8 @@ class PiggyBankRepository implements PiggyBankRepositoryInterface
$search->where('piggy_banks.name', 'LIKE', sprintf('%%%s%%', $query));
}
$search->orderBy('piggy_banks.order', 'ASC')
- ->orderBy('piggy_banks.name', 'ASC');
+ ->orderBy('piggy_banks.name', 'ASC')
+ ;
return $search->take($limit)->get();
}
diff --git a/app/Repositories/PiggyBank/PiggyBankRepositoryInterface.php b/app/Repositories/PiggyBank/PiggyBankRepositoryInterface.php
index 6a321a9587..7c1e12becc 100644
--- a/app/Repositories/PiggyBank/PiggyBankRepositoryInterface.php
+++ b/app/Repositories/PiggyBank/PiggyBankRepositoryInterface.php
@@ -37,184 +37,81 @@ use Illuminate\Support\Collection;
*/
interface PiggyBankRepositoryInterface
{
- /**
- * @param PiggyBank $piggyBank
- * @param string $amount
- * @param TransactionJournal|null $journal
- *
- * @return bool
- */
public function addAmount(PiggyBank $piggyBank, string $amount, ?TransactionJournal $journal = null): bool;
- /**
- * @param PiggyBankRepetition $repetition
- * @param string $amount
- * @param TransactionJournal $journal
- *
- * @return void
- */
public function addAmountToRepetition(PiggyBankRepetition $repetition, string $amount, TransactionJournal $journal): void;
- /**
- * @param PiggyBank $piggyBank
- * @param string $amount
- *
- * @return bool
- */
public function canAddAmount(PiggyBank $piggyBank, string $amount): bool;
- /**
- * @param PiggyBank $piggyBank
- * @param string $amount
- *
- * @return bool
- */
public function canRemoveAmount(PiggyBank $piggyBank, string $amount): bool;
/**
* Destroy piggy bank.
- *
- * @param PiggyBank $piggyBank
- *
- * @return bool
*/
public function destroy(PiggyBank $piggyBank): bool;
- /**
- *
- */
public function destroyAll(): void;
- /**
- * @param int $piggyBankId
- *
- * @return PiggyBank|null
- */
public function find(int $piggyBankId): ?PiggyBank;
/**
* Find by name or return NULL.
- *
- * @param string $name
- *
- * @return PiggyBank|null
*/
public function findByName(string $name): ?PiggyBank;
- /**
- * @param int|null $piggyBankId
- * @param string|null $piggyBankName
- *
- * @return PiggyBank|null
- */
public function findPiggyBank(?int $piggyBankId, ?string $piggyBankName): ?PiggyBank;
- /**
- * @param PiggyBank $piggyBank
- *
- * @return Collection
- */
public function getAttachments(PiggyBank $piggyBank): Collection;
/**
* Get current amount saved in piggy bank.
- *
- * @param PiggyBank $piggyBank
- *
- * @return string
*/
public function getCurrentAmount(PiggyBank $piggyBank): string;
/**
* Get all events.
- *
- * @param PiggyBank $piggyBank
- *
- * @return Collection
*/
public function getEvents(PiggyBank $piggyBank): Collection;
/**
* Used for connecting to a piggy bank.
- *
- * @param PiggyBank $piggyBank
- * @param PiggyBankRepetition $repetition
- * @param TransactionJournal $journal
- *
- * @return string
*/
public function getExactAmount(PiggyBank $piggyBank, PiggyBankRepetition $repetition, TransactionJournal $journal): string;
/**
* Highest order of all piggy banks.
- *
- * @return int
*/
public function getMaxOrder(): int;
/**
* Return note for piggy bank.
- *
- * @param PiggyBank $piggyBank
- *
- * @return string
*/
public function getNoteText(PiggyBank $piggyBank): string;
/**
* Return all piggy banks.
- *
- * @return Collection
*/
public function getPiggyBanks(): Collection;
/**
* Also add amount in name.
- *
- * @return Collection
*/
public function getPiggyBanksWithAmount(): Collection;
- /**
- * @param PiggyBank $piggyBank
- *
- * @return PiggyBankRepetition|null
- */
public function getRepetition(PiggyBank $piggyBank): ?PiggyBankRepetition;
/**
* Returns the suggested amount the user should save per month, or "".
- *
- * @param PiggyBank $piggyBank
- *
- * @return string
*/
public function getSuggestedMonthlyAmount(PiggyBank $piggyBank): string;
/**
* Get for piggy account what is left to put in piggies.
- *
- * @param PiggyBank $piggyBank
- * @param Carbon $date
- *
- * @return string
*/
public function leftOnAccount(PiggyBank $piggyBank, Carbon $date): string;
- /**
- * @param PiggyBank $piggyBank
- * @param string $amount
- * @param TransactionJournal|null $journal
- *
- * @return bool
- */
public function removeAmount(PiggyBank $piggyBank, string $amount, ?TransactionJournal $journal = null): bool;
- /**
- * @param PiggyBank $piggyBank
- *
- * @return PiggyBank
- */
public function removeObjectGroup(PiggyBank $piggyBank): PiggyBank;
/**
@@ -224,62 +121,29 @@ interface PiggyBankRepositoryInterface
/**
* Search for piggy banks.
- *
- * @param string $query
- * @param int $limit
- *
- * @return Collection
*/
public function searchPiggyBank(string $query, int $limit): Collection;
- /**
- * @param PiggyBank $piggyBank
- * @param string $amount
- *
- * @return PiggyBank
- */
public function setCurrentAmount(PiggyBank $piggyBank, string $amount): PiggyBank;
- /**
- * @param PiggyBank $piggyBank
- * @param string $objectGroupTitle
- *
- * @return PiggyBank
- */
public function setObjectGroup(PiggyBank $piggyBank, string $objectGroupTitle): PiggyBank;
/**
* Set specific piggy bank to specific order.
- *
- * @param PiggyBank $piggyBank
- * @param int $newOrder
- *
- * @return bool
*/
public function setOrder(PiggyBank $piggyBank, int $newOrder): bool;
- /**
- * @param User|Authenticatable|null $user
- */
- public function setUser(User | Authenticatable | null $user): void;
+ public function setUser(null|Authenticatable|User $user): void;
/**
* Store new piggy bank.
*
- * @param array $data
- *
- * @return PiggyBank
* @throws FireflyException
*/
public function store(array $data): PiggyBank;
/**
* Update existing piggy bank.
- *
- * @param PiggyBank $piggyBank
- * @param array $data
- *
- * @return PiggyBank
*/
public function update(PiggyBank $piggyBank, array $data): PiggyBank;
}
diff --git a/app/Repositories/Recurring/RecurringRepository.php b/app/Repositories/Recurring/RecurringRepository.php
index 5687387227..efd4f9eaa3 100644
--- a/app/Repositories/Recurring/RecurringRepository.php
+++ b/app/Repositories/Recurring/RecurringRepository.php
@@ -48,7 +48,6 @@ use Illuminate\Database\Eloquent\Builder;
use Illuminate\Pagination\LengthAwarePaginator;
use Illuminate\Support\Collection;
use Illuminate\Support\Facades\Log;
-use JsonException;
/**
* Class RecurringRepository
@@ -62,55 +61,52 @@ class RecurringRepository implements RecurringRepositoryInterface
private User $user;
- /**
- * @inheritDoc
- */
public function createdPreviously(Recurrence $recurrence, Carbon $date): bool
{
// if not, loop set and try to read the recurrence_date. If it matches start or end, return it as well.
$set
- = TransactionJournalMeta::where(function (Builder $q1) use ($recurrence) {
+ = TransactionJournalMeta::where(static function (Builder $q1) use ($recurrence): void {
$q1->where('name', 'recurrence_id');
$q1->where('data', json_encode((string)$recurrence->id));
})->get(['journal_meta.transaction_journal_id']);
// there are X journals made for this recurrence. Any of them meant for today?
foreach ($set as $journalMeta) {
- $count = TransactionJournalMeta::where(function (Builder $q2) use ($date) {
+ $count = TransactionJournalMeta::where(static function (Builder $q2) use ($date): void {
$string = (string)$date;
- Log::debug(sprintf('Search for date: %s', json_encode($string)));
+ app('log')->debug(sprintf('Search for date: %s', json_encode($string)));
$q2->where('name', 'recurrence_date');
$q2->where('data', json_encode($string));
})
- ->where('transaction_journal_id', $journalMeta->transaction_journal_id)
- ->count();
+ ->where('transaction_journal_id', $journalMeta->transaction_journal_id)
+ ->count()
+ ;
if ($count > 0) {
- Log::debug(sprintf('Looks like journal #%d was already created', $journalMeta->transaction_journal_id));
+ app('log')->debug(sprintf('Looks like journal #%d was already created', $journalMeta->transaction_journal_id));
+
return true;
}
}
+
return false;
}
/**
* Returns all of the user's recurring transactions.
- *
- * @return Collection
*/
public function get(): Collection
{
return $this->user->recurrences()
- ->with(['TransactionCurrency', 'TransactionType', 'RecurrenceRepetitions', 'RecurrenceTransactions'])
- ->orderBy('active', 'DESC')
- ->orderBy('transaction_type_id', 'ASC')
- ->orderBy('title', 'ASC')
- ->get();
+ ->with(['TransactionCurrency', 'TransactionType', 'RecurrenceRepetitions', 'RecurrenceTransactions'])
+ ->orderBy('active', 'DESC')
+ ->orderBy('transaction_type_id', 'ASC')
+ ->orderBy('title', 'ASC')
+ ->get()
+ ;
}
/**
* Destroy a recurring transaction.
- *
- * @param Recurrence $recurrence
*/
public function destroy(Recurrence $recurrence): void
{
@@ -119,34 +115,29 @@ class RecurringRepository implements RecurringRepositoryInterface
$service->destroy($recurrence);
}
- /**
- * @inheritDoc
- */
public function destroyAll(): void
{
+ Log::channel('audit')->info('Delete all recurring transactions through destroyAll');
$this->user->recurrences()->delete();
}
/**
* Get ALL recurring transactions.
- *
- * @return Collection
*/
public function getAll(): Collection
{
// grab ALL recurring transactions:
return Recurrence::with(['TransactionCurrency', 'TransactionType', 'RecurrenceRepetitions', 'RecurrenceTransactions'])
- ->orderBy('active', 'DESC')
- ->orderBy('title', 'ASC')
- ->get();
+ ->orderBy('active', 'DESC')
+ ->orderBy('title', 'ASC')
+ ->get()
+ ;
}
- /**
- * @inheritDoc
- */
public function getBillId(RecurrenceTransaction $recTransaction): ?int
{
$return = null;
+
/** @var RecurrenceTransactionMeta $meta */
foreach ($recTransaction->recurrenceTransactionMeta as $meta) {
if ('bill_id' === $meta->name) {
@@ -159,14 +150,11 @@ class RecurringRepository implements RecurringRepositoryInterface
/**
* Get the budget ID from a recurring transaction transaction.
- *
- * @param RecurrenceTransaction $recTransaction
- *
- * @return null|int
*/
public function getBudget(RecurrenceTransaction $recTransaction): ?int
{
$return = 0;
+
/** @var RecurrenceTransactionMeta $meta */
foreach ($recTransaction->recurrenceTransactionMeta as $meta) {
if ('budget_id' === $meta->name) {
@@ -179,14 +167,11 @@ class RecurringRepository implements RecurringRepositoryInterface
/**
* Get the category from a recurring transaction transaction.
- *
- * @param RecurrenceTransaction $recTransaction
- *
- * @return null|int
*/
public function getCategoryId(RecurrenceTransaction $recTransaction): ?int
{
$return = '';
+
/** @var RecurrenceTransactionMeta $meta */
foreach ($recTransaction->recurrenceTransactionMeta as $meta) {
if ('category_id' === $meta->name) {
@@ -199,14 +184,11 @@ class RecurringRepository implements RecurringRepositoryInterface
/**
* Get the category from a recurring transaction transaction.
- *
- * @param RecurrenceTransaction $recTransaction
- *
- * @return null|string
*/
public function getCategoryName(RecurrenceTransaction $recTransaction): ?string
{
$return = '';
+
/** @var RecurrenceTransactionMeta $meta */
foreach ($recTransaction->recurrenceTransactionMeta as $meta) {
if ('category_name' === $meta->name) {
@@ -219,71 +201,53 @@ class RecurringRepository implements RecurringRepositoryInterface
/**
* Returns the journals created for this recurrence, possibly limited by time.
- *
- * @param Recurrence $recurrence
- * @param Carbon|null $start
- * @param Carbon|null $end
- *
- * @return int
*/
public function getJournalCount(Recurrence $recurrence, Carbon $start = null, Carbon $end = null): int
{
$query = TransactionJournal::leftJoin('journal_meta', 'journal_meta.transaction_journal_id', '=', 'transaction_journals.id')
- ->where('transaction_journals.user_id', $recurrence->user_id)
- ->whereNull('transaction_journals.deleted_at')
- ->where('journal_meta.name', 'recurrence_id')
- ->where('journal_meta.data', '"' . $recurrence->id . '"');
+ ->where('transaction_journals.user_id', $recurrence->user_id)
+ ->whereNull('transaction_journals.deleted_at')
+ ->where('journal_meta.name', 'recurrence_id')
+ ->where('journal_meta.data', '"'.$recurrence->id.'"')
+ ;
if (null !== $start) {
$query->where('transaction_journals.date', '>=', $start->format('Y-m-d 00:00:00'));
}
if (null !== $end) {
$query->where('transaction_journals.date', '<=', $end->format('Y-m-d 00:00:00'));
}
- return $query->count(['transaction_journals.id']);
+
+ return $query->count('transaction_journals.id');
}
/**
* Get journal ID's for journals created by this recurring transaction.
- *
- * @param Recurrence $recurrence
- *
- * @return array
*/
public function getJournalIds(Recurrence $recurrence): array
{
return TransactionJournalMeta::leftJoin('transaction_journals', 'transaction_journals.id', '=', 'journal_meta.transaction_journal_id')
- ->where('transaction_journals.user_id', $this->user->id)
- ->where('journal_meta.name', '=', 'recurrence_id')
- ->where('journal_meta.data', '=', json_encode((string)$recurrence->id))
- ->get(['journal_meta.transaction_journal_id'])->pluck('transaction_journal_id')->toArray();
+ ->where('transaction_journals.user_id', $this->user->id)
+ ->where('journal_meta.name', '=', 'recurrence_id')
+ ->where('journal_meta.data', '=', json_encode((string)$recurrence->id))
+ ->get(['journal_meta.transaction_journal_id'])->pluck('transaction_journal_id')->toArray()
+ ;
}
/**
* Get the notes.
- *
- * @param Recurrence $recurrence
- *
- * @return string
*/
public function getNoteText(Recurrence $recurrence): string
{
- /** @var Note $note */
+ /** @var null|Note $note */
$note = $recurrence->notes()->first();
- if (null !== $note) {
- return (string)$note->text;
- }
- return '';
+ return (string)$note?->text;
}
- /**
- * @param RecurrenceTransaction $transaction
- *
- * @return int|null
- */
public function getPiggyBank(RecurrenceTransaction $transaction): ?int
{
$meta = $transaction->recurrenceTransactionMeta;
+
/** @var RecurrenceTransactionMeta $metaEntry */
foreach ($meta as $metaEntry) {
if ('piggy_bank_id' === $metaEntry->name) {
@@ -296,15 +260,11 @@ class RecurringRepository implements RecurringRepositoryInterface
/**
* Get the tags from the recurring transaction.
- *
- * @param RecurrenceTransaction $transaction
- *
- * @return array
- * @throws JsonException
*/
public function getTags(RecurrenceTransaction $transaction): array
{
$tags = [];
+
/** @var RecurrenceMeta $meta */
foreach ($transaction->recurrenceTransactionMeta as $meta) {
if ('tags' === $meta->name && '' !== $meta->value) {
@@ -315,59 +275,48 @@ class RecurringRepository implements RecurringRepositoryInterface
return $tags;
}
- /**
- * @param Recurrence $recurrence
- * @param int $page
- * @param int $pageSize
- *
- * @return LengthAwarePaginator
- */
public function getTransactionPaginator(Recurrence $recurrence, int $page, int $pageSize): LengthAwarePaginator
{
$journalMeta = TransactionJournalMeta::leftJoin('transaction_journals', 'transaction_journals.id', '=', 'journal_meta.transaction_journal_id')
- ->whereNull('transaction_journals.deleted_at')
- ->where('transaction_journals.user_id', $this->user->id)
- ->where('name', 'recurrence_id')
- ->where('data', json_encode((string)$recurrence->id))
- ->get()->pluck('transaction_journal_id')->toArray();
+ ->whereNull('transaction_journals.deleted_at')
+ ->where('transaction_journals.user_id', $this->user->id)
+ ->where('name', 'recurrence_id')
+ ->where('data', json_encode((string)$recurrence->id))
+ ->get()->pluck('transaction_journal_id')->toArray()
+ ;
$search = [];
foreach ($journalMeta as $journalId) {
$search[] = (int)$journalId;
}
+
/** @var GroupCollectorInterface $collector */
- $collector = app(GroupCollectorInterface::class);
+ $collector = app(GroupCollectorInterface::class);
$collector->setUser($recurrence->user);
$collector->withCategoryInformation()->withBudgetInformation()->setLimit($pageSize)->setPage($page)
- ->withAccountInformation();
+ ->withAccountInformation()
+ ;
$collector->setJournalIds($search);
return $collector->getPaginatedGroups();
}
- /**
- * @param User|Authenticatable|null $user
- */
- public function setUser(User | Authenticatable | null $user): void
+ public function setUser(null|Authenticatable|User $user): void
{
- if (null !== $user) {
+ if ($user instanceof User) {
$this->user = $user;
}
}
- /**
- * @param Recurrence $recurrence
- *
- * @return Collection
- */
public function getTransactions(Recurrence $recurrence): Collection
{
$journalMeta = TransactionJournalMeta::leftJoin('transaction_journals', 'transaction_journals.id', '=', 'journal_meta.transaction_journal_id')
- ->whereNull('transaction_journals.deleted_at')
- ->where('transaction_journals.user_id', $this->user->id)
- ->where('name', 'recurrence_id')
- ->where('data', json_encode((string)$recurrence->id))
- ->get()->pluck('transaction_journal_id')->toArray();
+ ->whereNull('transaction_journals.deleted_at')
+ ->where('transaction_journals.user_id', $this->user->id)
+ ->where('name', 'recurrence_id')
+ ->where('data', json_encode((string)$recurrence->id))
+ ->get()->pluck('transaction_journal_id')->toArray()
+ ;
$search = [];
foreach ($journalMeta as $journalId) {
@@ -378,7 +327,7 @@ class RecurringRepository implements RecurringRepositoryInterface
}
/** @var GroupCollectorInterface $collector */
- $collector = app(GroupCollectorInterface::class);
+ $collector = app(GroupCollectorInterface::class);
$collector->setUser($recurrence->user);
$collector->withCategoryInformation()->withBudgetInformation()->withAccountInformation();
@@ -390,13 +339,6 @@ class RecurringRepository implements RecurringRepositoryInterface
/**
* Calculate the next X iterations starting on the date given in $date.
- *
- * @param RecurrenceRepetition $repetition
- * @param Carbon $date
- * @param int $count
- *
- * @return array
- *
*/
public function getXOccurrences(RecurrenceRepetition $repetition, Carbon $date, int $count): array
{
@@ -427,17 +369,10 @@ class RecurringRepository implements RecurringRepositoryInterface
* Returns an array of Carbon objects.
*
* Only returns them of they are after $afterDate
- *
- * @param RecurrenceRepetition $repetition
- * @param Carbon $date
- * @param Carbon $afterDate
- * @param int $count
- *
- * @return array
*/
public function getXOccurrencesSince(RecurrenceRepetition $repetition, Carbon $date, Carbon $afterDate, int $count): array
{
- Log::debug('Now in getXOccurrencesSince()');
+ app('log')->debug('Now in getXOccurrencesSince()');
$skipMod = $repetition->repetition_skip + 1;
$occurrences = [];
if ('daily' === $repetition->repetition_type) {
@@ -465,12 +400,6 @@ class RecurringRepository implements RecurringRepositoryInterface
return $this->filterMaxDate($repeatUntil, $occurrences);
}
- /**
- * @param Carbon|null $max
- * @param array $occurrences
- *
- * @return array
- */
private function filterMaxDate(?Carbon $max, array $occurrences): array
{
if (null === $max) {
@@ -489,17 +418,19 @@ class RecurringRepository implements RecurringRepositoryInterface
/**
* Parse the repetition in a string that is user readable.
*
- * @param RecurrenceRepetition $repetition
- *
- * @return string
* @throws FireflyException
*/
public function repetitionDescription(RecurrenceRepetition $repetition): string
{
- Log::debug('Now in repetitionDescription()');
+ app('log')->debug('Now in repetitionDescription()');
+
/** @var Preference $pref */
$pref = app('preferences')->getForUser($this->user, 'language', config('firefly.default_language', 'en_US'));
$language = $pref->data;
+ if (is_array($language)) {
+ $language = 'en_US';
+ }
+ $language = (string)$language;
if ('daily' === $repetition->repetition_type) {
return (string)trans('firefly.recurring_daily', [], $language);
}
@@ -527,19 +458,21 @@ class RecurringRepository implements RecurringRepositoryInterface
);
}
if ('ndom' === $repetition->repetition_type) {
- $parts = explode(',', $repetition->repetition_moment);
+ $parts = explode(',', $repetition->repetition_moment);
// first part is number of week, second is weekday.
$dayOfWeek = trans(sprintf('config.dow_%s', $parts[1]), [], $language);
return (string)trans('firefly.recurring_ndom', ['weekday' => $dayOfWeek, 'dayOfMonth' => $parts[0]], $language);
}
if ('yearly' === $repetition->repetition_type) {
- //
$today = today(config('app.timezone'))->endOfYear();
$repDate = Carbon::createFromFormat('Y-m-d', $repetition->repetition_moment);
+ if (false === $repDate) {
+ $repDate = clone $today;
+ }
$diffInYears = $today->diffInYears($repDate);
$repDate->addYears($diffInYears); // technically not necessary.
- $string = $repDate->isoFormat((string)trans('config.month_and_day_no_year_js'));
+ $string = $repDate->isoFormat((string)trans('config.month_and_day_no_year_js'));
return (string)trans('firefly.recurring_yearly', ['date' => $string], $language);
}
@@ -547,9 +480,6 @@ class RecurringRepository implements RecurringRepositoryInterface
return '';
}
- /**
- * @inheritDoc
- */
public function searchRecurrence(string $query, int $limit): Collection
{
$search = $this->user->recurrences();
@@ -557,34 +487,24 @@ class RecurringRepository implements RecurringRepositoryInterface
$search->where('recurrences.title', 'LIKE', sprintf('%%%s%%', $query));
}
$search
- ->orderBy('recurrences.title', 'ASC');
+ ->orderBy('recurrences.title', 'ASC')
+ ;
return $search->take($limit)->get(['id', 'title', 'description']);
}
/**
- * @param array $data
- *
- * @return Recurrence
* @throws FireflyException
- * @throws JsonException
*/
public function store(array $data): Recurrence
{
/** @var RecurrenceFactory $factory */
$factory = app(RecurrenceFactory::class);
$factory->setUser($this->user);
- $result = $factory->create($data);
- if (null === $result) {
- throw new FireflyException($factory->getErrors()->first());
- }
- return $result;
+ return $factory->create($data);
}
- /**
- * @inheritDoc
- */
public function totalTransactions(Recurrence $recurrence, RecurrenceRepetition $repetition): int
{
// if repeat = null just return 0.
@@ -608,22 +528,15 @@ class RecurringRepository implements RecurringRepositoryInterface
/**
* Generate events in the date range.
- *
- * @param RecurrenceRepetition $repetition
- * @param Carbon $start
- * @param Carbon $end
- *
- * @return array
- *
*/
public function getOccurrencesInRange(RecurrenceRepetition $repetition, Carbon $start, Carbon $end): array
{
$occurrences = [];
$mutator = clone $start;
$mutator->startOfDay();
- $skipMod = $repetition->repetition_skip + 1;
- Log::debug(sprintf('Calculating occurrences for rep type "%s"', $repetition->repetition_type));
- Log::debug(sprintf('Mutator is now: %s', $mutator->format('Y-m-d')));
+ $skipMod = $repetition->repetition_skip + 1;
+ app('log')->debug(sprintf('Calculating occurrences for rep type "%s"', $repetition->repetition_type));
+ app('log')->debug(sprintf('Mutator is now: %s', $mutator->format('Y-m-d')));
if ('daily' === $repetition->repetition_type) {
$occurrences = $this->getDailyInRange($mutator, $end, $skipMod);
@@ -648,10 +561,6 @@ class RecurringRepository implements RecurringRepositoryInterface
/**
* Update a recurring transaction.
*
- * @param Recurrence $recurrence
- * @param array $data
- *
- * @return Recurrence
* @throws FireflyException
*/
public function update(Recurrence $recurrence, array $data): Recurrence
diff --git a/app/Repositories/Recurring/RecurringRepositoryInterface.php b/app/Repositories/Recurring/RecurringRepositoryInterface.php
index 3da9bacfe5..6c8963aaf4 100644
--- a/app/Repositories/Recurring/RecurringRepositoryInterface.php
+++ b/app/Repositories/Recurring/RecurringRepositoryInterface.php
@@ -35,22 +35,13 @@ use Illuminate\Support\Collection;
/**
* Interface RecurringRepositoryInterface
- *
*/
interface RecurringRepositoryInterface
{
- /**
- * @param Recurrence $recurrence
- * @param Carbon $date
- *
- * @return bool
- */
public function createdPreviously(Recurrence $recurrence, Carbon $date): bool;
/**
* Destroy a recurring transaction.
- *
- * @param Recurrence $recurrence
*/
public function destroy(Recurrence $recurrence): void;
@@ -61,135 +52,69 @@ interface RecurringRepositoryInterface
/**
* Returns all of the user's recurring transactions.
- *
- * @return Collection
*/
public function get(): Collection;
/**
* Get ALL recurring transactions.
- *
- * @return Collection
*/
public function getAll(): Collection;
/**
* Get the category from a recurring transaction transaction.
- *
- * @param RecurrenceTransaction $recTransaction
- *
- * @return null|int
*/
public function getBillId(RecurrenceTransaction $recTransaction): ?int;
/**
* Get the budget ID from a recurring transaction transaction.
- *
- * @param RecurrenceTransaction $recTransaction
- *
- * @return null|int
*/
public function getBudget(RecurrenceTransaction $recTransaction): ?int;
/**
* Get the category from a recurring transaction transaction.
- *
- * @param RecurrenceTransaction $recTransaction
- *
- * @return null|int
*/
public function getCategoryId(RecurrenceTransaction $recTransaction): ?int;
/**
* Get the category from a recurring transaction transaction.
- *
- * @param RecurrenceTransaction $recTransaction
- *
- * @return null|string
*/
public function getCategoryName(RecurrenceTransaction $recTransaction): ?string;
/**
* Returns the count of journals created for this recurrence, possibly limited by time.
- *
- * @param Recurrence $recurrence
- * @param Carbon|null $start
- * @param Carbon|null $end
- *
- * @return int
*/
public function getJournalCount(Recurrence $recurrence, Carbon $start = null, Carbon $end = null): int;
/**
* Get journal ID's for journals created by this recurring transaction.
- *
- * @param Recurrence $recurrence
- *
- * @return array
*/
public function getJournalIds(Recurrence $recurrence): array;
/**
* Get the notes.
- *
- * @param Recurrence $recurrence
- *
- * @return string
*/
public function getNoteText(Recurrence $recurrence): string;
/**
* Generate events in the date range.
- *
- * @param RecurrenceRepetition $repetition
- * @param Carbon $start
- * @param Carbon $end
- *
- * @return array
*/
public function getOccurrencesInRange(RecurrenceRepetition $repetition, Carbon $start, Carbon $end): array;
- /**
- * @param RecurrenceTransaction $transaction
- *
- * @return int|null
- */
public function getPiggyBank(RecurrenceTransaction $transaction): ?int;
/**
* Get the tags from the recurring transaction.
- *
- * @param RecurrenceTransaction $transaction
- *
- * @return array
*/
public function getTags(RecurrenceTransaction $transaction): array;
- /**
- * @param Recurrence $recurrence
- * @param int $page
- * @param int $pageSize
- *
- * @return LengthAwarePaginator
- */
public function getTransactionPaginator(Recurrence $recurrence, int $page, int $pageSize): LengthAwarePaginator;
- /**
- * @param Recurrence $recurrence
- *
- * @return Collection
- */
public function getTransactions(Recurrence $recurrence): Collection;
/**
* Calculate the next X iterations starting on the date given in $date.
* Returns an array of Carbon objects.
*
- * @param RecurrenceRepetition $repetition
- * @param Carbon $date
- * @param int $count
- *
- * @return array
* @throws FireflyException
*/
public function getXOccurrences(RecurrenceRepetition $repetition, Carbon $date, int $count): array;
@@ -200,65 +125,33 @@ interface RecurringRepositoryInterface
*
* Only returns them of they are after $afterDate
*
- * @param RecurrenceRepetition $repetition
- * @param Carbon $date
- * @param Carbon $afterDate
- * @param int $count
- *
- * @return array
* @throws FireflyException
*/
public function getXOccurrencesSince(RecurrenceRepetition $repetition, Carbon $date, Carbon $afterDate, int $count): array;
/**
* Parse the repetition in a string that is user readable.
- *
- * @param RecurrenceRepetition $repetition
- *
- * @return string
*/
public function repetitionDescription(RecurrenceRepetition $repetition): string;
- /**
- * @param string $query
- * @param int $limit
- *
- * @return Collection
- */
public function searchRecurrence(string $query, int $limit): Collection;
- /**
- * @param User|Authenticatable|null $user
- */
- public function setUser(User | Authenticatable | null $user): void;
+ public function setUser(null|Authenticatable|User $user): void;
/**
* Store a new recurring transaction.
*
- * @param array $data
- *
- * @return Recurrence
* @throws FireflyException
*/
public function store(array $data): Recurrence;
/**
* Calculate how many transactions are to be expected from this recurrence.
- *
- * @param Recurrence $recurrence
- * @param RecurrenceRepetition $repetition
- *
- * @return int
*/
public function totalTransactions(Recurrence $recurrence, RecurrenceRepetition $repetition): int;
/**
* Update a recurring transaction.
- *
- * @param Recurrence $recurrence
- * @param array $data
- *
- * @return Recurrence
*/
public function update(Recurrence $recurrence, array $data): Recurrence;
}
diff --git a/app/Repositories/Rule/RuleRepository.php b/app/Repositories/Rule/RuleRepository.php
index 09e02cbe75..2d3ef6d7d9 100644
--- a/app/Repositories/Rule/RuleRepository.php
+++ b/app/Repositories/Rule/RuleRepository.php
@@ -23,7 +23,6 @@ declare(strict_types=1);
namespace FireflyIII\Repositories\Rule;
-use Exception;
use FireflyIII\Exceptions\FireflyException;
use FireflyIII\Models\Rule;
use FireflyIII\Models\RuleAction;
@@ -34,11 +33,9 @@ use FireflyIII\Support\Search\OperatorQuerySearch;
use FireflyIII\User;
use Illuminate\Contracts\Auth\Authenticatable;
use Illuminate\Support\Collection;
-use Illuminate\Support\Facades\Log;
/**
* Class RuleRepository.
- *
*/
class RuleRepository implements RuleRepositoryInterface
{
@@ -46,10 +43,7 @@ class RuleRepository implements RuleRepositoryInterface
private $user;
/**
- * @param Rule $rule
- *
- * @return bool
- * @throws Exception
+ * @throws \Exception
*/
public function destroy(Rule $rule): bool
{
@@ -64,9 +58,6 @@ class RuleRepository implements RuleRepositoryInterface
return true;
}
- /**
- * @inheritDoc
- */
public function duplicate(Rule $rule): Rule
{
$newRule = $rule->replicate();
@@ -94,8 +85,6 @@ class RuleRepository implements RuleRepositoryInterface
/**
* Get all the users rules.
- *
- * @return Collection
*/
public function getAll(): Collection
{
@@ -104,85 +93,64 @@ class RuleRepository implements RuleRepositoryInterface
/**
* FIxXME can return null.
- *
- * @return RuleGroup
*/
public function getFirstRuleGroup(): RuleGroup
{
return $this->user->ruleGroups()->first();
}
- /**
- * @param RuleGroup $ruleGroup
- *
- * @return int
- */
public function getHighestOrderInRuleGroup(RuleGroup $ruleGroup): int
{
return (int)$ruleGroup->rules()->max('order');
}
/**
- * @param Rule $rule
- *
- * @return string
- *
* @throws FireflyException
*/
public function getPrimaryTrigger(Rule $rule): string
{
$count = $rule->ruleTriggers()->count();
if (0 === $count) {
- throw new FireflyException('Rules should have more than zero triggers, rule #' . $rule->id . ' has none!');
+ throw new FireflyException('Rules should have more than zero triggers, rule #'.$rule->id.' has none!');
}
return $rule->ruleTriggers()->where('trigger_type', 'user_action')->first()->trigger_value;
}
- /**
- * @return int
- */
public function count(): int
{
return $this->user->rules()->count();
}
- /**
- * @param Rule $rule
- *
- * @return Collection
- */
public function getRuleActions(Rule $rule): Collection
{
return $rule->ruleActions()->orderBy('order', 'ASC')->get();
}
- /**
- * @param Rule $rule
- *
- * @return Collection
- */
public function getRuleTriggers(Rule $rule): Collection
{
return $rule->ruleTriggers()->orderBy('order', 'ASC')->get();
}
- /**
- * @inheritDoc
- */
public function getSearchQuery(Rule $rule): string
{
$params = [];
+
/** @var RuleTrigger $trigger */
foreach ($rule->ruleTriggers as $trigger) {
if ('user_action' === $trigger->trigger_type) {
continue;
}
- $needsContext = config(sprintf('search.operators.%s.needs_context', $trigger->trigger_type)) ?? true;
+ $triggerType = $trigger->trigger_type;
+ if (str_starts_with($trigger->trigger_type, '-')) {
+ $triggerType = substr($trigger->trigger_type, 1);
+ }
+ $needsContext = config(sprintf('search.operators.%s.needs_context', $triggerType)) ?? true;
if (false === $needsContext) {
$params[] = sprintf('%s:true', OperatorQuerySearch::getRootOperator($trigger->trigger_type));
}
if (true === $needsContext) {
+ var_dump('x');
$params[] = sprintf('%s:"%s"', OperatorQuerySearch::getRootOperator($trigger->trigger_type), $trigger->trigger_value);
}
}
@@ -190,20 +158,19 @@ class RuleRepository implements RuleRepositoryInterface
return implode(' ', $params);
}
- /**
- * @inheritDoc
- */
public function getStoreRules(): Collection
{
$collection = $this->user->rules()
- ->leftJoin('rule_groups', 'rule_groups.id', '=', 'rules.rule_group_id')
- ->where('rules.active', true)
- ->where('rule_groups.active', true)
- ->orderBy('rule_groups.order', 'ASC')
- ->orderBy('rules.order', 'ASC')
- ->orderBy('rules.id', 'ASC')
- ->with(['ruleGroup', 'ruleTriggers'])->get(['rules.*']);
+ ->leftJoin('rule_groups', 'rule_groups.id', '=', 'rules.rule_group_id')
+ ->where('rules.active', true)
+ ->where('rule_groups.active', true)
+ ->orderBy('rule_groups.order', 'ASC')
+ ->orderBy('rules.order', 'ASC')
+ ->orderBy('rules.id', 'ASC')
+ ->with(['ruleGroup', 'ruleTriggers'])->get(['rules.*'])
+ ;
$filtered = new Collection();
+
/** @var Rule $rule */
foreach ($collection as $rule) {
/** @var RuleTrigger $ruleTrigger */
@@ -217,20 +184,19 @@ class RuleRepository implements RuleRepositoryInterface
return $filtered;
}
- /**
- * @inheritDoc
- */
public function getUpdateRules(): Collection
{
$collection = $this->user->rules()
- ->leftJoin('rule_groups', 'rule_groups.id', '=', 'rules.rule_group_id')
- ->where('rules.active', true)
- ->where('rule_groups.active', true)
- ->orderBy('rule_groups.order', 'ASC')
- ->orderBy('rules.order', 'ASC')
- ->orderBy('rules.id', 'ASC')
- ->with(['ruleGroup', 'ruleTriggers'])->get();
+ ->leftJoin('rule_groups', 'rule_groups.id', '=', 'rules.rule_group_id')
+ ->where('rules.active', true)
+ ->where('rule_groups.active', true)
+ ->orderBy('rule_groups.order', 'ASC')
+ ->orderBy('rules.order', 'ASC')
+ ->orderBy('rules.id', 'ASC')
+ ->with(['ruleGroup', 'ruleTriggers'])->get()
+ ;
$filtered = new Collection();
+
/** @var Rule $rule */
foreach ($collection as $rule) {
/** @var RuleTrigger $ruleTrigger */
@@ -244,9 +210,6 @@ class RuleRepository implements RuleRepositoryInterface
return $filtered;
}
- /**
- * @inheritDoc
- */
public function searchRule(string $query, int $limit): Collection
{
$search = $this->user->rules();
@@ -254,20 +217,18 @@ class RuleRepository implements RuleRepositoryInterface
$search->where('rules.title', 'LIKE', sprintf('%%%s%%', $query));
}
$search->orderBy('rules.order', 'ASC')
- ->orderBy('rules.title', 'ASC');
+ ->orderBy('rules.title', 'ASC')
+ ;
return $search->take($limit)->get(['id', 'title', 'description']);
}
/**
- * @param array $data
- *
- * @return Rule
* @throws FireflyException
*/
public function store(array $data): Rule
{
- $ruleGroup = null;
+ $ruleGroup = null;
if (array_key_exists('rule_group_id', $data)) {
$ruleGroup = $this->user->ruleGroups()->find($data['rule_group_id']);
}
@@ -279,7 +240,7 @@ class RuleRepository implements RuleRepositoryInterface
}
// start by creating a new rule:
- $rule = new Rule();
+ $rule = new Rule();
$rule->user()->associate($this->user);
$rule->userGroup()->associate($this->user->userGroup);
@@ -288,8 +249,8 @@ class RuleRepository implements RuleRepositoryInterface
$rule->active = array_key_exists('active', $data) ? $data['active'] : true;
$rule->strict = array_key_exists('strict', $data) ? $data['strict'] : false;
$rule->stop_processing = array_key_exists('stop_processing', $data) ? $data['stop_processing'] : false;
- $rule->title = $data['title'];
- $rule->description = array_key_exists('stop_processing', $data) ? $data['stop_processing'] : null;
+ $rule->title = array_key_exists('title', $data) ? $data['title'] : '';
+ $rule->description = array_key_exists('description', $data) ? $data['description'] : '';
$rule->save();
$rule->refresh();
@@ -298,9 +259,9 @@ class RuleRepository implements RuleRepositoryInterface
// reset order:
$this->resetRuleOrder($ruleGroup);
- Log::debug('Done with resetting.');
+ app('log')->debug('Done with resetting.');
if (array_key_exists('order', $data)) {
- Log::debug(sprintf('User has submitted order %d', $data['order']));
+ app('log')->debug(sprintf('User has submitted order %d', $data['order']));
$this->setOrder($rule, $data['order']);
}
@@ -314,24 +275,15 @@ class RuleRepository implements RuleRepositoryInterface
return $rule;
}
- /**
- * @param int $ruleId
- *
- * @return Rule|null
- */
public function find(int $ruleId): ?Rule
{
return $this->user->rules()->find($ruleId);
}
- /**
- * @param string $moment
- * @param Rule $rule
- */
private function setRuleTrigger(string $moment, Rule $rule): void
{
- /** @var RuleTrigger|null $trigger */
- $trigger = $rule->ruleTriggers()->where('trigger_type', 'user_action')->first();
+ /** @var null|RuleTrigger $trigger */
+ $trigger = $rule->ruleTriggers()->where('trigger_type', 'user_action')->first();
if (null !== $trigger) {
$trigger->trigger_value = $moment;
$trigger->save();
@@ -348,11 +300,6 @@ class RuleRepository implements RuleRepositoryInterface
$trigger->save();
}
- /**
- * @param RuleGroup $ruleGroup
- *
- * @return bool
- */
public function resetRuleOrder(RuleGroup $ruleGroup): bool
{
$groupRepository = app(RuleGroupRepositoryInterface::class);
@@ -362,66 +309,53 @@ class RuleRepository implements RuleRepositoryInterface
return true;
}
- /**
- * @param User|Authenticatable|null $user
- */
- public function setUser(User | Authenticatable | null $user): void
+ public function setUser(null|Authenticatable|User $user): void
{
- if (null !== $user) {
+ if ($user instanceof User) {
$this->user = $user;
}
}
- /**
- * @inheritDoc
- */
public function setOrder(Rule $rule, int $newOrder): void
{
- $oldOrder = (int)$rule->order;
- $groupId = (int)$rule->rule_group_id;
- $maxOrder = $this->maxOrder($rule->ruleGroup);
- $newOrder = $newOrder > $maxOrder ? $maxOrder + 1 : $newOrder;
- Log::debug(sprintf('New order will be %d', $newOrder));
+ $oldOrder = $rule->order;
+ $groupId = $rule->rule_group_id;
+ $maxOrder = $this->maxOrder($rule->ruleGroup);
+ $newOrder = $newOrder > $maxOrder ? $maxOrder + 1 : $newOrder;
+ app('log')->debug(sprintf('New order will be %d', $newOrder));
if ($newOrder > $oldOrder) {
$this->user->rules()
- ->where('rules.rule_group_id', $groupId)
- ->where('rules.order', '<=', $newOrder)
- ->where('rules.order', '>', $oldOrder)
- ->where('rules.id', '!=', $rule->id)
- ->decrement('rules.order');
+ ->where('rules.rule_group_id', $groupId)
+ ->where('rules.order', '<=', $newOrder)
+ ->where('rules.order', '>', $oldOrder)
+ ->where('rules.id', '!=', $rule->id)
+ ->decrement('rules.order')
+ ;
$rule->order = $newOrder;
- Log::debug(sprintf('Order of rule #%d ("%s") is now %d', $rule->id, $rule->title, $newOrder));
+ app('log')->debug(sprintf('Order of rule #%d ("%s") is now %d', $rule->id, $rule->title, $newOrder));
$rule->save();
return;
}
$this->user->rules()
- ->where('rules.rule_group_id', $groupId)
- ->where('rules.order', '>=', $newOrder)
- ->where('rules.order', '<', $oldOrder)
- ->where('rules.id', '!=', $rule->id)
- ->increment('rules.order');
+ ->where('rules.rule_group_id', $groupId)
+ ->where('rules.order', '>=', $newOrder)
+ ->where('rules.order', '<', $oldOrder)
+ ->where('rules.id', '!=', $rule->id)
+ ->increment('rules.order')
+ ;
$rule->order = $newOrder;
- Log::debug(sprintf('Order of rule #%d ("%s") is now %d', $rule->id, $rule->title, $newOrder));
+ app('log')->debug(sprintf('Order of rule #%d ("%s") is now %d', $rule->id, $rule->title, $newOrder));
$rule->save();
}
- /**
- * @inheritDoc
- */
public function maxOrder(RuleGroup $ruleGroup): int
{
return (int)$ruleGroup->rules()->max('order');
}
- /**
- * @param Rule $rule
- * @param array $data
- *
- * @return void
- */
private function storeTriggers(Rule $rule, array $data): void
{
$order = 1;
@@ -434,7 +368,36 @@ class RuleRepository implements RuleRepositoryInterface
$type = sprintf('-%s', $type);
}
- $triggerValues = [
+ // empty the value in case the rule needs no context
+ // TODO create a helper to automatically return these.
+ $needTrue = [
+ 'reconciled',
+ 'has_attachments',
+ 'has_any_category',
+ 'has_any_budget',
+ 'has_any_bill',
+ 'has_any_tag',
+ 'any_notes',
+ 'any_external_url',
+ 'has_no_attachments',
+ 'has_no_category',
+ 'has_no_budget',
+ 'has_no_bill',
+ 'has_no_tag',
+ 'no_notes',
+ 'no_external_url',
+ 'source_is_cash',
+ 'destination_is_cash',
+ 'account_is_cash',
+ 'exists',
+ 'no_external_id',
+ 'any_external_id',
+ ];
+ if (in_array($type, $needTrue, true)) {
+ $value = '';
+ }
+
+ $triggerValues = [
'action' => $type,
'value' => $value,
'stop_processing' => $stopProcessing,
@@ -446,15 +409,9 @@ class RuleRepository implements RuleRepositoryInterface
}
}
- /**
- * @param Rule $rule
- * @param array $values
- *
- * @return RuleTrigger
- */
public function storeTrigger(Rule $rule, array $values): RuleTrigger
{
- $ruleTrigger = new RuleTrigger();
+ $ruleTrigger = new RuleTrigger();
$ruleTrigger->rule()->associate($rule);
$ruleTrigger->order = $values['order'];
$ruleTrigger->active = $values['active'];
@@ -466,12 +423,6 @@ class RuleRepository implements RuleRepositoryInterface
return $ruleTrigger;
}
- /**
- * @param Rule $rule
- * @param array $data
- *
- * @return void
- */
private function storeActions(Rule $rule, array $data): void
{
$order = 1;
@@ -491,15 +442,9 @@ class RuleRepository implements RuleRepositoryInterface
}
}
- /**
- * @param Rule $rule
- * @param array $values
- *
- * @return RuleAction
- */
public function storeAction(Rule $rule, array $values): RuleAction
{
- $ruleAction = new RuleAction();
+ $ruleAction = new RuleAction();
$ruleAction->rule()->associate($rule);
$ruleAction->order = $values['order'];
$ruleAction->active = $values['active'];
@@ -511,12 +456,6 @@ class RuleRepository implements RuleRepositoryInterface
return $ruleAction;
}
- /**
- * @param Rule $rule
- * @param array $data
- *
- * @return Rule
- */
public function update(Rule $rule, array $data): Rule
{
// update rule:
@@ -530,19 +469,18 @@ class RuleRepository implements RuleRepositoryInterface
];
foreach ($fields as $field) {
if (array_key_exists($field, $data)) {
- $rule->$field = $data[$field];
+ $rule->{$field} = $data[$field];
}
}
$rule->save();
$rule->refresh();
- $group = $rule->ruleGroup;
+ $group = $rule->ruleGroup;
// update the order:
$this->resetRuleOrder($group);
if (array_key_exists('order', $data)) {
$this->moveRule($rule, $group, (int)$data['order']);
}
-
// update the triggers:
if (array_key_exists('trigger', $data) && 'update-journal' === $data['trigger']) {
$this->setRuleTrigger('update-journal', $rule);
@@ -569,9 +507,6 @@ class RuleRepository implements RuleRepositoryInterface
return $rule;
}
- /**
- * @inheritDoc
- */
public function moveRule(Rule $rule, RuleGroup $ruleGroup, int $order): Rule
{
if ($rule->rule_group_id !== $ruleGroup->id) {
diff --git a/app/Repositories/Rule/RuleRepositoryInterface.php b/app/Repositories/Rule/RuleRepositoryInterface.php
index a38590c6de..96cb48c06d 100644
--- a/app/Repositories/Rule/RuleRepositoryInterface.php
+++ b/app/Repositories/Rule/RuleRepositoryInterface.php
@@ -36,165 +36,61 @@ use Illuminate\Support\Collection;
*/
interface RuleRepositoryInterface
{
- /**
- * @return int
- */
public function count(): int;
- /**
- * @param Rule $rule
- *
- * @return bool
- */
public function destroy(Rule $rule): bool;
- /**
- * @param Rule $rule
- *
- * @return Rule
- */
public function duplicate(Rule $rule): Rule;
- /**
- * @param int $ruleId
- *
- * @return Rule|null
- */
public function find(int $ruleId): ?Rule;
/**
* Get all the users rules.
- *
- * @return Collection
*/
public function getAll(): Collection;
- /**
- * @return RuleGroup
- */
public function getFirstRuleGroup(): RuleGroup;
- /**
- * @param RuleGroup $ruleGroup
- *
- * @return int
- */
public function getHighestOrderInRuleGroup(RuleGroup $ruleGroup): int;
- /**
- * @param Rule $rule
- *
- * @return string
- */
public function getPrimaryTrigger(Rule $rule): string;
- /**
- * @param Rule $rule
- *
- * @return Collection
- */
public function getRuleActions(Rule $rule): Collection;
- /**
- * @param Rule $rule
- *
- * @return Collection
- */
public function getRuleTriggers(Rule $rule): Collection;
/**
* Return search query for rule.
- *
- * @param Rule $rule
- *
- * @return string
*/
public function getSearchQuery(Rule $rule): string;
/**
* Get all the users rules that trigger on storage.
- *
- * @return Collection
*/
public function getStoreRules(): Collection;
/**
* Get all the users rules that trigger on update.
- *
- * @return Collection
*/
public function getUpdateRules(): Collection;
- /**
- * @param RuleGroup $ruleGroup
- *
- * @return int
- */
public function maxOrder(RuleGroup $ruleGroup): int;
- /**
- * @param Rule $rule
- * @param RuleGroup $ruleGroup
- * @param int $order
- *
- * @return Rule
- */
public function moveRule(Rule $rule, RuleGroup $ruleGroup, int $order): Rule;
- /**
- * @param RuleGroup $ruleGroup
- *
- * @return bool
- */
public function resetRuleOrder(RuleGroup $ruleGroup): bool;
- /**
- * @param string $query
- * @param int $limit
- *
- * @return Collection
- */
public function searchRule(string $query, int $limit): Collection;
- /**
- * @param Rule $rule
- * @param int $newOrder
- */
public function setOrder(Rule $rule, int $newOrder): void;
- /**
- * @param User|Authenticatable|null $user
- */
- public function setUser(User | Authenticatable | null $user): void;
+ public function setUser(null|Authenticatable|User $user): void;
- /**
- * @param array $data
- *
- * @return Rule
- */
public function store(array $data): Rule;
- /**
- * @param Rule $rule
- * @param array $values
- *
- * @return RuleAction
- */
public function storeAction(Rule $rule, array $values): RuleAction;
- /**
- * @param Rule $rule
- * @param array $values
- *
- * @return RuleTrigger
- */
public function storeTrigger(Rule $rule, array $values): RuleTrigger;
- /**
- * @param Rule $rule
- * @param array $data
- *
- * @return Rule
- */
public function update(Rule $rule, array $data): Rule;
}
diff --git a/app/Repositories/RuleGroup/RuleGroupRepository.php b/app/Repositories/RuleGroup/RuleGroupRepository.php
index d26fe17600..dcfc689bfd 100644
--- a/app/Repositories/RuleGroup/RuleGroupRepository.php
+++ b/app/Repositories/RuleGroup/RuleGroupRepository.php
@@ -23,7 +23,6 @@ declare(strict_types=1);
namespace FireflyIII\Repositories\RuleGroup;
-use Exception;
use FireflyIII\Models\Rule;
use FireflyIII\Models\RuleAction;
use FireflyIII\Models\RuleGroup;
@@ -41,9 +40,6 @@ class RuleGroupRepository implements RuleGroupRepositoryInterface
{
private User $user;
- /**
- * @inheritDoc
- */
public function correctRuleGroupOrder(): void
{
$set = $this->user
@@ -51,40 +47,32 @@ class RuleGroupRepository implements RuleGroupRepositoryInterface
->orderBy('order', 'ASC')
->orderBy('active', 'DESC')
->orderBy('title', 'ASC')
- ->get(['rule_groups.id']);
+ ->get(['rule_groups.id'])
+ ;
$index = 1;
+
/** @var RuleGroup $ruleGroup */
foreach ($set as $ruleGroup) {
if ($ruleGroup->order !== $index) {
$ruleGroup->order = $index;
$ruleGroup->save();
}
- $index++;
+ ++$index;
}
}
- /**
- * @return Collection
- */
public function get(): Collection
{
return $this->user->ruleGroups()->orderBy('order', 'ASC')->get();
}
- /**
- * @return int
- */
public function count(): int
{
return $this->user->ruleGroups()->count();
}
/**
- * @param RuleGroup $ruleGroup
- * @param RuleGroup|null $moveTo
- *
- * @return bool
- * @throws Exception
+ * @throws \Exception
*/
public function destroy(RuleGroup $ruleGroup, ?RuleGroup $moveTo): bool
{
@@ -92,6 +80,7 @@ class RuleGroupRepository implements RuleGroupRepositoryInterface
foreach ($ruleGroup->rules as $rule) {
if (null === $moveTo) {
$rule->delete();
+
continue;
}
// move
@@ -109,9 +98,6 @@ class RuleGroupRepository implements RuleGroupRepositoryInterface
return true;
}
- /**
- * @return bool
- */
public function resetOrder(): bool
{
$set = $this->user
@@ -119,8 +105,10 @@ class RuleGroupRepository implements RuleGroupRepositoryInterface
->whereNull('deleted_at')
->orderBy('order', 'ASC')
->orderBy('title', 'DESC')
- ->get();
+ ->get()
+ ;
$count = 1;
+
/** @var RuleGroup $entry */
foreach ($set as $entry) {
if ($entry->order !== $count) {
@@ -137,23 +125,20 @@ class RuleGroupRepository implements RuleGroupRepositoryInterface
return true;
}
- /**
- * @param RuleGroup $ruleGroup
- *
- * @return bool
- */
public function resetRuleOrder(RuleGroup $ruleGroup): bool
{
$set = $ruleGroup->rules()
- ->orderBy('order', 'ASC')
- ->orderBy('title', 'DESC')
- ->orderBy('updated_at', 'DESC')
- ->get(['rules.*']);
+ ->orderBy('order', 'ASC')
+ ->orderBy('title', 'DESC')
+ ->orderBy('updated_at', 'DESC')
+ ->get(['rules.*'])
+ ;
$count = 1;
+
/** @var Rule $entry */
foreach ($set as $entry) {
- if ((int)$entry->order !== $count) {
- Log::debug(sprintf('Rule #%d was on spot %d but must be on spot %d', $entry->id, $entry->order, $count));
+ if ($entry->order !== $count) {
+ app('log')->debug(sprintf('Rule #%d was on spot %d but must be on spot %d', $entry->id, $entry->order, $count));
$entry->order = $count;
$entry->save();
}
@@ -166,57 +151,54 @@ class RuleGroupRepository implements RuleGroupRepositoryInterface
return true;
}
- /**
- * @param Rule $rule
- */
private function resetRuleActionOrder(Rule $rule): void
{
$actions = $rule->ruleActions()
- ->orderBy('order', 'ASC')
- ->orderBy('active', 'DESC')
- ->orderBy('action_type', 'ASC')
- ->get();
+ ->orderBy('order', 'ASC')
+ ->orderBy('active', 'DESC')
+ ->orderBy('action_type', 'ASC')
+ ->get()
+ ;
$index = 1;
+
/** @var RuleAction $action */
foreach ($actions as $action) {
- if ((int)$action->order !== $index) {
+ if ($action->order !== $index) {
$action->order = $index;
$action->save();
- Log::debug(sprintf('Rule action #%d was on spot %d but must be on spot %d', $action->id, $action->order, $index));
+ app('log')->debug(sprintf('Rule action #%d was on spot %d but must be on spot %d', $action->id, $action->order, $index));
}
- $index++;
+ ++$index;
}
}
- /**
- * @param Rule $rule
- */
private function resetRuleTriggerOrder(Rule $rule): void
{
$triggers = $rule->ruleTriggers()
- ->orderBy('order', 'ASC')
- ->orderBy('active', 'DESC')
- ->orderBy('trigger_type', 'ASC')
- ->get();
+ ->orderBy('order', 'ASC')
+ ->orderBy('active', 'DESC')
+ ->orderBy('trigger_type', 'ASC')
+ ->get()
+ ;
$index = 1;
+
/** @var RuleTrigger $trigger */
foreach ($triggers as $trigger) {
- $order = (int)$trigger->order;
+ $order = $trigger->order;
if ($order !== $index) {
$trigger->order = $index;
$trigger->save();
- Log::debug(sprintf('Rule trigger #%d was on spot %d but must be on spot %d', $trigger->id, $order, $index));
+ app('log')->debug(sprintf('Rule trigger #%d was on spot %d but must be on spot %d', $trigger->id, $order, $index));
}
- $index++;
+ ++$index;
}
}
- /**
- * @inheritDoc
- */
public function destroyAll(): void
{
+ Log::channel('audit')->info('Delete all rule groups through destroyAll');
$groups = $this->get();
+
/** @var RuleGroup $group */
foreach ($groups as $group) {
$group->rules()->delete();
@@ -224,118 +206,89 @@ class RuleGroupRepository implements RuleGroupRepositoryInterface
}
}
- /**
- * @param int $ruleGroupId
- *
- * @return RuleGroup|null
- */
public function find(int $ruleGroupId): ?RuleGroup
{
return $this->user->ruleGroups()->find($ruleGroupId);
}
- /**
- * @param string $title
- *
- * @return RuleGroup|null
- */
public function findByTitle(string $title): ?RuleGroup
{
return $this->user->ruleGroups()->where('title', $title)->first();
}
- /**
- * @return Collection
- */
public function getActiveGroups(): Collection
{
return $this->user->ruleGroups()->with(['rules'])->where('rule_groups.active', true)->orderBy('order', 'ASC')->get(['rule_groups.*']);
}
- /**
- * @param RuleGroup $group
- *
- * @return Collection
- */
public function getActiveRules(RuleGroup $group): Collection
{
return $group->rules()
- ->where('rules.active', true)
- ->get(['rules.*']);
+ ->where('rules.active', true)
+ ->get(['rules.*'])
+ ;
}
- /**
- * @param RuleGroup $group
- *
- * @return Collection
- */
public function getActiveStoreRules(RuleGroup $group): Collection
{
return $group->rules()
- ->leftJoin('rule_triggers', 'rules.id', '=', 'rule_triggers.rule_id')
- ->where('rule_triggers.trigger_type', 'user_action')
- ->where('rule_triggers.trigger_value', 'store-journal')
- ->where('rules.active', true)
- ->get(['rules.*']);
+ ->leftJoin('rule_triggers', 'rules.id', '=', 'rule_triggers.rule_id')
+ ->where('rule_triggers.trigger_type', 'user_action')
+ ->where('rule_triggers.trigger_value', 'store-journal')
+ ->where('rules.active', true)
+ ->get(['rules.*'])
+ ;
}
- /**
- * @param RuleGroup $group
- *
- * @return Collection
- */
public function getActiveUpdateRules(RuleGroup $group): Collection
{
return $group->rules()
- ->leftJoin('rule_triggers', 'rules.id', '=', 'rule_triggers.rule_id')
- ->where('rule_triggers.trigger_type', 'user_action')
- ->where('rule_triggers.trigger_value', 'update-journal')
- ->where('rules.active', true)
- ->get(['rules.*']);
+ ->leftJoin('rule_triggers', 'rules.id', '=', 'rule_triggers.rule_id')
+ ->where('rule_triggers.trigger_type', 'user_action')
+ ->where('rule_triggers.trigger_value', 'update-journal')
+ ->where('rules.active', true)
+ ->get(['rules.*'])
+ ;
}
- /**
- * @param string|null $filter
- *
- * @return Collection
- */
public function getAllRuleGroupsWithRules(?string $filter): Collection
{
$groups = $this->user->ruleGroups()
- ->orderBy('order', 'ASC')
- ->with(
- [
- 'rules' => static function (HasMany $query) {
- $query->orderBy('order', 'ASC');
- },
- 'rules.ruleTriggers' => static function (HasMany $query) {
- $query->orderBy('order', 'ASC');
- },
- 'rules.ruleActions' => static function (HasMany $query) {
- $query->orderBy('order', 'ASC');
- },
- ]
- )->get();
+ ->orderBy('order', 'ASC')
+ ->with(
+ [
+ 'rules' => static function (HasMany $query): void {
+ $query->orderBy('order', 'ASC');
+ },
+ 'rules.ruleTriggers' => static function (HasMany $query): void {
+ $query->orderBy('order', 'ASC');
+ },
+ 'rules.ruleActions' => static function (HasMany $query): void {
+ $query->orderBy('order', 'ASC');
+ },
+ ]
+ )->get()
+ ;
if (null === $filter) {
return $groups;
}
- Log::debug(sprintf('Will filter getRuleGroupsWithRules on "%s".', $filter));
+ app('log')->debug(sprintf('Will filter getRuleGroupsWithRules on "%s".', $filter));
return $groups->map(
- function (RuleGroup $group) use ($filter) {
- Log::debug(sprintf('Now filtering group #%d', $group->id));
+ static function (RuleGroup $group) use ($filter) {
+ app('log')->debug(sprintf('Now filtering group #%d', $group->id));
// filter the rules in the rule group:
$group->rules = $group->rules->filter(
- function (Rule $rule) use ($filter) {
- Log::debug(sprintf('Now filtering rule #%d', $rule->id));
+ static function (Rule $rule) use ($filter) {
+ app('log')->debug(sprintf('Now filtering rule #%d', $rule->id));
foreach ($rule->ruleTriggers as $trigger) {
if ('user_action' === $trigger->trigger_type && $filter === $trigger->trigger_value) {
- Log::debug(sprintf('Rule #%d triggers on %s, include it.', $rule->id, $filter));
+ app('log')->debug(sprintf('Rule #%d triggers on %s, include it.', $rule->id, $filter));
return true;
}
}
- Log::debug(sprintf('Rule #%d does not trigger on %s, do not include it.', $rule->id, $filter));
+ app('log')->debug(sprintf('Rule #%d does not trigger on %s, do not include it.', $rule->id, $filter));
return false;
}
@@ -346,9 +299,6 @@ class RuleGroupRepository implements RuleGroupRepositoryInterface
);
}
- /**
- * @return int
- */
public function getHighestOrderRuleGroup(): int
{
$entry = $this->user->ruleGroups()->max('order');
@@ -356,49 +306,45 @@ class RuleGroupRepository implements RuleGroupRepositoryInterface
return (int)$entry;
}
- /**
- * @param string|null $filter
- *
- * @return Collection
- */
public function getRuleGroupsWithRules(?string $filter): Collection
{
$groups = $this->user->ruleGroups()
- ->orderBy('order', 'ASC')
- ->where('active', true)
- ->with(
- [
- 'rules' => static function (HasMany $query) {
- $query->orderBy('order', 'ASC');
- },
- 'rules.ruleTriggers' => static function (HasMany $query) {
- $query->orderBy('order', 'ASC');
- },
- 'rules.ruleActions' => static function (HasMany $query) {
- $query->orderBy('order', 'ASC');
- },
- ]
- )->get();
+ ->orderBy('order', 'ASC')
+ ->where('active', true)
+ ->with(
+ [
+ 'rules' => static function (HasMany $query): void {
+ $query->orderBy('order', 'ASC');
+ },
+ 'rules.ruleTriggers' => static function (HasMany $query): void {
+ $query->orderBy('order', 'ASC');
+ },
+ 'rules.ruleActions' => static function (HasMany $query): void {
+ $query->orderBy('order', 'ASC');
+ },
+ ]
+ )->get()
+ ;
if (null === $filter) {
return $groups;
}
- Log::debug(sprintf('Will filter getRuleGroupsWithRules on "%s".', $filter));
+ app('log')->debug(sprintf('Will filter getRuleGroupsWithRules on "%s".', $filter));
return $groups->map(
- function (RuleGroup $group) use ($filter) {
- Log::debug(sprintf('Now filtering group #%d', $group->id));
+ static function (RuleGroup $group) use ($filter) {
+ app('log')->debug(sprintf('Now filtering group #%d', $group->id));
// filter the rules in the rule group:
$group->rules = $group->rules->filter(
- function (Rule $rule) use ($filter) {
- Log::debug(sprintf('Now filtering rule #%d', $rule->id));
+ static function (Rule $rule) use ($filter) {
+ app('log')->debug(sprintf('Now filtering rule #%d', $rule->id));
foreach ($rule->ruleTriggers as $trigger) {
if ('user_action' === $trigger->trigger_type && $filter === $trigger->trigger_value) {
- Log::debug(sprintf('Rule #%d triggers on %s, include it.', $rule->id, $filter));
+ app('log')->debug(sprintf('Rule #%d triggers on %s, include it.', $rule->id, $filter));
return true;
}
}
- Log::debug(sprintf('Rule #%d does not trigger on %s, do not include it.', $rule->id, $filter));
+ app('log')->debug(sprintf('Rule #%d does not trigger on %s, do not include it.', $rule->id, $filter));
return false;
}
@@ -409,28 +355,18 @@ class RuleGroupRepository implements RuleGroupRepositoryInterface
);
}
- /**
- * @param RuleGroup $group
- *
- * @return Collection
- */
public function getRules(RuleGroup $group): Collection
{
return $group->rules()
- ->get(['rules.*']);
+ ->get(['rules.*'])
+ ;
}
- /**
- * @inheritDoc
- */
public function maxOrder(): int
{
return (int)$this->user->ruleGroups()->where('active', true)->max('order');
}
- /**
- * @inheritDoc
- */
public function searchRuleGroup(string $query, int $limit): Collection
{
$search = $this->user->ruleGroups();
@@ -438,26 +374,19 @@ class RuleGroupRepository implements RuleGroupRepositoryInterface
$search->where('rule_groups.title', 'LIKE', sprintf('%%%s%%', $query));
}
$search->orderBy('rule_groups.order', 'ASC')
- ->orderBy('rule_groups.title', 'ASC');
+ ->orderBy('rule_groups.title', 'ASC')
+ ;
return $search->take($limit)->get(['id', 'title', 'description']);
}
- /**
- * @param User|Authenticatable|null $user
- */
- public function setUser(User | Authenticatable | null $user): void
+ public function setUser(null|Authenticatable|User $user): void
{
- if (null !== $user) {
+ if ($user instanceof User) {
$this->user = $user;
}
}
- /**
- * @param array $data
- *
- * @return RuleGroup
- */
public function store(array $data): RuleGroup
{
$newRuleGroup = new RuleGroup(
@@ -479,38 +408,31 @@ class RuleGroupRepository implements RuleGroupRepositoryInterface
return $newRuleGroup;
}
- /**
- * @inheritDoc
- */
public function setOrder(RuleGroup $ruleGroup, int $newOrder): void
{
- $oldOrder = (int)$ruleGroup->order;
+ $oldOrder = $ruleGroup->order;
if ($newOrder > $oldOrder) {
$this->user->ruleGroups()->where('rule_groups.order', '<=', $newOrder)->where('rule_groups.order', '>', $oldOrder)
- ->where('rule_groups.id', '!=', $ruleGroup->id)
- ->decrement('order');
+ ->where('rule_groups.id', '!=', $ruleGroup->id)
+ ->decrement('order')
+ ;
$ruleGroup->order = $newOrder;
- Log::debug(sprintf('Order of group #%d ("%s") is now %d', $ruleGroup->id, $ruleGroup->title, $newOrder));
+ app('log')->debug(sprintf('Order of group #%d ("%s") is now %d', $ruleGroup->id, $ruleGroup->title, $newOrder));
$ruleGroup->save();
return;
}
$this->user->ruleGroups()->where('rule_groups.order', '>=', $newOrder)->where('rule_groups.order', '<', $oldOrder)
- ->where('rule_groups.id', '!=', $ruleGroup->id)
- ->increment('order');
+ ->where('rule_groups.id', '!=', $ruleGroup->id)
+ ->increment('order')
+ ;
$ruleGroup->order = $newOrder;
- Log::debug(sprintf('Order of group #%d ("%s") is now %d', $ruleGroup->id, $ruleGroup->title, $newOrder));
+ app('log')->debug(sprintf('Order of group #%d ("%s") is now %d', $ruleGroup->id, $ruleGroup->title, $newOrder));
$ruleGroup->save();
}
- /**
- * @param RuleGroup $ruleGroup
- * @param array $data
- *
- * @return RuleGroup
- */
public function update(RuleGroup $ruleGroup, array $data): RuleGroup
{
// update the account:
diff --git a/app/Repositories/RuleGroup/RuleGroupRepositoryInterface.php b/app/Repositories/RuleGroup/RuleGroupRepositoryInterface.php
index 9bb34dfc2e..d334fbb473 100644
--- a/app/Repositories/RuleGroup/RuleGroupRepositoryInterface.php
+++ b/app/Repositories/RuleGroup/RuleGroupRepositoryInterface.php
@@ -38,17 +38,8 @@ interface RuleGroupRepositoryInterface
*/
public function correctRuleGroupOrder(): void;
- /**
- * @return int
- */
public function count(): int;
- /**
- * @param RuleGroup $ruleGroup
- * @param RuleGroup|null $moveTo
- *
- * @return bool
- */
public function destroy(RuleGroup $ruleGroup, ?RuleGroup $moveTo): bool;
/**
@@ -56,131 +47,50 @@ interface RuleGroupRepositoryInterface
*/
public function destroyAll(): void;
- /**
- * @param int $ruleGroupId
- *
- * @return RuleGroup|null
- */
public function find(int $ruleGroupId): ?RuleGroup;
- /**
- * @param string $title
- *
- * @return RuleGroup|null
- */
public function findByTitle(string $title): ?RuleGroup;
/**
* Get all rule groups.
- *
- * @return Collection
*/
public function get(): Collection;
- /**
- * @return Collection
- */
public function getActiveGroups(): Collection;
- /**
- * @param RuleGroup $group
- *
- * @return Collection
- */
public function getActiveRules(RuleGroup $group): Collection;
- /**
- * @param RuleGroup $group
- *
- * @return Collection
- */
public function getActiveStoreRules(RuleGroup $group): Collection;
- /**
- * @param RuleGroup $group
- *
- * @return Collection
- */
public function getActiveUpdateRules(RuleGroup $group): Collection;
/**
* Also inactive groups.
- *
- * @param string|null $filter
- *
- * @return Collection
*/
public function getAllRuleGroupsWithRules(?string $filter): Collection;
- /**
- * @return int
- */
public function getHighestOrderRuleGroup(): int;
- /**
- * @param string|null $filter
- *
- * @return Collection
- */
public function getRuleGroupsWithRules(?string $filter): Collection;
- /**
- * @param RuleGroup $group
- *
- * @return Collection
- */
public function getRules(RuleGroup $group): Collection;
/**
* Get highest possible order for a rule group.
- *
- * @return int
*/
public function maxOrder(): int;
- /**
- * @return bool
- */
public function resetOrder(): bool;
- /**
- * @param RuleGroup $ruleGroup
- *
- * @return bool
- */
public function resetRuleOrder(RuleGroup $ruleGroup): bool;
- /**
- * @param string $query
- * @param int $limit
- *
- * @return Collection
- */
public function searchRuleGroup(string $query, int $limit): Collection;
- /**
- * @param RuleGroup $ruleGroup
- * @param int $newOrder
- */
public function setOrder(RuleGroup $ruleGroup, int $newOrder): void;
- /**
- * @param User|Authenticatable|null $user
- */
- public function setUser(User | Authenticatable | null $user): void;
+ public function setUser(null|Authenticatable|User $user): void;
- /**
- * @param array $data
- *
- * @return RuleGroup
- */
public function store(array $data): RuleGroup;
- /**
- * @param RuleGroup $ruleGroup
- * @param array $data
- *
- * @return RuleGroup
- */
public function update(RuleGroup $ruleGroup, array $data): RuleGroup;
}
diff --git a/app/Repositories/Tag/OperationsRepository.php b/app/Repositories/Tag/OperationsRepository.php
index 874afc2f4e..334bf8009d 100644
--- a/app/Repositories/Tag/OperationsRepository.php
+++ b/app/Repositories/Tag/OperationsRepository.php
@@ -30,53 +30,43 @@ use FireflyIII\Models\TransactionType;
use FireflyIII\User;
use Illuminate\Contracts\Auth\Authenticatable;
use Illuminate\Support\Collection;
-use Psr\Container\ContainerExceptionInterface;
-use Psr\Container\NotFoundExceptionInterface;
/**
- *
* Class OperationsRepository
*/
class OperationsRepository implements OperationsRepositoryInterface
{
- /** @var User */
- private $user;
+ private User $user;
/**
* This method returns a list of all the withdrawal transaction journals (as arrays) set in that period
* which have the specified tag(s) set to them. It's grouped per currency, with as few details in the array
* as possible. Amounts are always negative.
- *
- * @param Carbon $start
- * @param Carbon $end
- * @param Collection|null $accounts
- * @param Collection|null $tags
- *
- * @return array
- * @throws ContainerExceptionInterface
- * @throws NotFoundExceptionInterface
*/
public function listExpenses(Carbon $start, Carbon $end, ?Collection $accounts = null, ?Collection $tags = null): array
{
/** @var GroupCollectorInterface $collector */
- $collector = app(GroupCollectorInterface::class);
+ $collector = app(GroupCollectorInterface::class);
$collector->setUser($this->user)->setRange($start, $end)->setTypes([TransactionType::WITHDRAWAL]);
+ $tagIds = [];
if (null !== $accounts && $accounts->count() > 0) {
$collector->setAccounts($accounts);
}
if (null !== $tags && $tags->count() > 0) {
$collector->setTags($tags);
+ $tagIds = $tags->pluck('id')->toArray();
}
- if (null === $tags || (null !== $tags && 0 === $tags->count())) {
+ if (null === $tags || 0 === $tags->count()) {
$collector->setTags($this->getTags());
+ $tagIds = $this->getTags()->pluck('id')->toArray();
}
- $collector->withCategoryInformation()->withAccountInformation()->withBudgetInformation()->withTagInformation();
+ $collector->withCategoryInformation()->withAccountInformation()->withBudgetInformation();
$journals = $collector->getExtractedJournals();
$array = [];
$listedJournals = [];
foreach ($journals as $journal) {
- $currencyId = (int)$journal['currency_id'];
- $array[$currencyId] = $array[$currencyId] ?? [
+ $currencyId = (int)$journal['currency_id'];
+ $array[$currencyId] ??= [
'tags' => [],
'currency_id' => $currencyId,
'currency_name' => $journal['currency_name'],
@@ -87,15 +77,19 @@ class OperationsRepository implements OperationsRepositoryInterface
// may have multiple tags:
foreach ($journal['tags'] as $tag) {
- $tagId = (int)$tag['id'];
- $tagName = (string)$tag['name'];
- $journalId = (int)$journal['transaction_journal_id'];
+ $tagId = (int)$tag['id'];
+ $tagName = (string)$tag['name'];
+ $journalId = (int)$journal['transaction_journal_id'];
+ if (!in_array($tagId, $tagIds, true)) {
+ continue;
+ }
+ // TODO not sure what this check does.
if (in_array($journalId, $listedJournals, true)) {
continue;
}
- $listedJournals[] = $journalId;
- $array[$currencyId]['tags'][$tagId] = $array[$currencyId]['tags'][$tagId] ?? [
+ $listedJournals[] = $journalId;
+ $array[$currencyId]['tags'][$tagId] ??= [
'id' => $tagId,
'name' => $tagName,
'transaction_journals' => [],
@@ -119,23 +113,16 @@ class OperationsRepository implements OperationsRepositoryInterface
return $array;
}
- /**
- * @param User|Authenticatable|null $user
- */
- public function setUser(User | Authenticatable | null $user): void
+ public function setUser(null|Authenticatable|User $user): void
{
- if (null !== $user) {
+ if ($user instanceof User) {
$this->user = $user;
}
}
- /**
- * @return Collection
- * @throws ContainerExceptionInterface
- * @throws NotFoundExceptionInterface
- */
private function getTags(): Collection
{
+ /** @var TagRepositoryInterface $repository */
$repository = app(TagRepositoryInterface::class);
return $repository->get();
@@ -145,29 +132,23 @@ class OperationsRepository implements OperationsRepositoryInterface
* This method returns a list of all the deposit transaction journals (as arrays) set in that period
* which have the specified tag(s) set to them. It's grouped per currency, with as few details in the array
* as possible. Amounts are always positive.
- *
- * @param Carbon $start
- * @param Carbon $end
- * @param Collection|null $accounts
- * @param Collection|null $tags
- *
- * @return array
- * @throws ContainerExceptionInterface
- * @throws NotFoundExceptionInterface
*/
public function listIncome(Carbon $start, Carbon $end, ?Collection $accounts = null, ?Collection $tags = null): array
{
/** @var GroupCollectorInterface $collector */
- $collector = app(GroupCollectorInterface::class);
+ $collector = app(GroupCollectorInterface::class);
$collector->setUser($this->user)->setRange($start, $end)->setTypes([TransactionType::DEPOSIT]);
+ $tagIds = [];
if (null !== $accounts && $accounts->count() > 0) {
$collector->setAccounts($accounts);
}
if (null !== $tags && $tags->count() > 0) {
$collector->setTags($tags);
+ $tagIds = $tags->pluck('id')->toArray();
}
- if (null === $tags || (null !== $tags && 0 === $tags->count())) {
+ if (null === $tags || 0 === $tags->count()) {
$collector->setTags($this->getTags());
+ $tagIds = $this->getTags()->pluck('id')->toArray();
}
$collector->withCategoryInformation()->withAccountInformation()->withBudgetInformation()->withTagInformation();
$journals = $collector->getExtractedJournals();
@@ -175,8 +156,8 @@ class OperationsRepository implements OperationsRepositoryInterface
$listedJournals = [];
foreach ($journals as $journal) {
- $currencyId = (int)$journal['currency_id'];
- $array[$currencyId] = $array[$currencyId] ?? [
+ $currencyId = (int)$journal['currency_id'];
+ $array[$currencyId] ??= [
'tags' => [],
'currency_id' => $currencyId,
'currency_name' => $journal['currency_name'],
@@ -187,16 +168,20 @@ class OperationsRepository implements OperationsRepositoryInterface
// may have multiple tags:
foreach ($journal['tags'] as $tag) {
- $tagId = (int)$tag['id'];
- $tagName = (string)$tag['name'];
- $journalId = (int)$journal['transaction_journal_id'];
+ $tagId = (int)$tag['id'];
+ $tagName = (string)$tag['name'];
+ $journalId = (int)$journal['transaction_journal_id'];
+
+ if (!in_array($tagId, $tagIds, true)) {
+ continue;
+ }
if (in_array($journalId, $listedJournals, true)) {
continue;
}
- $listedJournals[] = $journalId;
+ $listedJournals[] = $journalId;
- $array[$currencyId]['tags'][$tagId] = $array[$currencyId]['tags'][$tagId] ?? [
+ $array[$currencyId]['tags'][$tagId] ??= [
'id' => $tagId,
'name' => $tagName,
'transaction_journals' => [],
@@ -222,12 +207,6 @@ class OperationsRepository implements OperationsRepositoryInterface
/**
* Sum of withdrawal journals in period for a set of tags, grouped per currency. Amounts are always negative.
*
- * @param Carbon $start
- * @param Carbon $end
- * @param Collection|null $accounts
- * @param Collection|null $tags
- *
- * @return array
* @throws FireflyException
*/
public function sumExpenses(Carbon $start, Carbon $end, ?Collection $accounts = null, ?Collection $tags = null): array
@@ -238,12 +217,6 @@ class OperationsRepository implements OperationsRepositoryInterface
/**
* Sum of income journals in period for a set of tags, grouped per currency. Amounts are always positive.
*
- * @param Carbon $start
- * @param Carbon $end
- * @param Collection|null $accounts
- * @param Collection|null $tags
- *
- * @return array
* @throws FireflyException
*/
public function sumIncome(Carbon $start, Carbon $end, ?Collection $accounts = null, ?Collection $tags = null): array
diff --git a/app/Repositories/Tag/OperationsRepositoryInterface.php b/app/Repositories/Tag/OperationsRepositoryInterface.php
index aecd897518..b0143054c7 100644
--- a/app/Repositories/Tag/OperationsRepositoryInterface.php
+++ b/app/Repositories/Tag/OperationsRepositoryInterface.php
@@ -30,8 +30,6 @@ use Illuminate\Support\Collection;
/**
* Interface OperationsRepositoryInterface
- *
- * @package FireflyIII\Repositories\Tag
*/
interface OperationsRepositoryInterface
{
@@ -39,13 +37,6 @@ interface OperationsRepositoryInterface
* This method returns a list of all the withdrawal transaction journals (as arrays) set in that period
* which have the specified tag(s) set to them. It's grouped per currency, with as few details in the array
* as possible. Amounts are always negative.
- *
- * @param Carbon $start
- * @param Carbon $end
- * @param Collection|null $accounts
- * @param Collection|null $tags
- *
- * @return array
*/
public function listExpenses(Carbon $start, Carbon $end, ?Collection $accounts = null, ?Collection $tags = null): array;
@@ -53,42 +44,18 @@ interface OperationsRepositoryInterface
* This method returns a list of all the deposit transaction journals (as arrays) set in that period
* which have the specified tag(s) set to them. It's grouped per currency, with as few details in the array
* as possible. Amounts are always positive.
- *
- * @param Carbon $start
- * @param Carbon $end
- * @param Collection|null $accounts
- * @param Collection|null $tags
- *
- * @return array
*/
public function listIncome(Carbon $start, Carbon $end, ?Collection $accounts = null, ?Collection $tags = null): array;
- /**
- * @param User|Authenticatable|null $user
- */
- public function setUser(User | Authenticatable | null $user): void;
+ public function setUser(null|Authenticatable|User $user): void;
/**
* Sum of withdrawal journals in period for a set of tags, grouped per currency. Amounts are always negative.
- *
- * @param Carbon $start
- * @param Carbon $end
- * @param Collection|null $accounts
- * @param Collection|null $tags
- *
- * @return array
*/
public function sumExpenses(Carbon $start, Carbon $end, ?Collection $accounts = null, ?Collection $tags = null): array;
/**
* Sum of income journals in period for a set of tags, grouped per currency. Amounts are always positive.
- *
- * @param Carbon $start
- * @param Carbon $end
- * @param Collection|null $accounts
- * @param Collection|null $tags
- *
- * @return array
*/
public function sumIncome(Carbon $start, Carbon $end, ?Collection $accounts = null, ?Collection $tags = null): array;
}
diff --git a/app/Repositories/Tag/TagRepository.php b/app/Repositories/Tag/TagRepository.php
index 6b64f7e81f..052487081d 100644
--- a/app/Repositories/Tag/TagRepository.php
+++ b/app/Repositories/Tag/TagRepository.php
@@ -24,8 +24,6 @@ declare(strict_types=1);
namespace FireflyIII\Repositories\Tag;
use Carbon\Carbon;
-use DB;
-use Exception;
use FireflyIII\Factory\TagFactory;
use FireflyIII\Helpers\Collector\GroupCollectorInterface;
use FireflyIII\Models\Attachment;
@@ -37,33 +35,25 @@ use FireflyIII\User;
use Illuminate\Contracts\Auth\Authenticatable;
use Illuminate\Support\Collection;
use Illuminate\Support\Facades\Log;
-use Storage;
/**
* Class TagRepository.
- *
*/
class TagRepository implements TagRepositoryInterface
{
private User $user;
- /**
- * @return int
- */
public function count(): int
{
return $this->user->tags()->count();
}
/**
- * @param Tag $tag
- *
- * @return bool
- * @throws Exception
+ * @throws \Exception
*/
public function destroy(Tag $tag): bool
{
- DB::table('tag_transaction_journal')->where('tag_id', $tag->id)->delete();
+ \DB::table('tag_transaction_journal')->where('tag_id', $tag->id)->delete();
$tag->transactionJournals()->sync([]);
$tag->delete();
@@ -75,29 +65,21 @@ class TagRepository implements TagRepositoryInterface
*/
public function destroyAll(): void
{
+ Log::channel('audit')->info('Delete all tags through destroyAll');
$tags = $this->get();
+
/** @var Tag $tag */
foreach ($tags as $tag) {
- DB::table('tag_transaction_journal')->where('tag_id', $tag->id)->delete();
+ \DB::table('tag_transaction_journal')->where('tag_id', $tag->id)->delete();
$tag->delete();
}
}
- /**
- * @return Collection
- */
public function get(): Collection
{
- return $this->user->tags()->orderBy('tag', 'ASC')->get();
+ return $this->user->tags()->orderBy('tag', 'ASC')->get(['tags.*']);
}
- /**
- * @param Tag $tag
- * @param Carbon $start
- * @param Carbon $end
- *
- * @return array
- */
public function expenseInPeriod(Tag $tag, Carbon $start, Carbon $end): array
{
/** @var GroupCollectorInterface $collector */
@@ -109,61 +91,41 @@ class TagRepository implements TagRepositoryInterface
return $collector->getExtractedJournals();
}
- /**
- * @param User|Authenticatable|null $user
- */
- public function setUser(User | Authenticatable | null $user): void
+ public function setUser(null|Authenticatable|User $user): void
{
- if (null !== $user) {
+ if ($user instanceof User) {
$this->user = $user;
}
}
- /**
- * @param int $tagId
- *
- * @return Tag|null
- */
public function find(int $tagId): ?Tag
{
return $this->user->tags()->find($tagId);
}
- /**
- * @param string $tag
- *
- * @return Tag|null
- */
public function findByTag(string $tag): ?Tag
{
- /** @var Tag|null */
+ // @var Tag|null
return $this->user->tags()->where('tag', $tag)->first();
}
- /**
- * @param Tag $tag
- *
- * @return Carbon|null
- */
public function firstUseDate(Tag $tag): ?Carbon
{
- /** @var Carbon|null */
+ // @var Carbon|null
return $tag->transactionJournals()->orderBy('date', 'ASC')->first()?->date;
}
- /**
- * @inheritDoc
- */
public function getAttachments(Tag $tag): Collection
{
- $set = $tag->attachments()->get();
- /** @var Storage $disk */
- $disk = Storage::disk('upload');
+ $set = $tag->attachments()->get();
+
+ /** @var \Storage $disk */
+ $disk = \Storage::disk('upload');
return $set->each(
- static function (Attachment $attachment) use ($disk) {
- /** @var Note $note */
- $note = $attachment->notes()->first();
+ static function (Attachment $attachment) use ($disk): void {
+ /** @var null|Note $note */
+ $note = $attachment->notes()->first();
// only used in v1 view of tags
$attachment->file_exists = $disk->exists($attachment->fileName());
$attachment->notes_text = null === $note ? '' : $note->text;
@@ -171,28 +133,24 @@ class TagRepository implements TagRepositoryInterface
);
}
- /**
- * @param int|null $year
- *
- * @return array
- */
public function getTagsInYear(?int $year): array
{
// get all tags in the year (if present):
- $tagQuery = $this->user->tags()->with(['locations', 'attachments'])->orderBy('tags.tag');
+ $tagQuery = $this->user->tags()->with(['locations', 'attachments'])->orderBy('tags.tag');
// add date range (or not):
if (null === $year) {
- Log::debug('Get tags without a date.');
+ app('log')->debug('Get tags without a date.');
$tagQuery->whereNull('tags.date');
}
if (null !== $year) {
- Log::debug(sprintf('Get tags with year %s.', $year));
- $tagQuery->where('tags.date', '>=', $year . '-01-01 00:00:00')->where('tags.date', '<=', $year . '-12-31 23:59:59');
+ app('log')->debug(sprintf('Get tags with year %s.', $year));
+ $tagQuery->where('tags.date', '>=', $year.'-01-01 00:00:00')->where('tags.date', '<=', $year.'-12-31 23:59:59');
}
$collection = $tagQuery->get();
$return = [];
+
/** @var Tag $tag */
foreach ($collection as $tag) {
// return value for tag cloud:
@@ -208,13 +166,6 @@ class TagRepository implements TagRepositoryInterface
return $return;
}
- /**
- * @param Tag $tag
- * @param Carbon $start
- * @param Carbon $end
- *
- * @return array
- */
public function incomeInPeriod(Tag $tag, Carbon $start, Carbon $end): array
{
/** @var GroupCollectorInterface $collector */
@@ -226,43 +177,29 @@ class TagRepository implements TagRepositoryInterface
return $collector->getExtractedJournals();
}
- /**
- * @param Tag $tag
- *
- * @return Carbon|null
- */
public function lastUseDate(Tag $tag): ?Carbon
{
- /** @var Carbon|null */
+ // @var Carbon|null
return $tag->transactionJournals()->orderBy('date', 'DESC')->first()?->date;
}
/**
* Will return the newest tag (if known) or NULL.
- *
- * @return Tag|null
*/
public function newestTag(): ?Tag
{
- /** @var Tag|null */
+ // @var Tag|null
return $this->user->tags()->whereNotNull('date')->orderBy('date', 'DESC')->first();
}
- /**
- * @return Tag|null
- */
public function oldestTag(): ?Tag
{
- /** @var Tag|null */
+ // @var Tag|null
return $this->user->tags()->whereNotNull('date')->orderBy('date', 'ASC')->first();
}
/**
* Find one or more tags based on the query.
- *
- * @param string $query
- *
- * @return Collection
*/
public function searchTag(string $query): Collection
{
@@ -273,11 +210,6 @@ class TagRepository implements TagRepositoryInterface
/**
* Search the users tags.
- *
- * @param string $query
- * @param int $limit
- *
- * @return Collection
*/
public function searchTags(string $query, int $limit): Collection
{
@@ -291,11 +223,6 @@ class TagRepository implements TagRepositoryInterface
return $tags->take($limit)->get('tags.*');
}
- /**
- * @param array $data
- *
- * @return Tag
- */
public function store(array $data): Tag
{
/** @var TagFactory $factory */
@@ -305,14 +232,6 @@ class TagRepository implements TagRepositoryInterface
return $factory->create($data);
}
- /**
- * @param Tag $tag
- * @param Carbon|null $start
- * @param Carbon|null $end
- *
- * @return array
- *
- */
public function sumsOfTag(Tag $tag, ?Carbon $start, ?Carbon $end): array
{
/** @var GroupCollectorInterface $collector */
@@ -323,14 +242,25 @@ class TagRepository implements TagRepositoryInterface
}
$collector->setTag($tag)->withAccountInformation();
- $journals = $collector->getExtractedJournals();
+ $journals = $collector->getExtractedJournals();
- $sums = [];
+ $sums = [];
/** @var array $journal */
foreach ($journals as $journal) {
- $currencyId = (int)$journal['currency_id'];
- $sums[$currencyId] = $sums[$currencyId] ?? [
+ $found = false;
+
+ /** @var array $localTag */
+ foreach ($journal['tags'] as $localTag) {
+ if ($localTag['id'] === $tag->id) {
+ $found = true;
+ }
+ }
+ if (false === $found) {
+ continue;
+ }
+ $currencyId = (int)$journal['currency_id'];
+ $sums[$currencyId] ??= [
'currency_id' => $currencyId,
'currency_name' => $journal['currency_name'],
'currency_symbol' => $journal['currency_symbol'],
@@ -343,16 +273,16 @@ class TagRepository implements TagRepositoryInterface
];
// add amount to correct type:
- $amount = app('steam')->positive((string)$journal['amount']);
- $type = $journal['transaction_type_type'];
+ $amount = app('steam')->positive((string)$journal['amount']);
+ $type = $journal['transaction_type_type'];
if (TransactionType::WITHDRAWAL === $type) {
$amount = bcmul($amount, '-1');
}
$sums[$currencyId][$type] = bcadd($sums[$currencyId][$type], $amount);
- $foreignCurrencyId = $journal['foreign_currency_id'];
+ $foreignCurrencyId = $journal['foreign_currency_id'];
if (null !== $foreignCurrencyId && 0 !== $foreignCurrencyId) {
- $sums[$foreignCurrencyId] = $sums[$foreignCurrencyId] ?? [
+ $sums[$foreignCurrencyId] ??= [
'currency_id' => $foreignCurrencyId,
'currency_name' => $journal['foreign_currency_name'],
'currency_symbol' => $journal['foreign_currency_symbol'],
@@ -364,7 +294,7 @@ class TagRepository implements TagRepositoryInterface
TransactionType::OPENING_BALANCE => '0',
];
// add foreign amount to correct type:
- $amount = app('steam')->positive((string)$journal['foreign_amount']);
+ $amount = app('steam')->positive((string)$journal['foreign_amount']);
if (TransactionType::WITHDRAWAL === $type) {
$amount = bcmul($amount, '-1');
}
@@ -375,13 +305,20 @@ class TagRepository implements TagRepositoryInterface
return $sums;
}
- /**
- * @param Tag $tag
- * @param Carbon $start
- * @param Carbon $end
- *
- * @return array
- */
+ public function tagEndsWith(string $query): Collection
+ {
+ $search = sprintf('%%%s', $query);
+
+ return $this->user->tags()->where('tag', 'LIKE', $search)->get(['tags.*']);
+ }
+
+ public function tagStartsWith(string $query): Collection
+ {
+ $search = sprintf('%s%%', $query);
+
+ return $this->user->tags()->where('tag', 'LIKE', $search)->get(['tags.*']);
+ }
+
public function transferredInPeriod(Tag $tag, Carbon $start, Carbon $end): array
{
/** @var GroupCollectorInterface $collector */
@@ -392,12 +329,6 @@ class TagRepository implements TagRepositoryInterface
return $collector->getExtractedJournals();
}
- /**
- * @param Tag $tag
- * @param array $data
- *
- * @return Tag
- */
public function update(Tag $tag, array $data): Tag
{
if (array_key_exists('tag', $data)) {
@@ -428,7 +359,7 @@ class TagRepository implements TagRepositoryInterface
// otherwise, update or create.
if (!(null === $data['latitude'] && null === $data['longitude'] && null === $data['zoom_level'])) {
- $location = $this->getLocation($tag);
+ $location = $this->getLocation($tag);
if (null === $location) {
$location = new Location();
$location->locatable()->associate($tag);
@@ -447,12 +378,9 @@ class TagRepository implements TagRepositoryInterface
return $tag;
}
- /**
- * @inheritDoc
- */
public function getLocation(Tag $tag): ?Location
{
- /** @var Location|null */
+ // @var Location|null
return $tag->locations()->first();
}
}
diff --git a/app/Repositories/Tag/TagRepositoryInterface.php b/app/Repositories/Tag/TagRepositoryInterface.php
index 8343eb4725..d81efa1cf4 100644
--- a/app/Repositories/Tag/TagRepositoryInterface.php
+++ b/app/Repositories/Tag/TagRepositoryInterface.php
@@ -35,17 +35,10 @@ use Illuminate\Support\Collection;
*/
interface TagRepositoryInterface
{
- /**
- * @return int
- */
public function count(): int;
/**
* This method destroys a tag.
- *
- * @param Tag $tag
- *
- * @return bool
*/
public function destroy(Tag $tag): bool;
@@ -54,156 +47,78 @@ interface TagRepositoryInterface
*/
public function destroyAll(): void;
- /**
- * @param Tag $tag
- * @param Carbon $start
- * @param Carbon $end
- *
- * @return array
- */
public function expenseInPeriod(Tag $tag, Carbon $start, Carbon $end): array;
- /**
- * @param int $tagId
- *
- * @return Tag|null
- */
public function find(int $tagId): ?Tag;
- /**
- * @param string $tag
- *
- * @return Tag|null
- */
public function findByTag(string $tag): ?Tag;
- /**
- * @param Tag $tag
- *
- * @return Carbon|null
- */
public function firstUseDate(Tag $tag): ?Carbon;
/**
* This method returns all the user's tags.
- *
- * @return Collection
*/
public function get(): Collection;
- /**
- * @param Tag $tag
- *
- * @return Collection
- */
public function getAttachments(Tag $tag): Collection;
/**
* Return location, or NULL.
- *
- * @param Tag $tag
- *
- * @return Location|null
*/
public function getLocation(Tag $tag): ?Location;
- /**
- * @param int|null $year
- *
- * @return array
- */
public function getTagsInYear(?int $year): array;
- /**
- * @param Tag $tag
- * @param Carbon $start
- * @param Carbon $end
- *
- * @return array
- */
public function incomeInPeriod(Tag $tag, Carbon $start, Carbon $end): array;
- /**
- * @param Tag $tag
- *
- * @return Carbon|null
- */
public function lastUseDate(Tag $tag): ?Carbon;
/**
* Will return the newest tag (if known) or NULL.
- *
- * @return Tag|null
*/
public function newestTag(): ?Tag;
/**
* Will return the newest tag (if known) or NULL.
- *
- * @return Tag|null
*/
public function oldestTag(): ?Tag;
/**
* Find one or more tags based on the query.
- *
- * @param string $query
- *
- * @return Collection
*/
public function searchTag(string $query): Collection;
/**
* Search the users tags.
- *
- * @param string $query
- * @param int $limit
- *
- * @return Collection
*/
public function searchTags(string $query, int $limit): Collection;
- /**
- * @param User|Authenticatable|null $user
- */
- public function setUser(User | Authenticatable | null $user): void;
+ public function setUser(null|Authenticatable|User $user): void;
/**
* This method stores a tag.
- *
- * @param array $data
- *
- * @return Tag
*/
public function store(array $data): Tag;
/**
* Calculates various amounts in tag.
- *
- * @param Tag $tag
- * @param Carbon|null $start
- * @param Carbon|null $end
- *
- * @return array
*/
public function sumsOfTag(Tag $tag, ?Carbon $start, ?Carbon $end): array;
/**
- * @param Tag $tag
- * @param Carbon $start
- * @param Carbon $end
- *
- * @return array
+ * Find one or more tags that start with the string in the query
*/
+ public function tagEndsWith(string $query): Collection;
+
+ /**
+ * Find one or more tags that start with the string in the query
+ */
+ public function tagStartsWith(string $query): Collection;
+
public function transferredInPeriod(Tag $tag, Carbon $start, Carbon $end): array;
/**
* Update a tag.
- *
- * @param Tag $tag
- * @param array $data
- *
- * @return Tag
*/
public function update(Tag $tag, array $data): Tag;
}
diff --git a/app/Repositories/TransactionGroup/TransactionGroupRepository.php b/app/Repositories/TransactionGroup/TransactionGroupRepository.php
index 860d03187d..0d79d53085 100644
--- a/app/Repositories/TransactionGroup/TransactionGroupRepository.php
+++ b/app/Repositories/TransactionGroup/TransactionGroupRepository.php
@@ -24,8 +24,6 @@ declare(strict_types=1);
namespace FireflyIII\Repositories\TransactionGroup;
use Carbon\Carbon;
-use DB;
-use Exception;
use FireflyIII\Exceptions\DuplicateTransactionException;
use FireflyIII\Exceptions\FireflyException;
use FireflyIII\Factory\TransactionGroupFactory;
@@ -48,8 +46,6 @@ use FireflyIII\User;
use Illuminate\Contracts\Auth\Authenticatable;
use Illuminate\Database\Eloquent\Builder;
use Illuminate\Support\Collection;
-use Illuminate\Support\Facades\Log;
-use JsonException;
/**
* Class TransactionGroupRepository
@@ -58,9 +54,6 @@ class TransactionGroupRepository implements TransactionGroupRepositoryInterface
{
private User $user;
- /**
- * @inheritDoc
- */
public function countAttachments(int $journalId): int
{
/** @var TransactionJournal $journal */
@@ -71,33 +64,24 @@ class TransactionGroupRepository implements TransactionGroupRepositoryInterface
/**
* Find a transaction group by its ID.
- *
- * @param int $groupId
- *
- * @return TransactionGroup|null
*/
public function find(int $groupId): ?TransactionGroup
{
return $this->user->transactionGroups()->find($groupId);
}
- /**
- * @param TransactionGroup $group
- */
public function destroy(TransactionGroup $group): void
{
- Log::debug(sprintf('Now in %s', __METHOD__));
+ app('log')->debug(sprintf('Now in %s', __METHOD__));
$service = new TransactionGroupDestroyService();
$service->destroy($group);
}
- /**
- * @inheritDoc
- */
public function expandGroup(TransactionGroup $group): array
{
$result = $group->toArray();
$result['transaction_journals'] = [];
+
/** @var TransactionJournal $journal */
foreach ($group->transactionJournals as $journal) {
$result['transaction_journals'][] = $this->expandJournal($journal);
@@ -106,11 +90,6 @@ class TransactionGroupRepository implements TransactionGroupRepositoryInterface
return $result;
}
- /**
- * @param TransactionJournal $journal
- *
- * @return array
- */
private function expandJournal(TransactionJournal $journal): array
{
$array = $journal->toArray();
@@ -133,11 +112,6 @@ class TransactionGroupRepository implements TransactionGroupRepositoryInterface
return $array;
}
- /**
- * @param Transaction $transaction
- *
- * @return array
- */
private function expandTransaction(Transaction $transaction): array
{
$array = $transaction->toArray();
@@ -158,29 +132,27 @@ class TransactionGroupRepository implements TransactionGroupRepositoryInterface
/**
* Return all attachments for all journals in the group.
- *
- * @param TransactionGroup $group
- *
- * @return array
*/
public function getAttachments(TransactionGroup $group): array
{
$repository = app(AttachmentRepositoryInterface::class);
$repository->setUser($this->user);
- $journals = $group->transactionJournals->pluck('id')->toArray();
- $set = Attachment::whereIn('attachable_id', $journals)
- ->where('attachable_type', TransactionJournal::class)
- ->where('uploaded', true)
- ->whereNull('deleted_at')->get();
+ $journals = $group->transactionJournals->pluck('id')->toArray();
+ $set = Attachment::whereIn('attachable_id', $journals)
+ ->where('attachable_type', TransactionJournal::class)
+ ->where('uploaded', true)
+ ->whereNull('deleted_at')->get()
+ ;
+
+ $result = [];
- $result = [];
/** @var Attachment $attachment */
foreach ($set as $attachment) {
- $journalId = (int)$attachment->attachable_id;
- $result[$journalId] = $result[$journalId] ?? [];
- $current = $attachment->toArray();
- $current['file_exists'] = true;
- $current['notes'] = $repository->getNoteText($attachment);
+ $journalId = $attachment->attachable_id;
+ $result[$journalId] ??= [];
+ $current = $attachment->toArray();
+ $current['file_exists'] = true;
+ $current['notes'] = $repository->getNoteText($attachment);
// already determined that this attachable is a TransactionJournal.
$current['journal_title'] = $attachment->attachable->description; // @phpstan-ignore-line
$result[$journalId][] = $current;
@@ -189,29 +161,23 @@ class TransactionGroupRepository implements TransactionGroupRepositoryInterface
return $result;
}
- /**
- * @param User|Authenticatable|null $user
- */
- public function setUser(User | Authenticatable | null $user): void
+ public function setUser(null|Authenticatable|User $user): void
{
- if (null !== $user) {
+ if ($user instanceof User) {
$this->user = $user;
}
}
/**
* Get the note text for a journal (by ID).
- *
- * @param int $journalId
- *
- * @return string|null
*/
public function getNoteText(int $journalId): ?string
{
- /** @var Note|null $note */
+ /** @var null|Note $note */
$note = Note::where('noteable_id', $journalId)
- ->where('noteable_type', TransactionJournal::class)
- ->first();
+ ->where('noteable_type', TransactionJournal::class)
+ ->first()
+ ;
if (null === $note) {
return null;
}
@@ -221,28 +187,26 @@ class TransactionGroupRepository implements TransactionGroupRepositoryInterface
/**
* Return all journal links for all journals in the group.
- *
- * @param TransactionGroup $group
- *
- * @return array
*/
public function getLinks(TransactionGroup $group): array
{
$return = [];
$journals = $group->transactionJournals->pluck('id')->toArray();
$set = TransactionJournalLink::where(
- static function (Builder $q) use ($journals) {
+ static function (Builder $q) use ($journals): void {
$q->whereIn('source_id', $journals);
$q->orWhereIn('destination_id', $journals);
}
)
- ->with(['source', 'destination', 'source.transactions'])
- ->leftJoin('link_types', 'link_types.id', '=', 'journal_links.link_type_id')
- ->get(['journal_links.*', 'link_types.inward', 'link_types.outward', 'link_types.editable']);
+ ->with(['source', 'destination', 'source.transactions'])
+ ->leftJoin('link_types', 'link_types.id', '=', 'journal_links.link_type_id')
+ ->get(['journal_links.*', 'link_types.inward', 'link_types.outward', 'link_types.editable'])
+ ;
+
/** @var TransactionJournalLink $entry */
foreach ($set as $entry) {
- $journalId = in_array($entry->source_id, $journals, true) ? $entry->source_id : $entry->destination_id;
- $return[$journalId] = $return[$journalId] ?? [];
+ $journalId = in_array($entry->source_id, $journals, true) ? $entry->source_id : $entry->destination_id;
+ $return[$journalId] ??= [];
// phpstan: the editable field is provided by the query.
@@ -277,11 +241,6 @@ class TransactionGroupRepository implements TransactionGroupRepositoryInterface
return $return;
}
- /**
- * @param TransactionJournal $journal
- *
- * @return string
- */
private function getFormattedAmount(TransactionJournal $journal): string
{
/** @var Transaction $transaction */
@@ -300,11 +259,6 @@ class TransactionGroupRepository implements TransactionGroupRepositoryInterface
return $return;
}
- /**
- * @param TransactionJournal $journal
- *
- * @return string
- */
private function getFormattedForeignAmount(TransactionJournal $journal): string
{
/** @var Transaction $transaction */
@@ -315,10 +269,10 @@ class TransactionGroupRepository implements TransactionGroupRepositoryInterface
if (0 === bccomp('0', $transaction->foreign_amount)) {
return '';
}
- $currency = $transaction->foreignCurrency;
- $type = $journal->transactionType->type;
- $amount = app('steam')->positive($transaction->foreign_amount);
- $return = '';
+ $currency = $transaction->foreignCurrency;
+ $type = $journal->transactionType->type;
+ $amount = app('steam')->positive($transaction->foreign_amount);
+ $return = '';
if (TransactionType::WITHDRAWAL === $type) {
$return = app('amount')->formatAnything($currency, app('steam')->negative($amount));
}
@@ -329,9 +283,6 @@ class TransactionGroupRepository implements TransactionGroupRepositoryInterface
return $return;
}
- /**
- * @inheritDoc
- */
public function getLocation(int $journalId): ?Location
{
/** @var TransactionJournal $journal */
@@ -343,19 +294,16 @@ class TransactionGroupRepository implements TransactionGroupRepositoryInterface
/**
* Return object with all found meta field things as Carbon objects.
*
- * @param int $journalId
- * @param array $fields
- *
- * @return NullArrayObject
- * @throws Exception
+ * @throws \Exception
*/
public function getMetaDateFields(int $journalId, array $fields): NullArrayObject
{
- $query = DB::table('journal_meta')
- ->where('transaction_journal_id', $journalId)
- ->whereIn('name', $fields)
- ->whereNull('deleted_at')
- ->get(['name', 'data']);
+ $query = \DB::table('journal_meta')
+ ->where('transaction_journal_id', $journalId)
+ ->whereIn('name', $fields)
+ ->whereNull('deleted_at')
+ ->get(['name', 'data'])
+ ;
$return = [];
foreach ($query as $row) {
@@ -367,19 +315,15 @@ class TransactionGroupRepository implements TransactionGroupRepositoryInterface
/**
* Return object with all found meta field things.
- *
- * @param int $journalId
- * @param array $fields
- *
- * @return NullArrayObject
*/
public function getMetaFields(int $journalId, array $fields): NullArrayObject
{
- $query = DB::table('journal_meta')
- ->where('transaction_journal_id', $journalId)
- ->whereIn('name', $fields)
- ->whereNull('deleted_at')
- ->get(['name', 'data']);
+ $query = \DB::table('journal_meta')
+ ->where('transaction_journal_id', $journalId)
+ ->whereIn('name', $fields)
+ ->whereNull('deleted_at')
+ ->get(['name', 'data'])
+ ;
$return = [];
foreach ($query as $row) {
@@ -392,38 +336,33 @@ class TransactionGroupRepository implements TransactionGroupRepositoryInterface
/**
* Return all piggy bank events for all journals in the group.
*
- * @param TransactionGroup $group
- *
- * @return array
* @throws FireflyException
- * @throws JsonException
*/
public function getPiggyEvents(TransactionGroup $group): array
{
$return = [];
$journals = $group->transactionJournals->pluck('id')->toArray();
- $currency = app('amount')->getDefaultCurrencyByUser($this->user);
+ $currency = app('amount')->getDefaultCurrencyByUserGroup($this->user->userGroup);
$data = PiggyBankEvent::whereIn('transaction_journal_id', $journals)
- ->with('piggyBank', 'piggyBank.account')
- ->get(['piggy_bank_events.*']);
+ ->with('piggyBank', 'piggyBank.account')
+ ->get(['piggy_bank_events.*'])
+ ;
+
/** @var PiggyBankEvent $row */
foreach ($data as $row) {
if (null === $row->piggyBank) {
continue;
}
// get currency preference.
- $currencyPreference = AccountMeta::where('account_id', $row->piggyBank->account_id)
- ->where('name', 'currency_id')
- ->first();
+ $currencyPreference = AccountMeta::where('account_id', $row->piggyBank->account_id)
+ ->where('name', 'currency_id')
+ ->first()
+ ;
if (null !== $currencyPreference) {
$currency = TransactionCurrency::where('id', $currencyPreference->data)->first();
}
- if (null === $currencyPreference) {
- $currencyCode = app('preferences')->getForUser($this->user, 'currencyPreference', 'EUR')->data;
- $currency = TransactionCurrency::where('code', $currencyCode)->first();
- }
- $journalId = (int)$row->transaction_journal_id;
- $return[$journalId] = $return[$journalId] ?? [];
+ $journalId = $row->transaction_journal_id;
+ $return[$journalId] ??= [];
$return[$journalId][] = [
'piggy' => $row->piggyBank->name,
@@ -435,9 +374,6 @@ class TransactionGroupRepository implements TransactionGroupRepositoryInterface
return $return;
}
- /**
- * @inheritDoc
- */
public function getTagObjects(int $journalId): Collection
{
/** @var TransactionJournal $journal */
@@ -448,54 +384,45 @@ class TransactionGroupRepository implements TransactionGroupRepositoryInterface
/**
* Get the tags for a journal (by ID).
- *
- * @param int $journalId
- *
- * @return array
*/
public function getTags(int $journalId): array
{
- $result = DB::table('tag_transaction_journal')
- ->leftJoin('tags', 'tag_transaction_journal.tag_id', '=', 'tags.id')
- ->where('tag_transaction_journal.transaction_journal_id', $journalId)
- ->orderBy('tags.tag', 'ASC')
- ->get(['tags.tag']);
+ $result = \DB::table('tag_transaction_journal')
+ ->leftJoin('tags', 'tag_transaction_journal.tag_id', '=', 'tags.id')
+ ->where('tag_transaction_journal.transaction_journal_id', $journalId)
+ ->orderBy('tags.tag', 'ASC')
+ ->get(['tags.tag'])
+ ;
return $result->pluck('tag')->toArray();
}
/**
- * @param array $data
- *
- * @return TransactionGroup
* @throws DuplicateTransactionException
* @throws FireflyException
- * @throws JsonException
*/
public function store(array $data): TransactionGroup
{
/** @var TransactionGroupFactory $factory */
$factory = app(TransactionGroupFactory::class);
$factory->setUser($this->user);
+
try {
return $factory->create($data);
} catch (DuplicateTransactionException $e) {
app('log')->warning('Group repository caught group factory with a duplicate exception!');
+
throw new DuplicateTransactionException($e->getMessage(), 0, $e);
} catch (FireflyException $e) {
app('log')->warning('Group repository caught group factory with an exception!');
- Log::error($e->getMessage());
- Log::error($e->getTraceAsString());
+ app('log')->error($e->getMessage());
+ app('log')->error($e->getTraceAsString());
+
throw new FireflyException($e->getMessage(), 0, $e);
}
}
/**
- * @param TransactionGroup $transactionGroup
- * @param array $data
- *
- * @return TransactionGroup
- *
* @throws DuplicateTransactionException
* @throws FireflyException
*/
diff --git a/app/Repositories/TransactionGroup/TransactionGroupRepositoryInterface.php b/app/Repositories/TransactionGroup/TransactionGroupRepositoryInterface.php
index 8056677ee9..dfe1405ab7 100644
--- a/app/Repositories/TransactionGroup/TransactionGroupRepositoryInterface.php
+++ b/app/Repositories/TransactionGroup/TransactionGroupRepositoryInterface.php
@@ -37,130 +37,70 @@ use Illuminate\Support\Collection;
*/
interface TransactionGroupRepositoryInterface
{
- /**
- * @param int $journalId
- *
- * @return int
- */
public function countAttachments(int $journalId): int;
- /**
- * @param TransactionGroup $group
- */
public function destroy(TransactionGroup $group): void;
/**
* Return a group and expand all meta data etc.
- *
- * @param TransactionGroup $group
- *
- * @return array
*/
public function expandGroup(TransactionGroup $group): array;
/**
* Find a transaction group by its ID.
- *
- * @param int $groupId
- *
- * @return TransactionGroup|null
*/
public function find(int $groupId): ?TransactionGroup;
/**
* Return all attachments for all journals in the group.
- *
- * @param TransactionGroup $group
- *
- * @return array
*/
public function getAttachments(TransactionGroup $group): array;
/**
* Return all journal links for all journals in the group.
- *
- * @param TransactionGroup $group
- *
- * @return array
*/
public function getLinks(TransactionGroup $group): array;
/**
* Get the location of a journal or NULL.
- *
- * @param int $journalId
- *
- * @return Location|null
*/
public function getLocation(int $journalId): ?Location;
/**
* Return object with all found meta field things as Carbon objects.
- *
- * @param int $journalId
- * @param array $fields
- *
- * @return NullArrayObject
*/
public function getMetaDateFields(int $journalId, array $fields): NullArrayObject;
/**
* Return object with all found meta field things.
- *
- * @param int $journalId
- * @param array $fields
- *
- * @return NullArrayObject
*/
public function getMetaFields(int $journalId, array $fields): NullArrayObject;
/**
* Get the note text for a journal (by ID).
- *
- * @param int $journalId
- *
- * @return string|null
*/
public function getNoteText(int $journalId): ?string;
/**
* Return all piggy bank events for all journals in the group.
- *
- * @param TransactionGroup $group
- *
- * @return array
*/
public function getPiggyEvents(TransactionGroup $group): array;
/**
* Get the tags for a journal (by ID) as Tag objects.
- *
- * @param int $journalId
- *
- * @return Collection
*/
public function getTagObjects(int $journalId): Collection;
/**
* Get the tags for a journal (by ID).
- *
- * @param int $journalId
- *
- * @return array
*/
public function getTags(int $journalId): array;
- /**
- * @param User|Authenticatable|null $user
- */
- public function setUser(User | Authenticatable | null $user): void;
+ public function setUser(null|Authenticatable|User $user): void;
/**
* Create a new transaction group.
*
- * @param array $data
- *
- * @return TransactionGroup
* @throws DuplicateTransactionException
* @throws FireflyException
*/
@@ -168,11 +108,6 @@ interface TransactionGroupRepositoryInterface
/**
* Update an existing transaction group.
- *
- * @param TransactionGroup $transactionGroup
- * @param array $data
- *
- * @return TransactionGroup
*/
public function update(TransactionGroup $transactionGroup, array $data): TransactionGroup;
}
diff --git a/app/Repositories/TransactionType/TransactionTypeRepository.php b/app/Repositories/TransactionType/TransactionTypeRepository.php
index e5db6a1308..4e47c0cffa 100644
--- a/app/Repositories/TransactionType/TransactionTypeRepository.php
+++ b/app/Repositories/TransactionType/TransactionTypeRepository.php
@@ -25,42 +25,30 @@ namespace FireflyIII\Repositories\TransactionType;
use FireflyIII\Models\TransactionType;
use Illuminate\Support\Collection;
-use Illuminate\Support\Facades\Log;
/**
* Class TransactionTypeRepository
*/
class TransactionTypeRepository implements TransactionTypeRepositoryInterface
{
- /**
- * @param TransactionType|null $type
- * @param string|null $typeString
- *
- * @return TransactionType
- */
public function findTransactionType(?TransactionType $type, ?string $typeString): TransactionType
{
- Log::debug('Now looking for a transaction type.');
+ app('log')->debug('Now looking for a transaction type.');
if (null !== $type) {
- Log::debug(sprintf('Found $type in parameters, its %s. Will return it.', $type->type));
+ app('log')->debug(sprintf('Found $type in parameters, its %s. Will return it.', $type->type));
return $type;
}
- $typeString = $typeString ?? TransactionType::WITHDRAWAL;
- $search = $this->findByType($typeString);
+ $typeString ??= TransactionType::WITHDRAWAL;
+ $search = $this->findByType($typeString);
if (null === $search) {
$search = $this->findByType(TransactionType::WITHDRAWAL);
}
- Log::debug(sprintf('Tried to search for "%s", came up with "%s". Will return it.', $typeString, $search->type));
+ app('log')->debug(sprintf('Tried to search for "%s", came up with "%s". Will return it.', $typeString, $search->type));
return $search;
}
- /**
- * @param string $type
- *
- * @return TransactionType|null
- */
public function findByType(string $type): ?TransactionType
{
$search = ucfirst($type);
@@ -68,12 +56,6 @@ class TransactionTypeRepository implements TransactionTypeRepositoryInterface
return TransactionType::whereType($search)->first();
}
- /**
- * @param string $query
- * @param int $limit
- *
- * @return Collection
- */
public function searchTypes(string $query, int $limit): Collection
{
if ('' === $query) {
diff --git a/app/Repositories/TransactionType/TransactionTypeRepositoryInterface.php b/app/Repositories/TransactionType/TransactionTypeRepositoryInterface.php
index ff4c4b296f..862111f101 100644
--- a/app/Repositories/TransactionType/TransactionTypeRepositoryInterface.php
+++ b/app/Repositories/TransactionType/TransactionTypeRepositoryInterface.php
@@ -31,26 +31,9 @@ use Illuminate\Support\Collection;
*/
interface TransactionTypeRepositoryInterface
{
- /**
- * @param string $type
- *
- * @return TransactionType|null
- */
public function findByType(string $type): ?TransactionType;
- /**
- * @param TransactionType|null $type
- * @param string|null $typeString
- *
- * @return TransactionType
- */
public function findTransactionType(?TransactionType $type, ?string $typeString): TransactionType;
- /**
- * @param string $query
- * @param int $limit
- *
- * @return Collection
- */
public function searchTypes(string $query, int $limit): Collection;
}
diff --git a/app/Repositories/User/UserRepository.php b/app/Repositories/User/UserRepository.php
index 73b9c1edad..8cb3b53854 100644
--- a/app/Repositories/User/UserRepository.php
+++ b/app/Repositories/User/UserRepository.php
@@ -23,7 +23,6 @@ declare(strict_types=1);
namespace FireflyIII\Repositories\User;
-use Exception;
use FireflyIII\Exceptions\FireflyException;
use FireflyIII\Models\BudgetLimit;
use FireflyIII\Models\GroupMembership;
@@ -34,12 +33,9 @@ use FireflyIII\User;
use Illuminate\Contracts\Auth\Authenticatable;
use Illuminate\Database\QueryException;
use Illuminate\Support\Collection;
-use Illuminate\Support\Facades\Log;
-use Str;
/**
* Class UserRepository.
- *
*/
class UserRepository implements UserRepositoryInterface
{
@@ -47,21 +43,17 @@ class UserRepository implements UserRepositoryInterface
* This updates the users email address and records some things so it can be confirmed or undone later.
* The user is blocked until the change is confirmed.
*
- * @param User $user
- * @param string $newEmail
+ * @throws \Exception
*
- * @return bool
- * @throws Exception
* @see updateEmail
- *
*/
public function changeEmail(User $user, string $newEmail): bool
{
- $oldEmail = $user->email;
+ $oldEmail = $user->email;
// save old email as pref
app('preferences')->setForUser($user, 'previous_email_latest', $oldEmail);
- app('preferences')->setForUser($user, 'previous_email_' . date('Y-m-d-H-i-s'), $oldEmail);
+ app('preferences')->setForUser($user, 'previous_email_'.date('Y-m-d-H-i-s'), $oldEmail);
// set undo and confirm token:
app('preferences')->setForUser($user, 'email_change_undo_token', bin2hex(random_bytes(16)));
@@ -76,12 +68,6 @@ class UserRepository implements UserRepositoryInterface
return true;
}
- /**
- * @param User $user
- * @param string $password
- *
- * @return bool
- */
public function changePassword(User $user, string $password): bool
{
$user->password = bcrypt($password);
@@ -90,13 +76,6 @@ class UserRepository implements UserRepositoryInterface
return true;
}
- /**
- * @param User $user
- * @param bool $isBlocked
- * @param string $code
- *
- * @return bool
- */
public function changeStatus(User $user, bool $isBlocked, string $code): bool
{
// change blocked status and code:
@@ -107,36 +86,23 @@ class UserRepository implements UserRepositoryInterface
return true;
}
- /**
- * @param string $name
- * @param string $displayName
- * @param string $description
- *
- * @return Role
- */
public function createRole(string $name, string $displayName, string $description): Role
{
return Role::create(['name' => $name, 'display_name' => $displayName, 'description' => $description]);
}
- /**
- * @inheritDoc
- */
public function deleteInvite(InvitedUser $invite): void
{
- Log::debug(sprintf('Deleting invite #%d', $invite->id));
+ app('log')->debug(sprintf('Deleting invite #%d', $invite->id));
$invite->delete();
}
/**
- * @param User $user
- *
- * @return bool
- * @throws Exception
+ * @throws \Exception
*/
public function destroy(User $user): bool
{
- Log::debug(sprintf('Calling delete() on user %d', $user->id));
+ app('log')->debug(sprintf('Calling delete() on user %d', $user->id));
$user->groupMemberships()->delete();
$user->delete();
@@ -145,43 +111,30 @@ class UserRepository implements UserRepositoryInterface
return true;
}
- /**
- * @inheritDoc
- */
public function deleteEmptyGroups(): void
{
$groups = UserGroup::get();
+
/** @var UserGroup $group */
foreach ($groups as $group) {
$count = $group->groupMemberships()->count();
if (0 === $count) {
- Log::info(sprintf('Deleted empty group #%d ("%s")', $group->id, $group->title));
+ app('log')->info(sprintf('Deleted empty group #%d ("%s")', $group->id, $group->title));
$group->delete();
}
}
}
- /**
- * @return int
- */
public function count(): int
{
return $this->all()->count();
}
- /**
- * @return Collection
- */
public function all(): Collection
{
return User::orderBy('id', 'DESC')->get(['users.*']);
}
- /**
- * @param string $email
- *
- * @return User|null
- */
public function findByEmail(string $email): ?User
{
return User::where('email', $email)->first();
@@ -189,30 +142,20 @@ class UserRepository implements UserRepositoryInterface
/**
* Returns the first user in the DB. Generally only works when there is just one.
- *
- * @return null|User
*/
public function first(): ?User
{
return User::orderBy('id', 'ASC')->first();
}
- /**
- * @inheritDoc
- */
public function getInvitedUsers(): Collection
{
return InvitedUser::with('user')->get();
}
- /**
- * @param User $user
- *
- * @return string|null
- */
public function getRoleByUser(User $user): ?string
{
- /** @var Role|null $role */
+ /** @var null|Role $role */
$role = $user->roles()->first();
if (null !== $role) {
return $role->name;
@@ -222,31 +165,27 @@ class UserRepository implements UserRepositoryInterface
}
/**
- * @inheritDoc
* @throws FireflyException
*/
public function getRolesInGroup(User $user, int $groupId): array
{
- /** @var UserGroup $group */
- $group = UserGroup::find($groupId);
+ /** @var null|UserGroup $group */
+ $group = UserGroup::find($groupId);
if (null === $group) {
throw new FireflyException(sprintf('Could not find group #%d', $groupId));
}
$memberships = $group->groupMemberships()->where('user_id', $user->id)->get();
$roles = [];
+
/** @var GroupMembership $membership */
foreach ($memberships as $membership) {
$role = $membership->userRole;
$roles[] = $role->title;
}
+
return $roles;
}
- /**
- * @param int $userId
- *
- * @return User|null
- */
public function find(int $userId): ?User
{
return User::find($userId);
@@ -254,17 +193,13 @@ class UserRepository implements UserRepositoryInterface
/**
* Return basic user information.
- *
- * @param User $user
- *
- * @return array
*/
public function getUserData(User $user): array
{
- $return = [];
+ $return = [];
// two factor:
- $return['has_2fa'] = $user->mfa_secret !== null;
+ $return['has_2fa'] = null !== $user->mfa_secret;
$return['is_admin'] = $this->hasRole($user, 'owner');
$return['blocked'] = 1 === (int)$user->blocked;
$return['blocked_code'] = $user->blocked_code;
@@ -277,11 +212,12 @@ class UserRepository implements UserRepositoryInterface
$return['categories'] = $user->categories()->count();
$return['budgets'] = $user->budgets()->count();
$return['budgets_with_limits'] = BudgetLimit::distinct()
- ->leftJoin('budgets', 'budgets.id', '=', 'budget_limits.budget_id')
- ->where('amount', '>', 0)
- ->whereNull('budgets.deleted_at')
- ->where('budgets.user_id', $user->id)
- ->count('budget_limits.budget_id');
+ ->leftJoin('budgets', 'budgets.id', '=', 'budget_limits.budget_id')
+ ->where('amount', '>', 0)
+ ->whereNull('budgets.deleted_at')
+ ->where('budgets.user_id', $user->id)
+ ->count('budget_limits.budget_id')
+ ;
$return['rule_groups'] = $user->ruleGroups()->count();
$return['rules'] = $user->rules()->count();
$return['tags'] = $user->tags()->count();
@@ -289,37 +225,30 @@ class UserRepository implements UserRepositoryInterface
return $return;
}
- /**
- * @param User|Authenticatable|null $user
- * @param string $role
- *
- * @return bool
- */
- public function hasRole(User | Authenticatable | null $user, string $role): bool
+ public function hasRole(null|Authenticatable|User $user, string $role): bool
{
if (null === $user) {
return false;
}
- /** @var Role $userRole */
- foreach ($user->roles as $userRole) {
- if ($userRole->name === $role) {
- return true;
+ if ($user instanceof User) {
+ /** @var Role $userRole */
+ foreach ($user->roles as $userRole) {
+ if ($userRole->name === $role) {
+ return true;
+ }
}
}
return false;
}
- /**
- * @inheritDoc
- */
- public function inviteUser(User | Authenticatable | null $user, string $email): InvitedUser
+ public function inviteUser(null|Authenticatable|User $user, string $email): InvitedUser
{
- $now = today(config('app.timezone'));
+ $now = today(config('app.timezone'));
$now->addDays(2);
- $invitee = new InvitedUser();
+ $invitee = new InvitedUser();
$invitee->user()->associate($user);
- $invitee->invite_code = Str::random(64);
+ $invitee->invite_code = \Str::random(64);
$invitee->email = $email;
$invitee->redeemed = false;
$invitee->expires = $now;
@@ -328,13 +257,10 @@ class UserRepository implements UserRepositoryInterface
return $invitee;
}
- /**
- * @inheritDoc
- */
public function redeemCode(string $code): void
{
$obj = InvitedUser::where('invite_code', $code)->where('redeemed', 0)->first();
- if ($obj) {
+ if (null !== $obj) {
$obj->redeemed = true;
$obj->save();
}
@@ -342,9 +268,6 @@ class UserRepository implements UserRepositoryInterface
/**
* Set MFA code.
- *
- * @param User $user
- * @param string|null $code
*/
public function setMFACode(User $user, ?string $code): void
{
@@ -352,11 +275,6 @@ class UserRepository implements UserRepositoryInterface
$user->save();
}
- /**
- * @param array $data
- *
- * @return User
- */
public function store(array $data): User
{
$user = User::create(
@@ -364,7 +282,7 @@ class UserRepository implements UserRepositoryInterface
'blocked' => $data['blocked'] ?? false,
'blocked_code' => $data['blocked_code'] ?? null,
'email' => $data['email'],
- 'password' => Str::random(24),
+ 'password' => \Str::random(24),
]
);
$role = $data['role'] ?? '';
@@ -375,17 +293,11 @@ class UserRepository implements UserRepositoryInterface
return $user;
}
- /**
- * @param User $user
- * @param string $role
- *
- * @return bool
- */
public function attachRole(User $user, string $role): bool
{
$roleObject = Role::where('name', $role)->first();
if (null === $roleObject) {
- Log::error(sprintf('Could not find role "%s" in attachRole()', $role));
+ app('log')->error(sprintf('Could not find role "%s" in attachRole()', $role));
return false;
}
@@ -394,15 +306,12 @@ class UserRepository implements UserRepositoryInterface
$user->roles()->attach($roleObject);
} catch (QueryException $e) {
// don't care
- Log::error(sprintf('Query exception when giving user a role: %s', $e->getMessage()));
+ app('log')->error(sprintf('Query exception when giving user a role: %s', $e->getMessage()));
}
return true;
}
- /**
- * @param User $user
- */
public function unblockUser(User $user): void
{
$user->blocked = false;
@@ -413,10 +322,6 @@ class UserRepository implements UserRepositoryInterface
/**
* Update user info.
*
- * @param User $user
- * @param array $data
- *
- * @return User
* @throws FireflyException
*/
public function update(User $user, array $data): User
@@ -442,11 +347,8 @@ class UserRepository implements UserRepositoryInterface
* This updates the users email address. Same as changeEmail just without most logging. This makes sure that the
* undo/confirm routine can't catch this one. The user is NOT blocked.
*
- * @param User $user
- * @param string $newEmail
- *
- * @return bool
* @throws FireflyException
+ *
* @see changeEmail
*/
public function updateEmail(User $user, string $newEmail): bool
@@ -454,11 +356,11 @@ class UserRepository implements UserRepositoryInterface
if ('' === $newEmail) {
return true;
}
- $oldEmail = $user->email;
+ $oldEmail = $user->email;
// save old email as pref
app('preferences')->setForUser($user, 'admin_previous_email_latest', $oldEmail);
- app('preferences')->setForUser($user, 'admin_previous_email_' . date('Y-m-d-H-i-s'), $oldEmail);
+ app('preferences')->setForUser($user, 'admin_previous_email_'.date('Y-m-d-H-i-s'), $oldEmail);
$user->email = $newEmail;
$user->save();
@@ -468,9 +370,6 @@ class UserRepository implements UserRepositoryInterface
/**
* Remove any role the user has.
- *
- * @param User $user
- * @param string $role
*/
public function removeRole(User $user, string $role): void
{
@@ -481,23 +380,16 @@ class UserRepository implements UserRepositoryInterface
$user->roles()->detach($roleObj->id);
}
- /**
- * @param string $role
- *
- * @return Role|null
- */
public function getRole(string $role): ?Role
{
return Role::where('name', $role)->first();
}
- /**
- * @inheritDoc
- */
public function validateInviteCode(string $code): bool
{
$now = today(config('app.timezone'));
$invitee = InvitedUser::where('invite_code', $code)->where('expires', '>', $now->format('Y-m-d H:i:s'))->where('redeemed', 0)->first();
+
return null !== $invitee;
}
}
diff --git a/app/Repositories/User/UserRepositoryInterface.php b/app/Repositories/User/UserRepositoryInterface.php
index 3803d385ce..a76e8d770e 100644
--- a/app/Repositories/User/UserRepositoryInterface.php
+++ b/app/Repositories/User/UserRepositoryInterface.php
@@ -36,18 +36,11 @@ interface UserRepositoryInterface
{
/**
* Returns a collection of all users.
- *
- * @return Collection
*/
public function all(): Collection;
/**
* Gives a user a role.
- *
- * @param User $user
- * @param string $role
- *
- * @return bool
*/
public function attachRole(User $user, string $role): bool;
@@ -55,182 +48,74 @@ interface UserRepositoryInterface
* This updates the users email address and records some things so it can be confirmed or undone later.
* The user is blocked until the change is confirmed.
*
- * @param User $user
- * @param string $newEmail
- *
- * @return bool
* @see updateEmail
- *
*/
public function changeEmail(User $user, string $newEmail): bool;
/**
- * @param User $user
- * @param string $password
- *
* @return mixed
*/
public function changePassword(User $user, string $password);
- /**
- * @param User $user
- * @param bool $isBlocked
- * @param string $code
- *
- * @return bool
- */
public function changeStatus(User $user, bool $isBlocked, string $code): bool;
/**
* Returns a count of all users.
- *
- * @return int
*/
public function count(): int;
- /**
- * @param string $name
- * @param string $displayName
- * @param string $description
- *
- * @return Role
- */
public function createRole(string $name, string $displayName, string $description): Role;
- /**
- *
- */
public function deleteEmptyGroups(): void;
- /**
- * @param InvitedUser $invite
- *
- * @return void
- */
public function deleteInvite(InvitedUser $invite): void;
- /**
- * @param User $user
- *
- * @return bool
- */
public function destroy(User $user): bool;
- /**
- * @param int $userId
- *
- * @return User|null
- */
public function find(int $userId): ?User;
- /**
- * @param string $email
- *
- * @return User|null
- */
public function findByEmail(string $email): ?User;
/**
* Returns the first user in the DB. Generally only works when there is just one.
- *
- * @return null|User
*/
public function first(): ?User;
- /**
- * @return Collection
- */
public function getInvitedUsers(): Collection;
- /**
- * @param string $role
- *
- * @return Role|null
- */
public function getRole(string $role): ?Role;
- /**
- * @param User $user
- *
- * @return string|null
- */
public function getRoleByUser(User $user): ?string;
- /**
- * @param User $user
- * @param int $groupId
- *
- * @return array
- */
public function getRolesInGroup(User $user, int $groupId): array;
/**
* Return basic user information.
- *
- * @param User $user
- *
- * @return array
*/
public function getUserData(User $user): array;
- /**
- * @param User|Authenticatable|null $user
- * @param string $role
- *
- * @return bool
- */
- public function hasRole(User | Authenticatable | null $user, string $role): bool;
+ public function hasRole(null|Authenticatable|User $user, string $role): bool;
- /**
- * @param User|Authenticatable|null $user
- * @param string $email
- *
- * @return InvitedUser
- */
- public function inviteUser(User | Authenticatable | null $user, string $email): InvitedUser;
+ public function inviteUser(null|Authenticatable|User $user, string $email): InvitedUser;
- /**
- * @param string $code
- *
- * @return void
- */
public function redeemCode(string $code): void;
/**
* Remove any role the user has.
- *
- * @param User $user
- * @param string $role
*/
public function removeRole(User $user, string $role): void;
/**
* Set MFA code.
- *
- * @param User $user
- * @param string|null $code
*/
public function setMFACode(User $user, ?string $code): void;
- /**
- * @param array $data
- *
- * @return User
- */
public function store(array $data): User;
- /**
- * @param User $user
- */
public function unblockUser(User $user): void;
/**
* Update user info.
- *
- * @param User $user
- * @param array $data
- *
- * @return User
*/
public function update(User $user, array $data): User;
@@ -238,19 +123,9 @@ interface UserRepositoryInterface
* This updates the users email address. Same as changeEmail just without most logging. This makes sure that the
* undo/confirm routine can't catch this one. The user is NOT blocked.
*
- * @param User $user
- * @param string $newEmail
- *
- * @return bool
* @see changeEmail
- *
*/
public function updateEmail(User $user, string $newEmail): bool;
- /**
- * @param string $code
- *
- * @return bool
- */
public function validateInviteCode(string $code): bool;
}
diff --git a/app/Repositories/UserGroup/UserGroupRepository.php b/app/Repositories/UserGroup/UserGroupRepository.php
index 7be53c78f8..e27805fc2c 100644
--- a/app/Repositories/UserGroup/UserGroupRepository.php
+++ b/app/Repositories/UserGroup/UserGroupRepository.php
@@ -1,6 +1,5 @@
debug(sprintf('Going to destroy user group #%d ("%s").', $userGroup->id, $userGroup->title));
$memberships = $userGroup->groupMemberships()->get();
+
/** @var GroupMembership $membership */
foreach ($memberships as $membership) {
- /** @var User $user */
- $user = $membership->user()->first();
+ /** @var null|User $user */
+ $user = $membership->user()->first();
if (null === $user) {
continue;
}
@@ -70,6 +66,7 @@ class UserGroupRepository implements UserGroupRepositoryInterface
// user has other memberships, select one at random and assign it to the user.
if ($count > 0) {
app('log')->debug('User has other memberships and will be assigned a new administration.');
+
/** @var GroupMembership $first */
$first = $user->groupMemberships()->where('user_group_id', '!=', $userGroup->id)->inRandomOrder()->first();
$user->user_group_id = $first->id;
@@ -81,11 +78,11 @@ class UserGroupRepository implements UserGroupRepositoryInterface
// all users are now moved away from user group.
// time to DESTROY all objects.
// we have to do this one by one to trigger the necessary observers :(
- $objects = ['availableBudgets', 'bills', 'budgets', 'categories', 'currencyExchangeRates', 'objectGroups',
- 'recurrences', 'rules', 'ruleGroups', 'tags', 'transactionGroups', 'transactionJournals', 'piggyBanks', 'accounts', 'webhooks',
+ $objects = ['availableBudgets', 'bills', 'budgets', 'categories', 'currencyExchangeRates', 'objectGroups',
+ 'recurrences', 'rules', 'ruleGroups', 'tags', 'transactionGroups', 'transactionJournals', 'piggyBanks', 'accounts', 'webhooks',
];
foreach ($objects as $object) {
- foreach ($userGroup->$object()->get() as $item) {
+ foreach ($userGroup->{$object}()->get() as $item) { // @phpstan-ignore-line
$item->delete();
}
}
@@ -96,30 +93,28 @@ class UserGroupRepository implements UserGroupRepositoryInterface
/**
* Returns all groups the user is member in.
*
- * @inheritDoc
+ * {@inheritDoc}
*/
public function get(): Collection
{
$collection = new Collection();
$memberships = $this->user->groupMemberships()->get();
+
/** @var GroupMembership $membership */
foreach ($memberships as $membership) {
- /** @var UserGroup $group */
+ /** @var null|UserGroup $group */
$group = $membership->userGroup()->first();
if (null !== $group) {
$collection->push($group);
}
}
+
return $collection;
}
/**
* Because there is the chance that a group with this name already exists,
* Firefly III runs a little loop of combinations to make sure the group name is unique.
- *
- * @param User $user
- *
- * @return UserGroup
*/
private function createNewUserGroup(User $user): UserGroup
{
@@ -131,119 +126,125 @@ class UserGroupRepository implements UserGroupRepositoryInterface
$existingGroup = $this->findByName($groupName);
if (null === $existingGroup) {
$exists = false;
+
+ /** @var null|UserGroup $existingGroup */
$existingGroup = $this->store(['user' => $user, 'title' => $groupName]);
}
if (null !== $existingGroup) {
// group already exists
- $groupName = sprintf('%s-%s', $user->email, substr(sha1((string)(rand(1000, 9999) . microtime())), 0, 4));
+ $groupName = sprintf('%s-%s', $user->email, substr(sha1(rand(1000, 9999).microtime()), 0, 4));
}
- $loop++;
+ ++$loop;
}
+
return $existingGroup;
}
- /**
- * @param string $title
- *
- * @return UserGroup|null
- */
public function findByName(string $title): ?UserGroup
{
return UserGroup::whereTitle($title)->first();
}
/**
- * @param array $data
- *
- * @return UserGroup
* @throws FireflyException
*/
public function store(array $data): UserGroup
{
$data['user'] = $this->user;
+
/** @var UserGroupFactory $factory */
- $factory = app(UserGroupFactory::class);
+ $factory = app(UserGroupFactory::class);
+
return $factory->create($data);
}
/**
* Returns all groups.
*
- * @inheritDoc
+ * {@inheritDoc}
*/
public function getAll(): Collection
{
return UserGroup::all();
}
- /**
- * @inheritDoc
- */
- public function setUser(Authenticatable | User | null $user): void
+ public function setUser(null|Authenticatable|User $user): void
{
app('log')->debug(sprintf('Now in %s', __METHOD__));
- if (null !== $user) {
+ if ($user instanceof User) {
$this->user = $user;
}
}
- /**
- * @inheritDoc
- */
public function update(UserGroup $userGroup, array $data): UserGroup
{
$userGroup->title = $data['title'];
$userGroup->save();
+
return $userGroup;
}
/**
- * @inheritDoc
+ * @SuppressWarnings(PHPMD.NPathComplexity)
+ *
* @throws FireflyException
*/
public function updateMembership(UserGroup $userGroup, array $data): UserGroup
{
- $owner = UserRole::whereTitle(UserRoleEnum::OWNER)->first();
+ $owner = UserRole::whereTitle(UserRoleEnum::OWNER)->first();
app('log')->debug('in update membership');
- $user = null;
+
+ /** @var null|User $user */
+ $user = null;
if (array_key_exists('id', $data)) {
+ /** @var null|User $user */
$user = User::find($data['id']);
app('log')->debug('Found user by ID');
}
if (array_key_exists('email', $data) && '' !== (string)$data['email']) {
+ /** @var null|User $user */
$user = User::whereEmail($data['email'])->first();
app('log')->debug('Found user by email');
}
if (null === $user) {
// should throw error, but validator already catches this.
app('log')->debug('No user found');
+
return $userGroup;
}
// count the number of members in the group right now:
- $membershipCount = $userGroup->groupMemberships()->distinct()->get(['group_memberships.user_id'])->count();
+ $membershipCount = $userGroup->groupMemberships()->distinct()->count('group_memberships.user_id');
// if it's 1:
if (1 === $membershipCount) {
- $lastUserId = (int)$userGroup->groupMemberships()->distinct()->first(['group_memberships.user_id'])->user_id;
+ $lastUserId = $userGroup->groupMemberships()->distinct()->first(['group_memberships.user_id'])->user_id;
// if this is also the user we're editing right now, and we remove all of their roles:
if ($lastUserId === (int)$user->id && 0 === count($data['roles'])) {
app('log')->debug('User is last in this group, refuse to act');
+
throw new FireflyException('You cannot remove the last member from this user group. Delete the user group instead.');
}
// if this is also the user we're editing right now, and do not grant them the owner role:
if ($lastUserId === (int)$user->id && count($data['roles']) > 0 && !in_array(UserRoleEnum::OWNER->value, $data['roles'], true)) {
app('log')->debug('User needs to have owner role in this group, refuse to act');
+
throw new FireflyException('The last member in this user group must get or keep the "owner" role.');
}
}
if ($membershipCount > 1) {
// group has multiple members. How many are owner, except the user we're editing now?
$ownerCount = $userGroup->groupMemberships()
- ->where('user_role_id', $owner->id)
- ->where('user_id', '!=', $user->id)->count();
+ ->where('user_role_id', $owner->id)
+ ->where('user_id', '!=', $user->id)->count()
+ ;
// if there are no other owners and the current users does not get or keep the owner role, refuse.
- if (0 === $ownerCount && (0 === count($data['roles']) || (count($data['roles']) > 0 && !in_array(UserRoleEnum::OWNER->value, $data['roles'], true)))) {
+ if (
+ 0 === $ownerCount
+ && (0 === count($data['roles'])
+ || (count($data['roles']) > 0 // @phpstan-ignore-line
+ && !in_array(UserRoleEnum::OWNER->value, $data['roles'], true)))) {
app('log')->debug('User needs to keep owner role in this group, refuse to act');
+
throw new FireflyException('The last owner in this user group must keep the "owner" role.');
}
}
@@ -255,31 +256,30 @@ class UserGroupRepository implements UserGroupRepositoryInterface
foreach ($rolesSimplified as $role) {
try {
$enum = UserRoleEnum::from($role);
- } catch (ValueError $e) {
+ } catch (\ValueError $e) {
// TODO error message
continue;
}
$userRole = UserRole::whereTitle($enum->value)->first();
$user->groupMemberships()->create(['user_group_id' => $userGroup->id, 'user_role_id' => $userRole->id]);
}
+
return $userGroup;
}
- /**
- * @param array $roles
- *
- * @return array
- */
private function simplifyListByName(array $roles): array
{
if (in_array(UserRoleEnum::OWNER->value, $roles, true)) {
- app('log')->debug(sprintf('List of roles is [%1$s] but this includes "%2$s", so return [%2$s]', join(',', $roles), UserRoleEnum::OWNER->value));
+ app('log')->debug(sprintf('List of roles is [%1$s] but this includes "%2$s", so return [%2$s]', implode(',', $roles), UserRoleEnum::OWNER->value));
+
return [UserRoleEnum::OWNER->value];
}
if (in_array(UserRoleEnum::FULL->value, $roles, true)) {
- app('log')->debug(sprintf('List of roles is [%1$s] but this includes "%2$s", so return [%2$s]', join(',', $roles), UserRoleEnum::FULL->value));
+ app('log')->debug(sprintf('List of roles is [%1$s] but this includes "%2$s", so return [%2$s]', implode(',', $roles), UserRoleEnum::FULL->value));
+
return [UserRoleEnum::FULL->value];
}
+
return $roles;
}
}
diff --git a/app/Repositories/UserGroup/UserGroupRepositoryInterface.php b/app/Repositories/UserGroup/UserGroupRepositoryInterface.php
index 0cc3bf1cf6..2d2789804e 100644
--- a/app/Repositories/UserGroup/UserGroupRepositoryInterface.php
+++ b/app/Repositories/UserGroup/UserGroupRepositoryInterface.php
@@ -1,6 +1,5 @@
userGroup->accounts();
+ $dbQuery = $this->userGroup
+ ->accounts()
+ ->leftJoin('account_meta', 'accounts.id', '=', 'account_meta.account_id')
+ ->where('accounts.active', true)
+ ->where(
+ static function (EloquentBuilder $q1) use ($number): void { // @phpstan-ignore-line
+ $json = json_encode($number);
+ $q1->where('account_meta.name', '=', 'account_number');
+ $q1->where('account_meta.data', '=', $json);
+ }
+ )
+ ;
+
+ if (0 !== count($types)) {
+ $dbQuery->leftJoin('account_types', 'accounts.account_type_id', '=', 'account_types.id');
+ $dbQuery->whereIn('account_types.type', $types);
+ }
+
+ // @var Account|null
+ return $dbQuery->first(['accounts.*']);
+ }
+
+ public function findByIbanNull(string $iban, array $types): ?Account
+ {
+ $query = $this->userGroup->accounts()->where('iban', '!=', '')->whereNotNull('iban');
if (0 !== count($types)) {
$query->leftJoin('account_types', 'accounts.account_type_id', '=', 'account_types.id');
$query->whereIn('account_types.type', $types);
}
- Log::debug(sprintf('Searching for account named "%s" (of user #%d) of the following type(s)', $name, $this->user->id), ['types' => $types]);
+
+ // @var Account|null
+ return $query->where('iban', $iban)->first(['accounts.*']);
+ }
+
+ public function findByName(string $name, array $types): ?Account
+ {
+ $query = $this->userGroup->accounts();
+
+ if (0 !== count($types)) {
+ $query->leftJoin('account_types', 'accounts.account_type_id', '=', 'account_types.id');
+ $query->whereIn('account_types.type', $types);
+ }
+ app('log')->debug(sprintf('Searching for account named "%s" (of user #%d) of the following type(s)', $name, $this->user->id), ['types' => $types]);
$query->where('accounts.name', $name);
- /** @var Account $account */
+
+ /** @var null|Account $account */
$account = $query->first(['accounts.*']);
if (null === $account) {
- Log::debug(sprintf('There is no account with name "%s" of types', $name), $types);
+ app('log')->debug(sprintf('There is no account with name "%s" of types', $name), $types);
return null;
}
- Log::debug(sprintf('Found #%d (%s) with type id %d', $account->id, $account->name, $account->account_type_id));
+ app('log')->debug(sprintf('Found #%d (%s) with type id %d', $account->id, $account->name, $account->account_type_id));
return $account;
}
- /**
- * @param Account $account
- *
- * @return TransactionCurrency|null
- */
public function getAccountCurrency(Account $account): ?TransactionCurrency
{
- $type = $account->accountType->type;
- $list = config('firefly.valid_currency_account_types');
+ $type = $account->accountType->type;
+ $list = config('firefly.valid_currency_account_types');
// return null if not in this list.
if (!in_array($type, $list, true)) {
@@ -91,16 +119,11 @@ class AccountRepository implements AccountRepositoryInterface
/**
* Return meta value for account. Null if not found.
- *
- * @param Account $account
- * @param string $field
- *
- * @return null|string
*/
public function getMetaValue(Account $account, string $field): ?string
{
$result = $account->accountMeta->filter(
- function (AccountMeta $meta) use ($field) {
+ static function (AccountMeta $meta) use ($field) {
return strtolower($meta->name) === strtolower($field);
}
);
@@ -114,25 +137,16 @@ class AccountRepository implements AccountRepositoryInterface
return null;
}
- /**
- * @param int $accountId
- *
- * @return Account|null
- */
public function find(int $accountId): ?Account
{
$account = $this->user->accounts()->find($accountId);
if (null === $account) {
$account = $this->userGroup->accounts()->find($accountId);
}
+
return $account;
}
- /**
- * @param array $accountIds
- *
- * @return Collection
- */
public function getAccountsById(array $accountIds): Collection
{
$query = $this->userGroup->accounts();
@@ -147,9 +161,6 @@ class AccountRepository implements AccountRepositoryInterface
return $query->get(['accounts.*']);
}
- /**
- * @inheritDoc
- */
public function getAccountsByType(array $types, ?array $sort = []): Collection
{
$res = array_intersect([AccountType::ASSET, AccountType::MORTGAGE, AccountType::LOAN, AccountType::DEBT], $types);
@@ -172,14 +183,10 @@ class AccountRepository implements AccountRepositoryInterface
$query->orderBy('accounts.active', 'DESC');
$query->orderBy('accounts.name', 'ASC');
}
+
return $query->get(['accounts.*']);
}
- /**
- * @param array $types
- *
- * @return Collection
- */
public function getActiveAccountsByType(array $types): Collection
{
$query = $this->userGroup->accounts();
@@ -194,18 +201,16 @@ class AccountRepository implements AccountRepositoryInterface
return $query->get(['accounts.*']);
}
- /**
- * @inheritDoc
- */
public function searchAccount(string $query, array $types, int $limit): Collection
{
// search by group, not by user
$dbQuery = $this->userGroup->accounts()
- ->where('active', true)
- ->orderBy('accounts.order', 'ASC')
- ->orderBy('accounts.account_type_id', 'ASC')
- ->orderBy('accounts.name', 'ASC')
- ->with(['accountType']);
+ ->where('active', true)
+ ->orderBy('accounts.order', 'ASC')
+ ->orderBy('accounts.account_type_id', 'ASC')
+ ->orderBy('accounts.name', 'ASC')
+ ->with(['accountType'])
+ ;
if ('' !== $query) {
// split query on spaces just in case:
$parts = explode(' ', $query);
diff --git a/app/Repositories/UserGroups/Account/AccountRepositoryInterface.php b/app/Repositories/UserGroups/Account/AccountRepositoryInterface.php
index 379615acbe..bd0b8116fb 100644
--- a/app/Repositories/UserGroups/Account/AccountRepositoryInterface.php
+++ b/app/Repositories/UserGroups/Account/AccountRepositoryInterface.php
@@ -1,6 +1,5 @@
userGroup->bills()->orderBy('order', 'ASC')->get();
$current = 1;
foreach ($set as $bill) {
- if ((int)$bill->order !== $current) {
+ if ($bill->order !== $current) {
$bill->order = $current;
$bill->save();
}
- $current++;
+ ++$current;
}
}
- /**
- * @return Collection
- */
public function getBills(): Collection
{
return $this->userGroup->bills()
- ->orderBy('bills.name', 'ASC')
- ->get(['bills.*']);
+ ->orderBy('bills.name', 'ASC')
+ ->get(['bills.*'])
+ ;
}
- /**
- * @inheritDoc
- */
public function sumPaidInRange(Carbon $start, Carbon $end): array
{
+ Log::debug(sprintf('Created new ExchangeRateConverter in %s', __METHOD__));
$bills = $this->getActiveBills();
$default = app('amount')->getDefaultCurrency();
$return = [];
$converter = new ExchangeRateConverter();
+
/** @var Bill $bill */
foreach ($bills as $bill) {
/** @var Collection $set */
$set = $bill->transactionJournals()->after($start)->before($end)->get(['transaction_journals.*']);
$currency = $bill->transactionCurrency;
- $currencyId = (int)$bill->transaction_currency_id;
+ $currencyId = $bill->transaction_currency_id;
- $return[$currencyId] = $return[$currencyId] ?? [
- 'currency_id' => (string)$currency->id,
- 'currency_name' => $currency->name,
- 'currency_symbol' => $currency->symbol,
- 'currency_code' => $currency->code,
- 'currency_decimal_places' => (int)$currency->decimal_places,
- 'native_id' => (string)$default->id,
- 'native_name' => $default->name,
- 'native_symbol' => $default->symbol,
- 'native_code' => $default->code,
- 'native_decimal_places' => (int)$default->decimal_places,
- 'sum' => '0',
- 'native_sum' => '0',
+ $return[$currencyId] ??= [
+ 'currency_id' => (string)$currency->id,
+ 'currency_name' => $currency->name,
+ 'currency_symbol' => $currency->symbol,
+ 'currency_code' => $currency->code,
+ 'currency_decimal_places' => $currency->decimal_places,
+ 'native_currency_id' => (string)$default->id,
+ 'native_currency_name' => $default->name,
+ 'native_currency_symbol' => $default->symbol,
+ 'native_currency_code' => $default->code,
+ 'native_currency_decimal_places' => $default->decimal_places,
+ 'sum' => '0',
+ 'native_sum' => '0',
];
/** @var TransactionJournal $transactionJournal */
foreach ($set as $transactionJournal) {
- /** @var Transaction|null $sourceTransaction */
+ /** @var null|Transaction $sourceTransaction */
$sourceTransaction = $transactionJournal->transactions()->where('amount', '<', 0)->first();
if (null !== $sourceTransaction) {
- $amount = (string)$sourceTransaction->amount;
- if ((int)$sourceTransaction->foreign_currency_id === (int)$currency->id) {
+ $amount = $sourceTransaction->amount;
+ if ((int)$sourceTransaction->foreign_currency_id === $currency->id) {
// use foreign amount instead!
$amount = (string)$sourceTransaction->foreign_amount;
}
// convert to native currency
- $nativeAmount = $amount;
- if ($currencyId !== (int)$default->id) {
+ $nativeAmount = $amount;
+ if ($currencyId !== $default->id) {
// get rate and convert.
$nativeAmount = $converter->convert($currency, $default, $transactionJournal->date, $amount);
}
- if ((int)$sourceTransaction->foreign_currency_id === (int)$default->id) {
+ if ((int)$sourceTransaction->foreign_currency_id === $default->id) {
// ignore conversion, use foreign amount
$nativeAmount = (string)$sourceTransaction->foreign_amount;
}
@@ -123,29 +120,28 @@ class BillRepository implements BillRepositoryInterface
}
}
}
+ $converter->summarize();
+
return $return;
}
- /**
- * @return Collection
- */
public function getActiveBills(): Collection
{
return $this->userGroup->bills()
- ->where('active', true)
- ->orderBy('bills.name', 'ASC')
- ->get(['bills.*']);
+ ->where('active', true)
+ ->orderBy('bills.name', 'ASC')
+ ->get(['bills.*'])
+ ;
}
- /**
- * @inheritDoc
- */
public function sumUnpaidInRange(Carbon $start, Carbon $end): array
{
+ Log::debug(sprintf('Created new ExchangeRateConverter in %s', __METHOD__));
$bills = $this->getActiveBills();
$return = [];
$default = app('amount')->getDefaultCurrency();
$converter = new ExchangeRateConverter();
+
/** @var Bill $bill */
foreach ($bills as $bill) {
$dates = $this->getPayDatesInRange($bill, $start, $end);
@@ -154,27 +150,28 @@ class BillRepository implements BillRepositoryInterface
if ($total > 0) {
$currency = $bill->transactionCurrency;
- $currencyId = (int)$bill->transaction_currency_id;
+ $currencyId = $bill->transaction_currency_id;
$average = bcdiv(bcadd($bill->amount_max, $bill->amount_min), '2');
$nativeAverage = $converter->convert($currency, $default, $start, $average);
- $return[$currencyId] = $return[$currencyId] ?? [
- 'currency_id' => (string)$currency->id,
- 'currency_name' => $currency->name,
- 'currency_symbol' => $currency->symbol,
- 'currency_code' => $currency->code,
- 'currency_decimal_places' => (int)$currency->decimal_places,
- 'native_id' => (string)$default->id,
- 'native_name' => $default->name,
- 'native_symbol' => $default->symbol,
- 'native_code' => $default->code,
- 'native_decimal_places' => (int)$default->decimal_places,
- 'sum' => '0',
- 'native_sum' => '0',
+ $return[$currencyId] ??= [
+ 'currency_id' => (string)$currency->id,
+ 'currency_name' => $currency->name,
+ 'currency_symbol' => $currency->symbol,
+ 'currency_code' => $currency->code,
+ 'currency_decimal_places' => $currency->decimal_places,
+ 'native_currency_id' => (string)$default->id,
+ 'native_currency_name' => $default->name,
+ 'native_currency_symbol' => $default->symbol,
+ 'native_currency_code' => $default->code,
+ 'native_currency_decimal_places' => $default->decimal_places,
+ 'sum' => '0',
+ 'native_sum' => '0',
];
$return[$currencyId]['sum'] = bcadd($return[$currencyId]['sum'], bcmul($average, (string)$total));
$return[$currencyId]['native_sum'] = bcadd($return[$currencyId]['native_sum'], bcmul($nativeAverage, (string)$total));
}
}
+ $converter->summarize();
return $return;
}
@@ -182,34 +179,28 @@ class BillRepository implements BillRepositoryInterface
/**
* Between start and end, tells you on which date(s) the bill is expected to hit.
* TODO duplicate of function in other billrepositoryinterface
- *
- * @param Bill $bill
- * @param Carbon $start
- * @param Carbon $end
- *
- * @return Collection
*/
public function getPayDatesInRange(Bill $bill, Carbon $start, Carbon $end): Collection
{
$set = new Collection();
$currentStart = clone $start;
- //Log::debug(sprintf('Now at bill "%s" (%s)', $bill->name, $bill->repeat_freq));
- //Log::debug(sprintf('First currentstart is %s', $currentStart->format('Y-m-d')));
+ // app('log')->debug(sprintf('Now at bill "%s" (%s)', $bill->name, $bill->repeat_freq));
+ // app('log')->debug(sprintf('First currentstart is %s', $currentStart->format('Y-m-d')));
while ($currentStart <= $end) {
- //Log::debug(sprintf('Currentstart is now %s.', $currentStart->format('Y-m-d')));
+ // app('log')->debug(sprintf('Currentstart is now %s.', $currentStart->format('Y-m-d')));
$nextExpectedMatch = $this->nextDateMatch($bill, $currentStart);
- //Log::debug(sprintf('Next Date match after %s is %s', $currentStart->format('Y-m-d'), $nextExpectedMatch->format('Y-m-d')));
+ // app('log')->debug(sprintf('Next Date match after %s is %s', $currentStart->format('Y-m-d'), $nextExpectedMatch->format('Y-m-d')));
if ($nextExpectedMatch > $end) {// If nextExpectedMatch is after end, we continue
break;
}
$set->push(clone $nextExpectedMatch);
- //Log::debug(sprintf('Now %d dates in set.', $set->count()));
+ // app('log')->debug(sprintf('Now %d dates in set.', $set->count()));
$nextExpectedMatch->addDay();
- //Log::debug(sprintf('Currentstart (%s) has become %s.', $currentStart->format('Y-m-d'), $nextExpectedMatch->format('Y-m-d')));
+ // app('log')->debug(sprintf('Currentstart (%s) has become %s.', $currentStart->format('Y-m-d'), $nextExpectedMatch->format('Y-m-d')));
- $currentStart = clone $nextExpectedMatch;
+ $currentStart = clone $nextExpectedMatch;
}
return $set;
@@ -220,11 +211,6 @@ class BillRepository implements BillRepositoryInterface
* transaction. Whether it is there already, is not relevant.
*
* TODO duplicate of other repos
- *
- * @param Bill $bill
- * @param Carbon $date
- *
- * @return Carbon
*/
public function nextDateMatch(Bill $bill, Carbon $date): Carbon
{
diff --git a/app/Repositories/UserGroups/Bill/BillRepositoryInterface.php b/app/Repositories/UserGroups/Bill/BillRepositoryInterface.php
index ba68704938..6bf9d979a5 100644
--- a/app/Repositories/UserGroups/Bill/BillRepositoryInterface.php
+++ b/app/Repositories/UserGroups/Bill/BillRepositoryInterface.php
@@ -1,6 +1,5 @@
getDefaultCurrency();
$availableBudgets = $this->userGroup->availableBudgets()
- ->where('start_date', $start->format('Y-m-d'))
- ->where('end_date', $end->format('Y-m-d'))->get();
+ ->where('start_date', $start->format('Y-m-d'))
+ ->where('end_date', $end->format('Y-m-d'))->get()
+ ;
+
/** @var AvailableBudget $availableBudget */
foreach ($availableBudgets as $availableBudget) {
- $currencyId = (int)$availableBudget->transaction_currency_id;
- $return[$currencyId] = $return[$currencyId] ?? [
- 'currency_id' => $currencyId,
- 'currency_code' => $availableBudget->transactionCurrency->code,
- 'currency_symbol' => $availableBudget->transactionCurrency->symbol,
- 'currency_name' => $availableBudget->transactionCurrency->name,
- 'currency_decimal_places' => (int)$availableBudget->transactionCurrency->decimal_places,
- 'native_id' => $default->id,
- 'native_code' => $default->code,
- 'native_symbol' => $default->symbol,
- 'native_name' => $default->name,
- 'native_decimal_places' => (int)$default->decimal_places,
- 'amount' => '0',
- 'native_amount' => '0',
+ $currencyId = $availableBudget->transaction_currency_id;
+ $return[$currencyId] ??= [
+ 'currency_id' => $currencyId,
+ 'currency_code' => $availableBudget->transactionCurrency->code,
+ 'currency_symbol' => $availableBudget->transactionCurrency->symbol,
+ 'currency_name' => $availableBudget->transactionCurrency->name,
+ 'currency_decimal_places' => $availableBudget->transactionCurrency->decimal_places,
+ 'native_currency_id' => $default->id,
+ 'native_currency_code' => $default->code,
+ 'native_currency_symbol' => $default->symbol,
+ 'native_currency_name' => $default->name,
+ 'native_currency_decimal_places' => $default->decimal_places,
+ 'amount' => '0',
+ 'native_amount' => '0',
];
$nativeAmount = $converter->convert($availableBudget->transactionCurrency, $default, $availableBudget->start_date, $availableBudget->amount);
$return[$currencyId]['amount'] = bcadd($return[$currencyId]['amount'], $availableBudget->amount);
$return[$currencyId]['native_amount'] = bcadd($return[$currencyId]['native_amount'], $nativeAmount);
}
+ $converter->summarize();
+
return $return;
}
}
diff --git a/app/Repositories/UserGroups/Budget/AvailableBudgetRepositoryInterface.php b/app/Repositories/UserGroups/Budget/AvailableBudgetRepositoryInterface.php
index 6a24ad24da..6d1015f348 100644
--- a/app/Repositories/UserGroups/Budget/AvailableBudgetRepositoryInterface.php
+++ b/app/Repositories/UserGroups/Budget/AvailableBudgetRepositoryInterface.php
@@ -1,6 +1,5 @@
userGroup->budgets()->where('active', true)
- ->orderBy('order', 'ASC')
- ->orderBy('name', 'ASC')
- ->get();
+ ->orderBy('order', 'ASC')
+ ->orderBy('name', 'ASC')
+ ->get()
+ ;
}
}
diff --git a/app/Repositories/UserGroups/Budget/BudgetRepositoryInterface.php b/app/Repositories/UserGroups/Budget/BudgetRepositoryInterface.php
index 6d9ef85332..6b52c939be 100644
--- a/app/Repositories/UserGroups/Budget/BudgetRepositoryInterface.php
+++ b/app/Repositories/UserGroups/Budget/BudgetRepositoryInterface.php
@@ -1,6 +1,5 @@
setBudgets($this->getBudgets());
}
$collector->withBudgetInformation()->withAccountInformation()->withCategoryInformation();
- $journals = $collector->getExtractedJournals();
- $array = [];
+ $journals = $collector->getExtractedJournals();
+ $array = [];
foreach ($journals as $journal) {
- $currencyId = (int)$journal['currency_id'];
- $budgetId = (int)$journal['budget_id'];
- $budgetName = (string)$journal['budget_name'];
+ $currencyId = (int)$journal['currency_id'];
+ $budgetId = (int)$journal['budget_id'];
+ $budgetName = (string)$journal['budget_name'];
// catch "no budget" entries.
if (0 === $budgetId) {
@@ -72,7 +70,7 @@ class OperationsRepository implements OperationsRepositoryInterface
}
// info about the currency:
- $array[$currencyId] = $array[$currencyId] ?? [
+ $array[$currencyId] ??= [
'budgets' => [],
'currency_id' => $currencyId,
'currency_name' => $journal['currency_name'],
@@ -82,7 +80,7 @@ class OperationsRepository implements OperationsRepositoryInterface
];
// info about the budgets:
- $array[$currencyId]['budgets'][$budgetId] = $array[$currencyId]['budgets'][$budgetId] ?? [
+ $array[$currencyId]['budgets'][$budgetId] ??= [
'id' => $budgetId,
'name' => $budgetName,
'transaction_journals' => [],
@@ -90,8 +88,8 @@ class OperationsRepository implements OperationsRepositoryInterface
// add journal to array:
// only a subset of the fields.
- $journalId = (int)$journal['transaction_journal_id'];
- $final = [
+ $journalId = (int)$journal['transaction_journal_id'];
+ $final = [
'amount' => app('steam')->negative($journal['amount']),
'currency_id' => $journal['currency_id'],
'foreign_amount' => null,
@@ -124,9 +122,6 @@ class OperationsRepository implements OperationsRepositoryInterface
return $array;
}
- /**
- * @return Collection
- */
private function getBudgets(): Collection
{
/** @var BudgetRepositoryInterface $repository */
diff --git a/app/Repositories/UserGroups/Budget/OperationsRepositoryInterface.php b/app/Repositories/UserGroups/Budget/OperationsRepositoryInterface.php
index d6313824dc..e1eb8762a1 100644
--- a/app/Repositories/UserGroups/Budget/OperationsRepositoryInterface.php
+++ b/app/Repositories/UserGroups/Budget/OperationsRepositoryInterface.php
@@ -1,6 +1,5 @@
.
+ */
+
+declare(strict_types=1);
+
+namespace FireflyIII\Repositories\UserGroups\Category;
+
+use FireflyIII\Support\Repositories\UserGroup\UserGroupTrait;
+use Illuminate\Support\Collection;
+
+class CategoryRepository implements CategoryRepositoryInterface
+{
+ use UserGroupTrait;
+
+ public function searchCategory(string $query, int $limit): Collection
+ {
+ $search = $this->userGroup->categories();
+ if ('' !== $query) {
+ $search->where('name', 'LIKE', sprintf('%%%s%%', $query));
+ }
+
+ return $search->take($limit)->get();
+ }
+}
diff --git a/frontend/src/api/summary/basic.js b/app/Repositories/UserGroups/Category/CategoryRepositoryInterface.php
similarity index 64%
rename from frontend/src/api/summary/basic.js
rename to app/Repositories/UserGroups/Category/CategoryRepositoryInterface.php
index 2c4c185ebc..cd60c32523 100644
--- a/frontend/src/api/summary/basic.js
+++ b/app/Repositories/UserGroups/Category/CategoryRepositoryInterface.php
@@ -1,6 +1,7 @@
+.
*/
-import {api} from "boot/axios";
-import {format} from 'date-fns';
+declare(strict_types=1);
+namespace FireflyIII\Repositories\UserGroups\Category;
-export default class Basic {
- list(range, cacheKey) {
- let startStr = format(range.start, 'y-MM-dd');
- let endStr = format(range.end, 'y-MM-dd');
+use Illuminate\Support\Collection;
- return api.get('/api/v1/summary/basic', {params: {start: startStr, end: endStr, cache: cacheKey}});
- }
+interface CategoryRepositoryInterface
+{
+ /**
+ * Search for a category using wild cards. Uses the database, so case sensitive.
+ */
+ public function searchCategory(string $query, int $limit): Collection;
}
diff --git a/app/Repositories/UserGroups/Currency/CurrencyRepository.php b/app/Repositories/UserGroups/Currency/CurrencyRepository.php
new file mode 100644
index 0000000000..5f66f4dd0d
--- /dev/null
+++ b/app/Repositories/UserGroups/Currency/CurrencyRepository.php
@@ -0,0 +1,383 @@
+.
+ */
+
+declare(strict_types=1);
+
+namespace FireflyIII\Repositories\UserGroups\Currency;
+
+use FireflyIII\Exceptions\FireflyException;
+use FireflyIII\Factory\TransactionCurrencyFactory;
+use FireflyIII\Models\AccountMeta;
+use FireflyIII\Models\AvailableBudget;
+use FireflyIII\Models\Bill;
+use FireflyIII\Models\BudgetLimit;
+use FireflyIII\Models\RecurrenceTransaction;
+use FireflyIII\Models\Transaction;
+use FireflyIII\Models\TransactionCurrency;
+use FireflyIII\Repositories\User\UserRepositoryInterface;
+use FireflyIII\Services\Internal\Destroy\CurrencyDestroyService;
+use FireflyIII\Services\Internal\Update\CurrencyUpdateService;
+use FireflyIII\Support\Repositories\UserGroup\UserGroupTrait;
+use Illuminate\Support\Collection;
+
+/**
+ * Class CurrencyRepository
+ */
+class CurrencyRepository implements CurrencyRepositoryInterface
+{
+ use UserGroupTrait;
+
+ /**
+ * @throws FireflyException
+ */
+ public function currencyInUse(TransactionCurrency $currency): bool
+ {
+ $result = $this->currencyInUseAt($currency);
+
+ return null !== $result;
+ }
+
+ /**
+ * @throws FireflyException
+ */
+ public function currencyInUseAt(TransactionCurrency $currency): ?string
+ {
+ app('log')->debug(sprintf('Now in currencyInUse() for #%d ("%s")', $currency->id, $currency->code));
+ $countJournals = $this->countJournals($currency);
+ if ($countJournals > 0) {
+ app('log')->info(sprintf('Count journals is %d, return true.', $countJournals));
+
+ return 'journals';
+ }
+
+ // is the only currency left
+ if (1 === $this->getAll()->count()) {
+ app('log')->info('Is the last currency in the system, return true. ');
+
+ return 'last_left';
+ }
+
+ // is being used in accounts:
+ $meta = AccountMeta::where('name', 'currency_id')->where('data', json_encode((string)$currency->id))->count();
+ if ($meta > 0) {
+ app('log')->info(sprintf('Used in %d accounts as currency_id, return true. ', $meta));
+
+ return 'account_meta';
+ }
+
+ // is being used in bills:
+ $bills = Bill::where('transaction_currency_id', $currency->id)->count();
+ if ($bills > 0) {
+ app('log')->info(sprintf('Used in %d bills as currency, return true. ', $bills));
+
+ return 'bills';
+ }
+
+ // is being used in recurring transactions
+ $recurringAmount = RecurrenceTransaction::where('transaction_currency_id', $currency->id)->count();
+ $recurringForeign = RecurrenceTransaction::where('foreign_currency_id', $currency->id)->count();
+
+ if ($recurringAmount > 0 || $recurringForeign > 0) {
+ app('log')->info(sprintf('Used in %d recurring transactions as (foreign) currency id, return true. ', $recurringAmount + $recurringForeign));
+
+ return 'recurring';
+ }
+
+ // is being used in accounts (as integer)
+ $meta = AccountMeta::leftJoin('accounts', 'accounts.id', '=', 'account_meta.account_id')
+ ->whereNull('accounts.deleted_at')
+ ->where('account_meta.name', 'currency_id')->where('account_meta.data', json_encode($currency->id))->count()
+ ;
+ if ($meta > 0) {
+ app('log')->info(sprintf('Used in %d accounts as currency_id, return true. ', $meta));
+
+ return 'account_meta';
+ }
+
+ // is being used in available budgets
+ $availableBudgets = AvailableBudget::where('transaction_currency_id', $currency->id)->count();
+ if ($availableBudgets > 0) {
+ app('log')->info(sprintf('Used in %d available budgets as currency, return true. ', $availableBudgets));
+
+ return 'available_budgets';
+ }
+
+ // is being used in budget limits
+ $budgetLimit = BudgetLimit::where('transaction_currency_id', $currency->id)->count();
+ if ($budgetLimit > 0) {
+ app('log')->info(sprintf('Used in %d budget limits as currency, return true. ', $budgetLimit));
+
+ return 'budget_limits';
+ }
+
+ // is the default currency for the user or the system
+ $count = $this->userGroup->currencies()->where('transaction_currencies.id', $currency->id)->wherePivot('group_default', 1)->count();
+ if ($count > 0) {
+ app('log')->info('Is the default currency of the user, return true.');
+
+ return 'current_default';
+ }
+
+ // is the default currency for the user or the system
+ $count = $this->userGroup->currencies()->where('transaction_currencies.id', $currency->id)->wherePivot('group_default', 1)->count();
+ if ($count > 0) {
+ app('log')->info('Is the default currency of the user group, return true.');
+
+ return 'current_default';
+ }
+
+ app('log')->debug('Currency is not used, return false.');
+
+ return null;
+ }
+
+ private function countJournals(TransactionCurrency $currency): int
+ {
+ $count = $currency->transactions()->whereNull('deleted_at')->count() + $currency->transactionJournals()->whereNull('deleted_at')->count();
+
+ // also count foreign:
+ return $count + Transaction::where('foreign_currency_id', $currency->id)->count();
+ }
+
+ /**
+ * Returns ALL currencies, regardless of whether they are enabled or not.
+ */
+ public function getAll(): Collection
+ {
+ $all = TransactionCurrency::orderBy('code', 'ASC')->get();
+ $local = $this->get();
+
+ return $all->map(static function (TransactionCurrency $current) use ($local) {
+ $hasId = $local->contains(static function (TransactionCurrency $entry) use ($current) {
+ return $entry->id === $current->id;
+ });
+ $isDefault = $local->contains(static function (TransactionCurrency $entry) use ($current) {
+ return 1 === (int)$entry->pivot->group_default && $entry->id === $current->id;
+ });
+ $current->userGroupEnabled = $hasId;
+ $current->userGroupDefault = $isDefault;
+
+ return $current;
+ });
+ }
+
+ public function get(): Collection
+ {
+ $all = $this->userGroup->currencies()->orderBy('code', 'ASC')->withPivot(['group_default'])->get();
+ $all->map(static function (TransactionCurrency $current) {
+ $current->userGroupEnabled = true;
+ $current->userGroupDefault = 1 === (int)$current->pivot->group_default;
+
+ return $current;
+ });
+
+ return $all;
+ }
+
+ public function destroy(TransactionCurrency $currency): bool
+ {
+ /** @var UserRepositoryInterface $repository */
+ $repository = app(UserRepositoryInterface::class);
+ if ($repository->hasRole($this->user, 'owner')) {
+ /** @var CurrencyDestroyService $service */
+ $service = app(CurrencyDestroyService::class);
+ $service->destroy($currency);
+ }
+
+ return true;
+ }
+
+ /**
+ * Disables a currency
+ */
+ public function disable(TransactionCurrency $currency): void
+ {
+ $this->userGroup->currencies()->detach($currency->id);
+ $currency->enabled = false;
+ $currency->save();
+ }
+
+ public function findByName(string $name): ?TransactionCurrency
+ {
+ return TransactionCurrency::where('name', $name)->first();
+ }
+
+ /**
+ * Find by object, ID or code. Returns user default or system default.
+ *
+ * @throws FireflyException
+ */
+ public function findCurrency(?int $currencyId, ?string $currencyCode): TransactionCurrency
+ {
+ $result = $this->findCurrencyNull($currencyId, $currencyCode);
+
+ if (null === $result) {
+ app('log')->debug('Grabbing default currency for this user...');
+
+ /** @var null|TransactionCurrency $result */
+ $result = app('amount')->getDefaultCurrencyByUserGroup($this->user->userGroup);
+ }
+
+ app('log')->debug(sprintf('Final result: %s', $result->code));
+ if (false === $result->enabled) {
+ app('log')->debug(sprintf('Also enabled currency %s', $result->code));
+ $this->enable($result);
+ }
+
+ return $result;
+ }
+
+ /**
+ * Find by object, ID or code. Returns NULL if nothing found.
+ */
+ public function findCurrencyNull(?int $currencyId, ?string $currencyCode): ?TransactionCurrency
+ {
+ app('log')->debug('Now in findCurrencyNull()');
+ $result = $this->find((int)$currencyId);
+ if (null === $result) {
+ app('log')->debug(sprintf('Searching for currency with code %s...', $currencyCode));
+ $result = $this->findByCode((string)$currencyCode);
+ }
+ if (null !== $result && false === $result->enabled) {
+ app('log')->debug(sprintf('Also enabled currency %s', $result->code));
+ $this->enable($result);
+ }
+
+ return $result;
+ }
+
+ /**
+ * Find by ID, return NULL if not found.
+ */
+ public function find(int $currencyId): ?TransactionCurrency
+ {
+ return TransactionCurrency::find($currencyId);
+ }
+
+ /**
+ * Find by currency code, return NULL if unfound.
+ */
+ public function findByCode(string $currencyCode): ?TransactionCurrency
+ {
+ return TransactionCurrency::where('code', $currencyCode)->first();
+ }
+
+ public function enable(TransactionCurrency $currency): void
+ {
+ $this->userGroup->currencies()->syncWithoutDetaching([$currency->id]);
+ $currency->enabled = false;
+ $currency->save();
+ }
+
+ public function getByIds(array $ids): Collection
+ {
+ return TransactionCurrency::orderBy('code', 'ASC')->whereIn('id', $ids)->get();
+ }
+
+ public function isFallbackCurrency(TransactionCurrency $currency): bool
+ {
+ return $currency->code === config('firefly.default_currency', 'EUR');
+ }
+
+ public function makeDefault(TransactionCurrency $currency): void
+ {
+ app('log')->debug(sprintf('Enabled + made default currency %s for user #%d', $currency->code, $this->userGroup->id));
+ $this->userGroup->currencies()->detach($currency->id);
+ foreach ($this->userGroup->currencies()->get() as $item) {
+ $this->userGroup->currencies()->updateExistingPivot($item->id, ['group_default' => false]);
+ }
+ $this->userGroup->currencies()->syncWithoutDetaching([$currency->id => ['group_default' => true]]);
+ }
+
+ public function searchCurrency(string $search, int $limit): Collection
+ {
+ $query = TransactionCurrency::where('enabled', true);
+ if ('' !== $search) {
+ $query->where('name', 'LIKE', sprintf('%%%s%%', $search));
+ }
+
+ return $query->take($limit)->get();
+ }
+
+ /**
+ * @throws FireflyException
+ */
+ public function store(array $data): TransactionCurrency
+ {
+ /** @var TransactionCurrencyFactory $factory */
+ $factory = app(TransactionCurrencyFactory::class);
+ $result = $factory->create($data);
+
+ if (true === $data['enabled']) {
+ $this->userGroup->currencies()->attach($result->id);
+ }
+
+ return $result;
+ }
+
+ public function update(TransactionCurrency $currency, array $data): TransactionCurrency
+ {
+ app('log')->debug('Now in update()');
+ // can be true, false, null
+ $enabled = array_key_exists('enabled', $data) ? $data['enabled'] : null;
+ // can be true, false, but method only responds to "true".
+ $default = array_key_exists('default', $data) ? $data['default'] : false;
+
+ // remove illegal combo's:
+ if (false === $enabled && true === $default) {
+ $enabled = true;
+ }
+ if (false === $default) {
+ app('log')->warning(sprintf('Set default=false will NOT do anything for currency %s', $currency->code));
+ }
+
+ // update currency with current user specific settings
+ $currency->refreshForUser($this->user);
+
+ // currency is enabled, must be disabled.
+ if (false === $enabled) {
+ app('log')->debug(sprintf('Disabled currency %s for user #%d', $currency->code, $this->userGroup->id));
+ $this->userGroup->currencies()->detach($currency->id);
+ }
+ // currency must be enabled
+ if (true === $enabled) {
+ app('log')->debug(sprintf('Enabled currency %s for user #%d', $currency->code, $this->userGroup->id));
+ $this->userGroup->currencies()->detach($currency->id);
+ $this->userGroup->currencies()->syncWithoutDetaching([$currency->id => ['group_default' => false]]);
+ }
+
+ // currency must be made default.
+ if (true === $default) {
+ app('log')->debug(sprintf('Enabled + made default currency %s for user #%d', $currency->code, $this->userGroup->id));
+ $this->userGroup->currencies()->detach($currency->id);
+ foreach ($this->userGroup->currencies()->get() as $item) {
+ $this->userGroup->currencies()->updateExistingPivot($item->id, ['group_default' => false]);
+ }
+ $this->userGroup->currencies()->syncWithoutDetaching([$currency->id => ['group_default' => true]]);
+ }
+
+ /** @var CurrencyUpdateService $service */
+ $service = app(CurrencyUpdateService::class);
+
+ return $service->update($currency, $data);
+ }
+}
diff --git a/app/Repositories/UserGroups/Currency/CurrencyRepositoryInterface.php b/app/Repositories/UserGroups/Currency/CurrencyRepositoryInterface.php
new file mode 100644
index 0000000000..b989d1aa8a
--- /dev/null
+++ b/app/Repositories/UserGroups/Currency/CurrencyRepositoryInterface.php
@@ -0,0 +1,100 @@
+.
+ */
+
+declare(strict_types=1);
+
+namespace FireflyIII\Repositories\UserGroups\Currency;
+
+use FireflyIII\Exceptions\FireflyException;
+use FireflyIII\Models\TransactionCurrency;
+use FireflyIII\User;
+use Illuminate\Support\Collection;
+
+interface CurrencyRepositoryInterface
+{
+ public function currencyInUse(TransactionCurrency $currency): bool;
+
+ /**
+ * Currency is in use where exactly.
+ */
+ public function currencyInUseAt(TransactionCurrency $currency): ?string;
+
+ public function destroy(TransactionCurrency $currency): bool;
+
+ /**
+ * Disables a currency
+ */
+ public function disable(TransactionCurrency $currency): void;
+
+ /**
+ * Enables a currency
+ */
+ public function enable(TransactionCurrency $currency): void;
+
+ /**
+ * Find by ID, return NULL if not found.
+ */
+ public function find(int $currencyId): ?TransactionCurrency;
+
+ public function findByCode(string $currencyCode): ?TransactionCurrency;
+
+ public function findByName(string $name): ?TransactionCurrency;
+
+ /**
+ * Find by object, ID or code. Returns user default or system default.
+ */
+ public function findCurrency(?int $currencyId, ?string $currencyCode): TransactionCurrency;
+
+ /**
+ * Find by object, ID or code. Returns NULL if nothing found.
+ */
+ public function findCurrencyNull(?int $currencyId, ?string $currencyCode): ?TransactionCurrency;
+
+ /**
+ * Get the user group's currencies.
+ *
+ * @return Collection
+ */
+ public function get(): Collection;
+
+ /**
+ * Get ALL currencies.
+ */
+ public function getAll(): Collection;
+
+ public function getByIds(array $ids): Collection;
+
+ public function isFallbackCurrency(TransactionCurrency $currency): bool;
+
+ public function makeDefault(TransactionCurrency $currency): void;
+
+ public function searchCurrency(string $search, int $limit): Collection;
+
+ public function setUser(User $user): void;
+
+ /**
+ * @throws FireflyException
+ */
+ public function store(array $data): TransactionCurrency;
+
+ public function update(TransactionCurrency $currency, array $data): TransactionCurrency;
+}
diff --git a/app/Repositories/UserGroups/Journal/JournalRepository.php b/app/Repositories/UserGroups/Journal/JournalRepository.php
index 387438df74..3d9a77b6c8 100644
--- a/app/Repositories/UserGroups/Journal/JournalRepository.php
+++ b/app/Repositories/UserGroups/Journal/JournalRepository.php
@@ -33,13 +33,11 @@ class JournalRepository implements JournalRepositoryInterface
{
use UserGroupTrait;
- /**
- * @inheritDoc
- */
public function searchJournalDescriptions(string $search, int $limit): Collection
{
$query = $this->userGroup->transactionJournals()
- ->orderBy('date', 'DESC');
+ ->orderBy('date', 'DESC')
+ ;
if ('' !== $search) {
$query->where('description', 'LIKE', sprintf('%%%s%%', $search));
}
diff --git a/app/Repositories/UserGroups/Journal/JournalRepositoryInterface.php b/app/Repositories/UserGroups/Journal/JournalRepositoryInterface.php
index 5a2cd1b938..7e2c8c0c72 100644
--- a/app/Repositories/UserGroups/Journal/JournalRepositoryInterface.php
+++ b/app/Repositories/UserGroups/Journal/JournalRepositoryInterface.php
@@ -23,6 +23,7 @@ declare(strict_types=1);
namespace FireflyIII\Repositories\UserGroups\Journal;
+use FireflyIII\User;
use Illuminate\Support\Collection;
/**
@@ -32,11 +33,8 @@ interface JournalRepositoryInterface
{
/**
* Search in journal descriptions.
- *
- * @param string $search
- * @param int $limit
- *
- * @return Collection
*/
public function searchJournalDescriptions(string $search, int $limit): Collection;
+
+ public function setUser(User $user): void;
}
diff --git a/app/Repositories/UserGroups/PiggyBank/PiggyBankRepository.php b/app/Repositories/UserGroups/PiggyBank/PiggyBankRepository.php
index e6b80198b7..7652e55c0b 100644
--- a/app/Repositories/UserGroups/PiggyBank/PiggyBankRepository.php
+++ b/app/Repositories/UserGroups/PiggyBank/PiggyBankRepository.php
@@ -1,6 +1,5 @@
userGroup->piggyBanks()
- ->with(
- [
- 'account',
- 'objectGroups',
- ]
- )
- ->orderBy('order', 'ASC')->get();
+ ->with(
+ [
+ 'account',
+ 'objectGroups',
+ ]
+ )
+ ->orderBy('order', 'ASC')->get()
+ ;
}
}
diff --git a/app/Repositories/UserGroups/PiggyBank/PiggyBankRepositoryInterface.php b/app/Repositories/UserGroups/PiggyBank/PiggyBankRepositoryInterface.php
index 8a02a8e84d..32a98d5423 100644
--- a/app/Repositories/UserGroups/PiggyBank/PiggyBankRepositoryInterface.php
+++ b/app/Repositories/UserGroups/PiggyBank/PiggyBankRepositoryInterface.php
@@ -1,6 +1,5 @@
.
*/
-import {store} from 'quasar/wrappers'
-import {createStore} from 'vuex'
+declare(strict_types=1);
-// import example from './module-example'
-import fireflyiii from './fireflyiii'
-/*
- * If not building with SSR mode, you can
- * directly export the Store instantiation;
- *
- * The function below can be async too; either use
- * async/await or return a Promise which resolves
- * with the Store instance.
+namespace FireflyIII\Repositories\UserGroups\Tag;
+
+use FireflyIII\Support\Repositories\UserGroup\UserGroupTrait;
+use Illuminate\Support\Collection;
+
+/**
+ * Class TagRepository
*/
+class TagRepository implements TagRepositoryInterface
+{
+ use UserGroupTrait;
-export default store(function (/* { ssrContext } */) {
- return createStore({
- modules: {
- // example
- fireflyiii
- },
+ public function searchTag(string $query, int $limit): Collection
+ {
+ $search = $this->user->tags();
+ if ('' !== $query) {
+ $search->where('tag', 'LIKE', sprintf('%%%s%%', $query));
+ }
- // enable strict mode (adds overhead!)
- // for dev mode and --debug builds only
- strict: process.env.DEBUGGING
- })
-})
+ return $search->take($limit)->get(['tags.*']);
+ }
+}
diff --git a/frontend/src/api/system/user.js b/app/Repositories/UserGroups/Tag/TagRepositoryInterface.php
similarity index 67%
rename from frontend/src/api/system/user.js
rename to app/Repositories/UserGroups/Tag/TagRepositoryInterface.php
index 36d1e8464f..e001333113 100644
--- a/frontend/src/api/system/user.js
+++ b/app/Repositories/UserGroups/Tag/TagRepositoryInterface.php
@@ -1,6 +1,7 @@
+.
*/
-import {api} from "boot/axios";
+declare(strict_types=1);
-export default class AboutUser {
- get() {
- return api.get('/api/v1/about/user');
- }
+namespace FireflyIII\Repositories\UserGroups\Tag;
- put(identifier, submission) {
- console.log('here we are');
- return api.put('/api/v1/users/' + identifier, submission);
- }
+use Illuminate\Support\Collection;
- logout() {
- return api.post('/logout');
- }
+interface TagRepositoryInterface
+{
+ /**
+ * Find one or more tags based on the query.
+ */
+ public function searchTag(string $query, int $limit): Collection;
}
diff --git a/app/Repositories/Webhook/WebhookRepository.php b/app/Repositories/Webhook/WebhookRepository.php
index 451e376bae..7b30289926 100644
--- a/app/Repositories/Webhook/WebhookRepository.php
+++ b/app/Repositories/Webhook/WebhookRepository.php
@@ -29,7 +29,6 @@ use FireflyIII\Models\WebhookMessage;
use FireflyIII\User;
use Illuminate\Contracts\Auth\Authenticatable;
use Illuminate\Support\Collection;
-use Str;
/**
* Class WebhookRepository
@@ -38,88 +37,63 @@ class WebhookRepository implements WebhookRepositoryInterface
{
private User $user;
- /**
- * @inheritDoc
- */
public function all(): Collection
{
return $this->user->webhooks()->get();
}
- /**
- * @inheritDoc
- */
public function destroy(Webhook $webhook): void
{
$webhook->delete();
}
- /**
- * @inheritDoc
- */
public function destroyAttempt(WebhookAttempt $attempt): void
{
$attempt->delete();
}
- /**
- * @inheritDoc
- */
public function destroyMessage(WebhookMessage $message): void
{
$message->delete();
}
- /**
- * @inheritDoc
- */
public function getAttempts(WebhookMessage $webhookMessage): Collection
{
return $webhookMessage->webhookAttempts()->orderBy('created_at', 'DESC')->get(['webhook_attempts.*']);
}
- /**
- * @inheritDoc
- */
public function getMessages(Webhook $webhook): Collection
{
return $webhook->webhookMessages()
- ->orderBy('created_at', 'DESC')
- ->get(['webhook_messages.*']);
+ ->orderBy('created_at', 'DESC')
+ ->get(['webhook_messages.*'])
+ ;
}
- /**
- * @inheritDoc
- */
public function getReadyMessages(Webhook $webhook): Collection
{
return $webhook->webhookMessages()
- ->where('webhook_messages.sent', 0)
- ->where('webhook_messages.errored', 0)
- ->get(['webhook_messages.*'])
- ->filter(
- function (WebhookMessage $message) {
- return $message->webhookAttempts()->count() <= 2;
- }
- )->splice(0, 3);
+ ->where('webhook_messages.sent', 0)
+ ->where('webhook_messages.errored', 0)
+ ->get(['webhook_messages.*'])
+ ->filter(
+ static function (WebhookMessage $message) {
+ return $message->webhookAttempts()->count() <= 2;
+ }
+ )->splice(0, 3)
+ ;
}
- /**
- * @param User|Authenticatable|null $user
- */
- public function setUser(User | Authenticatable | null $user): void
+ public function setUser(null|Authenticatable|User $user): void
{
- if (null !== $user) {
+ if ($user instanceof User) {
$this->user = $user;
}
}
- /**
- * @inheritDoc
- */
public function store(array $data): Webhook
{
- $secret = Str::random(24);
+ $secret = \Str::random(24);
$fullData = [
'user_id' => $this->user->id,
'user_group_id' => $this->user->user_group_id,
@@ -135,9 +109,6 @@ class WebhookRepository implements WebhookRepositoryInterface
return Webhook::create($fullData);
}
- /**
- * @inheritDoc
- */
public function update(Webhook $webhook, array $data): Webhook
{
$webhook->active = $data['active'] ?? $webhook->active;
@@ -148,7 +119,7 @@ class WebhookRepository implements WebhookRepositoryInterface
$webhook->url = $data['url'] ?? $webhook->url;
if (true === $data['secret']) {
- $secret = Str::random(24);
+ $secret = \Str::random(24);
$webhook->secret = $secret;
}
diff --git a/app/Repositories/Webhook/WebhookRepositoryInterface.php b/app/Repositories/Webhook/WebhookRepositoryInterface.php
index c0dd28c6ae..a313f0b1f9 100644
--- a/app/Repositories/Webhook/WebhookRepositoryInterface.php
+++ b/app/Repositories/Webhook/WebhookRepositoryInterface.php
@@ -37,64 +37,24 @@ interface WebhookRepositoryInterface
{
/**
* Return all webhooks.
- *
- * @return Collection
*/
public function all(): Collection;
- /**
- * @param Webhook $webhook
- */
public function destroy(Webhook $webhook): void;
- /**
- * @param WebhookAttempt $attempt
- */
public function destroyAttempt(WebhookAttempt $attempt): void;
- /**
- * @param WebhookMessage $message
- */
public function destroyMessage(WebhookMessage $message): void;
- /**
- * @param WebhookMessage $webhookMessage
- *
- * @return Collection
- */
public function getAttempts(WebhookMessage $webhookMessage): Collection;
- /**
- * @param Webhook $webhook
- *
- * @return Collection
- */
public function getMessages(Webhook $webhook): Collection;
- /**
- * @param Webhook $webhook
- *
- * @return Collection
- */
public function getReadyMessages(Webhook $webhook): Collection;
- /**
- * @param User|Authenticatable|null $user
- */
- public function setUser(User | Authenticatable | null $user): void;
+ public function setUser(null|Authenticatable|User $user): void;
- /**
- * @param array $data
- *
- * @return Webhook
- */
public function store(array $data): Webhook;
- /**
- * @param Webhook $webhook
- * @param array $data
- *
- * @return Webhook
- */
public function update(Webhook $webhook, array $data): Webhook;
}
diff --git a/app/Rules/BelongsUser.php b/app/Rules/BelongsUser.php
index 296dc580b8..06e250cf63 100644
--- a/app/Rules/BelongsUser.php
+++ b/app/Rules/BelongsUser.php
@@ -24,7 +24,6 @@ declare(strict_types=1);
namespace FireflyIII\Rules;
-use Closure;
use FireflyIII\Exceptions\FireflyException;
use FireflyIII\Models\Account;
use FireflyIII\Models\Bill;
@@ -33,27 +32,23 @@ use FireflyIII\Models\Category;
use FireflyIII\Models\PiggyBank;
use FireflyIII\Models\TransactionJournal;
use Illuminate\Contracts\Validation\ValidationRule;
-use Illuminate\Support\Facades\Log;
/**
* Class BelongsUser
*/
class BelongsUser implements ValidationRule
{
- /**
- * @inheritDoc
- */
- public function validate(string $attribute, mixed $value, Closure $fail): void
+ public function validate(string $attribute, mixed $value, \Closure $fail): void
{
$attribute = $this->parseAttribute($attribute);
if (!auth()->check()) {
$fail('validation.belongs_user')->translate();
+
return;
}
- $attribute = (string)$attribute;
- Log::debug(sprintf('Going to validate %s', $attribute));
+ app('log')->debug(sprintf('Going to validate %s', $attribute));
- $result = match ($attribute) {
+ $result = match ($attribute) {
'piggy_bank_id' => $this->validatePiggyBankId((int)$value),
'piggy_bank_name' => $this->validatePiggyBankName($value),
'bill_id' => $this->validateBillId((int)$value),
@@ -70,11 +65,6 @@ class BelongsUser implements ValidationRule
}
}
- /**
- * @param string $attribute
- *
- * @return string
- */
private function parseAttribute(string $attribute): string
{
$parts = explode('.', $attribute);
@@ -88,25 +78,16 @@ class BelongsUser implements ValidationRule
return $attribute;
}
- /**
- * @param int $value
- *
- * @return bool
- */
private function validatePiggyBankId(int $value): bool
{
$count = PiggyBank::leftJoin('accounts', 'accounts.id', '=', 'piggy_banks.account_id')
- ->where('piggy_banks.id', '=', $value)
- ->where('accounts.user_id', '=', auth()->user()->id)->count();
+ ->where('piggy_banks.id', '=', $value)
+ ->where('accounts.user_id', '=', auth()->user()->id)->count()
+ ;
return 1 === $count;
}
- /**
- * @param string $value
- *
- * @return bool
- */
private function validatePiggyBankName(string $value): bool
{
$count = $this->countField(PiggyBank::class, 'name', $value);
@@ -114,14 +95,6 @@ class BelongsUser implements ValidationRule
return 1 === $count;
}
- /**
- * @param string $class
- * @param string $field
- * @param string $value
- *
- * @return int
- *
- */
protected function countField(string $class, string $field, string $value): int
{
$value = trim($value);
@@ -129,29 +102,25 @@ class BelongsUser implements ValidationRule
// get all objects belonging to user:
if (PiggyBank::class === $class) {
$objects = PiggyBank::leftJoin('accounts', 'accounts.id', '=', 'piggy_banks.account_id')
- ->where('accounts.user_id', '=', auth()->user()->id)->get(['piggy_banks.*']);
+ ->where('accounts.user_id', '=', auth()->user()->id)->get(['piggy_banks.*'])
+ ;
}
if (PiggyBank::class !== $class) {
$objects = $class::where('user_id', '=', auth()->user()->id)->get();
}
- $count = 0;
+ $count = 0;
foreach ($objects as $object) {
- $objectValue = trim((string)$object->$field);
- Log::debug(sprintf('Comparing object "%s" with value "%s"', $objectValue, $value));
+ $objectValue = trim((string)$object->{$field}); // @phpstan-ignore-line
+ app('log')->debug(sprintf('Comparing object "%s" with value "%s"', $objectValue, $value));
if ($objectValue === $value) {
- $count++;
- Log::debug(sprintf('Hit! Count is now %d', $count));
+ ++$count;
+ app('log')->debug(sprintf('Hit! Count is now %d', $count));
}
}
return $count;
}
- /**
- * @param int $value
- *
- * @return bool
- */
private function validateBillId(int $value): bool
{
if (0 === $value) {
@@ -162,11 +131,6 @@ class BelongsUser implements ValidationRule
return 1 === $count;
}
- /**
- * @param int $value
- *
- * @return bool
- */
private function validateJournalId(int $value): bool
{
if (0 === $value) {
@@ -177,24 +141,14 @@ class BelongsUser implements ValidationRule
return 1 === $count;
}
- /**
- * @param string $value
- *
- * @return bool
- */
private function validateBillName(string $value): bool
{
$count = $this->countField(Bill::class, 'name', $value);
- Log::debug(sprintf('Result of countField for bill name "%s" is %d', $value, $count));
+ app('log')->debug(sprintf('Result of countField for bill name "%s" is %d', $value, $count));
return 1 === $count;
}
- /**
- * @param int $value
- *
- * @return bool
- */
private function validateBudgetId(int $value): bool
{
if (0 === $value) {
@@ -205,11 +159,6 @@ class BelongsUser implements ValidationRule
return 1 === $count;
}
- /**
- * @param int $value
- *
- * @return bool
- */
private function validateCategoryId(int $value): bool
{
$count = Category::where('id', '=', $value)->where('user_id', '=', auth()->user()->id)->count();
@@ -217,11 +166,6 @@ class BelongsUser implements ValidationRule
return 1 === $count;
}
- /**
- * @param string $value
- *
- * @return bool
- */
private function validateBudgetName(string $value): bool
{
$count = $this->countField(Budget::class, 'name', $value);
@@ -229,11 +173,6 @@ class BelongsUser implements ValidationRule
return 1 === $count;
}
- /**
- * @param int $value
- *
- * @return bool
- */
private function validateAccountId(int $value): bool
{
if (0 === $value) {
diff --git a/app/Rules/BelongsUserGroup.php b/app/Rules/BelongsUserGroup.php
index 54cc6a57e2..5c0459705b 100644
--- a/app/Rules/BelongsUserGroup.php
+++ b/app/Rules/BelongsUserGroup.php
@@ -23,7 +23,6 @@ declare(strict_types=1);
namespace FireflyIII\Rules;
-use Closure;
use FireflyIII\Exceptions\FireflyException;
use FireflyIII\Models\Account;
use FireflyIII\Models\Bill;
@@ -33,7 +32,6 @@ use FireflyIII\Models\PiggyBank;
use FireflyIII\Models\TransactionJournal;
use FireflyIII\Models\UserGroup;
use Illuminate\Contracts\Validation\ValidationRule;
-use Illuminate\Support\Facades\Log;
/**
* Class BelongsUserGroup
@@ -47,28 +45,23 @@ class BelongsUserGroup implements ValidationRule
/**
* Create a new rule instance.
- *
- * @return void
*/
public function __construct(UserGroup $userGroup)
{
$this->userGroup = $userGroup;
}
- /**
- * @inheritDoc
- */
- public function validate(string $attribute, mixed $value, Closure $fail): void
+ public function validate(string $attribute, mixed $value, \Closure $fail): void
{
$attribute = $this->parseAttribute($attribute);
if (!auth()->check()) {
$fail('validation.belongs_user_or_user_group')->translate();
+
return;
}
- $attribute = (string)$attribute;
- Log::debug(sprintf('Group: Going to validate "%s"', $attribute));
+ app('log')->debug(sprintf('Group: Going to validate "%s"', $attribute));
- $result = match ($attribute) {
+ $result = match ($attribute) {
'piggy_bank_id' => $this->validatePiggyBankId((int)$value),
'piggy_bank_name' => $this->validatePiggyBankName($value),
'bill_id' => $this->validateBillId((int)$value),
@@ -85,11 +78,6 @@ class BelongsUserGroup implements ValidationRule
}
}
- /**
- * @param string $attribute
- *
- * @return string
- */
private function parseAttribute(string $attribute): string
{
$parts = explode('.', $attribute);
@@ -103,25 +91,16 @@ class BelongsUserGroup implements ValidationRule
return $attribute;
}
- /**
- * @param int $value
- *
- * @return bool
- */
private function validatePiggyBankId(int $value): bool
{
$count = PiggyBank::leftJoin('accounts', 'accounts.id', '=', 'piggy_banks.account_id')
- ->where('piggy_banks.id', '=', $value)
- ->where('accounts.user_group_id', '=', $this->userGroup->id)->count();
+ ->where('piggy_banks.id', '=', $value)
+ ->where('accounts.user_group_id', '=', $this->userGroup->id)->count()
+ ;
return 1 === $count;
}
- /**
- * @param string $value
- *
- * @return bool
- */
private function validatePiggyBankName(string $value): bool
{
$count = $this->countField(PiggyBank::class, 'name', $value);
@@ -129,14 +108,6 @@ class BelongsUserGroup implements ValidationRule
return 1 === $count;
}
- /**
- * @param string $class
- * @param string $field
- * @param string $value
- *
- * @return int
- *
- */
protected function countField(string $class, string $field, string $value): int
{
$value = trim($value);
@@ -144,17 +115,18 @@ class BelongsUserGroup implements ValidationRule
// get all objects belonging to user:
if (PiggyBank::class === $class) {
$objects = PiggyBank::leftJoin('accounts', 'accounts.id', '=', 'piggy_banks.account_id')
- ->where('accounts.user_group_id', '=', $this->userGroup->id)->get(['piggy_banks.*']);
+ ->where('accounts.user_group_id', '=', $this->userGroup->id)->get(['piggy_banks.*'])
+ ;
}
if (PiggyBank::class !== $class) {
$objects = $class::where('user_group_id', '=', $this->userGroup->id)->get();
}
- $count = 0;
+ $count = 0;
foreach ($objects as $object) {
- $objectValue = trim((string)$object->$field);
+ $objectValue = trim((string)$object->{$field}); // @phpstan-ignore-line
app('log')->debug(sprintf('Comparing object "%s" with value "%s"', $objectValue, $value));
if ($objectValue === $value) {
- $count++;
+ ++$count;
app('log')->debug(sprintf('Hit! Count is now %d', $count));
}
}
@@ -162,11 +134,6 @@ class BelongsUserGroup implements ValidationRule
return $count;
}
- /**
- * @param int $value
- *
- * @return bool
- */
private function validateBillId(int $value): bool
{
if (0 === $value) {
@@ -177,11 +144,6 @@ class BelongsUserGroup implements ValidationRule
return 1 === $count;
}
- /**
- * @param int $value
- *
- * @return bool
- */
private function validateJournalId(int $value): bool
{
if (0 === $value) {
@@ -192,11 +154,6 @@ class BelongsUserGroup implements ValidationRule
return 1 === $count;
}
- /**
- * @param string $value
- *
- * @return bool
- */
private function validateBillName(string $value): bool
{
$count = $this->countField(Bill::class, 'name', $value);
@@ -205,11 +162,6 @@ class BelongsUserGroup implements ValidationRule
return 1 === $count;
}
- /**
- * @param int $value
- *
- * @return bool
- */
private function validateBudgetId(int $value): bool
{
if (0 === $value) {
@@ -220,11 +172,6 @@ class BelongsUserGroup implements ValidationRule
return 1 === $count;
}
- /**
- * @param int $value
- *
- * @return bool
- */
private function validateCategoryId(int $value): bool
{
$count = Category::where('id', '=', $value)->where('user_group_id', '=', $this->userGroup->id)->count();
@@ -232,11 +179,6 @@ class BelongsUserGroup implements ValidationRule
return 1 === $count;
}
- /**
- * @param string $value
- *
- * @return bool
- */
private function validateBudgetName(string $value): bool
{
$count = $this->countField(Budget::class, 'name', $value);
@@ -244,11 +186,6 @@ class BelongsUserGroup implements ValidationRule
return 1 === $count;
}
- /**
- * @param int $value
- *
- * @return bool
- */
private function validateAccountId(int $value): bool
{
if (0 === $value) {
diff --git a/app/Rules/IsAssetAccountId.php b/app/Rules/IsAssetAccountId.php
index 46d2e04e42..5c4e715f36 100644
--- a/app/Rules/IsAssetAccountId.php
+++ b/app/Rules/IsAssetAccountId.php
@@ -25,43 +25,29 @@ namespace FireflyIII\Rules;
use FireflyIII\Models\Account;
use FireflyIII\Models\AccountType;
-use Illuminate\Contracts\Validation\Rule;
+use Illuminate\Contracts\Validation\ValidationRule;
/**
- *
* Class IsAssetAccountId
*/
-class IsAssetAccountId implements Rule
+class IsAssetAccountId implements ValidationRule
{
/**
- * Get the validation error message. This is not translated because only the API uses it.
- *
- * @return string
+ * @SuppressWarnings(PHPMD.UnusedFormalParameter)
*/
- public function message(): string
- {
- return 'This is not an asset account.';
- }
-
- /**
- * Determine if the validation rule passes.
- *
- * @param string $attribute
- * @param mixed $value
- *
- * @return bool
- */
- public function passes($attribute, $value): bool
+ public function validate(string $attribute, mixed $value, \Closure $fail): void
{
$accountId = (int)$value;
+
+ /** @var null|Account $account */
$account = Account::with('accountType')->find($accountId);
if (null === $account) {
- return false;
- }
- if ($account->accountType->type !== AccountType::ASSET && $account->accountType->type !== AccountType::DEFAULT) {
- return false;
- }
+ $fail('validation.no_asset_account')->translate();
- return true;
+ return;
+ }
+ if (AccountType::ASSET !== $account->accountType->type && AccountType::DEFAULT !== $account->accountType->type) {
+ $fail('validation.no_asset_account')->translate();
+ }
}
}
diff --git a/app/Rules/IsBoolean.php b/app/Rules/IsBoolean.php
index 3019b38ad5..4ca0ea2c63 100644
--- a/app/Rules/IsBoolean.php
+++ b/app/Rules/IsBoolean.php
@@ -24,46 +24,30 @@ declare(strict_types=1);
namespace FireflyIII\Rules;
-use Illuminate\Contracts\Validation\Rule;
+use Illuminate\Contracts\Validation\ValidationRule;
/**
* Class IsBoolean
*/
-class IsBoolean implements Rule
+class IsBoolean implements ValidationRule
{
/**
- * Get the validation error message.
- *
- * @return string
+ * @SuppressWarnings(PHPMD.UnusedFormalParameter)
*/
- public function message(): string
- {
- return (string)trans('validation.boolean');
- }
-
- /**
- * Determine if the validation rule passes.
- *
- * @param string $attribute
- * @param mixed $value
- *
- * @return bool
- */
- public function passes($attribute, $value): bool
+ public function validate(string $attribute, mixed $value, \Closure $fail): void
{
if (is_bool($value)) {
- return true;
+ return;
}
- if (is_int($value) && 0 === $value) {
- return true;
+ if (0 === $value) {
+ return;
}
- if (is_int($value) && 1 === $value) {
- return true;
+ if (1 === $value) {
+ return;
}
- if (is_string($value) && in_array($value, ['0', '1', 'true', 'false', 'on', 'off', 'yes', 'no', 'y', 'n'], true)) {
- return true;
+ if (in_array($value, ['0', '1', 'true', 'false', 'on', 'off', 'yes', 'no', 'y', 'n'], true)) {
+ return;
}
-
- return false;
+ $fail('validation.boolean')->translate();
}
}
diff --git a/app/Rules/IsDateOrTime.php b/app/Rules/IsDateOrTime.php
index 8a6132ae58..60ccb3a963 100644
--- a/app/Rules/IsDateOrTime.php
+++ b/app/Rules/IsDateOrTime.php
@@ -27,67 +27,60 @@ namespace FireflyIII\Rules;
use Carbon\Carbon;
use Carbon\Exceptions\InvalidDateException;
use Carbon\Exceptions\InvalidFormatException;
-use Illuminate\Contracts\Validation\Rule;
-use Illuminate\Support\Facades\Log;
+use Illuminate\Contracts\Validation\ValidationRule;
/**
* Class IsDateOrTime
*/
-class IsDateOrTime implements Rule
+class IsDateOrTime implements ValidationRule
{
/**
- * Get the validation error message.
- *
- * @return string
+ * @SuppressWarnings(PHPMD.UnusedFormalParameter)
*/
- public function message()
- {
- return (string)trans('validation.date_or_time');
- }
-
- /**
- * Determine if the validation rule passes.
- *
- * @param string $attribute
- * @param mixed $value
- *
- * @return bool
- */
- public function passes($attribute, $value): bool
+ public function validate(string $attribute, mixed $value, \Closure $fail): void
{
$value = (string)$value;
if ('' === $value) {
- return false;
+ $fail('validation.date_or_time')->translate();
+
+ return;
}
if (10 === strlen($value)) {
// probably a date format.
try {
Carbon::createFromFormat('Y-m-d', $value);
- } catch (InvalidDateException $e) {
- Log::error(sprintf('"%s" is not a valid date: %s', $value, $e->getMessage()));
+ } catch (InvalidDateException $e) { // @phpstan-ignore-line
+ app('log')->error(sprintf('"%s" is not a valid date: %s', $value, $e->getMessage()));
- return false;
- } catch (InvalidFormatException $e) {
- Log::error(sprintf('"%s" is of an invalid format: %s', $value, $e->getMessage()));
+ $fail('validation.date_or_time')->translate();
- return false;
+ return;
+ } catch (InvalidFormatException $e) { // @phpstan-ignore-line
+ app('log')->error(sprintf('"%s" is of an invalid format: %s', $value, $e->getMessage()));
+
+ $fail('validation.date_or_time')->translate();
+
+ return;
}
- return true;
+ return;
}
+
// is an atom string, I hope?
try {
Carbon::parse($value);
- } catch (InvalidDateException $e) {
- Log::error(sprintf('"%s" is not a valid date or time: %s', $value, $e->getMessage()));
+ } catch (InvalidDateException $e) { // @phpstan-ignore-line
+ app('log')->error(sprintf('"%s" is not a valid date or time: %s', $value, $e->getMessage()));
- return false;
+ $fail('validation.date_or_time')->translate();
+
+ return;
} catch (InvalidFormatException $e) {
- Log::error(sprintf('"%s" is of an invalid format: %s', $value, $e->getMessage()));
+ app('log')->error(sprintf('"%s" is of an invalid format: %s', $value, $e->getMessage()));
- return false;
+ $fail('validation.date_or_time')->translate();
+
+ return;
}
-
- return true;
}
}
diff --git a/app/Rules/IsDuplicateTransaction.php b/app/Rules/IsDuplicateTransaction.php
index 2bfb59089d..b729ff46c3 100644
--- a/app/Rules/IsDuplicateTransaction.php
+++ b/app/Rules/IsDuplicateTransaction.php
@@ -23,30 +23,24 @@ declare(strict_types=1);
namespace FireflyIII\Rules;
-use Illuminate\Contracts\Validation\Rule;
+use Illuminate\Contracts\Validation\ValidationRule;
/**
+ * TODO not sure where this is used.
+ *
* Class IsDuplicateTransaction
*/
-class IsDuplicateTransaction implements Rule
+class IsDuplicateTransaction implements ValidationRule
{
private string $value;
/**
- * @inheritDoc
+ * @SuppressWarnings(PHPMD.UnusedFormalParameter)
*/
- public function message()
- {
- return $this->value;
- }
-
- /**
- * @inheritDoc
- */
- public function passes($attribute, $value)
+ public function validate(string $attribute, mixed $value, \Closure $fail): void
{
$this->value = $value;
- return false;
+ $fail($this->value);
}
}
diff --git a/app/Rules/IsTransferAccount.php b/app/Rules/IsTransferAccount.php
index 8cf7d14b05..e61b07ee47 100644
--- a/app/Rules/IsTransferAccount.php
+++ b/app/Rules/IsTransferAccount.php
@@ -26,50 +26,37 @@ namespace FireflyIII\Rules;
use FireflyIII\Models\TransactionType;
use FireflyIII\Validation\AccountValidator;
-use Illuminate\Contracts\Validation\Rule;
-use Illuminate\Support\Facades\Log;
+use Illuminate\Contracts\Validation\ValidationRule;
/**
* Class IsTransferAccount
*/
-class IsTransferAccount implements Rule
+class IsTransferAccount implements ValidationRule
{
/**
- * Get the validation error message.
- *
- * @return string
+ * @SuppressWarnings(PHPMD.UnusedFormalParameter)
*/
- public function message(): string
+ public function validate(string $attribute, mixed $value, \Closure $fail): void
{
- return (string)trans('validation.not_transfer_account');
- }
+ app('log')->debug(sprintf('Now in %s(%s)', __METHOD__, $value));
- /**
- * Determine if the validation rule passes.
- *
- * @param string $attribute
- * @param mixed $value
- *
- * @return bool
- */
- public function passes($attribute, $value): bool
- {
- Log::debug(sprintf('Now in %s(%s)', __METHOD__, $value));
/** @var AccountValidator $validator */
- $validator = app(AccountValidator::class);
+ $validator = app(AccountValidator::class);
$validator->setTransactionType(TransactionType::TRANSFER);
$validator->setUser(auth()->user());
- $validAccount = $validator->validateSource(['name' => (string)$value,]);
+ $validAccount = $validator->validateSource(['name' => (string)$value]);
if (true === $validAccount) {
- Log::debug('Found account based on name. Return true.');
+ app('log')->debug('Found account based on name. Return true.');
// found by name, use repos to return.
- return true;
+ return;
}
- $validAccount = $validator->validateSource(['id' => (int)$value,]);
- Log::debug(sprintf('Search by id (%d), result is %s.', (int)$value, var_export($validAccount, true)));
+ $validAccount = $validator->validateSource(['id' => (int)$value]);
+ app('log')->debug(sprintf('Search by id (%d), result is %s.', (int)$value, var_export($validAccount, true)));
- return false !== $validAccount;
+ if (false === $validAccount) {
+ $fail('validation.not_transfer_account')->translate();
+ }
}
}
diff --git a/app/Rules/IsValidAmount.php b/app/Rules/IsValidAmount.php
new file mode 100644
index 0000000000..598dec8965
--- /dev/null
+++ b/app/Rules/IsValidAmount.php
@@ -0,0 +1,72 @@
+emptyString($value)) {
+ $fail('validation.filled')->translate();
+ $message = sprintf('IsValidAmount: "%s" cannot be empty.', $value);
+ Log::debug($message);
+ Log::channel('audit')->info($message);
+
+ return;
+ }
+
+ // must be a number:
+ if (!$this->isValidNumber($value)) {
+ $fail('validation.numeric')->translate();
+ $message = sprintf('IsValidAmount: "%s" is not a number.', $value);
+ Log::debug($message);
+ Log::channel('audit')->info($message);
+
+ return;
+ }
+
+ // must not be scientific notation:
+ if ($this->scientificNumber($value)) {
+ $fail('validation.scientific_notation')->translate();
+ $message = sprintf('IsValidAmount: "%s" cannot be in the scientific notation.', $value);
+ Log::debug($message);
+ Log::channel('audit')->info($message);
+
+ return;
+ }
+
+ // must be more than minus a lots:
+ if ($this->lessThanLots($value)) {
+ $amount = bcmul('-1', self::BIG_AMOUNT);
+ $fail('validation.gte.numeric')->translate(['value' => $amount]);
+ $message = sprintf('IsValidAmount: "%s" must be more than %s.', $value, $amount);
+ Log::debug($message);
+ Log::channel('audit')->info($message);
+
+ return;
+ }
+
+ // must be less than a large number
+ if ($this->moreThanLots($value)) {
+ $fail('validation.lte.numeric')->translate(['value' => self::BIG_AMOUNT]);
+ $message = sprintf('IsValidAmount: "%s" must be more than %s.', $value, self::BIG_AMOUNT);
+ Log::debug($message);
+ Log::channel('audit')->info($message);
+ }
+ Log::debug(sprintf('IsValidAmount: "%s" is a valid positive amount.', $value));
+ }
+}
diff --git a/app/Rules/IsValidAttachmentModel.php b/app/Rules/IsValidAttachmentModel.php
index fa21c25991..566737e86e 100644
--- a/app/Rules/IsValidAttachmentModel.php
+++ b/app/Rules/IsValidAttachmentModel.php
@@ -39,22 +39,17 @@ use FireflyIII\Repositories\Journal\JournalAPIRepositoryInterface;
use FireflyIII\Repositories\Journal\JournalRepositoryInterface;
use FireflyIII\Repositories\PiggyBank\PiggyBankRepositoryInterface;
use FireflyIII\Repositories\Tag\TagRepositoryInterface;
-use Illuminate\Contracts\Validation\Rule;
-use Illuminate\Support\Facades\Log;
+use Illuminate\Contracts\Validation\ValidationRule;
/**
* Class IsValidAttachmentModel
*/
-class IsValidAttachmentModel implements Rule
+class IsValidAttachmentModel implements ValidationRule
{
- /** @var string */
- private $model;
+ private string $model;
/**
* IsValidAttachmentModel constructor.
- *
- *
- * @param string $model
*/
public function __construct(string $model)
{
@@ -62,11 +57,6 @@ class IsValidAttachmentModel implements Rule
$this->model = $model;
}
- /**
- * @param string $model
- *
- * @return string
- */
private function normalizeModel(string $model): string
{
$search = ['FireflyIII\Models\\'];
@@ -77,53 +67,32 @@ class IsValidAttachmentModel implements Rule
}
/**
- * Get the validation error message.
- *
- * @return string
+ * @SuppressWarnings(PHPMD.UnusedFormalParameter)
*/
- public function message(): string
- {
- return (string)trans('validation.model_id_invalid');
- }
-
- /**
- * Determine if the validation rule passes.
- *
- * @param string $attribute
- * @param mixed $value
- *
- * @return bool
- */
- public function passes($attribute, $value): bool
+ public function validate(string $attribute, mixed $value, \Closure $fail): void
{
if (!auth()->check()) {
- return false;
- }
- $methods = [
- Account::class => 'validateAccount',
- Bill::class => 'validateBill',
- Budget::class => 'validateBudget',
- Category::class => 'validateCategory',
- PiggyBank::class => 'validatePiggyBank',
- Tag::class => 'validateTag',
- Transaction::class => 'validateTransaction',
- TransactionJournal::class => 'validateJournal',
- ];
- if (!array_key_exists($this->model, $methods)) {
- Log::error(sprintf('Cannot validate model "%s" in %s.', substr($this->model, 0, 20), __METHOD__));
+ $fail('validation.model_id_invalid')->translate();
- return false;
+ return;
}
- $method = $methods[$this->model];
+ $result = match ($this->model) {
+ Account::class => $this->validateAccount((int)$value),
+ Bill::class => $this->validateBill((int)$value),
+ Budget::class => $this->validateBudget((int)$value),
+ Category::class => $this->validateCategory((int)$value),
+ PiggyBank::class => $this->validatePiggyBank((int)$value),
+ Tag::class => $this->validateTag((int)$value),
+ Transaction::class => $this->validateTransaction((int)$value),
+ TransactionJournal::class => $this->validateJournal((int)$value),
+ default => false,
+ };
- return $this->$method((int)$value);
+ if (false === $result) {
+ $fail('validation.model_id_invalid')->translate();
+ }
}
- /**
- * @param int $value
- *
- * @return bool
- */
private function validateAccount(int $value): bool
{
/** @var AccountRepositoryInterface $repository */
@@ -133,11 +102,6 @@ class IsValidAttachmentModel implements Rule
return null !== $repository->find($value);
}
- /**
- * @param int $value
- *
- * @return bool
- */
private function validateBill(int $value): bool
{
/** @var BillRepositoryInterface $repository */
@@ -147,11 +111,6 @@ class IsValidAttachmentModel implements Rule
return null !== $repository->find($value);
}
- /**
- * @param int $value
- *
- * @return bool
- */
private function validateBudget(int $value): bool
{
/** @var BudgetRepositoryInterface $repository */
@@ -161,11 +120,6 @@ class IsValidAttachmentModel implements Rule
return null !== $repository->find($value);
}
- /**
- * @param int $value
- *
- * @return bool
- */
private function validateCategory(int $value): bool
{
/** @var CategoryRepositoryInterface $repository */
@@ -175,24 +129,6 @@ class IsValidAttachmentModel implements Rule
return null !== $repository->find($value);
}
- /**
- * @param int $value
- *
- * @return bool
- */
- private function validateJournal(int $value): bool
- {
- $repository = app(JournalRepositoryInterface::class);
- $repository->setUser(auth()->user());
-
- return null !== $repository->find($value);
- }
-
- /**
- * @param int $value
- *
- * @return bool
- */
private function validatePiggyBank(int $value): bool
{
/** @var PiggyBankRepositoryInterface $repository */
@@ -202,11 +138,6 @@ class IsValidAttachmentModel implements Rule
return null !== $repository->find($value);
}
- /**
- * @param int $value
- *
- * @return bool
- */
private function validateTag(int $value): bool
{
/** @var TagRepositoryInterface $repository */
@@ -216,17 +147,20 @@ class IsValidAttachmentModel implements Rule
return null !== $repository->find($value);
}
- /**
- * @param int $value
- *
- * @return bool
- */
private function validateTransaction(int $value): bool
{
/** @var JournalAPIRepositoryInterface $repository */
$repository = app(JournalAPIRepositoryInterface::class);
$repository->setUser(auth()->user());
- return null !== $repository->findTransaction((int)$value);
+ return null !== $repository->findTransaction($value);
+ }
+
+ private function validateJournal(int $value): bool
+ {
+ $repository = app(JournalRepositoryInterface::class);
+ $repository->setUser(auth()->user());
+
+ return null !== $repository->find($value);
}
}
diff --git a/app/Rules/IsValidBulkClause.php b/app/Rules/IsValidBulkClause.php
index 7a8bda7692..1a79add025 100644
--- a/app/Rules/IsValidBulkClause.php
+++ b/app/Rules/IsValidBulkClause.php
@@ -24,63 +24,47 @@ declare(strict_types=1);
namespace FireflyIII\Rules;
-use Illuminate\Contracts\Validation\Rule;
+use Illuminate\Contracts\Validation\ValidationRule;
use Illuminate\Support\Facades\Validator;
-use JsonException;
/**
* Class IsValidBulkClause
*/
-class IsValidBulkClause implements Rule
+class IsValidBulkClause implements ValidationRule
{
private string $error;
private array $rules;
- /**
- * @param string $type
- */
public function __construct(string $type)
{
$this->rules = config(sprintf('bulk.%s', $type));
$this->error = (string)trans('firefly.belongs_user');
}
- /**
- * @return string
- */
public function message(): string
{
return $this->error;
}
/**
- * @param string $attribute
- * @param mixed $value
- *
- * @return bool
+ * @SuppressWarnings(PHPMD.UnusedFormalParameter)
*/
- public function passes($attribute, $value): bool
+ public function validate(string $attribute, mixed $value, \Closure $fail): void
{
$result = $this->basicValidation((string)$value);
if (false === $result) {
- return false;
+ $fail($this->error);
}
-
- return true;
}
/**
* Does basic rule based validation.
- *
- * @param string $value
- *
- * @return bool
*/
private function basicValidation(string $value): bool
{
try {
$array = json_decode($value, true, 8, JSON_THROW_ON_ERROR);
- } catch (JsonException $e) {
+ } catch (\JsonException $e) {
$this->error = (string)trans('validation.json');
return false;
@@ -92,6 +76,7 @@ class IsValidBulkClause implements Rule
return false;
}
+
/**
* @var string $arrayKey
* @var mixed $arrayValue
@@ -107,7 +92,7 @@ class IsValidBulkClause implements Rule
'value' => $this->rules[$clause][$arrayKey],
]);
if ($validator->fails()) {
- $this->error = sprintf('%s: %s: %s', $clause, $arrayKey, join(', ', ($validator->errors()->get('value'))));
+ $this->error = sprintf('%s: %s: %s', $clause, $arrayKey, implode(', ', $validator->errors()->get('value')));
return false;
}
diff --git a/app/Rules/IsValidPositiveAmount.php b/app/Rules/IsValidPositiveAmount.php
new file mode 100644
index 0000000000..7a6b559c7f
--- /dev/null
+++ b/app/Rules/IsValidPositiveAmount.php
@@ -0,0 +1,67 @@
+emptyString($value)) {
+ $fail('validation.filled')->translate();
+ $message = sprintf('IsValidPositiveAmount: "%s" cannot be empty.', $value);
+ Log::debug($message);
+ Log::channel('audit')->info($message);
+
+ return;
+ }
+
+ // must be a number:
+ if (!$this->isValidNumber($value)) {
+ $fail('validation.numeric')->translate();
+ $message = sprintf('IsValidPositiveAmount: "%s" is not a number.', $value);
+ Log::debug($message);
+ Log::channel('audit')->info($message);
+
+ return;
+ }
+ // must not be scientific notation:
+ if ($this->scientificNumber($value)) {
+ $fail('validation.scientific_notation')->translate();
+ $message = sprintf('IsValidPositiveAmount: "%s" cannot be in the scientific notation.', $value);
+ Log::debug($message);
+ Log::channel('audit')->info($message);
+
+ return;
+ }
+ // must be more than zero:
+ if ($this->lessOrEqualToZero($value)) {
+ $fail('validation.more_than_zero')->translate();
+ $message = sprintf('IsValidPositiveAmount: "%s" must be more than zero.', $value);
+ Log::debug($message);
+ Log::channel('audit')->info($message);
+
+ return;
+ }
+ // must be less than a large number
+ if ($this->moreThanLots($value)) {
+ $fail('validation.lte.numeric')->translate(['value' => self::BIG_AMOUNT]);
+ $message = sprintf('IsValidPositiveAmount: "%s" must be less than %s.', $value, self::BIG_AMOUNT);
+ Log::debug($message);
+ Log::channel('audit')->info($message);
+ }
+ Log::debug(sprintf('IsValidPositiveAmount: "%s" is a valid positive amount.', $value));
+ }
+}
diff --git a/app/Rules/IsValidZeroOrMoreAmount.php b/app/Rules/IsValidZeroOrMoreAmount.php
new file mode 100644
index 0000000000..1d2866d06f
--- /dev/null
+++ b/app/Rules/IsValidZeroOrMoreAmount.php
@@ -0,0 +1,67 @@
+emptyString($value)) {
+ $fail('validation.filled')->translate();
+ $message = sprintf('IsValidZeroOrMoreAmount: "%s" cannot be empty.', $value);
+ Log::debug($message);
+ Log::channel('audit')->info($message);
+
+ return;
+ }
+
+ // must be a number:
+ if (!$this->isValidNumber($value)) {
+ $fail('validation.numeric')->translate();
+ $message = sprintf('IsValidZeroOrMoreAmount: "%s" is not a number.', $value);
+ Log::debug($message);
+ Log::channel('audit')->info($message);
+
+ return;
+ }
+ // must not be scientific notation:
+ if ($this->scientificNumber($value)) {
+ $fail('validation.scientific_notation')->translate();
+ $message = sprintf('IsValidZeroOrMoreAmount: "%s" cannot be in the scientific notation.', $value);
+ Log::debug($message);
+ Log::channel('audit')->info($message);
+
+ return;
+ }
+ // must be zero or more
+ if (!$this->zeroOrMore($value)) {
+ $fail('validation.more_than_zero_correct')->translate();
+ $message = sprintf('IsValidZeroOrMoreAmount: "%s" must be zero or more.', $value);
+ Log::debug($message);
+ Log::channel('audit')->info($message);
+
+ return;
+ }
+ // must be less than a large number
+ if ($this->moreThanLots($value)) {
+ $fail('validation.lte.numeric')->translate(['value' => self::BIG_AMOUNT]);
+ $message = sprintf('IsValidPositiveAmount: "%s" must be less than %s.', $value, self::BIG_AMOUNT);
+ Log::debug($message);
+ Log::channel('audit')->info($message);
+ }
+ Log::debug(sprintf('IsValidZeroOrMoreAmount: "%s" is a valid positive amount.', $value));
+ }
+}
diff --git a/app/Rules/LessThanPiggyTarget.php b/app/Rules/LessThanPiggyTarget.php
index e19589ea74..433d02dd2e 100644
--- a/app/Rules/LessThanPiggyTarget.php
+++ b/app/Rules/LessThanPiggyTarget.php
@@ -24,17 +24,15 @@ declare(strict_types=1);
namespace FireflyIII\Rules;
-use Illuminate\Contracts\Validation\Rule;
+use Illuminate\Contracts\Validation\ValidationRule;
/**
* Class LessThanPiggyTarget
*/
-class LessThanPiggyTarget implements Rule
+class LessThanPiggyTarget implements ValidationRule
{
/**
* Get the validation error message.
- *
- * @return string
*/
public function message(): string
{
@@ -42,15 +40,10 @@ class LessThanPiggyTarget implements Rule
}
/**
- * Determine if the validation rule passes.
- *
- * @param string $attribute
- * @param mixed $value
- *
- * @return bool
+ * @SuppressWarnings(PHPMD.UnusedFormalParameter)
*/
- public function passes($attribute, $value): bool
+ public function validate(string $attribute, mixed $value, \Closure $fail): void
{
- return true;
+ // TODO not sure if this is still used.
}
}
diff --git a/app/Rules/UniqueAccountNumber.php b/app/Rules/UniqueAccountNumber.php
index c9aaddafe8..1b5cb68d8e 100644
--- a/app/Rules/UniqueAccountNumber.php
+++ b/app/Rules/UniqueAccountNumber.php
@@ -26,27 +26,24 @@ namespace FireflyIII\Rules;
use FireflyIII\Models\Account;
use FireflyIII\Models\AccountMeta;
use FireflyIII\Models\AccountType;
-use Illuminate\Contracts\Validation\Rule;
-use Illuminate\Support\Facades\Log;
+use Illuminate\Contracts\Validation\ValidationRule;
/**
* Class UniqueAccountNumber
*/
-class UniqueAccountNumber implements Rule
+class UniqueAccountNumber implements ValidationRule
{
private ?Account $account;
private ?string $expectedType;
/**
* Create a new rule instance.
- *
- *
- * @param Account|null $account
- * @param string|null $expectedType
*/
public function __construct(?Account $account, ?string $expectedType)
{
- Log::debug('Constructed UniqueAccountNumber');
+ app('log')
+ ->debug('Constructed UniqueAccountNumber')
+ ;
$this->account = $account;
$this->expectedType = $expectedType;
// a very basic fix to make sure we get the correct account type:
@@ -59,14 +56,11 @@ class UniqueAccountNumber implements Rule
if ('asset' === $expectedType) {
$this->expectedType = AccountType::ASSET;
}
- Log::debug(sprintf('Expected type is "%s"', $this->expectedType));
+ app('log')->debug(sprintf('Expected type is "%s"', $this->expectedType));
}
/**
* Get the validation error message.
- *
- *
- * @return string
*/
public function message(): string
{
@@ -74,29 +68,23 @@ class UniqueAccountNumber implements Rule
}
/**
- * Determine if the validation rule passes.
- *
- * @param string $attribute
- * @param mixed $value
- *
- * @return bool
- *
+ * @SuppressWarnings(PHPMD.UnusedFormalParameter)
*/
- public function passes($attribute, $value): bool
+ public function validate(string $attribute, mixed $value, \Closure $fail): void
{
if (!auth()->check()) {
- return true;
+ return;
}
if (null === $this->expectedType) {
- return true;
+ return;
}
$maxCounts = $this->getMaxOccurrences();
foreach ($maxCounts as $type => $max) {
$count = $this->countHits($type, $value);
- Log::debug(sprintf('Count for "%s" and account number "%s" is %d', $type, $value, $count));
+ app('log')->debug(sprintf('Count for "%s" and account number "%s" is %d', $type, $value, $count));
if ($count > $max) {
- Log::debug(
+ app('log')->debug(
sprintf(
'account number "%s" is in use with %d account(s) of type "%s", which is too much for expected type "%s"',
$value,
@@ -106,18 +94,14 @@ class UniqueAccountNumber implements Rule
)
);
- return false;
+ $fail('validation.unique_account_number_for_user')->translate();
+
+ return;
}
}
- Log::debug('Account number is valid.');
-
- return true;
+ app('log')->debug('Account number is valid.');
}
- /**
- * @return array
- *
- */
private function getMaxOccurrences(): array
{
$maxCounts = [
@@ -140,20 +124,15 @@ class UniqueAccountNumber implements Rule
return $maxCounts;
}
- /**
- * @param string $type
- * @param string $accountNumber
- *
- * @return int
- */
private function countHits(string $type, string $accountNumber): int
{
$query = AccountMeta::leftJoin('accounts', 'accounts.id', '=', 'account_meta.account_id')
- ->leftJoin('account_types', 'account_types.id', '=', 'accounts.account_type_id')
- ->where('accounts.user_id', auth()->user()->id)
- ->where('account_types.type', $type)
- ->where('account_meta.name', '=', 'account_number')
- ->where('account_meta.data', json_encode($accountNumber));
+ ->leftJoin('account_types', 'account_types.id', '=', 'accounts.account_type_id')
+ ->where('accounts.user_id', auth()->user()->id)
+ ->where('account_types.type', $type)
+ ->where('account_meta.name', '=', 'account_number')
+ ->where('account_meta.data', json_encode($accountNumber))
+ ;
if (null !== $this->account) {
$query->where('accounts.id', '!=', $this->account->id);
diff --git a/app/Rules/UniqueIban.php b/app/Rules/UniqueIban.php
index 6a0c3940cb..3bc00be090 100644
--- a/app/Rules/UniqueIban.php
+++ b/app/Rules/UniqueIban.php
@@ -23,11 +23,9 @@ declare(strict_types=1);
namespace FireflyIII\Rules;
-use Closure;
use FireflyIII\Models\Account;
use FireflyIII\Models\AccountType;
use Illuminate\Contracts\Validation\ValidationRule;
-use Illuminate\Support\Facades\Log;
/**
* Class UniqueIban
@@ -39,10 +37,6 @@ class UniqueIban implements ValidationRule
/**
* Create a new rule instance.
- *
- *
- * @param Account|null $account
- * @param string|null $expectedType
*/
public function __construct(?Account $account, ?string $expectedType)
{
@@ -69,19 +63,13 @@ class UniqueIban implements ValidationRule
/**
* Get the validation error message.
- *
- *
- * @return string
*/
public function message(): string
{
return (string)trans('validation.unique_iban_for_user');
}
- /**
- * @inheritDoc
- */
- public function validate(string $attribute, mixed $value, Closure $fail): void
+ public function validate(string $attribute, mixed $value, \Closure $fail): void
{
if (!$this->passes($attribute, $value)) {
$fail((string)trans('validation.unique_iban_for_user'));
@@ -94,8 +82,7 @@ class UniqueIban implements ValidationRule
* @param string $attribute
* @param mixed $value
*
- * @return bool
- *
+ * @SuppressWarnings(PHPMD.UnusedFormalParameter)
*/
public function passes($attribute, $value): bool
{
@@ -109,15 +96,15 @@ class UniqueIban implements ValidationRule
foreach ($maxCounts as $type => $max) {
$count = $this->countHits($type, $value);
- Log::debug(sprintf('Count for "%s" and IBAN "%s" is %d', $type, $value, $count));
+ app('log')->debug(sprintf('Count for "%s" and IBAN "%s" is %d', $type, $value, $count));
if ($count > $max) {
- Log::debug(
+ app('log')->debug(
sprintf(
'IBAN "%s" is in use with %d account(s) of type "%s", which is too much for expected types "%s"',
$value,
$count,
$type,
- join(', ', $this->expectedTypes)
+ implode(', ', $this->expectedTypes)
)
);
@@ -128,10 +115,6 @@ class UniqueIban implements ValidationRule
return true;
}
- /**
- * @return array
- *
- */
private function getMaxOccurrences(): array
{
$maxCounts = [
@@ -155,12 +138,6 @@ class UniqueIban implements ValidationRule
return $maxCounts;
}
- /**
- * @param string $type
- * @param string $iban
- *
- * @return int
- */
private function countHits(string $type, string $iban): int
{
$typesArray = [$type];
@@ -168,11 +145,12 @@ class UniqueIban implements ValidationRule
$typesArray = [AccountType::LOAN, AccountType::DEBT, AccountType::MORTGAGE];
}
$query
- = auth()->user()
- ->accounts()
- ->leftJoin('account_types', 'account_types.id', '=', 'accounts.account_type_id')
- ->where('accounts.iban', $iban)
- ->whereIn('account_types.type', $typesArray);
+ = auth()->user()
+ ->accounts()
+ ->leftJoin('account_types', 'account_types.id', '=', 'accounts.account_type_id')
+ ->where('accounts.iban', $iban)
+ ->whereIn('account_types.type', $typesArray)
+ ;
if (null !== $this->account) {
$query->where('accounts.id', '!=', $this->account->id);
diff --git a/app/Rules/ValidJournals.php b/app/Rules/ValidJournals.php
index 11e56e89cf..a73ba98f2b 100644
--- a/app/Rules/ValidJournals.php
+++ b/app/Rules/ValidJournals.php
@@ -25,52 +25,33 @@ declare(strict_types=1);
namespace FireflyIII\Rules;
use FireflyIII\Models\TransactionJournal;
-use Illuminate\Contracts\Validation\Rule;
-use Illuminate\Support\Facades\Log;
+use Illuminate\Contracts\Validation\ValidationRule;
/**
* Class ValidJournals
- *
-
*/
-class ValidJournals implements Rule
+class ValidJournals implements ValidationRule
{
/**
- * Get the validation error message.
- *
- * @return string
+ * @SuppressWarnings(PHPMD.UnusedFormalParameter)
*/
- public function message(): string
+ public function validate(string $attribute, mixed $value, \Closure $fail): void
{
- return (string)trans('validation.invalid_selection');
- }
-
- /**
- * Determine if the validation rule passes.
- *
- * @param string $attribute
- * @param mixed $value
- *
- * @return bool
- *
- */
- public function passes($attribute, $value): bool
- {
- Log::debug('In ValidJournals::passes');
+ app('log')->debug('In ValidJournals::passes');
if (!is_array($value)) {
- return true;
+ return;
}
$userId = auth()->user()->id;
foreach ($value as $journalId) {
$count = TransactionJournal::where('id', $journalId)->where('user_id', $userId)->count();
if (0 === $count) {
- Log::debug(sprintf('Count for transaction #%d and user #%d is zero! Return FALSE', $journalId, $userId));
+ app('log')->debug(sprintf('Count for transaction #%d and user #%d is zero! Return FALSE', $journalId, $userId));
- return false;
+ $fail('validation.invalid_selection')->translate();
+
+ return;
}
}
- Log::debug('Return true!');
-
- return true;
+ app('log')->debug('Return true!');
}
}
diff --git a/app/Rules/ValidRecurrenceRepetitionType.php b/app/Rules/ValidRecurrenceRepetitionType.php
index 508835a5fb..d4015d1d7c 100644
--- a/app/Rules/ValidRecurrenceRepetitionType.php
+++ b/app/Rules/ValidRecurrenceRepetitionType.php
@@ -23,52 +23,36 @@ declare(strict_types=1);
namespace FireflyIII\Rules;
-use Illuminate\Contracts\Validation\Rule;
+use Illuminate\Contracts\Validation\ValidationRule;
/**
* Class ValidRecurrenceRepetitionType
- *
-
*/
-class ValidRecurrenceRepetitionType implements Rule
+class ValidRecurrenceRepetitionType implements ValidationRule
{
- /**
- * Get the validation error message.
- *
- * @return string
- */
- public function message(): string
- {
- return (string)trans('validation.valid_recurrence_rep_type');
- }
-
/**
* Determine if the validation rule passes.
*
- * @param string $attribute
- * @param mixed $value
- *
- * @return bool
- *
+ * @SuppressWarnings(PHPMD.UnusedFormalParameter)
*/
- public function passes($attribute, $value): bool
+ public function validate(string $attribute, mixed $value, \Closure $fail): void
{
$value = (string)$value;
if ('daily' === $value) {
- return true;
+ return;
}
- //monthly,17
- //ndom,3,7
+ // monthly,17
+ // ndom,3,7
if (in_array(substr($value, 0, 6), ['yearly', 'weekly'], true)) {
- return true;
+ return;
}
if (str_starts_with($value, 'monthly')) {
- return true;
+ return;
}
if (str_starts_with($value, 'ndom')) {
- return true;
+ return;
}
- return false;
+ $fail('validation.valid_recurrence_rep_type')->translate();
}
}
diff --git a/app/Rules/ValidRecurrenceRepetitionValue.php b/app/Rules/ValidRecurrenceRepetitionValue.php
index 10ec16ea84..637b26b56a 100644
--- a/app/Rules/ValidRecurrenceRepetitionValue.php
+++ b/app/Rules/ValidRecurrenceRepetitionValue.php
@@ -24,72 +24,47 @@ declare(strict_types=1);
namespace FireflyIII\Rules;
use Carbon\Carbon;
-use Illuminate\Contracts\Validation\Rule;
-use Illuminate\Support\Facades\Log;
-use InvalidArgumentException;
+use Illuminate\Contracts\Validation\ValidationRule;
/**
* Class ValidRecurrenceRepetitionValue
- *
-
*/
-class ValidRecurrenceRepetitionValue implements Rule
+class ValidRecurrenceRepetitionValue implements ValidationRule
{
/**
- * Get the validation error message.
- *
- * @return string
+ * @SuppressWarnings(PHPMD.UnusedFormalParameter)
*/
- public function message(): string
- {
- return (string)trans('validation.valid_recurrence_rep_type');
- }
-
- /**
- * Determine if the validation rule passes.
- *
- * @param string $attribute
- * @param mixed $value
- *
- * @return bool
- *
- */
- public function passes($attribute, $value): bool
+ public function validate(string $attribute, mixed $value, \Closure $fail): void
{
$value = (string)$value;
if ('daily' === $value) {
- return true;
+ return;
}
- if (str_starts_with($value, 'monthly')) {
- return $this->validateMonthly($value);
+ if (str_starts_with($value, 'monthly') && $this->validateMonthly($value)) {
+ return;
}
// Value is like: ndom,3,7
// nth x-day of the month.
- if (str_starts_with($value, 'ndom')) {
- return $this->validateNdom($value);
+ if (str_starts_with($value, 'ndom') && $this->validateNdom($value)) {
+ return;
}
// Value is like: weekly,7
- if (str_starts_with($value, 'weekly')) {
- return $this->validateWeekly($value);
+ if (str_starts_with($value, 'weekly') && $this->validateWeekly($value)) {
+ return;
}
// Value is like: yearly,2018-01-01
- if (str_starts_with($value, 'yearly')) {
- return $this->validateYearly($value);
+ if (str_starts_with($value, 'yearly') && $this->validateYearly($value)) {
+ return;
}
- return false;
+ $fail('validation.valid_recurrence_rep_type')->translate();
}
- /**
- * @param string $value
- *
- * @return bool
- */
private function validateMonthly(string $value): bool
{
$dayOfMonth = (int)substr($value, 8);
@@ -97,20 +72,14 @@ class ValidRecurrenceRepetitionValue implements Rule
return $dayOfMonth > 0 && $dayOfMonth < 32;
}
- /**
- * @param string $value
- *
- * @return bool
- *
- */
private function validateNdom(string $value): bool
{
$parameters = explode(',', substr($value, 5));
if (2 !== count($parameters)) {
return false;
}
- $nthDay = (int)($parameters[0] ?? 0.0);
- $dayOfWeek = (int)($parameters[1] ?? 0.0);
+ $nthDay = (int)($parameters[0] ?? 0.0);
+ $dayOfWeek = (int)($parameters[1] ?? 0.0);
if ($nthDay < 1 || $nthDay > 5) {
return false;
}
@@ -118,11 +87,6 @@ class ValidRecurrenceRepetitionValue implements Rule
return $dayOfWeek > 0 && $dayOfWeek < 8;
}
- /**
- * @param string $value
- *
- * @return bool
- */
private function validateWeekly(string $value): bool
{
$dayOfWeek = (int)substr($value, 7);
@@ -130,19 +94,15 @@ class ValidRecurrenceRepetitionValue implements Rule
return $dayOfWeek > 0 && $dayOfWeek < 8;
}
- /**
- * @param string $value
- *
- * @return bool
- */
private function validateYearly(string $value): bool
{
// rest of the string must be valid date:
$dateString = substr($value, 7);
+
try {
Carbon::createFromFormat('Y-m-d', $dateString);
- } catch (InvalidArgumentException $e) {
- Log::debug(sprintf('Could not parse date %s: %s', $dateString, $e->getMessage()));
+ } catch (\InvalidArgumentException $e) { // @phpstan-ignore-line
+ app('log')->debug(sprintf('Could not parse date %s: %s', $dateString, $e->getMessage()));
return false;
}
diff --git a/app/Services/FireflyIIIOrg/Update/UpdateRequest.php b/app/Services/FireflyIIIOrg/Update/UpdateRequest.php
index 2f09340c09..d45a9ff781 100644
--- a/app/Services/FireflyIIIOrg/Update/UpdateRequest.php
+++ b/app/Services/FireflyIIIOrg/Update/UpdateRequest.php
@@ -29,31 +29,25 @@ use FireflyIII\Events\NewVersionAvailable;
use GuzzleHttp\Client;
use GuzzleHttp\Exception\GuzzleException;
use Illuminate\Support\Facades\Log;
-use JsonException;
/**
* Class UpdateRequest
*/
class UpdateRequest implements UpdateRequestInterface
{
- /**
- * @param string $channel
- *
- * @return array
- */
public function getUpdateInformation(string $channel): array
{
- Log::debug(sprintf('Now in getUpdateInformation(%s)', $channel));
+ app('log')->debug(sprintf('Now in getUpdateInformation(%s)', $channel));
$information = [
'level' => 'error',
'message' => (string)trans('firefly.unknown_error'),
];
- // try get array from update server:
- $updateInfo = $this->contactServer($channel);
+ // try to get array from update server:
+ $updateInfo = $this->contactServer($channel);
if ('error' === $updateInfo['level']) {
- Log::error('Update information contains an error.');
- Log::error($updateInfo['message']);
+ app('log')->error('Update information contains an error.');
+ app('log')->error($updateInfo['message']);
$information['message'] = $updateInfo['message'];
return $information;
@@ -63,24 +57,20 @@ class UpdateRequest implements UpdateRequestInterface
return $this->parseResult($updateInfo);
}
- /**
- * @param string $channel
- *
- * @return array
- */
private function contactServer(string $channel): array
{
- Log::debug(sprintf('Now in contactServer(%s)', $channel));
+ app('log')->debug(sprintf('Now in contactServer(%s)', $channel));
// always fall back to current version:
- $return = [
+ $return = [
'version' => config('firefly.version'),
'date' => today(config('app.timezone'))->startOfDay(),
'level' => 'error',
'message' => (string)trans('firefly.unknown_error'),
];
- $url = config('firefly.update_endpoint');
- Log::debug(sprintf('Going to call %s', $url));
+ $url = config('firefly.update_endpoint');
+ app('log')->debug(sprintf('Going to call %s', $url));
+
try {
$client = new Client();
$options = [
@@ -91,141 +81,200 @@ class UpdateRequest implements UpdateRequestInterface
];
$res = $client->request('GET', $url, $options);
} catch (GuzzleException $e) {
- Log::error('Ran into Guzzle error.');
- Log::error($e->getMessage());
- Log::error($e->getTraceAsString());
+ app('log')->error('Ran into Guzzle error.');
+ app('log')->error($e->getMessage());
+ app('log')->error($e->getTraceAsString());
$return['message'] = sprintf('Guzzle: %s', strip_tags($e->getMessage()));
return $return;
}
if (200 !== $res->getStatusCode()) {
- Log::error(sprintf('Response status from server is %d.', $res->getStatusCode()));
- Log::error((string)$res->getBody());
+ app('log')->error(sprintf('Response status from server is %d.', $res->getStatusCode()));
+ app('log')->error((string)$res->getBody());
$return['message'] = sprintf('Error: %d', $res->getStatusCode());
return $return;
}
- $body = (string)$res->getBody();
+ $body = (string)$res->getBody();
+
try {
$json = json_decode($body, true, 512, JSON_THROW_ON_ERROR);
- } catch (JsonException $e) {
- Log::error('Body is not valid JSON');
- Log::error($body);
+ } catch (\JsonException $e) {
+ app('log')->error('Body is not valid JSON');
+ app('log')->error($body);
$return['message'] = 'Invalid JSON :(';
return $return;
}
if (!array_key_exists($channel, $json['firefly_iii'])) {
- Log::error(sprintf('No valid update channel "%s"', $channel));
- Log::error($body);
+ app('log')->error(sprintf('No valid update channel "%s"', $channel));
+ app('log')->error($body);
$return['message'] = sprintf('Unknown update channel "%s" :(', $channel);
}
// parse response a bit. No message yet.
$response = $json['firefly_iii'][$channel];
+ $date = Carbon::createFromFormat('Y-m-d', $response['date']);
+ if (false === $date) {
+ $date = today(config('app.timezone'));
+ }
$return['version'] = $response['version'];
$return['level'] = 'success';
- $return['date'] = Carbon::createFromFormat('Y-m-d', $response['date'])->startOfDay();
- Log::info('Response from update server', $response);
+ $return['date'] = $date->startOfDay();
+
+ app('log')->info('Response from update server', $response);
return $return;
}
/**
- * @param array $information
- *
- * @return array
+ * TODO make shorter
*/
private function parseResult(array $information): array
{
- Log::debug('Now in parseResult()', $information);
- $return = [
- 'level' => 'error',
- 'message' => (string)trans('firefly.unknown_error'),
- ];
- $current = config('firefly.version');
- $latest = $information['version'];
+ app('log')->debug('Now in parseResult()', $information);
+ $current = (string)config('firefly.version');
+ $latest = (string)$information['version'];
// strip the 'v' from the version if it's there.
if (str_starts_with($latest, 'v')) {
$latest = substr($latest, 1);
}
+ if (str_starts_with($current, 'develop')) {
+ return $this->parseResultDevelop($current, $latest, $information);
+ }
- $compare = version_compare($latest, $current);
+ $compare = version_compare($latest, $current);
- Log::debug(sprintf('Current version is "%s", latest is "%s", result is: %d', $current, $latest, $compare));
+ app('log')->debug(sprintf('Current version is "%s", latest is "%s", result is: %d', $current, $latest, $compare));
// -1: you're running a newer version:
if (-1 === $compare) {
- $return['level'] = 'info';
- $return['message'] = (string)trans('firefly.update_newer_version_alert', ['your_version' => $current, 'new_version' => $latest]);
- Log::debug('User is running a newer version', $return);
-
- return $return;
+ return $this->runsNewerVersion($current, $latest);
}
// running the current version:
if (0 === $compare) {
- $return['level'] = 'info';
- $return['message'] = (string)trans('firefly.update_current_version_alert', ['version' => $current]);
- Log::debug('User is the current version.', $return);
-
- return $return;
+ return $this->runsSameVersion($current);
}
// a newer version is available!
/** @var Carbon $released */
- $released = $information['date'];
- $today = today(config('app.timezone'))->startOfDay();
- $diff = $today->diffInDays($released);
- $expectedDiff = config('firefly.update_minimum_age') ?? 6;
- // it's still very fresh, and user wants a stable release:
- if ($diff <= $expectedDiff) {
+ $released = $information['date'];
+ $isBeta = $information['is_beta'] ?? false;
+ $isAlpha = $information['is_alpha'] ?? false;
+
+ // it's new but alpha:
+ if (true === $isAlpha) {
+ return $this->releasedNewAlpha($current, $latest, $released);
+ }
+
+ if (true === $isBeta) {
+ return $this->releasedNewBeta($current, $latest, $released);
+ }
+
+ return $this->releasedNewVersion($current, $latest, $released);
+ }
+
+ private function parseResultDevelop(string $current, string $latest, array $information): array
+ {
+ Log::debug(sprintf('User is running develop version "%s"', $current));
+ $parts = explode('/', $current);
+ $return = [];
+
+ /** @var Carbon $devDate */
+ $devDate = Carbon::createFromFormat('Y-m-d', $parts[1]);
+
+ if ($devDate->lte($information['date'])) {
+ Log::debug(sprintf('This development release is older, release = %s, latest version %s = %s', $devDate->format('Y-m-d'), $latest, $information['date']->format('Y-m-d')));
$return['level'] = 'info';
- $return['message'] = (string)trans(
- 'firefly.just_new_release',
- [
- 'version' => $latest,
- 'date' => $released->isoFormat((string)trans('config.month_and_day_js')),
- 'days' => $expectedDiff,
- ]
- );
- Log::debug('Release is very fresh.', $return);
+ $return['message'] = (string)trans('firefly.update_current_dev_older', ['version' => $current, 'new_version' => $latest]);
return $return;
}
+ Log::debug(sprintf('This development release is newer, release = %s, latest version %s = %s', $devDate->format('Y-m-d'), $latest, $information['date']->format('Y-m-d')));
+ $return['level'] = 'info';
+ $return['message'] = (string)trans('firefly.update_current_dev_newer', ['version' => $current, 'new_version' => $latest]);
- // it's been around for a while:
- $return['level'] = 'success';
- $return['message'] = (string)trans(
+ return $return;
+ }
+
+ private function runsNewerVersion(string $current, string $latest): array
+ {
+ $return = [
+ 'level' => 'info',
+ 'message' => (string)trans('firefly.update_newer_version_alert', ['your_version' => $current, 'new_version' => $latest]),
+ ];
+ app('log')->debug('User is running a newer version', $return);
+
+ return $return;
+ }
+
+ private function runsSameVersion(string $current): array
+ {
+ $return = [
+ 'level' => 'info',
+ 'message' => (string)trans('firefly.update_current_version_alert', ['version' => $current]),
+ ];
+ app('log')->debug('User is the current version.', $return);
+
+ return $return;
+ }
+
+ private function releasedNewAlpha(string $current, string $latest, Carbon $date): array
+ {
+ app('log')->debug('New release is also a alpha!');
+ $message = (string)trans(
'firefly.update_new_version_alert',
[
'your_version' => $current,
'new_version' => $latest,
- 'date' => $released->isoFormat((string)trans('config.month_and_day_js')),
+ 'date' => $date->isoFormat((string)trans('config.month_and_day_js')),
]
);
- Log::debug('New release is old enough.');
- // add warning in case of alpha or beta:
- // append warning if beta or alpha.
- $isBeta = $information['is_beta'] ?? false;
- if (true === $isBeta) {
- $return['message'] = sprintf('%s %s', $return['message'], trans('firefly.update_version_beta'));
- Log::debug('New release is also a beta!');
- }
+ return [
+ 'level' => 'success',
+ 'message' => sprintf('%s %s', $message, trans('firefly.update_version_alpha')),
+ ];
+ }
- $isAlpha = $information['is_alpha'] ?? false;
- if (true === $isAlpha) {
- $return['message'] = sprintf('%s %s', $return['message'], trans('firefly.update_version_alpha'));
- Log::debug('New release is also a alpha!');
- }
- Log::debug('New release is here!', $return);
+ private function releasedNewBeta(string $current, string $latest, Carbon $date): array
+ {
+ app('log')->debug('New release is also a beta!');
+ $message = (string)trans(
+ 'firefly.update_new_version_alert',
+ [
+ 'your_version' => $current,
+ 'new_version' => $latest,
+ 'date' => $date->isoFormat((string)trans('config.month_and_day_js')),
+ ]
+ );
- // send event, this may result in a notification.
- event(new NewVersionAvailable($return['message']));
+ return [
+ 'level' => 'success',
+ 'message' => sprintf('%s %s', $message, trans('firefly.update_version_beta')),
+ ];
+ }
- return $return;
+ private function releasedNewVersion(string $current, string $latest, Carbon $date): array
+ {
+ app('log')->debug('New release is old enough.');
+ $message = (string)trans(
+ 'firefly.update_new_version_alert',
+ [
+ 'your_version' => $current,
+ 'new_version' => $latest,
+ 'date' => $date->isoFormat((string)trans('config.month_and_day_js')),
+ ]
+ );
+ app('log')->debug('New release is here!', [$message]);
+ event(new NewVersionAvailable($message));
+
+ return [
+ 'level' => 'success',
+ 'message' => $message,
+ ];
}
}
diff --git a/app/Services/FireflyIIIOrg/Update/UpdateRequestInterface.php b/app/Services/FireflyIIIOrg/Update/UpdateRequestInterface.php
index de0e8f294b..f0e51d43be 100644
--- a/app/Services/FireflyIIIOrg/Update/UpdateRequestInterface.php
+++ b/app/Services/FireflyIIIOrg/Update/UpdateRequestInterface.php
@@ -29,10 +29,5 @@ namespace FireflyIII\Services\FireflyIIIOrg\Update;
*/
interface UpdateRequestInterface
{
- /**
- * @param string $channel
- *
- * @return array
- */
public function getUpdateInformation(string $channel): array;
}
diff --git a/app/Services/Internal/Destroy/AccountDestroyService.php b/app/Services/Internal/Destroy/AccountDestroyService.php
index af4fd4cace..c7ab06163b 100644
--- a/app/Services/Internal/Destroy/AccountDestroyService.php
+++ b/app/Services/Internal/Destroy/AccountDestroyService.php
@@ -23,7 +23,6 @@ declare(strict_types=1);
namespace FireflyIII\Services\Internal\Destroy;
-use DB;
use FireflyIII\Models\Account;
use FireflyIII\Models\PiggyBank;
use FireflyIII\Models\RecurrenceTransaction;
@@ -31,20 +30,12 @@ use FireflyIII\Models\Transaction;
use FireflyIII\Models\TransactionJournal;
use FireflyIII\Models\TransactionType;
use Illuminate\Database\Eloquent\Builder;
-use Illuminate\Support\Facades\Log;
-use stdClass;
/**
* Class AccountDestroyService
*/
class AccountDestroyService
{
- /**
- * @param Account $account
- * @param Account|null $moveTo
- *
- * @return void
- */
public function destroy(Account $account, ?Account $moveTo): void
{
// find and delete opening balance journal + opposing account
@@ -70,36 +61,36 @@ class AccountDestroyService
$account->delete();
}
- /**
- * @param Account $account
- */
private function destroyOpeningBalance(Account $account): void
{
- Log::debug(sprintf('Searching for opening balance for account #%d "%s"', $account->id, $account->name));
+ app('log')->debug(sprintf('Searching for opening balance for account #%d "%s"', $account->id, $account->name));
$set = $account->transactions()
- ->leftJoin('transaction_journals', 'transaction_journals.id', '=', 'transactions.transaction_journal_id')
- ->leftJoin('transaction_types', 'transaction_types.id', '=', 'transaction_journals.transaction_type_id')
- ->where('transaction_types.type', TransactionType::OPENING_BALANCE)
- ->get(['transactions.transaction_journal_id']);
+ ->leftJoin('transaction_journals', 'transaction_journals.id', '=', 'transactions.transaction_journal_id')
+ ->leftJoin('transaction_types', 'transaction_types.id', '=', 'transaction_journals.transaction_type_id')
+ ->where('transaction_types.type', TransactionType::OPENING_BALANCE)
+ ->get(['transactions.transaction_journal_id'])
+ ;
if ($set->count() > 0) {
- $journalId = (int)$set->first()->transaction_journal_id;
- Log::debug(sprintf('Found opening balance journal with ID #%d', $journalId));
+ $journalId = $set->first()->transaction_journal_id;
+ app('log')->debug(sprintf('Found opening balance journal with ID #%d', $journalId));
// get transactions with this journal (should be just one):
$transactions = Transaction::where('transaction_journal_id', $journalId)
- ->where('account_id', '!=', $account->id)
- ->get();
+ ->where('account_id', '!=', $account->id)
+ ->get()
+ ;
+
/** @var Transaction $transaction */
foreach ($transactions as $transaction) {
- Log::debug(sprintf('Found transaction with ID #%d', $transaction->id));
+ app('log')->debug(sprintf('Found transaction with ID #%d', $transaction->id));
$ibAccount = $transaction->account;
- Log::debug(sprintf('Connected to account #%d "%s"', $ibAccount->id, $ibAccount->name));
+ app('log')->debug(sprintf('Connected to account #%d "%s"', $ibAccount->id, $ibAccount->name));
$ibAccount->accountMeta()->delete();
$transaction->delete();
$ibAccount->delete();
}
- $journal = TransactionJournal::find($journalId);
+ $journal = TransactionJournal::find($journalId);
if (null !== $journal) {
/** @var JournalDestroyService $service */
$service = app(JournalDestroyService::class);
@@ -108,76 +99,66 @@ class AccountDestroyService
}
}
- /**
- * @param Account $account
- * @param Account $moveTo
- */
public function moveTransactions(Account $account, Account $moveTo): void
{
- Log::debug(sprintf('Move from account #%d to #%d', $account->id, $moveTo->id));
- DB::table('transactions')->where('account_id', $account->id)->update(['account_id' => $moveTo->id]);
+ app('log')->debug(sprintf('Move from account #%d to #%d', $account->id, $moveTo->id));
+ \DB::table('transactions')->where('account_id', $account->id)->update(['account_id' => $moveTo->id]);
$collection = Transaction::groupBy('transaction_journal_id', 'account_id')
- ->where('account_id', $moveTo->id)
- ->get(['transaction_journal_id', 'account_id', DB::raw('count(*) as the_count')]);
+ ->where('account_id', $moveTo->id)
+ ->get(['transaction_journal_id', 'account_id', \DB::raw('count(*) as the_count')]) // @phpstan-ignore-line
+ ;
if (0 === $collection->count()) {
return;
}
/** @var JournalDestroyService $service */
- $service = app(JournalDestroyService::class);
- $user = $account->user;
- /** @var stdClass $row */
+ $service = app(JournalDestroyService::class);
+ $user = $account->user;
+
+ /** @var \stdClass $row */
foreach ($collection as $row) {
if ((int)$row->the_count > 1) {
- $journalId = (int)$row->transaction_journal_id;
+ $journalId = $row->transaction_journal_id;
$journal = $user->transactionJournals()->find($journalId);
if (null !== $journal) {
- Log::debug(sprintf('Deleted journal #%d because it has the same source as destination.', $journal->id));
+ app('log')->debug(sprintf('Deleted journal #%d because it has the same source as destination.', $journal->id));
$service->destroy($journal);
}
}
}
}
- /**
- * @param Account $account
- * @param Account $moveTo
- */
private function updateRecurrences(Account $account, Account $moveTo): void
{
- DB::table('recurrences_transactions')->where('source_id', $account->id)->update(['source_id' => $moveTo->id]);
- DB::table('recurrences_transactions')->where('destination_id', $account->id)->update(['destination_id' => $moveTo->id]);
+ \DB::table('recurrences_transactions')->where('source_id', $account->id)->update(['source_id' => $moveTo->id]);
+ \DB::table('recurrences_transactions')->where('destination_id', $account->id)->update(['destination_id' => $moveTo->id]);
}
- /**
- * @param Account $account
- */
private function destroyJournals(Account $account): void
{
/** @var JournalDestroyService $service */
$service = app(JournalDestroyService::class);
- Log::debug('Now trigger account delete response #' . $account->id);
+ app('log')->debug('Now trigger account delete response #'.$account->id);
+
/** @var Transaction $transaction */
foreach ($account->transactions()->get() as $transaction) {
- Log::debug('Now at transaction #' . $transaction->id);
- /** @var TransactionJournal $journal */
+ app('log')->debug('Now at transaction #'.$transaction->id);
+
+ /** @var null|TransactionJournal $journal */
$journal = $transaction->transactionJournal()->first();
if (null !== $journal) {
- Log::debug('Call for deletion of journal #' . $journal->id);
+ app('log')->debug('Call for deletion of journal #'.$journal->id);
$service->destroy($journal);
}
}
}
- /**
- * @param Account $account
- */
private function destroyRecurrences(Account $account): void
{
- $recurrences = RecurrenceTransaction::where(
- static function (Builder $q) use ($account) {
+ $recurrences = RecurrenceTransaction::where(
+ static function (Builder $q) use ($account): void {
$q->where('source_id', $account->id);
$q->orWhere('destination_id', $account->id);
}
diff --git a/app/Services/Internal/Destroy/BillDestroyService.php b/app/Services/Internal/Destroy/BillDestroyService.php
index 6b0f48b007..a1cd2ce5f5 100644
--- a/app/Services/Internal/Destroy/BillDestroyService.php
+++ b/app/Services/Internal/Destroy/BillDestroyService.php
@@ -30,9 +30,6 @@ use FireflyIII\Models\Bill;
*/
class BillDestroyService
{
- /**
- * @param Bill $bill
- */
public function destroy(Bill $bill): void
{
$bill->delete();
diff --git a/app/Services/Internal/Destroy/BudgetDestroyService.php b/app/Services/Internal/Destroy/BudgetDestroyService.php
index d9675f743a..51058e4491 100644
--- a/app/Services/Internal/Destroy/BudgetDestroyService.php
+++ b/app/Services/Internal/Destroy/BudgetDestroyService.php
@@ -23,19 +23,13 @@ declare(strict_types=1);
namespace FireflyIII\Services\Internal\Destroy;
-use DB;
use FireflyIII\Models\Budget;
/**
* Class BudgetDestroyService
- *
-
*/
class BudgetDestroyService
{
- /**
- * @param Budget $budget
- */
public function destroy(Budget $budget): void
{
$budget->delete();
@@ -46,10 +40,10 @@ class BudgetDestroyService
}
// also delete all relations between categories and transaction journals:
- DB::table('budget_transaction_journal')->where('budget_id', (int)$budget->id)->delete();
+ \DB::table('budget_transaction_journal')->where('budget_id', $budget->id)->delete();
// also delete all relations between categories and transactions:
- DB::table('budget_transaction')->where('budget_id', (int)$budget->id)->delete();
+ \DB::table('budget_transaction')->where('budget_id', $budget->id)->delete();
// also delete all budget limits
foreach ($budget->budgetlimits()->get() as $limit) {
diff --git a/app/Services/Internal/Destroy/CategoryDestroyService.php b/app/Services/Internal/Destroy/CategoryDestroyService.php
index 36c2f74ef4..5a3211acb5 100644
--- a/app/Services/Internal/Destroy/CategoryDestroyService.php
+++ b/app/Services/Internal/Destroy/CategoryDestroyService.php
@@ -23,30 +23,24 @@ declare(strict_types=1);
namespace FireflyIII\Services\Internal\Destroy;
-use DB;
use FireflyIII\Models\Category;
/**
* Class CategoryDestroyService
- *
-
*/
class CategoryDestroyService
{
- /**
- * @param Category $category
- */
public function destroy(Category $category): void
{
$category->delete();
// also delete all relations between categories and transaction journals:
- DB::table('category_transaction_journal')->where('category_id', (int)$category->id)->delete();
+ \DB::table('category_transaction_journal')->where('category_id', $category->id)->delete();
// also delete all relations between categories and transactions:
- DB::table('category_transaction')->where('category_id', (int)$category->id)->delete();
+ \DB::table('category_transaction')->where('category_id', $category->id)->delete();
// delete references to category from recurring transactions.
- DB::table('rt_meta')->where('name', 'category_id')->where('value', $category->id)->delete();
+ \DB::table('rt_meta')->where('name', 'category_id')->where('value', $category->id)->delete();
}
}
diff --git a/app/Services/Internal/Destroy/CurrencyDestroyService.php b/app/Services/Internal/Destroy/CurrencyDestroyService.php
index 4a2295d32a..7482740c7d 100644
--- a/app/Services/Internal/Destroy/CurrencyDestroyService.php
+++ b/app/Services/Internal/Destroy/CurrencyDestroyService.php
@@ -27,14 +27,9 @@ use FireflyIII\Models\TransactionCurrency;
/**
* Class CurrencyDestroyService
- *
-
*/
class CurrencyDestroyService
{
- /**
- * @param TransactionCurrency $currency
- */
public function destroy(TransactionCurrency $currency): void
{
$currency->delete();
diff --git a/app/Services/Internal/Destroy/JournalDestroyService.php b/app/Services/Internal/Destroy/JournalDestroyService.php
index 0c52c769bd..026d99e12d 100644
--- a/app/Services/Internal/Destroy/JournalDestroyService.php
+++ b/app/Services/Internal/Destroy/JournalDestroyService.php
@@ -23,35 +23,31 @@ declare(strict_types=1);
namespace FireflyIII\Services\Internal\Destroy;
-use DB;
use FireflyIII\Models\Attachment;
use FireflyIII\Models\Transaction;
use FireflyIII\Models\TransactionJournal;
use FireflyIII\Models\TransactionJournalLink;
use FireflyIII\Models\TransactionJournalMeta;
-use Illuminate\Support\Facades\Log;
/**
* Class JournalDestroyService
*/
class JournalDestroyService
{
- /**
- * @param TransactionJournal $journal
- */
public function destroy(TransactionJournal $journal): void
{
- Log::debug(sprintf('Now in %s', __METHOD__));
+ app('log')->debug(sprintf('Now in %s', __METHOD__));
+
/** @var Transaction $transaction */
foreach ($journal->transactions()->get() as $transaction) {
- Log::debug(sprintf('Will now delete transaction #%d', $transaction->id));
+ app('log')->debug(sprintf('Will now delete transaction #%d', $transaction->id));
$transaction->delete();
}
// also delete journal_meta entries.
/** @var TransactionJournalMeta $meta */
foreach ($journal->transactionJournalMeta()->get() as $meta) {
- Log::debug(sprintf('Will now delete meta-entry #%d', $meta->id));
+ app('log')->debug(sprintf('Will now delete meta-entry #%d', $meta->id));
$meta->delete();
}
@@ -62,16 +58,19 @@ class JournalDestroyService
}
// delete all from 'budget_transaction_journal'
- DB::table('budget_transaction_journal')
- ->where('transaction_journal_id', $journal->id)->delete();
+ \DB::table('budget_transaction_journal')
+ ->where('transaction_journal_id', $journal->id)->delete()
+ ;
// delete all from 'category_transaction_journal'
- DB::table('category_transaction_journal')
- ->where('transaction_journal_id', $journal->id)->delete();
+ \DB::table('category_transaction_journal')
+ ->where('transaction_journal_id', $journal->id)->delete()
+ ;
// delete all from 'tag_transaction_journal'
- DB::table('tag_transaction_journal')
- ->where('transaction_journal_id', $journal->id)->delete();
+ \DB::table('tag_transaction_journal')
+ ->where('transaction_journal_id', $journal->id)->delete()
+ ;
// delete all links:
TransactionJournalLink::where('source_id', $journal->id)->delete();
diff --git a/app/Services/Internal/Destroy/RecurrenceDestroyService.php b/app/Services/Internal/Destroy/RecurrenceDestroyService.php
index 8937b13815..73949f34cb 100644
--- a/app/Services/Internal/Destroy/RecurrenceDestroyService.php
+++ b/app/Services/Internal/Destroy/RecurrenceDestroyService.php
@@ -33,8 +33,6 @@ class RecurrenceDestroyService
{
/**
* Delete recurrence by ID
- *
- * @param int $recurrenceId
*/
public function destroyById(int $recurrenceId): void
{
@@ -47,14 +45,12 @@ class RecurrenceDestroyService
/**
* Delete recurrence.
- *
- * @param Recurrence $recurrence
- *
*/
public function destroy(Recurrence $recurrence): void
{
// delete all meta data
$recurrence->recurrenceMeta()->delete();
+
// delete all transactions.
/** @var RecurrenceTransaction $transaction */
foreach ($recurrence->recurrenceTransactions as $transaction) {
diff --git a/app/Services/Internal/Destroy/TransactionGroupDestroyService.php b/app/Services/Internal/Destroy/TransactionGroupDestroyService.php
index 6ef875d46b..2b5621cf4a 100644
--- a/app/Services/Internal/Destroy/TransactionGroupDestroyService.php
+++ b/app/Services/Internal/Destroy/TransactionGroupDestroyService.php
@@ -25,21 +25,16 @@ namespace FireflyIII\Services\Internal\Destroy;
use FireflyIII\Events\DestroyedTransactionGroup;
use FireflyIII\Models\TransactionGroup;
-use Illuminate\Support\Facades\Log;
/**
* Class TransactionGroupDestroyService
- *
-
*/
class TransactionGroupDestroyService
{
- /**
- * @param TransactionGroup $transactionGroup
- */
public function destroy(TransactionGroup $transactionGroup): void
{
- Log::debug(sprintf('Now in %s', __METHOD__));
+ app('log')->debug(sprintf('Now in %s', __METHOD__));
+
/** @var JournalDestroyService $service */
$service = app(JournalDestroyService::class);
foreach ($transactionGroup->transactionJournals as $journal) {
diff --git a/app/Services/Internal/Support/AccountServiceTrait.php b/app/Services/Internal/Support/AccountServiceTrait.php
index d7db07baab..2920bef1c2 100644
--- a/app/Services/Internal/Support/AccountServiceTrait.php
+++ b/app/Services/Internal/Support/AccountServiceTrait.php
@@ -38,23 +38,14 @@ use FireflyIII\Models\TransactionGroup;
use FireflyIII\Models\TransactionJournal;
use FireflyIII\Repositories\Account\AccountRepositoryInterface;
use FireflyIII\Services\Internal\Destroy\TransactionGroupDestroyService;
-use Illuminate\Support\Facades\Log;
-use JsonException;
-use Validator;
/**
* Trait AccountServiceTrait
- *
*/
trait AccountServiceTrait
{
protected AccountRepositoryInterface $accountRepository;
- /**
- * @param null|string $iban
- *
- * @return null|string
- */
public function filterIban(?string $iban): ?string
{
if (null === $iban) {
@@ -62,23 +53,18 @@ trait AccountServiceTrait
}
$data = ['iban' => $iban];
$rules = ['iban' => 'required|iban'];
- $validator = Validator::make($data, $rules);
+ $validator = \Validator::make($data, $rules);
if ($validator->fails()) {
- Log::info(sprintf('Detected invalid IBAN ("%s"). Return NULL instead.', $iban));
+ app('log')->info(sprintf('Detected invalid IBAN ("%s"). Return NULL instead.', $iban));
return null;
}
-
return app('steam')->filterSpaces($iban);
}
/**
* Returns true if the data in the array is submitted but empty.
- *
- * @param array $data
- *
- * @return bool
*/
public function isEmptyOBData(array $data): bool
{
@@ -102,25 +88,23 @@ trait AccountServiceTrait
/**
* Update metadata for account. Depends on type which fields are valid.
*
+ * @SuppressWarnings(PHPMD.NPathComplexity)
+ *
* TODO this method treats expense accounts and liabilities the same way (tries to save interest)
- *
- * @param Account $account
- * @param array $data
- *
*/
public function updateMetaData(Account $account, array $data): void
{
- $fields = $this->validFields;
- if ($account->accountType->type === AccountType::ASSET) {
+ $fields = $this->validFields;
+ if (AccountType::ASSET === $account->accountType->type) {
$fields = $this->validAssetFields;
}
// remove currency_id if necessary.
- $type = $account->accountType->type;
- $list = config('firefly.valid_currency_account_types');
+ $type = $account->accountType->type;
+ $list = config('firefly.valid_currency_account_types');
if (!in_array($type, $list, true)) {
$pos = array_search('currency_id', $fields, true);
- if ($pos !== false) {
+ if (false !== $pos) {
unset($fields[$pos]);
}
}
@@ -134,13 +118,14 @@ trait AccountServiceTrait
}
// only asset account may have a role:
- if ($account->accountType->type !== AccountType::ASSET) {
+ if (AccountType::ASSET !== $account->accountType->type) {
$data['account_role'] = '';
}
- if ($account->accountType->type === AccountType::ASSET && array_key_exists('account_role', $data) && 'ccAsset' === $data['account_role']) {
+ if (AccountType::ASSET === $account->accountType->type && 'ccAsset' === $data['account_role']) {
$fields = $this->validCCFields;
}
+
/** @var AccountMetaFactory $factory */
$factory = app(AccountMetaFactory::class);
foreach ($fields as $field) {
@@ -163,15 +148,9 @@ trait AccountServiceTrait
}
}
- /**
- * @param Account $account
- * @param string $note
- *
- * @return bool
- */
public function updateNote(Account $account, string $note): bool
{
- $dbNote = $account->notes()->first();
+ $dbNote = $account->notes()->first();
if ('' === $note) {
if (null !== $dbNote) {
$dbNote->delete();
@@ -191,10 +170,6 @@ trait AccountServiceTrait
/**
* Verify if array contains valid data to possibly store or update the opening balance.
- *
- * @param array $data
- *
- * @return bool
*/
public function validOBData(array $data): bool
{
@@ -204,28 +179,28 @@ trait AccountServiceTrait
}
if ('' !== $data['opening_balance'] && array_key_exists('opening_balance_date', $data) && '' !== $data['opening_balance_date']
&& $data['opening_balance_date'] instanceof Carbon) {
- Log::debug('Array has valid opening balance data.');
+ app('log')->debug('Array has valid opening balance data.');
return true;
}
- Log::debug('Array does not have valid opening balance data.');
+ app('log')->debug('Array does not have valid opening balance data.');
return false;
}
/**
- * @param Account $account
- * @param array $data
- *
- * @return TransactionGroup
* @throws FireflyException
- * @throws JsonException
+ * *
* @deprecated
*/
protected function createOBGroup(Account $account, array $data): TransactionGroup
{
- Log::debug('Now going to create an OB group.');
+ app('log')->debug('Now going to create an OB group.');
$language = app('preferences')->getForUser($account->user, 'language', 'en_US')->data;
+ if (is_array($language)) {
+ $language = 'en_US';
+ }
+ $language = (string)$language;
$sourceId = null;
$sourceName = null;
$destId = null;
@@ -234,29 +209,30 @@ trait AccountServiceTrait
// amount is positive.
if (1 === bccomp($amount, '0')) {
- Log::debug(sprintf('Amount is %s, which is positive. Source is a new IB account, destination is #%d', $amount, $account->id));
+ app('log')->debug(sprintf('Amount is %s, which is positive. Source is a new IB account, destination is #%d', $amount, $account->id));
$sourceName = trans('firefly.initial_balance_description', ['account' => $account->name], $language);
$destId = $account->id;
}
// amount is not positive
if (-1 === bccomp($amount, '0')) {
- Log::debug(sprintf('Amount is %s, which is negative. Destination is a new IB account, source is #%d', $amount, $account->id));
+ app('log')->debug(sprintf('Amount is %s, which is negative. Destination is a new IB account, source is #%d', $amount, $account->id));
$destName = trans('firefly.initial_balance_account', ['account' => $account->name], $language);
$sourceId = $account->id;
}
// amount is 0
if (0 === bccomp($amount, '0')) {
- Log::debug('Amount is zero, so will not make an OB group.');
+ app('log')->debug('Amount is zero, so will not make an OB group.');
+
throw new FireflyException('Amount for new opening balance was unexpectedly 0.');
}
// make amount positive, regardless:
- $amount = app('steam')->positive($amount);
+ $amount = app('steam')->positive($amount);
// get or grab currency:
- $currency = $this->accountRepository->getAccountCurrency($account);
+ $currency = $this->accountRepository->getAccountCurrency($account);
if (null === $currency) {
- $currency = app('default')->getDefaultCurrencyByUser($account->user);
+ $currency = app('amount')->getDefaultCurrencyByUserGroup($account->user->userGroup);
}
// submit to factory:
@@ -289,17 +265,18 @@ trait AccountServiceTrait
],
],
];
- Log::debug('Going for submission in createOBGroup', $submission);
+ app('log')->debug('Going for submission in createOBGroup', $submission);
/** @var TransactionGroupFactory $factory */
- $factory = app(TransactionGroupFactory::class);
+ $factory = app(TransactionGroupFactory::class);
$factory->setUser($account->user);
try {
$group = $factory->create($submission);
} catch (DuplicateTransactionException $e) {
- Log::error($e->getMessage());
- Log::error($e->getTraceAsString());
+ app('log')->error($e->getMessage());
+ app('log')->error($e->getTraceAsString());
+
throw new FireflyException($e->getMessage(), 0, $e);
}
@@ -308,16 +285,15 @@ trait AccountServiceTrait
/**
* Delete TransactionGroup with liability credit in it.
- *
- * @param Account $account
*/
protected function deleteCreditTransaction(Account $account): void
{
- Log::debug(sprintf('deleteCreditTransaction() for account #%d', $account->id));
+ app('log')->debug(sprintf('deleteCreditTransaction() for account #%d', $account->id));
$creditGroup = $this->getCreditTransaction($account);
if (null !== $creditGroup) {
- Log::debug('Credit journal found, delete journal.');
+ app('log')->debug('Credit journal found, delete journal.');
+
/** @var TransactionGroupDestroyService $service */
$service = app(TransactionGroupDestroyService::class);
$service->destroy($creditGroup);
@@ -326,31 +302,26 @@ trait AccountServiceTrait
/**
* Returns the credit transaction group, or NULL if it does not exist.
- *
- * @param Account $account
- *
- * @return TransactionGroup|null
*/
protected function getCreditTransaction(Account $account): ?TransactionGroup
{
- Log::debug(sprintf('Now at %s', __METHOD__));
+ app('log')->debug(sprintf('Now at %s', __METHOD__));
return $this->accountRepository->getCreditTransactionGroup($account);
}
/**
* Delete TransactionGroup with opening balance in it.
- *
- * @param Account $account
*/
protected function deleteOBGroup(Account $account): void
{
- Log::debug(sprintf('deleteOB() for account #%d', $account->id));
+ app('log')->debug(sprintf('deleteOB() for account #%d', $account->id));
$openingBalanceGroup = $this->getOBGroup($account);
// opening balance data? update it!
if (null !== $openingBalanceGroup) {
- Log::debug('Opening balance journal found, delete journal.');
+ app('log')->debug('Opening balance journal found, delete journal.');
+
/** @var TransactionGroupDestroyService $service */
$service = app(TransactionGroupDestroyService::class);
$service->destroy($openingBalanceGroup);
@@ -359,10 +330,6 @@ trait AccountServiceTrait
/**
* Returns the opening balance group, or NULL if it does not exist.
- *
- * @param Account $account
- *
- * @return TransactionGroup|null
*/
protected function getOBGroup(Account $account): ?TransactionGroup
{
@@ -370,24 +337,20 @@ trait AccountServiceTrait
}
/**
- * @param int $currencyId
- * @param string $currencyCode
- *
- * @return TransactionCurrency
* @throws FireflyException
- * @throws JsonException
*/
protected function getCurrency(int $currencyId, string $currencyCode): TransactionCurrency
{
// find currency, or use default currency instead.
/** @var TransactionCurrencyFactory $factory */
- $factory = app(TransactionCurrencyFactory::class);
- /** @var TransactionCurrency|null $currency */
- $currency = $factory->find($currencyId, $currencyCode);
+ $factory = app(TransactionCurrencyFactory::class);
+
+ /** @var null|TransactionCurrency $currency */
+ $currency = $factory->find($currencyId, $currencyCode);
if (null === $currency) {
// use default currency:
- $currency = app('amount')->getDefaultCurrencyByUser($this->user);
+ $currency = app('amount')->getDefaultCurrencyByUserGroup($this->user->userGroup);
}
$currency->enabled = true;
$currency->save();
@@ -398,27 +361,20 @@ trait AccountServiceTrait
/**
* Create the opposing "credit liability" transaction for credit liabilities.
*
- *
- * @param Account $account
- * @param string $direction
- * @param string $openingBalance
- * @param Carbon $openingBalanceDate
- *
- * @return TransactionGroup
* @throws FireflyException
- * @throws JsonException
*/
protected function updateCreditTransaction(Account $account, string $direction, string $openingBalance, Carbon $openingBalanceDate): TransactionGroup
{
- Log::debug(sprintf('Now in %s', __METHOD__));
+ app('log')->debug(sprintf('Now in %s', __METHOD__));
if (0 === bccomp($openingBalance, '0')) {
- Log::debug('Amount is zero, so will not update liability credit/debit group.');
+ app('log')->debug('Amount is zero, so will not update liability credit/debit group.');
+
throw new FireflyException('Amount for update liability credit/debit was unexpectedly 0.');
}
// if direction is "debit" (i owe this debt), amount is negative.
// which means the liability will have a negative balance which the user must fill.
- $openingBalance = app('steam')->negative($openingBalance);
+ $openingBalance = app('steam')->negative($openingBalance);
// if direction is "credit" (I am owed this debt), amount is positive.
// which means the liability will have a positive balance which is drained when its paid back into any asset.
@@ -427,21 +383,21 @@ trait AccountServiceTrait
}
// create if not exists:
- $clGroup = $this->getCreditTransaction($account);
+ $clGroup = $this->getCreditTransaction($account);
if (null === $clGroup) {
return $this->createCreditTransaction($account, $openingBalance, $openingBalanceDate);
}
// if exists, update:
- $currency = $this->accountRepository->getAccountCurrency($account);
+ $currency = $this->accountRepository->getAccountCurrency($account);
if (null === $currency) {
- $currency = app('default')->getDefaultCurrencyByUser($account->user);
+ $currency = app('amount')->getDefaultCurrencyByUserGroup($account->user->userGroup);
}
// simply grab the first journal and change it:
- $journal = $this->getObJournal($clGroup);
- $clTransaction = $this->getOBTransaction($journal, $account);
- $accountTransaction = $this->getNotOBTransaction($journal, $account);
- $journal->date = $openingBalanceDate;
+ $journal = $this->getObJournal($clGroup);
+ $clTransaction = $this->getOBTransaction($journal, $account);
+ $accountTransaction = $this->getNotOBTransaction($journal, $account);
+ $journal->date = $openingBalanceDate;
$journal->transactionCurrency()->associate($currency);
// account always gains money:
@@ -449,8 +405,8 @@ trait AccountServiceTrait
$accountTransaction->transaction_currency_id = $currency->id;
// CL account always loses money:
- $clTransaction->amount = app('steam')->negative($openingBalance);
- $clTransaction->transaction_currency_id = $currency->id;
+ $clTransaction->amount = app('steam')->negative($openingBalance);
+ $clTransaction->transaction_currency_id = $currency->id;
// save both
$accountTransaction->save();
$clTransaction->save();
@@ -461,24 +417,23 @@ trait AccountServiceTrait
}
/**
- * @param Account $account
- * @param string $openingBalance
- * @param Carbon $openingBalanceDate
- *
- * @return TransactionGroup
* @throws FireflyException
- * @throws JsonException
*/
protected function createCreditTransaction(Account $account, string $openingBalance, Carbon $openingBalanceDate): TransactionGroup
{
- Log::debug('Now going to create an createCreditTransaction.');
+ app('log')->debug('Now going to create an createCreditTransaction.');
if (0 === bccomp($openingBalance, '0')) {
- Log::debug('Amount is zero, so will not make an liability credit group.');
+ app('log')->debug('Amount is zero, so will not make an liability credit group.');
+
throw new FireflyException('Amount for new liability credit was unexpectedly 0.');
}
- $language = app('preferences')->getForUser($account->user, 'language', 'en_US')->data;
+ $language = app('preferences')->getForUser($account->user, 'language', 'en_US')->data;
+ if (is_array($language)) {
+ $language = 'en_US';
+ }
+ $language = (string)$language;
// set source and/or destination based on whether the amount is positive or negative.
// first, assume the amount is positive and go from there:
@@ -496,12 +451,12 @@ trait AccountServiceTrait
}
// amount must be positive for the transaction to work.
- $amount = app('steam')->positive($openingBalance);
+ $amount = app('steam')->positive($openingBalance);
// get or grab currency:
- $currency = $this->accountRepository->getAccountCurrency($account);
+ $currency = $this->accountRepository->getAccountCurrency($account);
if (null === $currency) {
- $currency = app('default')->getDefaultCurrencyByUser($account->user);
+ $currency = app('amount')->getDefaultCurrencyByUserGroup($account->user->userGroup);
}
// submit to factory:
@@ -534,17 +489,18 @@ trait AccountServiceTrait
],
],
];
- Log::debug('Going for submission in createCreditTransaction', $submission);
+ app('log')->debug('Going for submission in createCreditTransaction', $submission);
/** @var TransactionGroupFactory $factory */
- $factory = app(TransactionGroupFactory::class);
+ $factory = app(TransactionGroupFactory::class);
$factory->setUser($account->user);
try {
$group = $factory->create($submission);
} catch (DuplicateTransactionException $e) {
- Log::error($e->getMessage());
- Log::error($e->getTraceAsString());
+ app('log')->error($e->getMessage());
+ app('log')->error($e->getTraceAsString());
+
throw new FireflyException($e->getMessage(), 0, $e);
}
@@ -554,14 +510,11 @@ trait AccountServiceTrait
/**
* TODO refactor to "getfirstjournal"
*
- * @param TransactionGroup $group
- *
- * @return TransactionJournal
* @throws FireflyException
*/
private function getObJournal(TransactionGroup $group): TransactionJournal
{
- /** @var TransactionJournal $journal */
+ /** @var null|TransactionJournal $journal */
$journal = $group->transactionJournals()->first();
if (null === $journal) {
throw new FireflyException(sprintf('Group #%d has no OB journal', $group->id));
@@ -573,15 +526,11 @@ trait AccountServiceTrait
/**
* TODO Rename to getOpposingTransaction
*
- * @param TransactionJournal $journal
- * @param Account $account
- *
- * @return Transaction
* @throws FireflyException
*/
private function getOBTransaction(TransactionJournal $journal, Account $account): Transaction
{
- /** @var Transaction $transaction */
+ /** @var null|Transaction $transaction */
$transaction = $journal->transactions()->where('account_id', '!=', $account->id)->first();
if (null === $transaction) {
throw new FireflyException(sprintf('Could not get OB transaction for journal #%d', $journal->id));
@@ -591,15 +540,11 @@ trait AccountServiceTrait
}
/**
- * @param TransactionJournal $journal
- * @param Account $account
- *
- * @return Transaction
* @throws FireflyException
*/
private function getNotOBTransaction(TransactionJournal $journal, Account $account): Transaction
{
- /** @var Transaction $transaction */
+ /** @var null|Transaction $transaction */
$transaction = $journal->transactions()->where('account_id', $account->id)->first();
if (null === $transaction) {
throw new FireflyException(sprintf('Could not get non-OB transaction for journal #%d', $journal->id));
@@ -612,28 +557,22 @@ trait AccountServiceTrait
* Update or create the opening balance group.
* Since opening balance and date can still be empty strings, it may fail.
*
- * @param Account $account
- * @param string $openingBalance
- * @param Carbon $openingBalanceDate
- *
- * @return TransactionGroup
* @throws FireflyException
- * @throws JsonException
*/
protected function updateOBGroupV2(Account $account, string $openingBalance, Carbon $openingBalanceDate): TransactionGroup
{
- Log::debug(sprintf('Now in %s', __METHOD__));
+ app('log')->debug(sprintf('Now in %s', __METHOD__));
// create if not exists:
- $obGroup = $this->getOBGroup($account);
+ $obGroup = $this->getOBGroup($account);
if (null === $obGroup) {
return $this->createOBGroupV2($account, $openingBalance, $openingBalanceDate);
}
- Log::debug('Update OB group');
+ app('log')->debug('Update OB group');
// if exists, update:
- $currency = $this->accountRepository->getAccountCurrency($account);
+ $currency = $this->accountRepository->getAccountCurrency($account);
if (null === $currency) {
- $currency = app('default')->getDefaultCurrencyByUser($account->user);
+ $currency = app('amount')->getDefaultCurrencyByUserGroup($account->user->userGroup);
}
// simply grab the first journal and change it:
@@ -643,27 +582,26 @@ trait AccountServiceTrait
$journal->date = $openingBalanceDate;
$journal->transactionCurrency()->associate($currency);
-
// if amount is negative:
if (1 === bccomp('0', $openingBalance)) {
- Log::debug('Amount is negative.');
+ app('log')->debug('Amount is negative.');
// account transaction loses money:
$accountTransaction->amount = app('steam')->negative($openingBalance);
$accountTransaction->transaction_currency_id = $currency->id;
// OB account transaction gains money
- $obTransaction->amount = app('steam')->positive($openingBalance);
- $obTransaction->transaction_currency_id = $currency->id;
+ $obTransaction->amount = app('steam')->positive($openingBalance);
+ $obTransaction->transaction_currency_id = $currency->id;
}
if (-1 === bccomp('0', $openingBalance)) {
- Log::debug('Amount is positive.');
+ app('log')->debug('Amount is positive.');
// account gains money:
$accountTransaction->amount = app('steam')->positive($openingBalance);
$accountTransaction->transaction_currency_id = $currency->id;
// OB account loses money:
- $obTransaction->amount = app('steam')->negative($openingBalance);
- $obTransaction->transaction_currency_id = $currency->id;
+ $obTransaction->amount = app('steam')->negative($openingBalance);
+ $obTransaction->transaction_currency_id = $currency->id;
}
// save both
$accountTransaction->save();
@@ -675,18 +613,16 @@ trait AccountServiceTrait
}
/**
- * @param Account $account
- * @param string $openingBalance
- * @param Carbon $openingBalanceDate
- *
- * @return TransactionGroup
* @throws FireflyException
- * @throws JsonException
*/
protected function createOBGroupV2(Account $account, string $openingBalance, Carbon $openingBalanceDate): TransactionGroup
{
- Log::debug('Now going to create an OB group.');
+ app('log')->debug('Now going to create an OB group.');
$language = app('preferences')->getForUser($account->user, 'language', 'en_US')->data;
+ if (is_array($language)) {
+ $language = 'en_US';
+ }
+ $language = (string)$language;
$sourceId = null;
$sourceName = null;
$destId = null;
@@ -694,29 +630,30 @@ trait AccountServiceTrait
// amount is positive.
if (1 === bccomp($openingBalance, '0')) {
- Log::debug(sprintf('Amount is %s, which is positive. Source is a new IB account, destination is #%d', $openingBalance, $account->id));
+ app('log')->debug(sprintf('Amount is %s, which is positive. Source is a new IB account, destination is #%d', $openingBalance, $account->id));
$sourceName = trans('firefly.initial_balance_description', ['account' => $account->name], $language);
$destId = $account->id;
}
// amount is not positive
if (-1 === bccomp($openingBalance, '0')) {
- Log::debug(sprintf('Amount is %s, which is negative. Destination is a new IB account, source is #%d', $openingBalance, $account->id));
+ app('log')->debug(sprintf('Amount is %s, which is negative. Destination is a new IB account, source is #%d', $openingBalance, $account->id));
$destName = trans('firefly.initial_balance_account', ['account' => $account->name], $language);
$sourceId = $account->id;
}
// amount is 0
if (0 === bccomp($openingBalance, '0')) {
- Log::debug('Amount is zero, so will not make an OB group.');
+ app('log')->debug('Amount is zero, so will not make an OB group.');
+
throw new FireflyException('Amount for new opening balance was unexpectedly 0.');
}
// make amount positive, regardless:
- $amount = app('steam')->positive($openingBalance);
+ $amount = app('steam')->positive($openingBalance);
// get or grab currency:
- $currency = $this->accountRepository->getAccountCurrency($account);
+ $currency = $this->accountRepository->getAccountCurrency($account);
if (null === $currency) {
- $currency = app('default')->getDefaultCurrencyByUser($account->user);
+ $currency = app('amount')->getDefaultCurrencyByUserGroup($account->user->userGroup);
}
// submit to factory:
@@ -749,17 +686,18 @@ trait AccountServiceTrait
],
],
];
- Log::debug('Going for submission in createOBGroupV2', $submission);
+ app('log')->debug('Going for submission in createOBGroupV2', $submission);
/** @var TransactionGroupFactory $factory */
- $factory = app(TransactionGroupFactory::class);
+ $factory = app(TransactionGroupFactory::class);
$factory->setUser($account->user);
try {
$group = $factory->create($submission);
} catch (DuplicateTransactionException $e) {
- Log::error($e->getMessage());
- Log::error($e->getTraceAsString());
+ app('log')->error($e->getMessage());
+ app('log')->error($e->getTraceAsString());
+
throw new FireflyException($e->getMessage(), 0, $e);
}
diff --git a/app/Services/Internal/Support/BillServiceTrait.php b/app/Services/Internal/Support/BillServiceTrait.php
index a30385423b..7bace4e657 100644
--- a/app/Services/Internal/Support/BillServiceTrait.php
+++ b/app/Services/Internal/Support/BillServiceTrait.php
@@ -26,20 +26,12 @@ namespace FireflyIII\Services\Internal\Support;
use FireflyIII\Models\Bill;
use FireflyIII\Models\Note;
use FireflyIII\Models\RuleAction;
-use Illuminate\Support\Facades\Log;
/**
* Trait BillServiceTrait
- *
-
*/
trait BillServiceTrait
{
- /**
- * @param Bill $bill
- * @param string $oldName
- * @param string $newName
- */
public function updateBillActions(Bill $bill, string $oldName, string $newName): void
{
if ($oldName === $newName) {
@@ -47,23 +39,18 @@ trait BillServiceTrait
}
$ruleIds = $bill->user->rules()->get(['id'])->pluck('id')->toArray();
$set = RuleAction::whereIn('rule_id', $ruleIds)
- ->where('action_type', 'link_to_bill')
- ->where('action_value', $oldName)->get();
+ ->where('action_type', 'link_to_bill')
+ ->where('action_value', $oldName)->get()
+ ;
/** @var RuleAction $ruleAction */
foreach ($set as $ruleAction) {
- Log::debug(sprintf('Updated rule action #%d to search for new bill name "%s"', $ruleAction->id, $newName));
+ app('log')->debug(sprintf('Updated rule action #%d to search for new bill name "%s"', $ruleAction->id, $newName));
$ruleAction->action_value = $newName;
$ruleAction->save();
}
}
- /**
- * @param Bill $bill
- * @param string $note
- *
- * @return bool
- */
public function updateNote(Bill $bill, string $note): bool
{
if ('' === $note) {
@@ -74,7 +61,7 @@ trait BillServiceTrait
return true;
}
- $dbNote = $bill->notes()->first();
+ $dbNote = $bill->notes()->first();
if (null === $dbNote) {
$dbNote = new Note();
$dbNote->noteable()->associate($bill);
diff --git a/app/Services/Internal/Support/CreditRecalculateService.php b/app/Services/Internal/Support/CreditRecalculateService.php
index c221ab4131..1ca08e58f4 100644
--- a/app/Services/Internal/Support/CreditRecalculateService.php
+++ b/app/Services/Internal/Support/CreditRecalculateService.php
@@ -28,6 +28,7 @@ use FireflyIII\Exceptions\FireflyException;
use FireflyIII\Factory\AccountMetaFactory;
use FireflyIII\Models\Account;
use FireflyIII\Models\Transaction;
+use FireflyIII\Models\TransactionCurrency;
use FireflyIII\Models\TransactionGroup;
use FireflyIII\Models\TransactionJournal;
use FireflyIII\Models\TransactionType;
@@ -54,9 +55,6 @@ class CreditRecalculateService
$this->work = [];
}
- /**
- *
- */
public function recalculate(): void
{
if (true !== config('firefly.feature_flags.handle_debts')) {
@@ -75,9 +73,6 @@ class CreditRecalculateService
$this->processWork();
}
- /**
- *
- */
private function processGroup(): void
{
/** @var TransactionJournal $journal */
@@ -85,15 +80,13 @@ class CreditRecalculateService
try {
$this->findByJournal($journal);
} catch (FireflyException $e) {
- Log::error($e->getTraceAsString());
- Log::error(sprintf('Could not find work account for transaction group #%d.', $this->group->id));
+ app('log')->error($e->getTraceAsString());
+ app('log')->error(sprintf('Could not find work account for transaction group #%d.', $this->group->id));
}
}
}
/**
- * @param TransactionJournal $journal
- *
* @throws FireflyException
*/
private function findByJournal(TransactionJournal $journal): void
@@ -102,7 +95,7 @@ class CreditRecalculateService
$destination = $this->getDestinationAccount($journal);
// destination or source must be liability.
- $valid = config('firefly.valid_liabilities');
+ $valid = config('firefly.valid_liabilities');
if (in_array($destination->accountType->type, $valid, true)) {
$this->work[] = $destination;
}
@@ -112,9 +105,6 @@ class CreditRecalculateService
}
/**
- * @param TransactionJournal $journal
- *
- * @return Account
* @throws FireflyException
*/
private function getSourceAccount(TransactionJournal $journal): Account
@@ -123,19 +113,17 @@ class CreditRecalculateService
}
/**
- * @param TransactionJournal $journal
- * @param string $direction
- *
- * @return Account
* @throws FireflyException
*/
private function getAccountByDirection(TransactionJournal $journal, string $direction): Account
{
- /** @var Transaction $transaction */
- $transaction = $journal->transactions()->where('amount', $direction, '0')->first();
+ /** @var null|Transaction $transaction */
+ $transaction = $journal->transactions()->where('amount', $direction, '0')->first();
if (null === $transaction) {
throw new FireflyException(sprintf('Cannot find "%s"-transaction of journal #%d', $direction, $journal->id));
}
+
+ /** @var null|Account $foundAccount */
$foundAccount = $transaction->account;
if (null === $foundAccount) {
throw new FireflyException(sprintf('Cannot find "%s"-account of transaction #%d of journal #%d', $direction, $transaction->id, $journal->id));
@@ -145,9 +133,6 @@ class CreditRecalculateService
}
/**
- * @param TransactionJournal $journal
- *
- * @return Account
* @throws FireflyException
*/
private function getDestinationAccount(TransactionJournal $journal): Account
@@ -155,9 +140,6 @@ class CreditRecalculateService
return $this->getAccountByDirection($journal, '>');
}
- /**
- *
- */
private function processAccount(): void
{
$valid = config('firefly.valid_liabilities');
@@ -166,9 +148,6 @@ class CreditRecalculateService
}
}
- /**
- *
- */
private function processWork(): void
{
$this->repository = app(AccountRepositoryInterface::class);
@@ -177,12 +156,9 @@ class CreditRecalculateService
}
}
- /**
- * @param Account $account
- */
private function processWorkAccount(Account $account): void
{
- app('log')->debug(sprintf('Now processing account #%d ("%s")', $account->id, $account->name));
+ app('log')->debug(sprintf('Now processing account #%d ("%s"). All amounts with 2 decimals!', $account->id, $account->name));
// get opening balance (if present)
$this->repository->setUser($account->user);
$direction = (string)$this->repository->getMetaValue($account, 'liability_direction');
@@ -194,14 +170,12 @@ class CreditRecalculateService
$this->validateOpeningBalance($account, $openingBalance);
}
}
- $startOfDebt = $this->repository->getOpeningBalanceAmount($account) ?? '0';
- $leftOfDebt = app('steam')->positive($startOfDebt);
- $currency = $this->repository->getAccountCurrency($account);
- $decimals = (int)($currency?->decimal_places ?? 2);
- app('log')->debug(sprintf('Start of debt is "%s", so initial left of debt is "%s"', app('steam')->bcround($startOfDebt, $decimals), app('steam')->bcround($leftOfDebt, $decimals)));
+ $startOfDebt = $this->repository->getOpeningBalanceAmount($account) ?? '0';
+ $leftOfDebt = app('steam')->positive($startOfDebt);
+ app('log')->debug(sprintf('Start of debt is "%s", so initial left of debt is "%s"', app('steam')->bcround($startOfDebt, 2), app('steam')->bcround($leftOfDebt, 2)));
/** @var AccountMetaFactory $factory */
- $factory = app(AccountMetaFactory::class);
+ $factory = app(AccountMetaFactory::class);
// amount is positive or negative, doesn't matter.
$factory->crud($account, 'start_of_debt', $startOfDebt);
@@ -209,12 +183,14 @@ class CreditRecalculateService
app('log')->debug(sprintf('Debt direction is "%s"', $direction));
// now loop all transactions (except opening balance and credit thing)
- $transactions = $account->transactions()
- ->leftJoin('transaction_journals', 'transaction_journals.id', '=', 'transactions.transaction_journal_id')
- ->orderBy('transaction_journals.date', 'ASC')
- ->get(['transactions.*']);
- $total = $transactions->count();
+ $transactions = $account->transactions()
+ ->leftJoin('transaction_journals', 'transaction_journals.id', '=', 'transactions.transaction_journal_id')
+ ->orderBy('transaction_journals.date', 'ASC')
+ ->get(['transactions.*'])
+ ;
+ $total = $transactions->count();
app('log')->debug(sprintf('Found %d transaction(s) to process.', $total));
+
/** @var Transaction $transaction */
foreach ($transactions as $index => $transaction) {
app('log')->debug(sprintf('[%d/%d] Processing transaction.', $index + 1, $total));
@@ -226,19 +202,15 @@ class CreditRecalculateService
/**
* If account direction is "debit" ("I owe this amount") the opening balance must always be AWAY from the account:
- *
- * @param Account $account
- * @param TransactionJournal $openingBalance
- *
- * @return void
*/
- private function validateOpeningBalance(Account $account, TransactionJournal $openingBalance)
+ private function validateOpeningBalance(Account $account, TransactionJournal $openingBalance): void
{
/** @var Transaction $source */
$source = $openingBalance->transactions()->where('amount', '<', 0)->first();
+
/** @var Transaction $dest */
- $dest = $openingBalance->transactions()->where('amount', '>', 0)->first();
- if ((int)$source->account_id !== $account->id) {
+ $dest = $openingBalance->transactions()->where('amount', '>', 0)->first();
+ if ($source->account_id !== $account->id) {
app('log')->info(sprintf('Liability #%d has a reversed opening balance. Will fix this now.', $account->id));
app('log')->debug(sprintf('Source amount "%s" is now "%s"', $source->amount, app('steam')->positive($source->amount)));
app('log')->debug(sprintf('Destination amount "%s" is now "%s"', $dest->amount, app('steam')->negative($dest->amount)));
@@ -255,200 +227,236 @@ class CreditRecalculateService
}
$source->save();
$dest->save();
+
return;
}
app('log')->debug('Opening balance is valid');
}
/**
- * @param Account $account
- * @param string $direction
- * @param Transaction $transaction
- * @param string $leftOfDebt
+ * A complex and long method, but rarely used luckily.
*
- * @return string
+ * @SuppressWarnings(PHPMD.ExcessiveMethodLength)
+ * @SuppressWarnings(PHPMD.NPathComplexity)
+ * @SuppressWarnings(PHPMD.CyclomaticComplexity)
*/
private function processTransaction(Account $account, string $direction, Transaction $transaction, string $leftOfDebt): string
{
$journal = $transaction->transactionJournal;
$foreignCurrency = $transaction->foreignCurrency;
$accountCurrency = $this->repository->getAccountCurrency($account);
- $groupId = $journal->transaction_group_id;
- $decimals = (int)$accountCurrency->decimal_places;
$type = $journal->transactionType->type;
- /** @var Transaction $destTransaction */
- $destTransaction = $journal->transactions()->where('amount', '>', '0')->first();
- /** @var Transaction $sourceTransaction */
- $sourceTransaction = $journal->transactions()->where('amount', '<', '0')->first();
-
-
- app('log')->debug(sprintf('Left of debt is: %s', app('steam')->bcround($leftOfDebt, $decimals)));
+ app('log')->debug(sprintf('Left of debt is: %s', app('steam')->bcround($leftOfDebt, 2)));
if ('' === $direction) {
app('log')->warning('Direction is empty, so do nothing.');
+
return $leftOfDebt;
}
if (TransactionType::LIABILITY_CREDIT === $type || TransactionType::OPENING_BALANCE === $type) {
app('log')->warning(sprintf('Transaction type is "%s", so do nothing.', $type));
+
return $leftOfDebt;
}
+ Log::debug(sprintf('Liability direction is "%s"', $direction));
// amount to use depends on the currency:
- $usedAmount = $transaction->amount;
- app('log')->debug(sprintf('Amount of transaction is %s', app('steam')->bcround($usedAmount, $decimals)));
- if (null !== $foreignCurrency && $foreignCurrency->id === $accountCurrency->id) {
- $usedAmount = $transaction->foreign_amount;
- app('log')->debug(sprintf('Overruled by foreign amount. Amount of transaction is now %s', app('steam')->bcround($usedAmount, $decimals)));
- }
+ $usedAmount = $this->getAmountToUse($transaction, $accountCurrency, $foreignCurrency);
+ $isSameAccount = $account->id === $transaction->account_id;
+ $isDebit = 'debit' === $direction;
+ $isCredit = 'credit' === $direction;
- // Case 1
- // it's a withdrawal into this liability (from asset).
- // if it's a credit ("I am owed"), this increases the amount due,
- // because we're lending person X more money
- if (
- $type === TransactionType::WITHDRAWAL
- && (int)$account->id === (int)$transaction->account_id
- && 1 === bccomp($usedAmount, '0')
- && 'credit' === $direction
- ) {
+ if ($isSameAccount && $isCredit && $this->isWithdrawalIn($usedAmount, $type)) { // case 1
$usedAmount = app('steam')->positive($usedAmount);
$result = bcadd($leftOfDebt, $usedAmount);
- app('log')->debug(sprintf('Case 1 (withdrawal into credit liability): %s + %s = %s', app('steam')->bcround($leftOfDebt, $decimals), app('steam')->bcround($usedAmount, $decimals), app('steam')->bcround($result, $decimals)));
+ app('log')->debug(sprintf('Case 1 (withdrawal into credit liability): %s + %s = %s', app('steam')->bcround($leftOfDebt, 2), app('steam')->bcround($usedAmount, 2), app('steam')->bcround($result, 2)));
+
return $result;
}
- // Case 2
- // it's a withdrawal away from this liability (into expense account).
- // if it's a credit ("I am owed"), this decreases the amount due,
- // because we're sending money away from the loan (like loan forgiveness)
- if (
- $type === TransactionType::WITHDRAWAL
- && (int)$account->id === (int)$sourceTransaction->account_id
- && -1 === bccomp($usedAmount, '0')
- && 'credit' === $direction
- ) {
+ if ($isSameAccount && $isCredit && $this->isWithdrawalOut($usedAmount, $type)) { // case 2
$usedAmount = app('steam')->positive($usedAmount);
$result = bcsub($leftOfDebt, $usedAmount);
- app('log')->debug(sprintf('Case 2 (withdrawal away from liability): %s - %s = %s', app('steam')->bcround($leftOfDebt, $decimals), app('steam')->bcround($usedAmount, $decimals), app('steam')->bcround($result, $decimals)));
+ app('log')->debug(sprintf('Case 2 (withdrawal away from liability): %s - %s = %s', app('steam')->bcround($leftOfDebt, 2), app('steam')->bcround($usedAmount, 2), app('steam')->bcround($result, 2)));
+
return $result;
}
- // case 3
- // it's a deposit out of this liability (to asset).
- // if it's a credit ("I am owed") this decreases the amount due.
- // because the person is paying us back.
- if (
- $type === TransactionType::DEPOSIT
- && (int)$account->id === (int)$transaction->account_id
- && -1 === bccomp($usedAmount, '0')
- && 'credit' === $direction
- ) {
+ if ($isSameAccount && $isCredit && $this->isDepositOut($usedAmount, $type)) { // case 3
$usedAmount = app('steam')->positive($usedAmount);
$result = bcsub($leftOfDebt, $usedAmount);
- app('log')->debug(sprintf('Case 3 (deposit away from liability): %s - %s = %s', app('steam')->bcround($leftOfDebt, $decimals), app('steam')->bcround($usedAmount, $decimals), app('steam')->bcround($result, $decimals)));
+ app('log')->debug(sprintf('Case 3 (deposit away from liability): %s - %s = %s', app('steam')->bcround($leftOfDebt, 2), app('steam')->bcround($usedAmount, 2), app('steam')->bcround($result, 2)));
+
return $result;
}
- // case 4
- // it's a deposit into this liability (from revenue account).
- // if it's a credit ("I am owed") this increases the amount due.
- // because the person is having to pay more money.
- if (
- $type === TransactionType::DEPOSIT
- && (int)$account->id === (int)$destTransaction->account_id
- && 1 === bccomp($usedAmount, '0')
- && 'credit' === $direction
- ) {
+ if ($isSameAccount && $isCredit && $this->isDepositIn($usedAmount, $type)) { // case 4
$usedAmount = app('steam')->positive($usedAmount);
$result = bcadd($leftOfDebt, $usedAmount);
- app('log')->debug(sprintf('Case 4 (deposit into credit liability): %s + %s = %s', app('steam')->bcround($leftOfDebt, $decimals), app('steam')->bcround($usedAmount, $decimals), app('steam')->bcround($result, $decimals)));
+ app('log')->debug(sprintf('Case 4 (deposit into credit liability): %s + %s = %s', app('steam')->bcround($leftOfDebt, 2), app('steam')->bcround($usedAmount, 2), app('steam')->bcround($result, 2)));
+
return $result;
}
- // case 5: transfer into loan (from other loan).
- // if it's a credit ("I am owed") this increases the amount due,
- // because the person has to pay more back.
- if (
- $type === TransactionType::TRANSFER
- && (int)$account->id === (int)$destTransaction->account_id
- && 1 === bccomp($usedAmount, '0')
- && 'credit' === $direction
- ) {
+ if ($isSameAccount && $isCredit && $this->isTransferIn($usedAmount, $type)) { // case 5
$usedAmount = app('steam')->positive($usedAmount);
$result = bcadd($leftOfDebt, $usedAmount);
- app('log')->debug(sprintf('Case 5 (transfer into credit liability): %s + %s = %s', app('steam')->bcround($leftOfDebt, $decimals), app('steam')->bcround($usedAmount, $decimals), app('steam')->bcround($result, $decimals)));
+ app('log')->debug(sprintf('Case 5 (transfer into credit liability): %s + %s = %s', app('steam')->bcround($leftOfDebt, 2), app('steam')->bcround($usedAmount, 2), app('steam')->bcround($result, 2)));
+
return $result;
}
- // Case 6
- // it's a withdrawal into this liability (from asset).
- // if it's a debit ("I owe this amount"), this decreases the amount due,
- // because we're paying off the debt
- if (
- $type === TransactionType::WITHDRAWAL
- && (int)$account->id === (int)$transaction->account_id
- && 1 === bccomp($usedAmount, '0')
- && 'debit' === $direction
- ) {
+ if ($isSameAccount && $isDebit && $this->isWithdrawalIn($usedAmount, $type)) { // case 6
$usedAmount = app('steam')->positive($usedAmount);
$result = bcsub($leftOfDebt, $usedAmount);
- app('log')->debug(sprintf('Case 6 (withdrawal into debit liability): %s + %s = %s', app('steam')->bcround($leftOfDebt, $decimals), app('steam')->bcround($usedAmount, $decimals), app('steam')->bcround($result, $decimals)));
+ app('log')->debug(sprintf('Case 6 (withdrawal into debit liability): %s - %s = %s', app('steam')->bcround($leftOfDebt, 2), app('steam')->bcround($usedAmount, 2), app('steam')->bcround($result, 2)));
+
return $result;
}
- // case 7
- // it's a deposit out of this liability (to asset).
- // if it's a credit ("I am owed") this increases the amount due.
- // because we are borrowing more money.
- if (
- $type === TransactionType::DEPOSIT
- && (int)$account->id === (int)$transaction->account_id
- && -1 === bccomp($usedAmount, '0')
- && 'debit' === $direction
- ) {
+ if ($isSameAccount && $isDebit && $this->isDepositOut($usedAmount, $type)) { // case 7
$usedAmount = app('steam')->positive($usedAmount);
$result = bcadd($leftOfDebt, $usedAmount);
- app('log')->debug(sprintf('Case 7 (deposit away from liability): %s - %s = %s', app('steam')->bcround($leftOfDebt, $decimals), app('steam')->bcround($usedAmount, $decimals), app('steam')->bcround($result, $decimals)));
+ app('log')->debug(sprintf('Case 7 (deposit away from liability): %s + %s = %s', app('steam')->bcround($leftOfDebt, 2), app('steam')->bcround($usedAmount, 2), app('steam')->bcround($result, 2)));
+
return $result;
}
- // case 8
- // it's a withdrawal from this liability (to expense account).
- // if it's a debit ("I owe this amount") this increase the amount due.
- // because we are paying interest.
- if (
- $type === TransactionType::WITHDRAWAL
- && (int)$account->id === (int)$transaction->account_id
- && -1 === bccomp($usedAmount, '0')
- && 'debit' === $direction
- ) {
+ if ($isSameAccount && $isDebit && $this->isWithdrawalOut($usedAmount, $type)) { // case 8
$usedAmount = app('steam')->positive($usedAmount);
$result = bcadd($leftOfDebt, $usedAmount);
- app('log')->debug(sprintf('Case 8 (withdrawal away from liability): %s + %s = %s', app('steam')->bcround($leftOfDebt, $decimals), app('steam')->bcround($usedAmount, $decimals), app('steam')->bcround($result, $decimals)));
+ app('log')->debug(sprintf('Case 8 (withdrawal away from liability): %s + %s = %s', app('steam')->bcround($leftOfDebt, 2), app('steam')->bcround($usedAmount, 2), app('steam')->bcround($result, 2)));
+
return $result;
}
+ if ($isSameAccount && $isDebit && $this->isTransferIn($usedAmount, $type)) { // case 9
+ $usedAmount = app('steam')->positive($usedAmount);
+ $result = bcadd($leftOfDebt, $usedAmount);
+ app('log')->debug(sprintf('Case 9 (transfer into debit liability, means you owe more): %s + %s = %s', app('steam')->bcround($leftOfDebt, 2), app('steam')->bcround($usedAmount, 2), app('steam')->bcround($result, 2)));
+
+ return $result;
+ }
+ if ($isSameAccount && $isDebit && $this->isTransferOut($usedAmount, $type)) { // case 10
+ $usedAmount = app('steam')->positive($usedAmount);
+ $result = bcsub($leftOfDebt, $usedAmount);
+ app('log')->debug(sprintf('Case 5 (transfer out of debit liability, means you owe less): %s - %s = %s', app('steam')->bcround($leftOfDebt, 2), app('steam')->bcround($usedAmount, 2), app('steam')->bcround($result, 2)));
+
+ return $result;
+ }
// in any other case, remove amount from left of debt.
if (in_array($type, [TransactionType::WITHDRAWAL, TransactionType::DEPOSIT, TransactionType::TRANSFER], true)) {
$usedAmount = app('steam')->negative($usedAmount);
$result = bcadd($leftOfDebt, $usedAmount);
- app('log')->debug(sprintf('Case X (all other cases): %s + %s = %s', app('steam')->bcround($leftOfDebt, $decimals), app('steam')->bcround($usedAmount, $decimals), app('steam')->bcround($result, $decimals)));
+ app('log')->debug(sprintf('Case X (all other cases): %s + %s = %s', app('steam')->bcround($leftOfDebt, 2), app('steam')->bcround($usedAmount, 2), app('steam')->bcround($result, 2)));
+
return $result;
}
- Log::warning(sprintf('[-1] Catch-all, should not happen. Left of debt = %s', app('steam')->bcround($leftOfDebt, $decimals)));
+ app('log')->warning(sprintf('[-1] Catch-all, should not happen. Left of debt = %s', app('steam')->bcround($leftOfDebt, 2)));
return $leftOfDebt;
}
+ private function getAmountToUse(Transaction $transaction, TransactionCurrency $accountCurrency, ?TransactionCurrency $foreignCurrency): string
+ {
+ $usedAmount = $transaction->amount;
+ app('log')->debug(sprintf('Amount of transaction is %s', app('steam')->bcround($usedAmount, 2)));
+ if (null !== $foreignCurrency && $foreignCurrency->id === $accountCurrency->id) {
+ $usedAmount = $transaction->foreign_amount;
+ app('log')->debug(sprintf('Overruled by foreign amount. Amount of transaction is now %s', app('steam')->bcround($usedAmount, 2)));
+ }
+
+ return $usedAmount;
+ }
+
/**
- * @param Account|null $account
+ * It's a withdrawal into this liability (from asset).
+ *
+ * Case 1 = credit
+ * if it's a credit ("I am owed"), this increases the amount due,
+ * because we're lending person X more money
+ *
+ * Case 6 = debit
+ * if it's a debit ("I owe this amount"), this decreases the amount due,
+ * because we're paying off the debt
*/
+ private function isWithdrawalIn(string $amount, string $transactionType): bool
+ {
+ return TransactionType::WITHDRAWAL === $transactionType && 1 === bccomp($amount, '0');
+ }
+
+ /**
+ * it's a withdrawal away from this liability (into expense account).
+ *
+ * Case 2
+ * if it's a credit ("I am owed"), this decreases the amount due,
+ * because we're sending money away from the loan (like loan forgiveness)
+ *
+ * Case 8
+ * if it's a debit ("I owe this amount") this increase the amount due.
+ * because we are paying interest.
+ */
+ private function isWithdrawalOut(string $amount, string $transactionType): bool
+ {
+ return TransactionType::WITHDRAWAL === $transactionType && -1 === bccomp($amount, '0');
+ }
+
+ /**
+ * it's a deposit out of this liability (to asset).
+ *
+ * case 3
+ * if it's a credit ("I am owed") this decreases the amount due.
+ * because the person is paying us back.
+ *
+ * case 7
+ * if it's a debit ("I owe") this increases the amount due.
+ * because we are borrowing more money.
+ */
+ private function isDepositOut(string $amount, string $transactionType): bool
+ {
+ return TransactionType::DEPOSIT === $transactionType && -1 === bccomp($amount, '0');
+ }
+
+ /**
+ * case 4
+ * it's a deposit into this liability (from revenue account).
+ * if it's a credit ("I am owed") this increases the amount due.
+ * because the person is having to pay more money.
+ */
+ private function isDepositIn(string $amount, string $transactionType): bool
+ {
+ return TransactionType::DEPOSIT === $transactionType && 1 === bccomp($amount, '0');
+ }
+
+ /**
+ * case 5: transfer into loan (from other loan).
+ * if it's a credit ("I am owed") this increases the amount due,
+ * because the person has to pay more back.
+ *
+ * case 8: transfer into loan (from other loan).
+ * if it's a debit ("I owe") this decreases the amount due.
+ * because the person has to pay more back.
+ */
+ private function isTransferIn(string $amount, string $transactionType): bool
+ {
+ return TransactionType::TRANSFER === $transactionType && 1 === bccomp($amount, '0');
+ }
+
+ /**
+ * it's a transfer out of loan (from other loan)
+ *
+ * case 9
+ * if it's a debit ("I owe") this decreases the amount due.
+ * because we remove money from the amount left to owe
+ */
+ private function isTransferOut(string $amount, string $transactionType): bool
+ {
+ return TransactionType::TRANSFER === $transactionType && -1 === bccomp($amount, '0');
+ }
+
public function setAccount(?Account $account): void
{
$this->account = $account;
}
- /**
- * @param TransactionGroup $group
- */
public function setGroup(TransactionGroup $group): void
{
$this->group = $group;
diff --git a/app/Services/Internal/Support/JournalServiceTrait.php b/app/Services/Internal/Support/JournalServiceTrait.php
index f82bfd83db..b6f716ece5 100644
--- a/app/Services/Internal/Support/JournalServiceTrait.php
+++ b/app/Services/Internal/Support/JournalServiceTrait.php
@@ -35,11 +35,9 @@ use FireflyIII\Repositories\Account\AccountRepositoryInterface;
use FireflyIII\Repositories\Budget\BudgetRepositoryInterface;
use FireflyIII\Repositories\Category\CategoryRepositoryInterface;
use FireflyIII\Support\NullArrayObject;
-use Illuminate\Support\Facades\Log;
/**
* Trait JournalServiceTrait
- *
*/
trait JournalServiceTrait
{
@@ -49,17 +47,12 @@ trait JournalServiceTrait
private TagFactory $tagFactory;
/**
- * @param string $transactionType
- * @param string $direction
- * @param array $data
- *
- * @return Account|null
* @throws FireflyException
*/
protected function getAccount(string $transactionType, string $direction, array $data): ?Account
{
// some debug logging:
- Log::debug(sprintf('Now in getAccount(%s)', $direction), $data);
+ app('log')->debug(sprintf('Now in getAccount(%s)', $direction), $data);
// expected type of source account, in order of preference
/** @var array $array */
@@ -68,33 +61,32 @@ trait JournalServiceTrait
unset($array);
// and now try to find it, based on the type of transaction.
- $message = 'Transaction = %s, %s account should be in: %s. Direction is %s.';
- Log::debug(sprintf($message, $transactionType, $direction, implode(', ', $expectedTypes[$transactionType] ?? ['UNKNOWN']), $direction));
+ $message = 'Transaction = %s, %s account should be in: %s. Direction is %s.';
+ app('log')->debug(sprintf($message, $transactionType, $direction, implode(', ', $expectedTypes[$transactionType] ?? ['UNKNOWN']), $direction));
- $result = $this->findAccountById($data, $expectedTypes[$transactionType]);
- $result = $this->findAccountByIban($result, $data, $expectedTypes[$transactionType]);
- $ibanResult = $result;
- $result = $this->findAccountByNumber($result, $data, $expectedTypes[$transactionType]);
- $numberResult = $result;
- $result = $this->findAccountByName($result, $data, $expectedTypes[$transactionType]);
- $nameResult = $result;
+ $result = $this->findAccountById($data, $expectedTypes[$transactionType]);
+ $result = $this->findAccountByIban($result, $data, $expectedTypes[$transactionType]);
+ $ibanResult = $result;
+ $result = $this->findAccountByNumber($result, $data, $expectedTypes[$transactionType]);
+ $numberResult = $result;
+ $result = $this->findAccountByName($result, $data, $expectedTypes[$transactionType]);
+ $nameResult = $result;
// if $result (find by name) is NULL, but IBAN is set, any result of the search by NAME can't overrule
// this account. In such a case, the name search must be retried with a new name.
if (null !== $nameResult && null === $numberResult && null === $ibanResult && '' !== (string)$data['iban'] && '' !== (string)$nameResult->iban) {
$data['name'] = sprintf('%s (%s)', $data['name'], $data['iban']);
- Log::debug(sprintf('Search again using the new name, "%s".', $data['name']));
- $result = $this->findAccountByName(null, $data, $expectedTypes[$transactionType]);
+ app('log')->debug(sprintf('Search again using the new name, "%s".', $data['name']));
+ $result = $this->findAccountByName(null, $data, $expectedTypes[$transactionType]);
}
// the account that Firefly III creates must be "creatable", aka select the one we can create from the list just in case
$creatableType = $this->getCreatableType($expectedTypes[$transactionType]);
-
// if the result is NULL but the ID is set, an account could exist of the wrong type.
// that data can be used to create a new account of the right type.
if (null === $result && null !== $data['id'] && null !== $creatableType) {
- Log::debug(sprintf('Account #%d may exist and be of the wrong type, use data to create one of the right type.', $data['id']));
+ app('log')->debug(sprintf('Account #%d may exist and be of the wrong type, use data to create one of the right type.', $data['id']));
$temp = $this->findAccountById(['id' => $data['id']], []);
if (null !== $temp) {
$tempData = [
@@ -107,123 +99,108 @@ trait JournalServiceTrait
}
}
if (null === $result && null !== $creatableType) {
- Log::debug('If nothing is found, create it.');
+ app('log')->debug('If nothing is found, create it.');
$result = $this->createAccount($result, $data, $creatableType);
}
if (null === $result) {
- Log::debug('If cant be created, return cash account.');
+ app('log')->debug('If cant be created, return cash account.');
$result = $this->getCashAccount($result, $data, $expectedTypes[$transactionType]);
}
+
return $result;
}
- /**
- * @param array $data
- * @param array $types
- *
- * @return Account|null
- */
private function findAccountById(array $data, array $types): ?Account
{
// first attempt, find by ID.
if (null !== $data['id']) {
$search = $this->accountRepository->find((int)$data['id']);
if (null !== $search && in_array($search->accountType->type, $types, true)) {
- Log::debug(
+ app('log')->debug(
sprintf('Found "account_id" object: #%d, "%s" of type %s (1)', $search->id, $search->name, $search->accountType->type)
);
+
return $search;
}
if (null !== $search && 0 === count($types)) {
- Log::debug(
+ app('log')->debug(
sprintf('Found "account_id" object: #%d, "%s" of type %s (2)', $search->id, $search->name, $search->accountType->type)
);
+
return $search;
}
}
- Log::debug(sprintf('Found no account by ID #%d of types', $data['id']), $types);
+ app('log')->debug(sprintf('Found no account by ID #%d of types', $data['id']), $types);
+
return null;
}
- /**
- * @param Account|null $account
- * @param array $data
- * @param array $types
- *
- * @return Account|null
- */
private function findAccountByIban(?Account $account, array $data, array $types): ?Account
{
if (null !== $account) {
- Log::debug(sprintf('Already have account #%d ("%s"), return that.', $account->id, $account->name));
+ app('log')->debug(sprintf('Already have account #%d ("%s"), return that.', $account->id, $account->name));
+
return $account;
}
if (null === $data['iban'] || '' === $data['iban']) {
- Log::debug('IBAN is empty, will not search for IBAN.');
+ app('log')->debug('IBAN is empty, will not search for IBAN.');
+
return null;
}
// find by preferred type.
$source = $this->accountRepository->findByIbanNull($data['iban'], [$types[0]]);
// or any expected type.
- $source = $source ?? $this->accountRepository->findByIbanNull($data['iban'], $types);
+ $source ??= $this->accountRepository->findByIbanNull($data['iban'], $types);
if (null !== $source) {
- Log::debug(sprintf('Found "account_iban" object: #%d, %s', $source->id, $source->name));
+ app('log')->debug(sprintf('Found "account_iban" object: #%d, %s', $source->id, $source->name));
return $source;
}
- Log::debug(sprintf('Found no account with IBAN "%s" of expected types', $data['iban']), $types);
+ app('log')->debug(sprintf('Found no account with IBAN "%s" of expected types', $data['iban']), $types);
+
return null;
}
- /**
- * @param Account|null $account
- * @param array $data
- * @param array $types
- *
- * @return Account|null
- */
private function findAccountByNumber(?Account $account, array $data, array $types): ?Account
{
if (null !== $account) {
- Log::debug(sprintf('Already have account #%d ("%s"), return that.', $account->id, $account->name));
+ app('log')->debug(sprintf('Already have account #%d ("%s"), return that.', $account->id, $account->name));
+
return $account;
}
if (null === $data['number'] || '' === $data['number']) {
- Log::debug('Account number is empty, will not search for account number.');
+ app('log')->debug('Account number is empty, will not search for account number.');
+
return null;
}
// find by preferred type.
$source = $this->accountRepository->findByAccountNumber((string)$data['number'], [$types[0]]);
// or any expected type.
- $source = $source ?? $this->accountRepository->findByAccountNumber((string)$data['number'], $types);
+ $source ??= $this->accountRepository->findByAccountNumber((string)$data['number'], $types);
if (null !== $source) {
- Log::debug(sprintf('Found account: #%d, %s', $source->id, $source->name));
+ app('log')->debug(sprintf('Found account: #%d, %s', $source->id, $source->name));
return $source;
}
- Log::debug(sprintf('Found no account with account number "%s" of expected types', $data['number']), $types);
+ app('log')->debug(sprintf('Found no account with account number "%s" of expected types', $data['number']), $types);
+
return null;
}
- /**
- * @param Account|null $account
- * @param array $data
- * @param array $types
- *
- * @return Account|null
- */
private function findAccountByName(?Account $account, array $data, array $types): ?Account
{
if (null !== $account) {
- Log::debug(sprintf('Already have account #%d ("%s"), return that.', $account->id, $account->name));
+ app('log')->debug(sprintf('Already have account #%d ("%s"), return that.', $account->id, $account->name));
+
return $account;
}
if (null === $data['name'] || '' === $data['name']) {
- Log::debug('Account name is empty, will not search for account name.');
+ app('log')->debug('Account name is empty, will not search for account name.');
+
return null;
}
@@ -231,50 +208,44 @@ trait JournalServiceTrait
$source = $this->accountRepository->findByName($data['name'], [$types[0]]);
// or any expected type.
- $source = $source ?? $this->accountRepository->findByName($data['name'], $types);
+ $source ??= $this->accountRepository->findByName($data['name'], $types);
if (null !== $source) {
- Log::debug(sprintf('Found "account_name" object: #%d, %s', $source->id, $source->name));
+ app('log')->debug(sprintf('Found "account_name" object: #%d, %s', $source->id, $source->name));
return $source;
}
- Log::debug(sprintf('Found no account with account name "%s" of expected types', $data['name']), $types);
+ app('log')->debug(sprintf('Found no account with account name "%s" of expected types', $data['name']), $types);
+
return null;
}
- /**
- * @param array $types
- *
- * @return null|string
- */
private function getCreatableType(array $types): ?string
{
$result = null;
$list = config('firefly.dynamic_creation_allowed');
+
/** @var string $type */
foreach ($types as $type) {
if (true === in_array($type, $list, true)) {
$result = $type;
+
break;
}
}
+
return $result;
}
/**
- * @param Account|null $account
- * @param array $data
- * @param string $preferredType
- *
- * @return Account|null
* @throws FireflyException
*/
private function createAccount(?Account $account, array $data, string $preferredType): ?Account
{
- Log::debug('Now in createAccount()', $data);
+ app('log')->debug('Now in createAccount()', $data);
// return new account.
if (null !== $account) {
- Log::debug(
+ app('log')->debug(
sprintf(
'Was given %s account #%d ("%s") so will simply return that.',
$account->accountType->type,
@@ -290,20 +261,21 @@ trait JournalServiceTrait
}
// fix name of account if only IBAN is given:
if ('' === (string)$data['name'] && '' !== (string)$data['iban']) {
- Log::debug(sprintf('Account name is now IBAN ("%s")', $data['iban']));
+ app('log')->debug(sprintf('Account name is now IBAN ("%s")', $data['iban']));
$data['name'] = $data['iban'];
}
// fix name of account if only number is given:
if ('' === (string)$data['name'] && '' !== (string)$data['number']) {
- Log::debug(sprintf('Account name is now account number ("%s")', $data['number']));
+ app('log')->debug(sprintf('Account name is now account number ("%s")', $data['number']));
$data['name'] = $data['number'];
}
// if name is still NULL, return NULL.
if ('' === (string)$data['name']) {
- Log::debug('Account name is still NULL, return NULL.');
+ app('log')->debug('Account name is still NULL, return NULL.');
+
return null;
}
- //$data['name'] = $data['name'] ?? '(no name)';
+ // $data['name'] = $data['name'] ?? '(no name)';
$account = $this->accountRepository->store(
[
@@ -334,13 +306,6 @@ trait JournalServiceTrait
return $account;
}
- /**
- * @param Account|null $account
- * @param array $data
- * @param array $types
- *
- * @return Account|null
- */
private function getCashAccount(?Account $account, array $data, array $types): ?Account
{
// return cash account.
@@ -348,14 +313,12 @@ trait JournalServiceTrait
&& in_array(AccountType::CASH, $types, true)) {
$account = $this->accountRepository->getCashAccount();
}
- Log::debug('Cannot return cash account, return input instead.');
+ app('log')->debug('Cannot return cash account, return input instead.');
+
return $account;
}
/**
- * @param string $amount
- *
- * @return string
* @throws FireflyException
*/
protected function getAmount(string $amount): string
@@ -363,7 +326,7 @@ trait JournalServiceTrait
if ('' === $amount) {
throw new FireflyException(sprintf('The amount cannot be an empty string: "%s"', $amount));
}
- Log::debug(sprintf('Now in getAmount("%s")', $amount));
+ app('log')->debug(sprintf('Now in getAmount("%s")', $amount));
if (0 === bccomp('0', $amount)) {
throw new FireflyException(sprintf('The amount seems to be zero: "%s"', $amount));
}
@@ -371,39 +334,28 @@ trait JournalServiceTrait
return $amount;
}
- /**
- * @param string|null $amount
- *
- * @return string|null
- */
protected function getForeignAmount(?string $amount): ?string
{
if (null === $amount) {
- Log::debug('No foreign amount info in array. Return NULL');
+ app('log')->debug('No foreign amount info in array. Return NULL');
return null;
}
if ('' === $amount) {
- Log::debug('Foreign amount is empty string, return NULL.');
+ app('log')->debug('Foreign amount is empty string, return NULL.');
return null;
}
if (0 === bccomp('0', $amount)) {
- Log::debug('Foreign amount is 0.0, return NULL.');
+ app('log')->debug('Foreign amount is 0.0, return NULL.');
return null;
}
- Log::debug(sprintf('Foreign amount is %s', $amount));
+ app('log')->debug(sprintf('Foreign amount is %s', $amount));
return $amount;
}
- /**
- * @param TransactionJournal $journal
- * @param NullArrayObject $data
- *
-
- */
protected function storeBudget(TransactionJournal $journal, NullArrayObject $data): void
{
if (TransactionType::WITHDRAWAL !== $journal->transactionType->type) {
@@ -413,7 +365,7 @@ trait JournalServiceTrait
}
$budget = $this->budgetRepository->findBudget($data['budget_id'], $data['budget_name']);
if (null !== $budget) {
- Log::debug(sprintf('Link budget #%d to journal #%d', $budget->id, $journal->id));
+ app('log')->debug(sprintf('Link budget #%d to journal #%d', $budget->id, $journal->id));
$journal->budgets()->sync([$budget->id]);
return;
@@ -422,17 +374,11 @@ trait JournalServiceTrait
$journal->budgets()->sync([]);
}
- /**
- * @param TransactionJournal $journal
- * @param NullArrayObject $data
- *
-
- */
protected function storeCategory(TransactionJournal $journal, NullArrayObject $data): void
{
$category = $this->categoryRepository->findCategory($data['category_id'], $data['category_name']);
if (null !== $category) {
- Log::debug(sprintf('Link category #%d to journal #%d', $category->id, $journal->id));
+ app('log')->debug(sprintf('Link category #%d to journal #%d', $category->id, $journal->id));
$journal->categories()->sync([$category->id]);
return;
@@ -441,12 +387,6 @@ trait JournalServiceTrait
$journal->categories()->sync([]);
}
- /**
- * @param TransactionJournal $journal
- * @param string|null $notes
- *
-
- */
protected function storeNotes(TransactionJournal $journal, ?string $notes): void
{
$notes = (string)$notes;
@@ -458,48 +398,41 @@ trait JournalServiceTrait
}
$note->text = $notes;
$note->save();
- Log::debug(sprintf('Stored notes for journal #%d', $journal->id));
+ app('log')->debug(sprintf('Stored notes for journal #%d', $journal->id));
return;
}
- if ('' === $notes && null !== $note) {
- // try to delete existing notes.
- $note->delete();
- }
+ // try to delete existing notes.
+ $note?->delete();
}
/**
* Link tags to journal.
- *
- * @param TransactionJournal $journal
- * @param array|null $tags
- *
-
*/
protected function storeTags(TransactionJournal $journal, ?array $tags): void
{
- Log::debug('Now in storeTags()', $tags ?? []);
+ app('log')->debug('Now in storeTags()', $tags ?? []);
$this->tagFactory->setUser($journal->user);
$set = [];
if (!is_array($tags)) {
- Log::debug('Tags is not an array, break.');
+ app('log')->debug('Tags is not an array, break.');
return;
}
- Log::debug('Start of loop.');
+ app('log')->debug('Start of loop.');
foreach ($tags as $string) {
$string = (string)$string;
- Log::debug(sprintf('Now at tag "%s"', $string));
+ app('log')->debug(sprintf('Now at tag "%s"', $string));
if ('' !== $string) {
$tag = $this->tagFactory->findOrCreate($string);
if (null !== $tag) {
- $set[] = (int)$tag->id;
+ $set[] = $tag->id;
}
}
}
$set = array_unique($set);
- Log::debug('End of loop.');
- Log::debug(sprintf('Total nr. of tags: %d', count($tags)), $tags);
+ app('log')->debug('End of loop.');
+ app('log')->debug(sprintf('Total nr. of tags: %d', count($tags)), $tags);
$journal->tags()->sync($set);
}
}
diff --git a/app/Services/Internal/Support/LocationServiceTrait.php b/app/Services/Internal/Support/LocationServiceTrait.php
index c2e1766e68..38b63f963d 100644
--- a/app/Services/Internal/Support/LocationServiceTrait.php
+++ b/app/Services/Internal/Support/LocationServiceTrait.php
@@ -32,15 +32,9 @@ use Illuminate\Database\Eloquent\Model;
*/
trait LocationServiceTrait
{
- /**
- * @param Model $model
- * @param array $data
- *
- * @return Location|null
- */
protected function storeNewLocation(Model $model, array $data): ?Location
{
- $data['store_location'] = $data['store_location'] ?? false;
+ $data['store_location'] ??= false;
if ($data['store_location']) {
$location = new Location();
$location->latitude = $data['latitude'] ?? config('firefly.default_location.latitude');
diff --git a/app/Services/Internal/Support/RecurringTransactionTrait.php b/app/Services/Internal/Support/RecurringTransactionTrait.php
index 324764f1b4..443448e330 100644
--- a/app/Services/Internal/Support/RecurringTransactionTrait.php
+++ b/app/Services/Internal/Support/RecurringTransactionTrait.php
@@ -40,21 +40,12 @@ use FireflyIII\Models\RecurrenceTransaction;
use FireflyIII\Models\RecurrenceTransactionMeta;
use FireflyIII\Repositories\Account\AccountRepositoryInterface;
use FireflyIII\Validation\AccountValidator;
-use Illuminate\Support\Facades\Log;
-use JsonException;
/**
* Trait RecurringTransactionTrait
- *
*/
trait RecurringTransactionTrait
{
- /**
- * @param Recurrence $recurrence
- * @param string $note
- *
- * @return bool
- */
public function updateNote(Recurrence $recurrence, string $note): bool
{
if ('' === $note) {
@@ -65,7 +56,7 @@ trait RecurringTransactionTrait
return true;
}
- $dbNote = $recurrence->notes()->first();
+ $dbNote = $recurrence->notes()->first();
if (null === $dbNote) {
$dbNote = new Note();
$dbNote->noteable()->associate($recurrence);
@@ -76,10 +67,6 @@ trait RecurringTransactionTrait
return true;
}
- /**
- * @param Recurrence $recurrence
- * @param array $repetitions
- */
protected function createRepetitions(Recurrence $recurrence, array $repetitions): void
{
/** @var array $array */
@@ -99,37 +86,35 @@ trait RecurringTransactionTrait
/**
* Store transactions of a recurring transactions. It's complex but readable.
*
- * @param Recurrence $recurrence
- * @param array $transactions
- *
* @throws FireflyException
- * @throws JsonException
+ *
+ * @SuppressWarnings(PHPMD.NPathComplexity)
*/
protected function createTransactions(Recurrence $recurrence, array $transactions): void
{
- Log::debug('Now in createTransactions()');
+ app('log')->debug('Now in createTransactions()');
foreach ($transactions as $index => $array) {
- Log::debug(sprintf('Now at transaction #%d', $index));
- $sourceTypes = config(sprintf('firefly.expected_source_types.source.%s', $recurrence->transactionType->type));
- $destTypes = config(sprintf('firefly.expected_source_types.destination.%s', $recurrence->transactionType->type));
- $source = $this->findAccount($sourceTypes, $array['source_id'], null);
- $destination = $this->findAccount($destTypes, $array['destination_id'], null);
+ app('log')->debug(sprintf('Now at transaction #%d', $index));
+ $sourceTypes = config(sprintf('firefly.expected_source_types.source.%s', $recurrence->transactionType->type));
+ $destTypes = config(sprintf('firefly.expected_source_types.destination.%s', $recurrence->transactionType->type));
+ $source = $this->findAccount($sourceTypes, $array['source_id'], null);
+ $destination = $this->findAccount($destTypes, $array['destination_id'], null);
/** @var TransactionCurrencyFactory $factory */
$factory = app(TransactionCurrencyFactory::class);
$currency = $factory->find($array['currency_id'] ?? null, $array['currency_code'] ?? null);
$foreignCurrency = $factory->find($array['foreign_currency_id'] ?? null, $array['foreign_currency_code'] ?? null);
if (null === $currency) {
- $currency = app('amount')->getDefaultCurrencyByUser($recurrence->user);
+ $currency = app('amount')->getDefaultCurrencyByUserGroup($recurrence->user->userGroup);
}
- Log::debug(
+ app('log')->debug(
sprintf('Will set the validator type to %s based on the type of the recurrence (#%d).', $recurrence->transactionType->type, $recurrence->id)
);
// once the accounts have been determined, we still verify their validity:
/** @var AccountValidator $validator */
- $validator = app(AccountValidator::class);
+ $validator = app(AccountValidator::class);
$validator->setUser($recurrence->user);
$validator->setTransactionType($recurrence->transactionType->type);
@@ -144,7 +129,7 @@ trait RecurringTransactionTrait
unset($array['foreign_amount']);
}
// TODO typeOverrule. The account validator may have a different opinion on the type of the transaction.
- $transaction = new RecurrenceTransaction(
+ $transaction = new RecurrenceTransaction(
[
'recurrence_id' => $recurrence->id,
'transaction_currency_id' => $currency->id,
@@ -179,40 +164,35 @@ trait RecurringTransactionTrait
}
}
- /**
- * @param array $expectedTypes
- * @param int|null $accountId
- * @param string|null $accountName
- *
- * @return Account
- * @throws JsonException
- */
protected function findAccount(array $expectedTypes, ?int $accountId, ?string $accountName): Account
{
- $result = null;
- $accountId = (int)$accountId;
- $accountName = (string)$accountName;
+ $result = null;
+ $accountId = (int)$accountId;
+ $accountName = (string)$accountName;
+
/** @var AccountRepositoryInterface $repository */
- $repository = app(AccountRepositoryInterface::class);
+ $repository = app(AccountRepositoryInterface::class);
$repository->setUser($this->user);
// if user has submitted an account ID, search for it.
- $result = $repository->find((int)$accountId);
+ $result = $repository->find($accountId);
if (null !== $result) {
return $result;
}
// if user has submitted a name, search for it:
- $result = $repository->findByName($accountName, $expectedTypes);
+ $result = $repository->findByName($accountName, $expectedTypes);
if (null !== $result) {
return $result;
}
// maybe we can create it? Try to avoid LOAN and other asset types.
$cannotCreate = [AccountType::ASSET, AccountType::DEBT, AccountType::LOAN, AccountType::MORTGAGE, AccountType::CREDITCARD];
+
/** @var AccountFactory $factory */
- $factory = app(AccountFactory::class);
+ $factory = app(AccountFactory::class);
$factory->setUser($this->user);
+
/** @var string $expectedType */
foreach ($expectedTypes as $expectedType) {
if (in_array($expectedType, $cannotCreate, true)) {
@@ -222,7 +202,7 @@ trait RecurringTransactionTrait
try {
$result = $factory->findOrCreate($accountName, $expectedType);
} catch (FireflyException $e) {
- Log::error($e->getMessage());
+ app('log')->error($e->getMessage());
}
}
}
@@ -230,43 +210,35 @@ trait RecurringTransactionTrait
return $result ?? $repository->getCashAccount();
}
- /**
- * @param RecurrenceTransaction $transaction
- * @param int $budgetId
- */
private function setBudget(RecurrenceTransaction $transaction, int $budgetId): void
{
$budgetFactory = app(BudgetFactory::class);
$budgetFactory->setUser($transaction->recurrence->user);
- $budget = $budgetFactory->find($budgetId, null);
+ $budget = $budgetFactory->find($budgetId, null);
if (null === $budget) {
return;
}
- $meta = $transaction->recurrenceTransactionMeta()->where('name', 'budget_id')->first();
+ $meta = $transaction->recurrenceTransactionMeta()->where('name', 'budget_id')->first();
if (null === $meta) {
$meta = new RecurrenceTransactionMeta();
$meta->rt_id = $transaction->id;
$meta->name = 'budget_id';
}
- $meta->value = $budget->id;
+ $meta->value = $budget->id;
$meta->save();
}
- /**
- * @param RecurrenceTransaction $transaction
- * @param int $billId
- */
private function setBill(RecurrenceTransaction $transaction, int $billId): void
{
$billFactory = app(BillFactory::class);
$billFactory->setUser($transaction->recurrence->user);
- $bill = $billFactory->find($billId, null);
+ $bill = $billFactory->find($billId, null);
if (null === $bill) {
return;
}
- $meta = $transaction->recurrenceTransactionMeta()->where('name', 'bill_id')->first();
+ $meta = $transaction->recurrenceTransactionMeta()->where('name', 'bill_id')->first();
if (null === $meta) {
$meta = new RecurrenceTransactionMeta();
$meta->rt_id = $transaction->id;
@@ -276,15 +248,11 @@ trait RecurringTransactionTrait
$meta->save();
}
- /**
- * @param RecurrenceTransaction $transaction
- * @param int $categoryId
- */
private function setCategory(RecurrenceTransaction $transaction, int $categoryId): void
{
$categoryFactory = app(CategoryFactory::class);
$categoryFactory->setUser($transaction->recurrence->user);
- $category = $categoryFactory->findOrCreate($categoryId, null);
+ $category = $categoryFactory->findOrCreate($categoryId, null);
if (null === $category) {
// remove category:
$transaction->recurrenceTransactionMeta()->where('name', 'category_id')->delete();
@@ -293,29 +261,25 @@ trait RecurringTransactionTrait
return;
}
$transaction->recurrenceTransactionMeta()->where('name', 'category_name')->delete();
- $meta = $transaction->recurrenceTransactionMeta()->where('name', 'category_id')->first();
+ $meta = $transaction->recurrenceTransactionMeta()->where('name', 'category_id')->first();
if (null === $meta) {
$meta = new RecurrenceTransactionMeta();
$meta->rt_id = $transaction->id;
$meta->name = 'category_id';
}
- $meta->value = $category->id;
+ $meta->value = $category->id;
$meta->save();
}
- /**
- * @param RecurrenceTransaction $transaction
- * @param int $piggyId
- */
protected function updatePiggyBank(RecurrenceTransaction $transaction, int $piggyId): void
{
/** @var PiggyBankFactory $factory */
- $factory = app(PiggyBankFactory::class);
+ $factory = app(PiggyBankFactory::class);
$factory->setUser($transaction->recurrence->user);
$piggyBank = $factory->find($piggyId, null);
if (null !== $piggyBank) {
- /** @var RecurrenceMeta|null $entry */
- $entry = $transaction->recurrenceTransactionMeta()->where('name', 'piggy_bank_id')->first();
+ /** @var null|RecurrenceMeta $entry */
+ $entry = $transaction->recurrenceTransactionMeta()->where('name', 'piggy_bank_id')->first();
if (null === $entry) {
$entry = RecurrenceTransactionMeta::create(['rt_id' => $transaction->id, 'name' => 'piggy_bank_id', 'value' => $piggyBank->id]);
}
@@ -328,15 +292,11 @@ trait RecurringTransactionTrait
}
}
- /**
- * @param RecurrenceTransaction $transaction
- * @param array $tags
- */
protected function updateTags(RecurrenceTransaction $transaction, array $tags): void
{
if (0 !== count($tags)) {
- /** @var RecurrenceMeta|null $entry */
- $entry = $transaction->recurrenceTransactionMeta()->where('name', 'tags')->first();
+ /** @var null|RecurrenceMeta $entry */
+ $entry = $transaction->recurrenceTransactionMeta()->where('name', 'tags')->first();
if (null === $entry) {
$entry = RecurrenceTransactionMeta::create(['rt_id' => $transaction->id, 'name' => 'tags', 'value' => json_encode($tags)]);
}
@@ -349,24 +309,15 @@ trait RecurringTransactionTrait
}
}
- /**
- * @param Recurrence $recurrence
- *
-
- */
protected function deleteRepetitions(Recurrence $recurrence): void
{
$recurrence->recurrenceRepetitions()->delete();
}
- /**
- * @param Recurrence $recurrence
- *
-
- */
protected function deleteTransactions(Recurrence $recurrence): void
{
- Log::debug('deleteTransactions()');
+ app('log')->debug('deleteTransactions()');
+
/** @var RecurrenceTransaction $transaction */
foreach ($recurrence->recurrenceTransactions as $transaction) {
$transaction->recurrenceTransactionMeta()->delete();
diff --git a/app/Services/Internal/Support/TransactionTypeTrait.php b/app/Services/Internal/Support/TransactionTypeTrait.php
index d06f93af88..5814b95cb9 100644
--- a/app/Services/Internal/Support/TransactionTypeTrait.php
+++ b/app/Services/Internal/Support/TransactionTypeTrait.php
@@ -26,11 +26,9 @@ namespace FireflyIII\Services\Internal\Support;
use FireflyIII\Exceptions\FireflyException;
use FireflyIII\Factory\TransactionTypeFactory;
use FireflyIII\Models\TransactionType;
-use Illuminate\Support\Facades\Log;
/**
* Trait TransactionTypeTrait
- *
*/
trait TransactionTypeTrait
{
@@ -38,9 +36,6 @@ trait TransactionTypeTrait
* Get the transaction type. Since this is mandatory, will throw an exception when nothing comes up. Will always
* use TransactionType repository.
*
- * @param string $type
- *
- * @return TransactionType
* @throws FireflyException
*/
protected function findTransactionType(string $type): TransactionType
@@ -48,7 +43,8 @@ trait TransactionTypeTrait
$factory = app(TransactionTypeFactory::class);
$transactionType = $factory->find($type);
if (null === $transactionType) {
- Log::error(sprintf('Could not find transaction type for "%s"', $type));
+ app('log')->error(sprintf('Could not find transaction type for "%s"', $type));
+
throw new FireflyException(sprintf('Could not find transaction type for "%s"', $type));
}
diff --git a/app/Services/Internal/Update/AccountUpdateService.php b/app/Services/Internal/Update/AccountUpdateService.php
index 5630684833..6e38975ea6 100644
--- a/app/Services/Internal/Update/AccountUpdateService.php
+++ b/app/Services/Internal/Update/AccountUpdateService.php
@@ -31,8 +31,6 @@ use FireflyIII\Models\Location;
use FireflyIII\Repositories\Account\AccountRepositoryInterface;
use FireflyIII\Services\Internal\Support\AccountServiceTrait;
use FireflyIII\User;
-use Illuminate\Support\Facades\Log;
-use JsonException;
/**
* Class AccountUpdateService
@@ -47,7 +45,6 @@ class AccountUpdateService
protected array $validCCFields;
protected array $validFields;
private array $canHaveOpeningBalance;
- private array $canHaveVirtual;
private User $user;
/**
@@ -55,7 +52,6 @@ class AccountUpdateService
*/
public function __construct()
{
- $this->canHaveVirtual = config('firefly.can_have_virtual_amounts');
$this->canHaveOpeningBalance = config('firefly.can_have_opening_balance');
$this->validAssetFields = config('firefly.valid_asset_fields');
$this->validCCFields = config('firefly.valid_cc_fields');
@@ -66,16 +62,11 @@ class AccountUpdateService
/**
* Update account data.
*
- * @param Account $account
- * @param array $data
- *
- * @return Account
* @throws FireflyException
- * @throws JsonException
*/
public function update(Account $account, array $data): Account
{
- Log::debug(sprintf('Now in %s', __METHOD__));
+ app('log')->debug(sprintf('Now in %s', __METHOD__));
$this->accountRepository->setUser($account->user);
$this->user = $account->user;
$account = $this->updateAccount($account, $data);
@@ -83,7 +74,7 @@ class AccountUpdateService
// find currency, or use default currency instead.
if (array_key_exists('currency_id', $data) || array_key_exists('currency_code', $data)) {
- $currency = $this->getCurrency((int)($data['currency_id'] ?? null), (string)($data['currency_code'] ?? null));
+ $currency = $this->getCurrency((int)($data['currency_id'] ?? null), (string)($data['currency_code'] ?? null));
unset($data['currency_code'], $data['currency_id']);
$data['currency_id'] = $currency->id;
}
@@ -113,20 +104,11 @@ class AccountUpdateService
return $account;
}
- /**
- * @param User $user
- */
public function setUser(User $user): void
{
$this->user = $user;
}
- /**
- * @param Account $account
- * @param array $data
- *
- * @return Account
- */
private function updateAccount(Account $account, array $data): Account
{
// update the account itself:
@@ -141,7 +123,7 @@ class AccountUpdateService
}
// set liability, but account must already be a liability.
- //$liabilityType = $data['liability_type'] ?? '';
+ // $liabilityType = $data['liability_type'] ?? '';
if ($this->isLiability($account) && array_key_exists('liability_type', $data)) {
$type = $this->getAccountType($data['liability_type']);
$account->account_type_id = $type->id;
@@ -166,11 +148,6 @@ class AccountUpdateService
return $account;
}
- /**
- * @param Account $account
- *
- * @return bool
- */
private function isLiability(Account $account): bool
{
$type = $account->accountType->type;
@@ -178,91 +155,74 @@ class AccountUpdateService
return in_array($type, [AccountType::DEBT, AccountType::LOAN, AccountType::MORTGAGE], true);
}
- /**
- * @param string $type
- *
- * @return AccountType
- */
private function getAccountType(string $type): AccountType
{
return AccountType::whereType(ucfirst($type))->first();
}
- /**
- * @param Account $account
- * @param array $data
- *
- * @return Account
- */
public function updateAccountOrder(Account $account, array $data): Account
{
// skip if no order info
if (!array_key_exists('order', $data) || $data['order'] === $account->order) {
- Log::debug(sprintf('Account order will not be touched because its not set or already at %d.', $account->order));
+ app('log')->debug(sprintf('Account order will not be touched because its not set or already at %d.', $account->order));
return $account;
}
// skip if not of orderable type.
- $type = $account->accountType->type;
+ $type = $account->accountType->type;
if (!in_array($type, [AccountType::ASSET, AccountType::MORTGAGE, AccountType::LOAN, AccountType::DEBT], true)) {
- Log::debug('Will not change order of this account.');
+ app('log')->debug('Will not change order of this account.');
return $account;
}
// get account type ID's because a join and an update is hard:
- $oldOrder = (int)$account->order;
- $newOrder = $data['order'];
- Log::debug(sprintf('Order is set to be updated from %s to %s', $oldOrder, $newOrder));
- $list = $this->getTypeIds([AccountType::MORTGAGE, AccountType::LOAN, AccountType::DEBT]);
- if ($type === AccountType::ASSET) {
+ $oldOrder = $account->order;
+ $newOrder = $data['order'];
+ app('log')->debug(sprintf('Order is set to be updated from %s to %s', $oldOrder, $newOrder));
+ $list = $this->getTypeIds([AccountType::MORTGAGE, AccountType::LOAN, AccountType::DEBT]);
+ if (AccountType::ASSET === $type) {
$list = $this->getTypeIds([AccountType::ASSET]);
}
if ($newOrder > $oldOrder) {
$this->user->accounts()->where('accounts.order', '<=', $newOrder)->where('accounts.order', '>', $oldOrder)
- ->where('accounts.id', '!=', $account->id)
- ->whereIn('accounts.account_type_id', $list)
- ->decrement('order');
+ ->where('accounts.id', '!=', $account->id)
+ ->whereIn('accounts.account_type_id', $list)
+ ->decrement('order')
+ ;
$account->order = $newOrder;
- Log::debug(sprintf('Order of account #%d ("%s") is now %d', $account->id, $account->name, $newOrder));
+ app('log')->debug(sprintf('Order of account #%d ("%s") is now %d', $account->id, $account->name, $newOrder));
$account->save();
return $account;
}
$this->user->accounts()->where('accounts.order', '>=', $newOrder)->where('accounts.order', '<', $oldOrder)
- ->where('accounts.id', '!=', $account->id)
- ->whereIn('accounts.account_type_id', $list)
- ->increment('order');
+ ->where('accounts.id', '!=', $account->id)
+ ->whereIn('accounts.account_type_id', $list)
+ ->increment('order')
+ ;
$account->order = $newOrder;
- Log::debug(sprintf('Order of account #%d ("%s") is now %d', $account->id, $account->name, $newOrder));
+ app('log')->debug(sprintf('Order of account #%d ("%s") is now %d', $account->id, $account->name, $newOrder));
$account->save();
return $account;
}
- /**
- * @param array $array
- *
- * @return array
- */
private function getTypeIds(array $array): array
{
$return = [];
+
/** @var string $type */
foreach ($array as $type) {
/** @var AccountType $type */
$type = AccountType::whereType($type)->first();
- $return[] = (int)$type->id;
+ $return[] = $type->id;
}
return $return;
}
- /**
- * @param Account $account
- * @param array $data
- */
private function updateLocation(Account $account, array $data): void
{
$updateLocation = $data['update_location'] ?? false;
@@ -275,7 +235,7 @@ class AccountUpdateService
// otherwise, update or create.
if (!(null === $data['latitude'] && null === $data['longitude'] && null === $data['zoom_level'])) {
- $location = $this->accountRepository->getLocation($account);
+ $location = $this->accountRepository->getLocation($account);
if (null === $location) {
$location = new Location();
$location->locatable()->associate($account);
@@ -290,9 +250,6 @@ class AccountUpdateService
}
/**
- * @param Account $account
- * @param array $data
- *
* @throws FireflyException
*/
private function updateOpeningBalance(Account $account, array $data): void
@@ -326,8 +283,6 @@ class AccountUpdateService
}
/**
- * @param Account $account
- *
* @throws FireflyException
*/
private function updatePreferences(Account $account): void
@@ -336,22 +291,25 @@ class AccountUpdateService
if (true === $account->active) {
return;
}
- $preference = app('preferences')->getForUser($account->user, 'frontpageAccounts');
+ $preference = app('preferences')->getForUser($account->user, 'frontpageAccounts');
if (null === $preference) {
return;
}
- $array = $preference->data;
- Log::debug('Old array is: ', $array);
- Log::debug(sprintf('Must remove : %d', $account->id));
- $removeAccountId = (int)$account->id;
+ $array = $preference->data;
+ if (!is_array($array)) {
+ $array = [$array];
+ }
+ app('log')->debug('Old array is: ', $array);
+ app('log')->debug(sprintf('Must remove : %d', $account->id));
+ $removeAccountId = $account->id;
$new = [];
foreach ($array as $value) {
if ((int)$value !== $removeAccountId) {
- Log::debug(sprintf('Will include: %d', $value));
+ app('log')->debug(sprintf('Will include: %d', $value));
$new[] = (int)$value;
}
}
- Log::debug('Final new array is', $new);
+ app('log')->debug('Final new array is', $new);
app('preferences')->setForUser($account->user, 'frontpageAccounts', $new);
}
}
diff --git a/app/Services/Internal/Update/BillUpdateService.php b/app/Services/Internal/Update/BillUpdateService.php
index 025bdf4f0d..1567867575 100644
--- a/app/Services/Internal/Update/BillUpdateService.php
+++ b/app/Services/Internal/Update/BillUpdateService.php
@@ -33,8 +33,6 @@ use FireflyIII\Repositories\ObjectGroup\CreatesObjectGroups;
use FireflyIII\Services\Internal\Support\BillServiceTrait;
use FireflyIII\User;
use Illuminate\Support\Collection;
-use Illuminate\Support\Facades\Log;
-use JsonException;
/**
* Class BillUpdateService
@@ -47,34 +45,29 @@ class BillUpdateService
protected User $user;
/**
- * @param Bill $bill
- * @param array $data
- *
- * @return Bill
* @throws FireflyException
- * @throws JsonException
*/
public function update(Bill $bill, array $data): Bill
{
$this->user = $bill->user;
if (array_key_exists('currency_id', $data) || array_key_exists('currency_code', $data)) {
- $factory = app(TransactionCurrencyFactory::class);
- $currency = $factory->find((int)($data['currency_id'] ?? null), $data['currency_code'] ?? null) ??
- app('amount')->getDefaultCurrencyByUser($bill->user);
+ $factory = app(TransactionCurrencyFactory::class);
+ $currency = $factory->find((int)($data['currency_id'] ?? null), $data['currency_code'] ?? null) ??
+ app('amount')->getDefaultCurrencyByUserGroup($bill->user->userGroup);
// enable the currency if it isn't.
- $currency->enabled = true;
+ $currency->enabled = true;
$currency->save();
$bill->transaction_currency_id = $currency->id;
$bill->save();
}
// update bill properties:
- $bill = $this->updateBillProperties($bill, $data);
+ $bill = $this->updateBillProperties($bill, $data);
$bill->save();
$bill->refresh();
// old values
- $oldData = [
+ $oldData = [
'name' => $bill->name,
'amount_min' => $bill->amount_min,
'amount_max' => $bill->amount_max,
@@ -88,7 +81,7 @@ class BillUpdateService
// update order.
if (array_key_exists('order', $data)) {
// update the order of the piggy bank:
- $oldOrder = (int)$bill->order;
+ $oldOrder = $bill->order;
$newOrder = (int)($data['order'] ?? $oldOrder);
if ($oldOrder !== $newOrder) {
$this->updateOrder($bill, $oldOrder, $newOrder);
@@ -114,10 +107,8 @@ class BillUpdateService
return $bill;
}
// remove if name is empty. Should be overruled by ID.
- if ('' === $objectGroupTitle) {
- $bill->objectGroups()->sync([]);
- $bill->save();
- }
+ $bill->objectGroups()->sync([]);
+ $bill->save();
}
if (array_key_exists('object_group_id', $data)) {
// try also with ID:
@@ -131,20 +122,15 @@ class BillUpdateService
return $bill;
}
- if (0 === $objectGroupId) {
- $bill->objectGroups()->sync([]);
- $bill->save();
- }
+ $bill->objectGroups()->sync([]);
+ $bill->save();
}
return $bill;
}
/**
- * @param Bill $bill
- * @param array $data
- *
- * @return Bill
+ * @SuppressWarnings(PHPMD.NPathComplexity)
*/
private function updateBillProperties(Bill $bill, array $data): Bill
{
@@ -184,48 +170,41 @@ class BillUpdateService
return $bill;
}
- /**
- * @param Bill $bill
- * @param int $oldOrder
- * @param int $newOrder
- */
private function updateOrder(Bill $bill, int $oldOrder, int $newOrder): void
{
if ($newOrder > $oldOrder) {
$this->user->bills()->where('order', '<=', $newOrder)->where('order', '>', $oldOrder)
- ->where('bills.id', '!=', $bill->id)
- ->decrement('bills.order');
+ ->where('bills.id', '!=', $bill->id)
+ ->decrement('bills.order')
+ ;
$bill->order = $newOrder;
$bill->save();
}
if ($newOrder < $oldOrder) {
$this->user->bills()->where('order', '>=', $newOrder)->where('order', '<', $oldOrder)
- ->where('bills.id', '!=', $bill->id)
- ->increment('bills.order');
+ ->where('bills.id', '!=', $bill->id)
+ ->increment('bills.order')
+ ;
$bill->order = $newOrder;
$bill->save();
}
}
- /**
- * @param Bill $bill
- * @param array $oldData
- * @param array $newData
- */
private function updateBillTriggers(Bill $bill, array $oldData, array $newData): void
{
- Log::debug(sprintf('Now in updateBillTriggers(%d, "%s")', $bill->id, $bill->name));
+ app('log')->debug(sprintf('Now in updateBillTriggers(%d, "%s")', $bill->id, $bill->name));
+
/** @var BillRepositoryInterface $repository */
$repository = app(BillRepositoryInterface::class);
$repository->setUser($bill->user);
- $rules = $repository->getRulesForBill($bill);
+ $rules = $repository->getRulesForBill($bill);
if (0 === $rules->count()) {
- Log::debug('Found no rules.');
+ app('log')->debug('Found no rules.');
return;
}
- Log::debug(sprintf('Found %d rules', $rules->count()));
- $fields = [
+ app('log')->debug(sprintf('Found %d rules', $rules->count()));
+ $fields = [
'name' => 'description_contains',
'amount_min' => 'amount_more',
'amount_max' => 'amount_less',
@@ -236,45 +215,35 @@ class BillUpdateService
continue;
}
if ($oldData[$field] === $newData[$field]) {
- Log::debug(sprintf('Field %s is unchanged ("%s"), continue.', $field, $oldData[$field]));
+ app('log')->debug(sprintf('Field %s is unchanged ("%s"), continue.', $field, $oldData[$field]));
+
continue;
}
$this->updateRules($rules, $ruleTriggerKey, $oldData[$field], $newData[$field]);
}
}
- /**
- * @param Collection $rules
- * @param string $key
- * @param string $oldValue
- * @param string $newValue
- */
private function updateRules(Collection $rules, string $key, string $oldValue, string $newValue): void
{
/** @var Rule $rule */
foreach ($rules as $rule) {
$trigger = $this->getRuleTrigger($rule, $key);
if (null !== $trigger && $trigger->trigger_value === $oldValue) {
- Log::debug(sprintf('Updated rule trigger #%d from value "%s" to value "%s"', $trigger->id, $oldValue, $newValue));
+ app('log')->debug(sprintf('Updated rule trigger #%d from value "%s" to value "%s"', $trigger->id, $oldValue, $newValue));
$trigger->trigger_value = $newValue;
$trigger->save();
+
continue;
}
if (null !== $trigger && $trigger->trigger_value !== $oldValue && in_array($key, ['amount_more', 'amount_less'], true)
&& 0 === bccomp($trigger->trigger_value, $oldValue)) {
- Log::debug(sprintf('Updated rule trigger #%d from value "%s" to value "%s"', $trigger->id, $oldValue, $newValue));
+ app('log')->debug(sprintf('Updated rule trigger #%d from value "%s" to value "%s"', $trigger->id, $oldValue, $newValue));
$trigger->trigger_value = $newValue;
$trigger->save();
}
}
}
- /**
- * @param Rule $rule
- * @param string $key
- *
- * @return RuleTrigger|null
- */
private function getRuleTrigger(Rule $rule, string $key): ?RuleTrigger
{
return $rule->ruleTriggers()->where('trigger_type', $key)->first();
diff --git a/app/Services/Internal/Update/CategoryUpdateService.php b/app/Services/Internal/Update/CategoryUpdateService.php
index 0d2cdba3f7..8d4a7067e5 100644
--- a/app/Services/Internal/Update/CategoryUpdateService.php
+++ b/app/Services/Internal/Update/CategoryUpdateService.php
@@ -23,22 +23,19 @@ declare(strict_types=1);
namespace FireflyIII\Services\Internal\Update;
-use Exception;
use FireflyIII\Models\Category;
use FireflyIII\Models\Note;
use FireflyIII\Models\RecurrenceTransactionMeta;
use FireflyIII\Models\RuleAction;
use FireflyIII\Models\RuleTrigger;
-use Illuminate\Support\Facades\Log;
+use FireflyIII\User;
/**
* Class CategoryUpdateService
- *
-
*/
class CategoryUpdateService
{
- private $user;
+ private User $user;
/**
* Constructor.
@@ -46,7 +43,9 @@ class CategoryUpdateService
public function __construct()
{
if (auth()->check()) {
- $this->user = auth()->user();
+ /** @var User $user */
+ $user = auth()->user();
+ $this->user = $user;
}
}
@@ -59,11 +58,7 @@ class CategoryUpdateService
}
/**
- * @param Category $category
- * @param array $data
- *
- * @return Category
- * @throws Exception
+ * @throws \Exception
*/
public function update(Category $category, array $data): Category
{
@@ -82,71 +77,61 @@ class CategoryUpdateService
return $category;
}
- /**
- * @param string $oldName
- * @param string $newName
- */
private function updateRuleTriggers(string $oldName, string $newName): void
{
- $types = ['category_is',];
+ $types = ['category_is'];
$triggers = RuleTrigger::leftJoin('rules', 'rules.id', '=', 'rule_triggers.rule_id')
- ->where('rules.user_id', $this->user->id)
- ->whereIn('rule_triggers.trigger_type', $types)
- ->where('rule_triggers.trigger_value', $oldName)
- ->get(['rule_triggers.*']);
- Log::debug(sprintf('Found %d triggers to update.', $triggers->count()));
+ ->where('rules.user_id', $this->user->id)
+ ->whereIn('rule_triggers.trigger_type', $types)
+ ->where('rule_triggers.trigger_value', $oldName)
+ ->get(['rule_triggers.*'])
+ ;
+ app('log')->debug(sprintf('Found %d triggers to update.', $triggers->count()));
+
/** @var RuleTrigger $trigger */
foreach ($triggers as $trigger) {
$trigger->trigger_value = $newName;
$trigger->save();
- Log::debug(sprintf('Updated trigger %d: %s', $trigger->id, $trigger->trigger_value));
+ app('log')->debug(sprintf('Updated trigger %d: %s', $trigger->id, $trigger->trigger_value));
}
}
- /**
- * @param string $oldName
- * @param string $newName
- */
private function updateRuleActions(string $oldName, string $newName): void
{
- $types = ['set_category',];
+ $types = ['set_category'];
$actions = RuleAction::leftJoin('rules', 'rules.id', '=', 'rule_actions.rule_id')
- ->where('rules.user_id', $this->user->id)
- ->whereIn('rule_actions.action_type', $types)
- ->where('rule_actions.action_value', $oldName)
- ->get(['rule_actions.*']);
- Log::debug(sprintf('Found %d actions to update.', $actions->count()));
+ ->where('rules.user_id', $this->user->id)
+ ->whereIn('rule_actions.action_type', $types)
+ ->where('rule_actions.action_value', $oldName)
+ ->get(['rule_actions.*'])
+ ;
+ app('log')->debug(sprintf('Found %d actions to update.', $actions->count()));
+
/** @var RuleAction $action */
foreach ($actions as $action) {
$action->action_value = $newName;
$action->save();
- Log::debug(sprintf('Updated action %d: %s', $action->id, $action->action_value));
+ app('log')->debug(sprintf('Updated action %d: %s', $action->id, $action->action_value));
}
}
- /**
- * @param string $oldName
- * @param string $newName
- */
private function updateRecurrences(string $oldName, string $newName): void
{
RecurrenceTransactionMeta::leftJoin('recurrences_transactions', 'rt_meta.rt_id', '=', 'recurrences_transactions.id')
- ->leftJoin('recurrences', 'recurrences.id', '=', 'recurrences_transactions.recurrence_id')
- ->where('recurrences.user_id', $this->user->id)
- ->where('rt_meta.name', 'category_name')
- ->where('rt_meta.value', $oldName)
- ->update(['rt_meta.value' => $newName]);
+ ->leftJoin('recurrences', 'recurrences.id', '=', 'recurrences_transactions.recurrence_id')
+ ->where('recurrences.user_id', $this->user->id)
+ ->where('rt_meta.name', 'category_name')
+ ->where('rt_meta.value', $oldName)
+ ->update(['rt_meta.value' => $newName])
+ ;
}
/**
- * @param Category $category
- * @param array $data
- *
- * @throws Exception
+ * @throws \Exception
*/
private function updateNotes(Category $category, array $data): void
{
- $note = array_key_exists('notes', $data) ? $data['notes'] : null;
+ $note = array_key_exists('notes', $data) ? $data['notes'] : null;
if (null === $note) {
return;
}
@@ -158,7 +143,7 @@ class CategoryUpdateService
return;
}
- $dbNote = $category->notes()->first();
+ $dbNote = $category->notes()->first();
if (null === $dbNote) {
$dbNote = new Note();
$dbNote->noteable()->associate($category);
diff --git a/app/Services/Internal/Update/CurrencyUpdateService.php b/app/Services/Internal/Update/CurrencyUpdateService.php
index c01444e4e8..3a6adf9705 100644
--- a/app/Services/Internal/Update/CurrencyUpdateService.php
+++ b/app/Services/Internal/Update/CurrencyUpdateService.php
@@ -27,17 +27,9 @@ use FireflyIII\Models\TransactionCurrency;
/**
* Class CurrencyUpdateService
- *
-
*/
class CurrencyUpdateService
{
- /**
- * @param TransactionCurrency $currency
- * @param array $data
- *
- * @return TransactionCurrency
- */
public function update(TransactionCurrency $currency, array $data): TransactionCurrency
{
if (array_key_exists('code', $data) && '' !== (string)$data['code']) {
@@ -52,14 +44,13 @@ class CurrencyUpdateService
$currency->name = e($data['name']);
}
- if (array_key_exists('enabled', $data) && is_bool($data['enabled'])) {
- $currency->enabled = (bool)$data['enabled'];
- }
+ $currency->enabled = false;
if (array_key_exists('decimal_places', $data) && is_int($data['decimal_places'])) {
- $currency->decimal_places = (int)$data['decimal_places'];
+ $currency->decimal_places = $data['decimal_places'];
}
-
+ $currency->userGroupEnabled = null;
+ $currency->userGroupDefault = null;
$currency->save();
return $currency;
diff --git a/app/Services/Internal/Update/GroupCloneService.php b/app/Services/Internal/Update/GroupCloneService.php
index 21a0e3bbc4..e3353d6ada 100644
--- a/app/Services/Internal/Update/GroupCloneService.php
+++ b/app/Services/Internal/Update/GroupCloneService.php
@@ -39,27 +39,17 @@ use FireflyIII\Models\TransactionJournalMeta;
*/
class GroupCloneService
{
- /**
- * @param TransactionGroup $group
- *
- * @return TransactionGroup
- */
public function cloneGroup(TransactionGroup $group): TransactionGroup
{
$newGroup = $group->replicate();
$newGroup->save();
foreach ($group->transactionJournals as $journal) {
- $this->cloneJournal($journal, $newGroup, (int)$group->id);
+ $this->cloneJournal($journal, $newGroup, $group->id);
}
return $newGroup;
}
- /**
- * @param TransactionJournal $journal
- * @param TransactionGroup $newGroup
- * @param int $originalGroup
- */
private function cloneJournal(TransactionJournal $journal, TransactionGroup $newGroup, int $originalGroup): void
{
$newJournal = $journal->replicate();
@@ -83,6 +73,7 @@ class GroupCloneService
foreach ($journal->transactionJournalMeta as $meta) {
$this->cloneMeta($meta, $newJournal);
}
+
// clone category
/** @var Category $category */
foreach ($journal->categories as $category) {
@@ -105,8 +96,8 @@ class GroupCloneService
// add relation.
// TODO clone ALL linked piggy banks
- /** @var PiggyBankEvent $event */
- $event = $journal->piggyBankEvents()->first();
+ /** @var null|PiggyBankEvent $event */
+ $event = $journal->piggyBankEvents()->first();
if (null !== $event) {
$piggyBank = $event->piggyBank;
$factory = app(PiggyBankEventFactory::class);
@@ -114,10 +105,6 @@ class GroupCloneService
}
}
- /**
- * @param Transaction $transaction
- * @param TransactionJournal $newJournal
- */
private function cloneTransaction(Transaction $transaction, TransactionJournal $newJournal): void
{
$newTransaction = $transaction->replicate();
@@ -126,11 +113,6 @@ class GroupCloneService
$newTransaction->save();
}
- /**
- * @param Note $note
- * @param TransactionJournal $newJournal
- * @param int $oldGroupId
- */
private function cloneNote(Note $note, TransactionJournal $newJournal, int $oldGroupId): void
{
$newNote = $note->replicate();
@@ -142,10 +124,6 @@ class GroupCloneService
$newNote->save();
}
- /**
- * @param TransactionJournalMeta $meta
- * @param TransactionJournal $newJournal
- */
private function cloneMeta(TransactionJournalMeta $meta, TransactionJournal $newJournal): void
{
$newMeta = $meta->replicate();
diff --git a/app/Services/Internal/Update/GroupUpdateService.php b/app/Services/Internal/Update/GroupUpdateService.php
index 3fc5e45876..412c9f3a0c 100644
--- a/app/Services/Internal/Update/GroupUpdateService.php
+++ b/app/Services/Internal/Update/GroupUpdateService.php
@@ -30,8 +30,6 @@ use FireflyIII\Factory\TransactionJournalFactory;
use FireflyIII\Models\TransactionGroup;
use FireflyIII\Models\TransactionJournal;
use FireflyIII\Services\Internal\Destroy\JournalDestroyService;
-use Illuminate\Support\Facades\Log;
-use JsonException;
/**
* Class GroupUpdateService
@@ -41,23 +39,19 @@ class GroupUpdateService
/**
* Update a transaction group.
*
- * @param TransactionGroup $transactionGroup
- * @param array $data
- *
- * @return TransactionGroup
* @throws DuplicateTransactionException
* @throws FireflyException
- * @throws JsonException
*/
public function update(TransactionGroup $transactionGroup, array $data): TransactionGroup
{
- Log::debug(sprintf('Now in %s', __METHOD__));
- Log::debug('Now in group update service', $data);
+ app('log')->debug(sprintf('Now in %s', __METHOD__));
+ app('log')->debug('Now in group update service', $data);
+
/** @var array $transactions */
$transactions = $data['transactions'] ?? [];
// update group name.
if (array_key_exists('group_title', $data)) {
- Log::debug(sprintf('Update transaction group #%d title.', $transactionGroup->id));
+ app('log')->debug(sprintf('Update transaction group #%d title.', $transactionGroup->id));
$oldTitle = $transactionGroup->title;
$transactionGroup->title = $data['group_title'];
$transactionGroup->save();
@@ -72,9 +66,8 @@ class GroupUpdateService
);
}
-
if (0 === count($transactions)) {
- Log::debug('No transactions submitted, do nothing.');
+ app('log')->debug('No transactions submitted, do nothing.');
return $transactionGroup;
}
@@ -82,37 +75,40 @@ class GroupUpdateService
if (1 === count($transactions) && 1 === $transactionGroup->transactionJournals()->count()) {
/** @var TransactionJournal $first */
$first = $transactionGroup->transactionJournals()->first();
- Log::debug(
+ app('log')->debug(
sprintf('Will now update journal #%d (only journal in group #%d)', $first->id, $transactionGroup->id)
);
$this->updateTransactionJournal($transactionGroup, $first, reset($transactions));
+ $transactionGroup->touch();
$transactionGroup->refresh();
app('preferences')->mark();
return $transactionGroup;
}
- Log::debug('Going to update split group.');
+ app('log')->debug('Going to update split group.');
- $existing = $transactionGroup->transactionJournals->pluck('id')->toArray();
- $updated = $this->updateTransactions($transactionGroup, $transactions);
- Log::debug('Array of updated IDs: ', $updated);
+ $existing = $transactionGroup->transactionJournals->pluck('id')->toArray();
+ $updated = $this->updateTransactions($transactionGroup, $transactions);
+ app('log')->debug('Array of updated IDs: ', $updated);
if (0 === count($updated)) {
- Log::error('There were no transactions updated or created. Will not delete anything.');
+ app('log')->error('There were no transactions updated or created. Will not delete anything.');
+ $transactionGroup->touch();
$transactionGroup->refresh();
app('preferences')->mark();
return $transactionGroup;
}
- $result = array_diff($existing, $updated);
- Log::debug('Result of DIFF: ', $result);
+ $result = array_diff($existing, $updated);
+ app('log')->debug('Result of DIFF: ', $result);
if (count($result) > 0) {
/** @var string $deletedId */
foreach ($result as $deletedId) {
/** @var TransactionJournal $journal */
$journal = $transactionGroup->transactionJournals()->find((int)$deletedId);
+
/** @var JournalDestroyService $service */
$service = app(JournalDestroyService::class);
$service->destroy($journal);
@@ -120,6 +116,7 @@ class GroupUpdateService
}
app('preferences')->mark();
+ $transactionGroup->touch();
$transactionGroup->refresh();
return $transactionGroup;
@@ -127,23 +124,20 @@ class GroupUpdateService
/**
* Update single journal.
- *
- * @param TransactionGroup $transactionGroup
- * @param TransactionJournal $journal
- * @param array $data
*/
private function updateTransactionJournal(
TransactionGroup $transactionGroup,
TransactionJournal $journal,
array $data
): void {
- Log::debug(sprintf('Now in %s', __METHOD__));
+ app('log')->debug(sprintf('Now in %s', __METHOD__));
if (0 === count($data)) {
return;
}
if (1 === count($data) && array_key_exists('transaction_journal_id', $data)) {
return;
}
+
/** @var JournalUpdateService $updateService */
$updateService = app(JournalUpdateService::class);
$updateService->setTransactionGroup($transactionGroup);
@@ -153,58 +147,56 @@ class GroupUpdateService
}
/**
- * @param TransactionGroup $transactionGroup
- * @param array $transactions
- *
- * @return array
* @throws DuplicateTransactionException
* @throws FireflyException
- * @throws JsonException
*/
private function updateTransactions(TransactionGroup $transactionGroup, array $transactions): array
{
- Log::debug(sprintf('Now in %s', __METHOD__));
+ app('log')->debug(sprintf('Now in %s', __METHOD__));
// updated or created transaction journals:
$updated = [];
+
/**
* @var int $index
* @var array $transaction
*/
foreach ($transactions as $index => $transaction) {
- Log::debug(sprintf('Now at #%d of %d', ($index + 1), count($transactions)), $transaction);
+ app('log')->debug(sprintf('Now at #%d of %d', $index + 1, count($transactions)), $transaction);
$journalId = (int)($transaction['transaction_journal_id'] ?? 0);
- /** @var TransactionJournal|null $journal */
- $journal = $transactionGroup->transactionJournals()->find($journalId);
+
+ /** @var null|TransactionJournal $journal */
+ $journal = $transactionGroup->transactionJournals()->find($journalId);
if (null === $journal) {
- Log::debug('This entry has no existing journal: make a new split.');
+ app('log')->debug('This entry has no existing journal: make a new split.');
// force the transaction type on the transaction data.
// by plucking it from another journal in the group:
if (!array_key_exists('type', $transaction)) {
- Log::debug('No transaction type is indicated.');
- /** @var TransactionJournal|null $randomJournal */
+ app('log')->debug('No transaction type is indicated.');
+
+ /** @var null|TransactionJournal $randomJournal */
$randomJournal = $transactionGroup->transactionJournals()->inRandomOrder()->with(
['transactionType']
)->first();
if (null !== $randomJournal) {
$transaction['type'] = $randomJournal->transactionType->type;
- Log::debug(sprintf('Transaction type set to %s.', $transaction['type']));
+ app('log')->debug(sprintf('Transaction type set to %s.', $transaction['type']));
}
}
- Log::debug('Call createTransactionJournal');
+ app('log')->debug('Call createTransactionJournal');
$newJournal = $this->createTransactionJournal($transactionGroup, $transaction);
- Log::debug('Done calling createTransactionJournal');
+ app('log')->debug('Done calling createTransactionJournal');
if (null !== $newJournal) {
$updated[] = $newJournal->id;
}
if (null === $newJournal) {
- Log::error('createTransactionJournal returned NULL, indicating something went wrong.');
+ app('log')->error('createTransactionJournal returned NULL, indicating something went wrong.');
}
}
if (null !== $journal) {
- Log::debug('Call updateTransactionJournal');
+ app('log')->debug('Call updateTransactionJournal');
$this->updateTransactionJournal($transactionGroup, $journal, $transaction);
$updated[] = $journal->id;
- Log::debug('Done calling updateTransactionJournal');
+ app('log')->debug('Done calling updateTransactionJournal');
}
}
@@ -212,14 +204,8 @@ class GroupUpdateService
}
/**
- * @param TransactionGroup $transactionGroup
- * @param array $data
- *
- * @return TransactionJournal|null
- *
* @throws DuplicateTransactionException
* @throws FireflyException
- * @throws JsonException
*/
private function createTransactionJournal(TransactionGroup $transactionGroup, array $data): ?TransactionJournal
{
@@ -228,14 +214,17 @@ class GroupUpdateService
$data,
],
];
+
/** @var TransactionJournalFactory $factory */
- $factory = app(TransactionJournalFactory::class);
+ $factory = app(TransactionJournalFactory::class);
$factory->setUser($transactionGroup->user);
+
try {
$collection = $factory->create($submission);
} catch (FireflyException $e) {
- Log::error($e->getMessage());
- Log::error($e->getTraceAsString());
+ app('log')->error($e->getMessage());
+ app('log')->error($e->getTraceAsString());
+
throw new FireflyException(
sprintf('Could not create new transaction journal: %s', $e->getMessage()),
0,
@@ -243,7 +232,7 @@ class GroupUpdateService
);
}
$collection->each(
- function (TransactionJournal $journal) use ($transactionGroup) {
+ static function (TransactionJournal $journal) use ($transactionGroup): void {
$transactionGroup->transactionJournals()->save($journal);
}
);
diff --git a/app/Services/Internal/Update/JournalUpdateService.php b/app/Services/Internal/Update/JournalUpdateService.php
index 8fbb53cf55..b6ecdc31a6 100644
--- a/app/Services/Internal/Update/JournalUpdateService.php
+++ b/app/Services/Internal/Update/JournalUpdateService.php
@@ -25,6 +25,7 @@ namespace FireflyIII\Services\Internal\Update;
use Carbon\Carbon;
use Carbon\Exceptions\InvalidDateException;
+use Carbon\Exceptions\InvalidFormatException;
use FireflyIII\Events\TriggeredAuditLog;
use FireflyIII\Exceptions\FireflyException;
use FireflyIII\Factory\TagFactory;
@@ -39,11 +40,10 @@ 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\UserGroups\Currency\CurrencyRepositoryInterface;
use FireflyIII\Services\Internal\Support\JournalServiceTrait;
use FireflyIII\Support\NullArrayObject;
use FireflyIII\Validation\AccountValidator;
-use Illuminate\Support\Facades\Log;
/**
* Class to centralise code that updates a journal given the input by system.
@@ -99,23 +99,17 @@ class JournalUpdateService
'external_url',
];
$this->metaDate = ['interest_date', 'book_date', 'process_date', 'due_date', 'payment_date',
- 'invoice_date',];
+ 'invoice_date', ];
}
- /**
- * @param array $data
- */
public function setData(array $data): void
{
$this->data = $data;
}
- /**
- * @param TransactionGroup $transactionGroup
- */
public function setTransactionGroup(TransactionGroup $transactionGroup): void
{
- $this->transactionGroup = $transactionGroup;
+ $this->transactionGroup = $transactionGroup;
$this->billRepository->setUser($transactionGroup->user);
$this->categoryRepository->setUser($transactionGroup->user);
$this->budgetRepository->setUser($transactionGroup->user);
@@ -127,28 +121,21 @@ class JournalUpdateService
$this->sourceTransaction = null;
}
- /**
- * @param TransactionJournal $transactionJournal
- */
public function setTransactionJournal(TransactionJournal $transactionJournal): void
{
$this->transactionJournal = $transactionJournal;
}
- /**
- *
- */
public function update(): void
{
- Log::debug(sprintf('Now in %s', __METHOD__));
- Log::debug(sprintf('Now in JournalUpdateService for journal #%d.', $this->transactionJournal->id));
+ app('log')->debug(sprintf('Now in %s', __METHOD__));
+ app('log')->debug(sprintf('Now in JournalUpdateService for journal #%d.', $this->transactionJournal->id));
-
- $this->data['reconciled'] = array_key_exists('reconciled', $this->data) ? $this->data['reconciled'] : false;
+ $this->data['reconciled'] = array_key_exists('reconciled', $this->data) ? $this->data['reconciled'] : null;
// can we update account data using the new type?
if ($this->hasValidAccounts()) {
- Log::info('Account info is valid, now update.');
+ app('log')->info('Account info is valid, now update.');
// update accounts:
$this->updateAccounts();
@@ -181,22 +168,16 @@ class JournalUpdateService
$this->transactionJournal->refresh();
}
- /**
- * @return bool
- */
private function hasValidAccounts(): bool
{
return $this->hasValidSourceAccount() && $this->hasValidDestinationAccount();
}
- /**
- * @return bool
- */
private function hasValidSourceAccount(): bool
{
- Log::debug('Now in hasValidSourceAccount().');
- $sourceId = $this->data['source_id'] ?? null;
- $sourceName = $this->data['source_name'] ?? null;
+ app('log')->debug('Now in hasValidSourceAccount().');
+ $sourceId = $this->data['source_id'] ?? null;
+ $sourceName = $this->data['source_name'] ?? null;
if (!$this->hasFields(['source_id', 'source_name'])) {
$origSourceAccount = $this->getOriginalSourceAccount();
@@ -206,16 +187,16 @@ class JournalUpdateService
// make new account validator.
$expectedType = $this->getExpectedType();
- Log::debug(sprintf('Expected type (new or unchanged) is %s', $expectedType));
+ app('log')->debug(sprintf('Expected type (new or unchanged) is %s', $expectedType));
// make a new validator.
/** @var AccountValidator $validator */
- $validator = app(AccountValidator::class);
+ $validator = app(AccountValidator::class);
$validator->setTransactionType($expectedType);
$validator->setUser($this->transactionJournal->user);
- $result = $validator->validateSource(['id' => $sourceId]);
- Log::debug(
+ $result = $validator->validateSource(['id' => $sourceId]);
+ app('log')->debug(
sprintf('hasValidSourceAccount(%d, "%s") will return %s', $sourceId, $sourceName, var_export($result, true))
);
@@ -225,11 +206,6 @@ class JournalUpdateService
return $result;
}
- /**
- * @param array $fields
- *
- * @return bool
- */
private function hasFields(array $fields): bool
{
foreach ($fields as $field) {
@@ -241,9 +217,6 @@ class JournalUpdateService
return false;
}
- /**
- * @return Account
- */
private function getOriginalSourceAccount(): Account
{
if (null === $this->sourceAccount) {
@@ -254,9 +227,6 @@ class JournalUpdateService
return $this->sourceAccount;
}
- /**
- * @return Transaction
- */
private function getSourceTransaction(): Transaction
{
if (null === $this->sourceTransaction) {
@@ -266,7 +236,7 @@ class JournalUpdateService
0
)->first();
}
- Log::debug(sprintf('getSourceTransaction: %s', $this->sourceTransaction->amount));
+ app('log')->debug(sprintf('getSourceTransaction: %s', $this->sourceTransaction->amount));
return $this->sourceTransaction;
}
@@ -277,12 +247,10 @@ class JournalUpdateService
*
* If the array contains key 'type' and the value is correct, this is returned. Otherwise, the original type is
* returned.
- *
- * @return string
*/
private function getExpectedType(): string
{
- Log::debug('Now in getExpectedType()');
+ app('log')->debug('Now in getExpectedType()');
if ($this->hasFields(['type'])) {
return ucfirst('opening-balance' === $this->data['type'] ? 'opening balance' : $this->data['type']);
}
@@ -290,34 +258,31 @@ class JournalUpdateService
return $this->transactionJournal->transactionType->type;
}
- /**
- * @return bool
- */
private function hasValidDestinationAccount(): bool
{
- Log::debug('Now in hasValidDestinationAccount().');
- $destId = $this->data['destination_id'] ?? null;
- $destName = $this->data['destination_name'] ?? null;
+ app('log')->debug('Now in hasValidDestinationAccount().');
+ $destId = $this->data['destination_id'] ?? null;
+ $destName = $this->data['destination_name'] ?? null;
if (!$this->hasFields(['destination_id', 'destination_name'])) {
- Log::debug('No destination info submitted, grab the original data.');
+ app('log')->debug('No destination info submitted, grab the original data.');
$destination = $this->getOriginalDestinationAccount();
$destId = $destination->id;
$destName = $destination->name;
}
// make new account validator.
- $expectedType = $this->getExpectedType();
- Log::debug(sprintf('Expected type (new or unchanged) is %s', $expectedType));
+ $expectedType = $this->getExpectedType();
+ app('log')->debug(sprintf('Expected type (new or unchanged) is %s', $expectedType));
// make a new validator.
/** @var AccountValidator $validator */
- $validator = app(AccountValidator::class);
+ $validator = app(AccountValidator::class);
$validator->setTransactionType($expectedType);
$validator->setUser($this->transactionJournal->user);
$validator->source = $this->getValidSourceAccount();
$result = $validator->validateDestination(['id' => $destId, 'name' => $destName]);
- Log::debug(
+ app('log')->debug(
sprintf(
'hasValidDestinationAccount(%d, "%s") will return %s',
$destId,
@@ -332,9 +297,6 @@ class JournalUpdateService
return $result;
}
- /**
- * @return Account
- */
private function getOriginalDestinationAccount(): Account
{
if (null === $this->destinationAccount) {
@@ -347,8 +309,6 @@ class JournalUpdateService
/**
* Get destination transaction.
- *
- * @return Transaction
*/
private function getDestinationTransaction(): Transaction
{
@@ -361,18 +321,16 @@ class JournalUpdateService
/**
* Does a validation and returns the source account. This method will break if the source isn't really valid.
- *
- * @return Account
*/
private function getValidSourceAccount(): Account
{
- Log::debug('Now in getValidSourceAccount().');
+ app('log')->debug('Now in getValidSourceAccount().');
if (!$this->hasFields(['source_id', 'source_name'])) {
return $this->getOriginalSourceAccount();
}
- $sourceInfo = [
+ $sourceInfo = [
'id' => (int)($this->data['source_id'] ?? null),
'name' => $this->data['source_name'] ?? null,
'iban' => $this->data['source_iban'] ?? null,
@@ -381,15 +339,16 @@ class JournalUpdateService
];
$expectedType = $this->getExpectedType();
+
try {
$result = $this->getAccount($expectedType, 'source', $sourceInfo);
} catch (FireflyException $e) {
- Log::error(sprintf('Cant get the valid source account: %s', $e->getMessage()));
+ app('log')->error(sprintf('Cant get the valid source account: %s', $e->getMessage()));
$result = $this->getOriginalSourceAccount();
}
- Log::debug(sprintf('getValidSourceAccount() will return #%d ("%s")', $result->id, $result->name));
+ app('log')->debug(sprintf('getValidSourceAccount() will return #%d ("%s")', $result->id, $result->name));
return $result;
}
@@ -399,12 +358,12 @@ class JournalUpdateService
*/
private function updateAccounts(): void
{
- $source = $this->getValidSourceAccount();
- $destination = $this->getValidDestinationAccount();
+ $source = $this->getValidSourceAccount();
+ $destination = $this->getValidDestinationAccount();
// cowardly refuse to update if both accounts are the same.
if ($source->id === $destination->id) {
- Log::error(sprintf('Source + dest accounts are equal (%d, "%s")', $source->id, $source->name));
+ app('log')->error(sprintf('Source + dest accounts are equal (%d, "%s")', $source->id, $source->name));
return;
}
@@ -413,31 +372,29 @@ class JournalUpdateService
$origSourceTransaction->account()->associate($source);
$origSourceTransaction->save();
- $destTransaction = $this->getDestinationTransaction();
+ $destTransaction = $this->getDestinationTransaction();
$destTransaction->account()->associate($destination);
$destTransaction->save();
// refresh transactions.
$this->sourceTransaction->refresh();
$this->destinationTransaction->refresh();
- Log::debug(sprintf('Will set source to #%d ("%s")', $source->id, $source->name));
- Log::debug(sprintf('Will set dest to #%d ("%s")', $destination->id, $destination->name));
+ app('log')->debug(sprintf('Will set source to #%d ("%s")', $source->id, $source->name));
+ app('log')->debug(sprintf('Will set dest to #%d ("%s")', $destination->id, $destination->name));
}
/**
* Does a validation and returns the destination account. This method will break if the dest isn't really valid.
- *
- * @return Account
*/
private function getValidDestinationAccount(): Account
{
- Log::debug('Now in getValidDestinationAccount().');
+ app('log')->debug('Now in getValidDestinationAccount().');
if (!$this->hasFields(['destination_id', 'destination_name'])) {
return $this->getOriginalDestinationAccount();
}
- $destInfo = [
+ $destInfo = [
'id' => (int)($this->data['destination_id'] ?? null),
'name' => $this->data['destination_name'] ?? null,
'iban' => $this->data['destination_iban'] ?? null,
@@ -447,11 +404,12 @@ class JournalUpdateService
// make new account validator.
$expectedType = $this->getExpectedType();
- Log::debug(sprintf('Expected type (new or unchanged) is %s', $expectedType));
+ app('log')->debug(sprintf('Expected type (new or unchanged) is %s', $expectedType));
+
try {
$result = $this->getAccount($expectedType, 'destination', $destInfo);
} catch (FireflyException $e) {
- Log::error(sprintf('getValidDestinationAccount() threw unexpected error: %s', $e->getMessage()));
+ app('log')->error(sprintf('getValidDestinationAccount() threw unexpected error: %s', $e->getMessage()));
$result = $this->getOriginalDestinationAccount();
}
@@ -463,10 +421,10 @@ class JournalUpdateService
*/
private function updateType(): void
{
- Log::debug('Now in updateType()');
+ app('log')->debug('Now in updateType()');
if ($this->hasFields(['type'])) {
- $type = 'opening-balance' === $this->data['type'] ? 'opening balance' : $this->data['type'];
- Log::debug(
+ $type = 'opening-balance' === $this->data['type'] ? 'opening balance' : $this->data['type'];
+ app('log')->debug(
sprintf(
'Trying to change journal #%d from a %s to a %s.',
$this->transactionJournal->id,
@@ -479,7 +437,7 @@ class JournalUpdateService
$typeFactory = app(TransactionTypeFactory::class);
$result = $typeFactory->find($this->data['type']);
if (null !== $result) {
- Log::debug('Changed transaction type!');
+ app('log')->debug('Changed transaction type!');
$this->transactionJournal->transaction_type_id = $result->id;
$this->transactionJournal->save();
@@ -488,7 +446,7 @@ class JournalUpdateService
return;
}
- Log::debug('No type field present.');
+ app('log')->debug('No type field present.');
}
/**
@@ -507,67 +465,59 @@ class JournalUpdateService
$billName = (string)($this->data['bill_name'] ?? '');
$bill = $this->billRepository->findBill($billId, $billName);
$this->transactionJournal->bill_id = $bill?->id;
- Log::debug('Updated bill ID');
+ app('log')->debug('Updated bill ID');
}
}
/**
* Update journal generic field. Cannot be set to NULL.
- *
- * @param string $fieldName
*/
private function updateField(string $fieldName): void
{
if (array_key_exists($fieldName, $this->data) && '' !== (string)$this->data[$fieldName]) {
- $value = $this->data[$fieldName];
+ $value = $this->data[$fieldName];
if ('date' === $fieldName) {
if ($value instanceof Carbon) {
// update timezone.
$value->setTimezone(config('app.timezone'));
}
- if (!($value instanceof Carbon)) {
+ if (!$value instanceof Carbon) {
$value = new Carbon($value);
}
// do some parsing.
- Log::debug(sprintf('Create date value from string "%s".', $value));
+ app('log')->debug(sprintf('Create date value from string "%s".', $value));
}
event(
new TriggeredAuditLog(
$this->transactionJournal->user,
$this->transactionJournal,
sprintf('update_%s', $fieldName),
- $this->transactionJournal->$fieldName,
+ $this->transactionJournal->{$fieldName}, // @phpstan-ignore-line
$value
)
);
- $this->transactionJournal->$fieldName = $value;
- Log::debug(sprintf('Updated %s', $fieldName));
+ $this->transactionJournal->{$fieldName} = $value; // @phpstan-ignore-line
+ app('log')->debug(sprintf('Updated %s', $fieldName));
}
}
- /**
- *
- */
private function updateCategory(): void
{
// update category
if ($this->hasFields(['category_id', 'category_name'])) {
- Log::debug('Will update category.');
+ app('log')->debug('Will update category.');
$this->storeCategory($this->transactionJournal, new NullArrayObject($this->data));
}
}
- /**
- *
- */
private function updateBudget(): void
{
// update budget
if ($this->hasFields(['budget_id', 'budget_name'])) {
- Log::debug('Will update budget.');
+ app('log')->debug('Will update budget.');
$this->storeBudget($this->transactionJournal, new NullArrayObject($this->data));
}
// is transfer? remove budget
@@ -576,21 +526,15 @@ class JournalUpdateService
}
}
- /**
- *
- */
private function updateTags(): void
{
if ($this->hasFields(['tags'])) {
- Log::debug('Will update tags.');
+ app('log')->debug('Will update tags.');
$tags = $this->data['tags'] ?? null;
$this->storeTags($this->transactionJournal, $tags);
}
}
- /**
- *
- */
private function updateReconciled(): void
{
if (array_key_exists('reconciled', $this->data) && is_bool($this->data['reconciled'])) {
@@ -598,9 +542,6 @@ class JournalUpdateService
}
}
- /**
- *
- */
private function updateNotes(): void
{
// update notes.
@@ -610,28 +551,22 @@ class JournalUpdateService
}
}
- /**
- *
- */
private function updateMeta(): void
{
// update meta fields.
// first string
if ($this->hasFields($this->metaString)) {
- Log::debug('Meta string fields are present.');
+ app('log')->debug('Meta string fields are present.');
$this->updateMetaFields();
}
// then date fields.
if ($this->hasFields($this->metaDate)) {
- Log::debug('Meta date fields are present.');
+ app('log')->debug('Meta date fields are present.');
$this->updateMetaDateFields();
}
}
- /**
- *
- */
private function updateMetaFields(): void
{
/** @var TransactionJournalMetaFactory $factory */
@@ -640,8 +575,8 @@ class JournalUpdateService
foreach ($this->metaString as $field) {
if ($this->hasFields([$field])) {
$value = '' === $this->data[$field] ? null : $this->data[$field];
- Log::debug(sprintf('Field "%s" is present ("%s"), try to update it.', $field, $value));
- $set = [
+ app('log')->debug(sprintf('Field "%s" is present ("%s"), try to update it.', $field, $value));
+ $set = [
'journal' => $this->transactionJournal,
'name' => $field,
'data' => $value,
@@ -651,9 +586,6 @@ class JournalUpdateService
}
}
- /**
- *
- */
private function updateMetaDateFields(): void
{
/** @var TransactionJournalMetaFactory $factory */
@@ -663,12 +595,12 @@ class JournalUpdateService
if ($this->hasFields([$field])) {
try {
$value = '' === (string)$this->data[$field] ? null : new Carbon($this->data[$field]);
- } catch (InvalidDateException $e) {
- Log::debug(sprintf('%s is not a valid date value: %s', $this->data[$field], $e->getMessage()));
+ } catch (InvalidDateException|InvalidFormatException $e) { // @phpstan-ignore-line
+ app('log')->debug(sprintf('%s is not a valid date value: %s', $this->data[$field], $e->getMessage()));
return;
}
- Log::debug(sprintf('Field "%s" is present ("%s"), try to update it.', $field, $value));
+ app('log')->debug(sprintf('Field "%s" is present ("%s"), try to update it.', $field, $value));
$set = [
'journal' => $this->transactionJournal,
'name' => $field,
@@ -679,72 +611,62 @@ class JournalUpdateService
}
}
- /**
- *
- */
private function updateCurrency(): void
{
// update transactions.
if (!$this->hasFields(['currency_id', 'currency_code'])) {
return;
}
- $currencyId = $this->data['currency_id'] ?? null;
- $currencyCode = $this->data['currency_code'] ?? null;
- $currency = $this->currencyRepository->findCurrency($currencyId, $currencyCode);
- if (null !== $currency) {
- // update currency everywhere.
- $this->transactionJournal->transaction_currency_id = $currency->id;
- $this->transactionJournal->save();
+ $currencyId = $this->data['currency_id'] ?? null;
+ $currencyCode = $this->data['currency_code'] ?? null;
+ $currency = $this->currencyRepository->findCurrency($currencyId, $currencyCode);
+ // update currency everywhere.
+ $this->transactionJournal->transaction_currency_id = $currency->id;
+ $this->transactionJournal->save();
- $source = $this->getSourceTransaction();
- $source->transaction_currency_id = $currency->id;
- $source->save();
+ $source = $this->getSourceTransaction();
+ $source->transaction_currency_id = $currency->id;
+ $source->save();
- $dest = $this->getDestinationTransaction();
- $dest->transaction_currency_id = $currency->id;
- $dest->save();
+ $dest = $this->getDestinationTransaction();
+ $dest->transaction_currency_id = $currency->id;
+ $dest->save();
- // refresh transactions.
- $this->sourceTransaction->refresh();
- $this->destinationTransaction->refresh();
- Log::debug(sprintf('Updated currency to #%d (%s)', $currency->id, $currency->code));
- }
+ // refresh transactions.
+ $this->sourceTransaction->refresh();
+ $this->destinationTransaction->refresh();
+ app('log')->debug(sprintf('Updated currency to #%d (%s)', $currency->id, $currency->code));
}
- /**
- *
- */
private function updateAmount(): void
{
- Log::debug(sprintf('Now in %s', __METHOD__));
+ app('log')->debug(sprintf('Now in %s', __METHOD__));
if (!$this->hasFields(['amount'])) {
return;
}
- $value = $this->data['amount'] ?? '';
- Log::debug(sprintf('Amount is now "%s"', $value));
+ $value = $this->data['amount'] ?? '';
+ app('log')->debug(sprintf('Amount is now "%s"', $value));
+
try {
$amount = $this->getAmount($value);
} catch (FireflyException $e) {
- Log::debug(sprintf('getAmount("%s") returns error: %s', $value, $e->getMessage()));
+ app('log')->debug(sprintf('getAmount("%s") returns error: %s', $value, $e->getMessage()));
return;
}
$origSourceTransaction = $this->getSourceTransaction();
$origSourceTransaction->amount = app('steam')->negative($amount);
$origSourceTransaction->save();
- $destTransaction = $this->getDestinationTransaction();
- $destTransaction->amount = app('steam')->positive($amount);
+ $destTransaction = $this->getDestinationTransaction();
+ $destTransaction->amount = app('steam')->positive($amount);
$destTransaction->save();
// refresh transactions.
$this->sourceTransaction->refresh();
$this->destinationTransaction->refresh();
- Log::debug(sprintf('Updated amount to "%s"', $amount));
+ app('log')->debug(sprintf('Updated amount to "%s"', $amount));
}
- /**
- *
- */
private function updateForeignAmount(): void
{
// amount, foreign currency.
@@ -766,7 +688,7 @@ class JournalUpdateService
// not the same as normal currency
if (null !== $foreignCurrency && $foreignCurrency->id === $this->transactionJournal->transaction_currency_id) {
- Log::error(sprintf('Foreign currency is equal to normal currency (%s)', $foreignCurrency->code));
+ app('log')->error(sprintf('Foreign currency is equal to normal currency (%s)', $foreignCurrency->code));
return;
}
@@ -776,11 +698,11 @@ class JournalUpdateService
$source->foreign_currency_id = $foreignCurrency->id;
$source->foreign_amount = app('steam')->negative($foreignAmount);
$source->save();
- $dest->foreign_currency_id = $foreignCurrency->id;
- $dest->foreign_amount = app('steam')->positive($foreignAmount);
+ $dest->foreign_currency_id = $foreignCurrency->id;
+ $dest->foreign_amount = app('steam')->positive($foreignAmount);
$dest->save();
- Log::debug(
+ app('log')->debug(
sprintf(
'Update foreign info to %s (#%d) %s',
$foreignCurrency->code,
@@ -800,12 +722,12 @@ class JournalUpdateService
$source->foreign_amount = null;
$source->save();
- $dest->foreign_currency_id = null;
- $dest->foreign_amount = null;
+ $dest->foreign_currency_id = null;
+ $dest->foreign_amount = null;
$dest->save();
- Log::debug(sprintf('Foreign amount is "%s" so remove foreign amount info.', $amount));
+ app('log')->debug(sprintf('Foreign amount is "%s" so remove foreign amount info.', $amount));
}
- Log::info('Not enough info to update foreign currency info.');
+ app('log')->info('Not enough info to update foreign currency info.');
// refresh transactions.
$this->sourceTransaction->refresh();
diff --git a/app/Services/Internal/Update/RecurrenceUpdateService.php b/app/Services/Internal/Update/RecurrenceUpdateService.php
index 559f333fd3..13119a36cb 100644
--- a/app/Services/Internal/Update/RecurrenceUpdateService.php
+++ b/app/Services/Internal/Update/RecurrenceUpdateService.php
@@ -32,18 +32,14 @@ use FireflyIII\Models\RecurrenceTransaction;
use FireflyIII\Services\Internal\Support\RecurringTransactionTrait;
use FireflyIII\Services\Internal\Support\TransactionTypeTrait;
use FireflyIII\User;
-use Illuminate\Support\Facades\Log;
-use JsonException;
/**
* Class RecurrenceUpdateService
- *
-
*/
class RecurrenceUpdateService
{
- use TransactionTypeTrait;
use RecurringTransactionTrait;
+ use TransactionTypeTrait;
private User $user;
@@ -52,10 +48,6 @@ class RecurrenceUpdateService
*
* TODO if the user updates the type, the accounts must be validated again.
*
- * @param Recurrence $recurrence
- * @param array $data
- *
- * @return Recurrence
* @throws FireflyException
*/
public function update(Recurrence $recurrence, array $data): Recurrence
@@ -99,7 +91,7 @@ class RecurrenceUpdateService
// update all repetitions
if (array_key_exists('repetitions', $data)) {
- Log::debug('Will update repetitions array');
+ app('log')->debug('Will update repetitions array');
// update each repetition or throw error yay
$this->updateRepetitions($recurrence, $data['repetitions'] ?? []);
}
@@ -112,10 +104,6 @@ class RecurrenceUpdateService
return $recurrence;
}
- /**
- * @param Recurrence $recurrence
- * @param string $text
- */
private function setNoteText(Recurrence $recurrence, string $text): void
{
$dbNote = $recurrence->notes()->first();
@@ -133,10 +121,6 @@ class RecurrenceUpdateService
}
/**
- *
- * @param Recurrence $recurrence
- * @param array $repetitions
- *
* @throws FireflyException
*/
private function updateRepetitions(Recurrence $recurrence, array $repetitions): void
@@ -148,16 +132,16 @@ class RecurrenceUpdateService
}
// user added or removed repetitions, delete all and recreate:
if ($originalCount !== count($repetitions)) {
- Log::debug('Delete existing repetitions and create new ones.');
+ app('log')->debug('Delete existing repetitions and create new ones.');
$this->deleteRepetitions($recurrence);
$this->createRepetitions($recurrence, $repetitions);
return;
}
// loop all and try to match them:
- Log::debug('Loop and find');
+ app('log')->debug('Loop and find');
foreach ($repetitions as $current) {
- $match = $this->matchRepetition($recurrence, $current);
+ $match = $this->matchRepetition($recurrence, $current);
if (null === $match) {
throw new FireflyException('Cannot match recurring repetition to existing repetition. Not sure what to do. Break.');
}
@@ -169,88 +153,76 @@ class RecurrenceUpdateService
];
foreach ($fields as $field => $column) {
if (array_key_exists($field, $current)) {
- $match->$column = $current[$field];
+ $match->{$column} = $current[$field];
$match->save();
}
}
}
}
- /**
- * @param Recurrence $recurrence
- * @param array $data
- *
- * @return RecurrenceRepetition|null
- */
private function matchRepetition(Recurrence $recurrence, array $data): ?RecurrenceRepetition
{
$originalCount = $recurrence->recurrenceRepetitions()->count();
if (1 === $originalCount) {
- Log::debug('Return the first one');
- /** @var RecurrenceRepetition|null */
+ app('log')->debug('Return the first one');
+
+ // @var RecurrenceRepetition|null
return $recurrence->recurrenceRepetitions()->first();
}
// find it:
- $fields = [
+ $fields = [
'id' => 'id',
'type' => 'repetition_type',
'moment' => 'repetition_moment',
'skip' => 'repetition_skip',
'weekend' => 'weekend',
];
- $query = $recurrence->recurrenceRepetitions();
+ $query = $recurrence->recurrenceRepetitions();
foreach ($fields as $field => $column) {
if (array_key_exists($field, $data)) {
$query->where($column, $data[$field]);
}
}
- /** @var RecurrenceRepetition|null */
+
+ // @var RecurrenceRepetition|null
return $query->first();
}
/**
* TODO this method is very complex.
*
- * @param Recurrence $recurrence
- * @param array $transactions
- *
* @throws FireflyException
- * @throws JsonException
*/
private function updateTransactions(Recurrence $recurrence, array $transactions): void
{
- Log::debug('Now in updateTransactions()');
- $originalCount = $recurrence->recurrenceTransactions()->count();
- Log::debug(sprintf('Original count is %d', $originalCount));
+ app('log')->debug('Now in updateTransactions()');
+ $originalCount = $recurrence->recurrenceTransactions()->count();
+ app('log')->debug(sprintf('Original count is %d', $originalCount));
if (0 === count($transactions)) {
// won't drop transactions, rather avoid.
- Log::warning('No transactions to update, too scared to continue!');
+ app('log')->warning('No transactions to update, too scared to continue!');
+
return;
}
$combinations = [];
$originalTransactions = $recurrence->recurrenceTransactions()->get()->toArray();
- /**
- * First, make sure to loop all existing transactions and match them to a counterpart in the submitted transactions array.
- */
+ // First, make sure to loop all existing transactions and match them to a counterpart in the submitted transactions array.
foreach ($originalTransactions as $i => $originalTransaction) {
foreach ($transactions as $ii => $submittedTransaction) {
if (array_key_exists('id', $submittedTransaction) && (int)$originalTransaction['id'] === (int)$submittedTransaction['id']) {
- Log::debug(sprintf('Match original transaction #%d with an entry in the submitted array.', $originalTransaction['id']));
+ app('log')->debug(sprintf('Match original transaction #%d with an entry in the submitted array.', $originalTransaction['id']));
$combinations[] = [
'original' => $originalTransaction,
'submitted' => $submittedTransaction,
];
- unset($originalTransactions[$i]);
- unset($transactions[$ii]);
+ unset($originalTransactions[$i], $transactions[$ii]);
}
}
}
- /**
- * If one left of both we can match those as well and presto.
- */
+ // If one left of both we can match those as well and presto.
if (1 === count($originalTransactions) && 1 === count($transactions)) {
- $first = array_shift($originalTransactions);
- Log::debug(sprintf('One left of each, link them (ID is #%d)', $first['id']));
+ $first = array_shift($originalTransactions);
+ app('log')->debug(sprintf('One left of each, link them (ID is #%d)', $first['id']));
$combinations[] = [
'original' => $first,
'submitted' => array_shift($transactions),
@@ -265,7 +237,7 @@ class RecurrenceUpdateService
}
// anything left in the original transactions array can be deleted.
foreach ($originalTransactions as $original) {
- Log::debug(sprintf('Original transaction #%d is unmatched, delete it!', $original['id']));
+ app('log')->debug(sprintf('Original transaction #%d is unmatched, delete it!', $original['id']));
$this->deleteTransaction($recurrence, (int)$original['id']);
}
// anything left is new.
@@ -273,45 +245,51 @@ class RecurrenceUpdateService
}
/**
- * @param Recurrence $recurrence
- * @param array $combination
+ * It's a complex method but nothing surprising.
*
- * @return void
+ * @SuppressWarnings(PHPMD.NPathComplexity)
+ * @SuppressWarnings(PHPMD.CyclomaticComplexity)
*/
private function updateCombination(Recurrence $recurrence, array $combination): void
{
- $original = $combination['original'];
- $submitted = $combination['submitted'];
- /** @var RecurrenceTransaction $transaction */
- $transaction = $recurrence->recurrenceTransactions()->find($original['id']);
- Log::debug(sprintf('Now in updateCombination(#%d)', $original['id']));
-
+ $original = $combination['original'];
+ $submitted = $combination['submitted'];
$currencyFactory = app(TransactionCurrencyFactory::class);
+ /** @var RecurrenceTransaction $transaction */
+ $transaction = $recurrence->recurrenceTransactions()->find($original['id']);
+ app('log')->debug(sprintf('Now in updateCombination(#%d)', $original['id']));
+
// loop all and try to match them:
$currency = null;
$foreignCurrency = null;
if (array_key_exists('currency_id', $submitted) || array_key_exists('currency_code', $submitted)) {
- $currency = $currencyFactory->find($submitted['currency_id'] ?? null, $currency['currency_code'] ?? null);
+ $currency = $currencyFactory->find(
+ array_key_exists('currency_id', $submitted) ? (int)$submitted['currency_id'] : null,
+ array_key_exists('currency_code', $submitted) ? $submitted['currency_code'] : null
+ );
}
if (null === $currency) {
unset($submitted['currency_id'], $submitted['currency_code']);
}
if (null !== $currency) {
- $submitted['currency_id'] = (int)$currency->id;
+ $submitted['currency_id'] = $currency->id;
}
if (array_key_exists('foreign_currency_id', $submitted) || array_key_exists('foreign_currency_code', $submitted)) {
- $foreignCurrency = $currencyFactory->find($submitted['foreign_currency_id'] ?? null, $currency['foreign_currency_code'] ?? null);
+ $foreignCurrency = $currencyFactory->find(
+ array_key_exists('foreign_currency_id', $submitted) ? (int)$submitted['foreign_currency_id'] : null,
+ array_key_exists('foreign_currency_code', $submitted) ? $submitted['foreign_currency_code'] : null
+ );
}
if (null === $foreignCurrency) {
unset($submitted['foreign_currency_id'], $currency['foreign_currency_code']);
}
if (null !== $foreignCurrency) {
- $submitted['foreign_currency_id'] = (int)$foreignCurrency->id;
+ $submitted['foreign_currency_id'] = $foreignCurrency->id;
}
// update fields that are part of the recurring transaction itself.
- $fields = [
+ $fields = [
'source_id' => 'source_id',
'destination_id' => 'destination_id',
'amount' => 'amount',
@@ -322,7 +300,7 @@ class RecurrenceUpdateService
];
foreach ($fields as $field => $column) {
if (array_key_exists($field, $submitted)) {
- $transaction->$column = $submitted[$field];
+ $transaction->{$column} = $submitted[$field];
$transaction->save();
}
}
@@ -336,13 +314,13 @@ class RecurrenceUpdateService
// reset category if name is set but empty:
// can be removed when v1 is retired.
if (array_key_exists('category_name', $submitted) && '' === (string)$submitted['category_name']) {
- Log::debug('Category name is submitted but is empty. Set category to be empty.');
+ app('log')->debug('Category name is submitted but is empty. Set category to be empty.');
$submitted['category_name'] = null;
$submitted['category_id'] = 0;
}
if (array_key_exists('category_id', $submitted)) {
- Log::debug(sprintf('Category ID is submitted, set category to be %d.', (int)$submitted['category_id']));
+ app('log')->debug(sprintf('Category ID is submitted, set category to be %d.', (int)$submitted['category_id']));
$this->setCategory($transaction, (int)$submitted['category_id']);
}
@@ -354,15 +332,9 @@ class RecurrenceUpdateService
}
}
- /**
- * @param Recurrence $recurrence
- * @param int $transactionId
- *
- * @return void
- */
private function deleteTransaction(Recurrence $recurrence, int $transactionId): void
{
- Log::debug(sprintf('Will delete transaction #%d in recurrence #%d.', $transactionId, $recurrence->id));
+ app('log')->debug(sprintf('Will delete transaction #%d in recurrence #%d.', $transactionId, $recurrence->id));
$recurrence->recurrenceTransactions()->where('id', $transactionId)->delete();
}
}
diff --git a/app/Services/Password/PwndVerifierV2.php b/app/Services/Password/PwndVerifierV2.php
index 76d7bf1a2f..79067b27f3 100644
--- a/app/Services/Password/PwndVerifierV2.php
+++ b/app/Services/Password/PwndVerifierV2.php
@@ -26,21 +26,14 @@ namespace FireflyIII\Services\Password;
use GuzzleHttp\Client;
use GuzzleHttp\Exception\GuzzleException;
use GuzzleHttp\Exception\RequestException;
-use Illuminate\Support\Facades\Log;
/**
* Class PwndVerifierV2.
- *
-
*/
class PwndVerifierV2 implements Verifier
{
/**
* Verify the given password against (some) service.
- *
- * @param string $password
- *
- * @return bool
*/
public function validPassword(string $password): bool
{
@@ -57,28 +50,28 @@ class PwndVerifierV2 implements Verifier
'timeout' => 3.1415,
];
- Log::debug(sprintf('hash prefix is %s', $prefix));
- Log::debug(sprintf('rest is %s', $rest));
+ app('log')->debug(sprintf('hash prefix is %s', $prefix));
+ app('log')->debug(sprintf('rest is %s', $rest));
try {
$client = new Client();
$res = $client->request('GET', $url, $opt);
- } catch (GuzzleException | RequestException $e) {
- Log::error(sprintf('Could not verify password security: %s', $e->getMessage()));
+ } catch (GuzzleException|RequestException $e) {
+ app('log')->error(sprintf('Could not verify password security: %s', $e->getMessage()));
return true;
}
- Log::debug(sprintf('Status code returned is %d', $res->getStatusCode()));
+ app('log')->debug(sprintf('Status code returned is %d', $res->getStatusCode()));
if (404 === $res->getStatusCode()) {
return true;
}
$strpos = stripos($res->getBody()->getContents(), $rest);
if (false === $strpos) {
- Log::debug(sprintf('%s was not found in result body. Return true.', $rest));
+ app('log')->debug(sprintf('%s was not found in result body. Return true.', $rest));
return true;
}
- Log::debug(sprintf('Found %s, return FALSE.', $rest));
+ app('log')->debug(sprintf('Found %s, return FALSE.', $rest));
return false;
}
diff --git a/app/Services/Password/Verifier.php b/app/Services/Password/Verifier.php
index 372771e484..705053bbfb 100644
--- a/app/Services/Password/Verifier.php
+++ b/app/Services/Password/Verifier.php
@@ -30,10 +30,6 @@ interface Verifier
{
/**
* Verify the given password against (some) service.
- *
- * @param string $password
- *
- * @return bool
*/
public function validPassword(string $password): bool;
}
diff --git a/app/Services/Webhook/StandardWebhookSender.php b/app/Services/Webhook/StandardWebhookSender.php
index 0d4bff7069..1f667b9f23 100644
--- a/app/Services/Webhook/StandardWebhookSender.php
+++ b/app/Services/Webhook/StandardWebhookSender.php
@@ -29,9 +29,8 @@ use FireflyIII\Models\WebhookAttempt;
use FireflyIII\Models\WebhookMessage;
use GuzzleHttp\Client;
use GuzzleHttp\Exception\ConnectException;
+use GuzzleHttp\Exception\GuzzleException;
use GuzzleHttp\Exception\RequestException;
-use Illuminate\Support\Facades\Log;
-use JsonException;
/**
* Class StandardWebhookSender
@@ -41,16 +40,15 @@ class StandardWebhookSender implements WebhookSenderInterface
private WebhookMessage $message;
private int $version = 1;
- /**
- * @inheritDoc
- */
public function getVersion(): int
{
return $this->version;
}
/**
- * @inheritDoc
+ * @throws GuzzleException
+ *
+ * @SuppressWarnings(PHPMD.ExcessiveMethodLength)
*/
public function send(): void
{
@@ -59,16 +57,17 @@ class StandardWebhookSender implements WebhookSenderInterface
$signatureGenerator = app(SignatureGeneratorInterface::class);
$this->message->sent = true;
$this->message->save();
+
try {
$signature = $signatureGenerator->generate($this->message);
} catch (FireflyException $e) {
- Log::error('Did not send message because of a Firefly III Exception.');
- Log::error($e->getMessage());
- Log::error($e->getTraceAsString());
- $attempt = new WebhookAttempt();
+ app('log')->error('Did not send message because of a Firefly III Exception.');
+ app('log')->error($e->getMessage());
+ app('log')->error($e->getTraceAsString());
+ $attempt = new WebhookAttempt();
$attempt->webhookMessage()->associate($this->message);
- $attempt->status_code = 0;
- $attempt->logs = sprintf('Exception: %s', $e->getMessage());
+ $attempt->status_code = 0;
+ $attempt->logs = sprintf('Exception: %s', $e->getMessage());
$attempt->save();
$this->message->errored = true;
$this->message->sent = false;
@@ -77,18 +76,18 @@ class StandardWebhookSender implements WebhookSenderInterface
return;
}
- Log::debug(sprintf('Trying to send webhook message #%d', $this->message->id));
+ app('log')->debug(sprintf('Trying to send webhook message #%d', $this->message->id));
try {
$json = json_encode($this->message->message, JSON_THROW_ON_ERROR);
- } catch (JsonException $e) {
- Log::error('Did not send message because of a JSON error.');
- Log::error($e->getMessage());
- Log::error($e->getTraceAsString());
- $attempt = new WebhookAttempt();
+ } catch (\JsonException $e) {
+ app('log')->error('Did not send message because of a JSON error.');
+ app('log')->error($e->getMessage());
+ app('log')->error($e->getTraceAsString());
+ $attempt = new WebhookAttempt();
$attempt->webhookMessage()->associate($this->message);
- $attempt->status_code = 0;
- $attempt->logs = sprintf('Json error: %s', $e->getMessage());
+ $attempt->status_code = 0;
+ $attempt->logs = sprintf('Json error: %s', $e->getMessage());
$attempt->save();
$this->message->errored = true;
$this->message->sent = false;
@@ -96,7 +95,7 @@ class StandardWebhookSender implements WebhookSenderInterface
return;
}
- $options = [
+ $options = [
'body' => $json,
'headers' => [
'Content-Type' => 'application/json',
@@ -107,31 +106,31 @@ class StandardWebhookSender implements WebhookSenderInterface
'timeout' => 10,
],
];
- $client = new Client();
+ $client = new Client();
+
try {
$res = $client->request('POST', $this->message->webhook->url, $options);
- } catch (RequestException | ConnectException $e) {
- Log::error('The webhook could NOT be submitted but Firefly III caught the error below.');
- Log::error($e->getMessage());
- Log::error($e->getTraceAsString());
+ } catch (ConnectException|RequestException $e) {
+ app('log')->error('The webhook could NOT be submitted but Firefly III caught the error below.');
+ app('log')->error($e->getMessage());
+ app('log')->error($e->getTraceAsString());
-
- $logs = sprintf("%s\n%s", $e->getMessage(), $e->getTraceAsString());
+ $logs = sprintf("%s\n%s", $e->getMessage(), $e->getTraceAsString());
$this->message->errored = true;
$this->message->sent = false;
$this->message->save();
- $attempt = new WebhookAttempt();
+ $attempt = new WebhookAttempt();
$attempt->webhookMessage()->associate($this->message);
- $attempt->status_code = 0;
+ $attempt->status_code = 0;
if (method_exists($e, 'hasResponse') && method_exists($e, 'getResponse')) {
$attempt->status_code = $e->hasResponse() ? $e->getResponse()->getStatusCode() : 0;
- Log::error(sprintf('The status code of the error response is: %d', $attempt->status_code));
- $body = (string)($e->hasResponse() ? $e->getResponse()->getBody() : '');
- Log::error(sprintf('The body of the error response is: %s', $body));
+ app('log')->error(sprintf('The status code of the error response is: %d', $attempt->status_code));
+ $body = (string)($e->hasResponse() ? $e->getResponse()->getBody() : '');
+ app('log')->error(sprintf('The body of the error response is: %s', $body));
}
- $attempt->logs = $logs;
+ $attempt->logs = $logs;
$attempt->save();
return;
@@ -139,14 +138,11 @@ class StandardWebhookSender implements WebhookSenderInterface
$this->message->sent = true;
$this->message->save();
- Log::debug(sprintf('Webhook message #%d was sent. Status code %d', $this->message->id, $res->getStatusCode()));
- Log::debug(sprintf('Webhook request body size: %d bytes', strlen($json)));
- Log::debug(sprintf('Response body: %s', $res->getBody()));
+ app('log')->debug(sprintf('Webhook message #%d was sent. Status code %d', $this->message->id, $res->getStatusCode()));
+ app('log')->debug(sprintf('Webhook request body size: %d bytes', strlen($json)));
+ app('log')->debug(sprintf('Response body: %s', $res->getBody()));
}
- /**
- * @inheritDoc
- */
public function setMessage(WebhookMessage $message): void
{
$this->message = $message;
diff --git a/app/Services/Webhook/WebhookSenderInterface.php b/app/Services/Webhook/WebhookSenderInterface.php
index 6b827fa9d0..67c7d569be 100644
--- a/app/Services/Webhook/WebhookSenderInterface.php
+++ b/app/Services/Webhook/WebhookSenderInterface.php
@@ -30,18 +30,9 @@ use FireflyIII\Models\WebhookMessage;
*/
interface WebhookSenderInterface
{
- /**
- * @return int
- */
public function getVersion(): int;
- /**
- *
- */
public function send(): void;
- /**
- * @param WebhookMessage $message
- */
public function setMessage(WebhookMessage $message): void;
}
diff --git a/app/Support/Amount.php b/app/Support/Amount.php
index fdad00c33d..3a58e52b0d 100644
--- a/app/Support/Amount.php
+++ b/app/Support/Amount.php
@@ -23,20 +23,14 @@ declare(strict_types=1);
namespace FireflyIII\Support;
-use Crypt;
use FireflyIII\Exceptions\FireflyException;
use FireflyIII\Models\TransactionCurrency;
+use FireflyIII\Models\UserGroup;
use FireflyIII\User;
-use Illuminate\Contracts\Encryption\DecryptException;
use Illuminate\Support\Collection;
-use NumberFormatter;
-use Psr\Container\ContainerExceptionInterface;
-use Psr\Container\NotFoundExceptionInterface;
/**
* Class Amount.
- *
-
*/
class Amount
{
@@ -44,42 +38,32 @@ class Amount
* This method will properly format the given number, in color or "black and white",
* as a currency, given two things: the currency required and the current locale.
*
- * @param TransactionCurrency $format
- * @param string $amount
- * @param bool $coloured
- *
- * @return string
* @throws FireflyException
*/
public function formatAnything(TransactionCurrency $format, string $amount, bool $coloured = null): string
{
- return $this->formatFlat($format->symbol, (int)$format->decimal_places, $amount, $coloured);
+ return $this->formatFlat($format->symbol, $format->decimal_places, $amount, $coloured);
}
/**
* This method will properly format the given number, in color or "black and white",
* as a currency, given two things: the currency required and the current locale.
*
- * @param string $symbol
- * @param int $decimalPlaces
- * @param string $amount
- * @param bool $coloured
- *
- * @return string
- *
* @throws FireflyException
+ *
+ * @SuppressWarnings(PHPMD.MissingImport)
*/
public function formatFlat(string $symbol, int $decimalPlaces, string $amount, bool $coloured = null): string
{
- $locale = app('steam')->getLocale();
- $rounded = app('steam')->bcround($amount, $decimalPlaces);
- $coloured = $coloured ?? true;
+ $locale = app('steam')->getLocale();
+ $rounded = app('steam')->bcround($amount, $decimalPlaces);
+ $coloured ??= true;
- $fmt = new NumberFormatter($locale, NumberFormatter::CURRENCY);
- $fmt->setSymbol(NumberFormatter::CURRENCY_SYMBOL, $symbol);
- $fmt->setAttribute(NumberFormatter::MIN_FRACTION_DIGITS, $decimalPlaces);
- $fmt->setAttribute(NumberFormatter::MAX_FRACTION_DIGITS, $decimalPlaces);
- $result = $fmt->format((float)$rounded); // intentional float
+ $fmt = new \NumberFormatter($locale, \NumberFormatter::CURRENCY);
+ $fmt->setSymbol(\NumberFormatter::CURRENCY_SYMBOL, $symbol);
+ $fmt->setAttribute(\NumberFormatter::MIN_FRACTION_DIGITS, $decimalPlaces);
+ $fmt->setAttribute(\NumberFormatter::MAX_FRACTION_DIGITS, $decimalPlaces);
+ $result = (string)$fmt->format((float)$rounded); // intentional float
if (true === $coloured) {
if (1 === bccomp($rounded, '0')) {
@@ -95,106 +79,57 @@ class Amount
return $result;
}
- /**
- * @return Collection
- */
public function getAllCurrencies(): Collection
{
return TransactionCurrency::orderBy('code', 'ASC')->get();
}
- /**
- * @return Collection
- */
public function getCurrencies(): Collection
{
- return TransactionCurrency::where('enabled', true)->orderBy('code', 'ASC')->get();
+ /** @var User $user */
+ $user = auth()->user();
+
+ return $user->currencies()->orderBy('code', 'ASC')->get();
}
- /**
- * @return string
- * @throws FireflyException
- * @throws ContainerExceptionInterface
- * @throws NotFoundExceptionInterface
- */
- public function getCurrencyCode(): string
- {
- $cache = new CacheProperties();
- $cache->addProperty('getCurrencyCode');
- if ($cache->has()) {
- return $cache->get();
- }
- $currencyPreference = app('preferences')->get('currencyPreference', config('firefly.default_currency', 'EUR'));
-
- $currency = TransactionCurrency::where('code', $currencyPreference->data)->first();
- if ($currency) {
- $cache->store($currency->code);
-
- return $currency->code;
- }
- $cache->store(config('firefly.default_currency', 'EUR'));
-
- return (string)config('firefly.default_currency', 'EUR');
- }
-
- /**
- * @return TransactionCurrency
- * @throws FireflyException
- */
public function getDefaultCurrency(): TransactionCurrency
{
/** @var User $user */
$user = auth()->user();
- return $this->getDefaultCurrencyByUser($user);
+ return $this->getDefaultCurrencyByUserGroup($user->userGroup);
}
- /**
- * @param User $user
- *
- * @return TransactionCurrency
- * @throws FireflyException
- */
- public function getDefaultCurrencyByUser(User $user): TransactionCurrency
+ public function getDefaultCurrencyByUserGroup(UserGroup $userGroup): TransactionCurrency
{
- $cache = new CacheProperties();
- $cache->addProperty('getDefaultCurrency');
- $cache->addProperty($user->id);
+ $cache = new CacheProperties();
+ $cache->addProperty('getDefaultCurrencyByGroup');
+ $cache->addProperty($userGroup->id);
if ($cache->has()) {
return $cache->get();
}
- $currencyPreference = app('preferences')->getForUser($user, 'currencyPreference', config('firefly.default_currency', 'EUR'));
- $currencyPrefStr = $currencyPreference ? $currencyPreference->data : 'EUR';
-
- // at this point the currency preference could be encrypted, if coming from an old version.
- $currencyCode = $this->tryDecrypt((string)$currencyPrefStr);
-
- // could still be json encoded:
- /** @var TransactionCurrency|null $currency */
- $currency = TransactionCurrency::where('code', $currencyCode)->first();
- if (null === $currency) {
- // get EUR
- $currency = TransactionCurrency::where('code', 'EUR')->first();
+ $default = $userGroup->currencies()->where('group_default', true)->first();
+ if (null === $default) {
+ $default = $this->getSystemCurrency();
+ // could be the user group has no default right now.
+ $userGroup->currencies()->sync([$default->id => ['group_default' => true]]);
}
- $cache->store($currency);
+ $cache->store($default);
- return $currency;
+ return $default;
+ }
+
+ public function getSystemCurrency(): TransactionCurrency
+ {
+ return TransactionCurrency::where('code', 'EUR')->first();
}
/**
- * @param string $value
- *
- * @return string
+ * @deprecated use getDefaultCurrencyByUserGroup instead
*/
- private function tryDecrypt(string $value): string
+ public function getDefaultCurrencyByUser(User $user): TransactionCurrency
{
- try {
- $value = Crypt::decrypt($value); // verified
- } catch (DecryptException $e) {
- // @ignoreException
- }
-
- return $value;
+ return $this->getDefaultCurrencyByUserGroup($user->userGroup);
}
/**
@@ -203,7 +138,6 @@ class Amount
*
* Used only in one place.
*
- * @return array
* @throws FireflyException
*/
public function getJsConfig(): array
@@ -224,39 +158,34 @@ class Amount
}
/**
- * @return array
* @throws FireflyException
+ *
+ * @SuppressWarnings(PHPMD.MissingImport)
*/
private function getLocaleInfo(): array
{
// get config from preference, not from translation:
- $locale = app('steam')->getLocale();
- $array = app('steam')->getLocaleArray($locale);
+ $locale = app('steam')->getLocale();
+ $array = app('steam')->getLocaleArray($locale);
setlocale(LC_MONETARY, $array);
- $info = localeconv();
+ $info = localeconv();
// correct variables
- $info['n_cs_precedes'] = $this->getLocaleField($info, 'n_cs_precedes');
- $info['p_cs_precedes'] = $this->getLocaleField($info, 'p_cs_precedes');
+ $info['n_cs_precedes'] = $this->getLocaleField($info, 'n_cs_precedes');
+ $info['p_cs_precedes'] = $this->getLocaleField($info, 'p_cs_precedes');
- $info['n_sep_by_space'] = $this->getLocaleField($info, 'n_sep_by_space');
- $info['p_sep_by_space'] = $this->getLocaleField($info, 'p_sep_by_space');
+ $info['n_sep_by_space'] = $this->getLocaleField($info, 'n_sep_by_space');
+ $info['p_sep_by_space'] = $this->getLocaleField($info, 'p_sep_by_space');
- $fmt = new NumberFormatter($locale, NumberFormatter::CURRENCY);
+ $fmt = new \NumberFormatter($locale, \NumberFormatter::CURRENCY);
- $info['mon_decimal_point'] = $fmt->getSymbol(NumberFormatter::MONETARY_SEPARATOR_SYMBOL);
- $info['mon_thousands_sep'] = $fmt->getSymbol(NumberFormatter::MONETARY_GROUPING_SEPARATOR_SYMBOL);
+ $info['mon_decimal_point'] = $fmt->getSymbol(\NumberFormatter::MONETARY_SEPARATOR_SYMBOL);
+ $info['mon_thousands_sep'] = $fmt->getSymbol(\NumberFormatter::MONETARY_GROUPING_SEPARATOR_SYMBOL);
return $info;
}
- /**
- * @param array $info
- * @param string $field
- *
- * @return bool
- */
private function getLocaleField(array $info, string $field): bool
{
return (is_bool($info[$field]) && true === $info[$field])
@@ -268,19 +197,11 @@ class Amount
* int $signPosn = $localeconv['n_sign_posn']
* string $sign = $localeconv['negative_sign']
* bool $csPrecedes = $localeconv['n_cs_precedes'].
- *
- * @param bool $sepBySpace
- * @param int $signPosn
- * @param string $sign
- * @param bool $csPrecedes
- *
- * @return string
- *
*/
public static function getAmountJsConfig(bool $sepBySpace, int $signPosn, string $sign, bool $csPrecedes): string
{
// negative first:
- $space = ' ';
+ $space = ' ';
// require space between symbol and amount?
if (false === $sepBySpace) {
@@ -289,11 +210,11 @@ class Amount
// there are five possible positions for the "+" or "-" sign (if it is even used)
// pos_a and pos_e could be the ( and ) symbol.
- $posA = ''; // before everything
- $posB = ''; // before currency symbol
- $posC = ''; // after currency symbol
- $posD = ''; // before amount
- $posE = ''; // after everything
+ $posA = ''; // before everything
+ $posB = ''; // before currency symbol
+ $posC = ''; // after currency symbol
+ $posD = ''; // before amount
+ $posE = ''; // after everything
// format would be (currency before amount)
// AB%sC_D%vE
@@ -308,40 +229,40 @@ class Amount
// ( and ) around the whole thing
$posA = '(';
$posE = ')';
+
break;
+
case 1:
// The sign string precedes the quantity and currency_symbol
$posA = $sign;
+
break;
+
case 2:
// The sign string succeeds the quantity and currency_symbol
$posE = $sign;
+
break;
+
case 3:
// The sign string immediately precedes the currency_symbol
$posB = $sign;
+
break;
+
case 4:
// The sign string immediately succeeds the currency_symbol
$posC = $sign;
}
// default is amount before currency
- $format = $posA . $posD . '%v' . $space . $posB . '%s' . $posC . $posE;
+ $format = $posA.$posD.'%v'.$space.$posB.'%s'.$posC.$posE;
if ($csPrecedes) {
// alternative is currency before amount
- $format = $posA . $posB . '%s' . $posC . $space . $posD . '%v' . $posE;
+ $format = $posA.$posB.'%s'.$posC.$space.$posD.'%v'.$posE;
}
return $format;
}
-
- /**
- * @return TransactionCurrency
- */
- public function getSystemCurrency(): TransactionCurrency
- {
- return TransactionCurrency::where('code', 'EUR')->first();
- }
}
diff --git a/app/Support/Authentication/RemoteUserGuard.php b/app/Support/Authentication/RemoteUserGuard.php
index c5ae8198d1..fa3ed47409 100644
--- a/app/Support/Authentication/RemoteUserGuard.php
+++ b/app/Support/Authentication/RemoteUserGuard.php
@@ -31,70 +31,59 @@ use Illuminate\Contracts\Auth\Guard;
use Illuminate\Contracts\Auth\UserProvider;
use Illuminate\Contracts\Foundation\Application;
use Illuminate\Http\Request;
-use Illuminate\Support\Facades\Log;
-use Psr\Container\ContainerExceptionInterface;
-use Psr\Container\NotFoundExceptionInterface;
/**
* Class RemoteUserGuard
*/
class RemoteUserGuard implements Guard
{
- protected Application $application;
- protected $provider;
- protected $user;
+ protected Application $application;
+ protected UserProvider $provider;
+ protected ?User $user;
/**
* Create a new authentication guard.
- *
- * @param UserProvider $provider
- * @param Application $app
- *
- * @throws ContainerExceptionInterface
- * @throws NotFoundExceptionInterface
*/
public function __construct(UserProvider $provider, Application $app)
{
- /** @var Request $request */
- $request = $app->get('request');
- Log::debug(sprintf('Created RemoteUserGuard for %s "%s"', $request?->getMethod(), $request?->getRequestUri()));
+ /** @var null|Request $request */
+ $request = $app->get('request');
+ app('log')->debug(sprintf('Created RemoteUserGuard for %s "%s"', $request?->getMethod(), $request?->getRequestUri()));
$this->application = $app;
$this->provider = $provider;
$this->user = null;
}
- /**
- *
- */
public function authenticate(): void
{
- Log::debug(sprintf('Now at %s', __METHOD__));
+ app('log')->debug(sprintf('Now at %s', __METHOD__));
if (null !== $this->user) {
- Log::debug(sprintf('%s is found: #%d, "%s".', get_class($this->user), $this->user->id, $this->user->email));
+ app('log')->debug(sprintf('%s is found: #%d, "%s".', get_class($this->user), $this->user->id, $this->user->email));
return;
}
// Get the user identifier from $_SERVER or apache filtered headers
- $header = config('auth.guard_header', 'REMOTE_USER');
- $userID = request()->server($header) ?? null;
+ $header = config('auth.guard_header', 'REMOTE_USER');
+ $userID = request()->server($header) ?? null;
if (function_exists('apache_request_headers')) {
- Log::debug('Use apache_request_headers to find user ID.');
+ app('log')->debug('Use apache_request_headers to find user ID.');
$userID = request()->server($header) ?? apache_request_headers()[$header] ?? null;
}
if (null === $userID || '' === $userID) {
- Log::error(sprintf('No user in header "%s".', $header));
+ app('log')->error(sprintf('No user in header "%s".', $header));
+
throw new FireflyException('The guard header was unexpectedly empty. See the logs.');
}
- Log::debug(sprintf('User ID found in header is "%s"', $userID));
+ app('log')->debug(sprintf('User ID found in header is "%s"', $userID));
/** @var User $retrievedUser */
$retrievedUser = $this->provider->retrieveById($userID);
// store email address if present in header and not already set.
- $header = config('auth.guard_email');
+ $header = config('auth.guard_email');
if (null !== $header) {
$emailAddress = (string)(request()->server($header) ?? apache_request_headers()[$header] ?? null);
@@ -109,85 +98,81 @@ class RemoteUserGuard implements Guard
}
}
- Log::debug(sprintf('Result of getting user from provider: %s', $retrievedUser->email));
- $this->user = $retrievedUser;
+ app('log')->debug(sprintf('Result of getting user from provider: %s', $retrievedUser->email));
+ $this->user = $retrievedUser;
}
- /**
- * @inheritDoc
- */
public function guest(): bool
{
- Log::debug(sprintf('Now at %s', __METHOD__));
+ app('log')->debug(sprintf('Now at %s', __METHOD__));
+
return !$this->check();
}
- /**
- * @inheritDoc
- */
public function check(): bool
{
- Log::debug(sprintf('Now at %s', __METHOD__));
- return !is_null($this->user());
+ app('log')->debug(sprintf('Now at %s', __METHOD__));
+
+ return null !== $this->user();
}
- /**
- * @inheritDoc
- */
public function user(): ?User
{
- Log::debug(sprintf('Now at %s', __METHOD__));
+ app('log')->debug(sprintf('Now at %s', __METHOD__));
$user = $this->user;
if (null === $user) {
- Log::debug('User is NULL');
+ app('log')->debug('User is NULL');
+
return null;
}
return $user;
}
- /**
- * @inheritDoc
- */
public function hasUser(): bool
{
- Log::debug(sprintf('Now at %s', __METHOD__));
+ app('log')->debug(sprintf('Now at %s', __METHOD__));
+
throw new FireflyException('Did not implement RemoteUserGuard::hasUser()');
}
/**
- * @inheritDoc
+ * @SuppressWarnings(PHPMD.ShortMethodName)
*/
- public function id(): ?User
+ public function id(): null|int|string
{
- Log::debug(sprintf('Now at %s', __METHOD__));
- return $this->user;
+ app('log')->debug(sprintf('Now at %s', __METHOD__));
+
+ return $this->user?->id;
+ }
+
+ public function setUser(null|Authenticatable|User $user): void
+ {
+ app('log')->debug(sprintf('Now at %s', __METHOD__));
+ if ($user instanceof User) {
+ $this->user = $user;
+
+ return;
+ }
+ app('log')->error(sprintf('Did not set user at %s', __METHOD__));
}
/**
- * @inheritDoc
+ * @throws FireflyException
+ *
+ * @SuppressWarnings(PHPMD.UnusedFormalParameter)
*/
- public function setUser(Authenticatable $user)
+ public function validate(array $credentials = []): bool
{
- Log::debug(sprintf('Now at %s', __METHOD__));
- $this->user = $user;
- }
+ app('log')->debug(sprintf('Now at %s', __METHOD__));
- /**
- * @inheritDoc
- */
- public function validate(array $credentials = [])
- {
- Log::debug(sprintf('Now at %s', __METHOD__));
throw new FireflyException('Did not implement RemoteUserGuard::validate()');
}
- /**
- * @return bool
- */
public function viaRemember(): bool
{
- Log::debug(sprintf('Now at %s', __METHOD__));
+ app('log')->debug(sprintf('Now at %s', __METHOD__));
+
return false;
}
}
diff --git a/app/Support/Authentication/RemoteUserProvider.php b/app/Support/Authentication/RemoteUserProvider.php
index 73499a7679..c507e9478b 100644
--- a/app/Support/Authentication/RemoteUserProvider.php
+++ b/app/Support/Authentication/RemoteUserProvider.php
@@ -30,8 +30,6 @@ use FireflyIII\Models\Role;
use FireflyIII\User;
use Illuminate\Contracts\Auth\Authenticatable;
use Illuminate\Contracts\Auth\UserProvider;
-use Illuminate\Support\Facades\Log;
-use Str;
/**
* Class RemoteUserProvider
@@ -39,29 +37,34 @@ use Str;
class RemoteUserProvider implements UserProvider
{
/**
- * @inheritDoc
+ * @throws FireflyException
+ *
+ * @SuppressWarnings(PHPMD.UnusedFormalParameter)
*/
- public function retrieveByCredentials(array $credentials)
+ public function retrieveByCredentials(array $credentials): ?Authenticatable
{
- Log::debug(sprintf('Now at %s', __METHOD__));
+ app('log')->debug(sprintf('Now at %s', __METHOD__));
+
throw new FireflyException(sprintf('Did not implement %s', __METHOD__));
}
/**
- * @inheritDoc
+ * @param mixed $identifier
+ *
+ * @throws FireflyException
*/
public function retrieveById($identifier): User
{
- Log::debug(sprintf('Now at %s(%s)', __METHOD__, $identifier));
+ app('log')->debug(sprintf('Now at %s(%s)', __METHOD__, $identifier));
$user = User::where('email', $identifier)->first();
if (null === $user) {
- Log::debug(sprintf('User with email "%s" not found. Will be created.', $identifier));
+ app('log')->debug(sprintf('User with email "%s" not found. Will be created.', $identifier));
$user = User::create(
[
'blocked' => false,
'blocked_code' => null,
'email' => $identifier,
- 'password' => bcrypt(Str::random(64)),
+ 'password' => bcrypt(\Str::random(64)),
]
);
// if this is the first user, give them admin as well.
@@ -72,35 +75,49 @@ class RemoteUserProvider implements UserProvider
// make sure the user gets an administration as well.
CreateGroupMemberships::createGroupMembership($user);
}
- Log::debug(sprintf('Going to return user #%d (%s)', $user->id, $user->email));
+ app('log')->debug(sprintf('Going to return user #%d (%s)', $user->id, $user->email));
return $user;
}
/**
- * @inheritDoc
+ * @param mixed $identifier
+ * @param mixed $token
+ *
+ * @throws FireflyException
+ *
+ * @SuppressWarnings(PHPMD.UnusedFormalParameter)
*/
- public function retrieveByToken($identifier, $token)
+ public function retrieveByToken($identifier, $token): ?Authenticatable
{
- Log::debug(sprintf('Now at %s', __METHOD__));
+ app('log')->debug(sprintf('Now at %s', __METHOD__));
+
throw new FireflyException(sprintf('A) Did not implement %s', __METHOD__));
}
/**
- * @inheritDoc
+ * @SuppressWarnings(PHPMD.UnusedFormalParameter)
+ *
+ * @param mixed $token
+ *
+ * @throws FireflyException
*/
- public function updateRememberToken(Authenticatable $user, $token)
+ public function updateRememberToken(Authenticatable $user, $token): void
{
- Log::debug(sprintf('Now at %s', __METHOD__));
+ app('log')->debug(sprintf('Now at %s', __METHOD__));
+
throw new FireflyException(sprintf('B) Did not implement %s', __METHOD__));
}
/**
- * @inheritDoc
+ * @throws FireflyException
+ *
+ * @SuppressWarnings(PHPMD.UnusedFormalParameter)
*/
- public function validateCredentials(Authenticatable $user, array $credentials)
+ public function validateCredentials(Authenticatable $user, array $credentials): bool
{
- Log::debug(sprintf('Now at %s', __METHOD__));
+ app('log')->debug(sprintf('Now at %s', __METHOD__));
+
throw new FireflyException(sprintf('C) Did not implement %s', __METHOD__));
}
}
diff --git a/app/Support/Binder/AccountList.php b/app/Support/Binder/AccountList.php
index 728f77f402..79c8d65575 100644
--- a/app/Support/Binder/AccountList.php
+++ b/app/Support/Binder/AccountList.php
@@ -26,7 +26,6 @@ namespace FireflyIII\Support\Binder;
use FireflyIII\Models\AccountType;
use Illuminate\Routing\Route;
use Illuminate\Support\Collection;
-use Illuminate\Support\Facades\Log;
use Symfony\Component\HttpKernel\Exception\NotFoundHttpException;
/**
@@ -35,12 +34,7 @@ use Symfony\Component\HttpKernel\Exception\NotFoundHttpException;
class AccountList implements BinderInterface
{
/**
- * @param string $value
- * @param Route $route
- *
- * @return Collection
* @throws NotFoundHttpException
- *
*/
public static function routeBinder(string $value, Route $route): Collection
{
@@ -49,27 +43,31 @@ class AccountList implements BinderInterface
if ('allAssetAccounts' === $value) {
/** @var Collection $collection */
$collection = auth()->user()->accounts()
- ->leftJoin('account_types', 'account_types.id', '=', 'accounts.account_type_id')
- ->whereIn('account_types.type', [AccountType::ASSET, AccountType::LOAN, AccountType::DEBT, AccountType::MORTGAGE])
- ->orderBy('accounts.name', 'ASC')
- ->get(['accounts.*']);
+ ->leftJoin('account_types', 'account_types.id', '=', 'accounts.account_type_id')
+ ->whereIn('account_types.type', [AccountType::ASSET, AccountType::LOAN, AccountType::DEBT, AccountType::MORTGAGE])
+ ->orderBy('accounts.name', 'ASC')
+ ->get(['accounts.*'])
+ ;
}
if ('allAssetAccounts' !== $value) {
- $incoming = array_map('\intval', explode(',', $value));
- $list = array_merge(array_unique($incoming), [0]);
+ $incoming = array_map('\intval', explode(',', $value));
+ $list = array_merge(array_unique($incoming), [0]);
+
/** @var Collection $collection */
$collection = auth()->user()->accounts()
- ->leftJoin('account_types', 'account_types.id', '=', 'accounts.account_type_id')
- ->whereIn('accounts.id', $list)
- ->orderBy('accounts.name', 'ASC')
- ->get(['accounts.*']);
+ ->leftJoin('account_types', 'account_types.id', '=', 'accounts.account_type_id')
+ ->whereIn('accounts.id', $list)
+ ->orderBy('accounts.name', 'ASC')
+ ->get(['accounts.*'])
+ ;
}
if ($collection->count() > 0) {
return $collection;
}
}
- Log::error(sprintf('Trying to show account list (%s), but user is not logged in or list is empty.', $route->uri));
+ app('log')->error(sprintf('Trying to show account list (%s), but user is not logged in or list is empty.', $route->uri));
+
throw new NotFoundHttpException();
}
}
diff --git a/app/Support/Binder/BinderInterface.php b/app/Support/Binder/BinderInterface.php
index 7a9c489268..345c357f7c 100644
--- a/app/Support/Binder/BinderInterface.php
+++ b/app/Support/Binder/BinderInterface.php
@@ -31,9 +31,6 @@ use Illuminate\Routing\Route;
interface BinderInterface
{
/**
- * @param string $value
- * @param Route $route
- *
* @return mixed
*/
public static function routeBinder(string $value, Route $route);
diff --git a/app/Support/Binder/BudgetList.php b/app/Support/Binder/BudgetList.php
index 8545171385..6526ebd38a 100644
--- a/app/Support/Binder/BudgetList.php
+++ b/app/Support/Binder/BudgetList.php
@@ -34,37 +34,33 @@ use Symfony\Component\HttpKernel\Exception\NotFoundHttpException;
class BudgetList implements BinderInterface
{
/**
- * @param string $value
- * @param Route $route
- *
- * @return Collection
* @throws NotFoundHttpException
- *
*/
public static function routeBinder(string $value, Route $route): Collection
{
if (auth()->check()) {
if ('allBudgets' === $value) {
return auth()->user()->budgets()->where('active', true)
- ->orderBy('order', 'ASC')
- ->orderBy('name', 'ASC')
- ->get();
+ ->orderBy('order', 'ASC')
+ ->orderBy('name', 'ASC')
+ ->get()
+ ;
}
- $list = array_unique(array_map('\intval', explode(',', $value)));
+ $list = array_unique(array_map('\intval', explode(',', $value)));
-
- if (0 === count($list)) {
+ if (0 === count($list)) { // @phpstan-ignore-line
app('log')->warning('Budget list count is zero, return 404.');
+
throw new NotFoundHttpException();
}
-
/** @var Collection $collection */
$collection = auth()->user()->budgets()
- ->where('active', true)
- ->whereIn('id', $list)
- ->get();
+ ->where('active', true)
+ ->whereIn('id', $list)
+ ->get()
+ ;
// add empty budget if applicable.
if (in_array(0, $list, true)) {
@@ -76,6 +72,7 @@ class BudgetList implements BinderInterface
}
}
app('log')->warning('BudgetList fallback to 404.');
+
throw new NotFoundHttpException();
}
}
diff --git a/app/Support/Binder/CLIToken.php b/app/Support/Binder/CLIToken.php
index 207224fb3c..f965e505c8 100644
--- a/app/Support/Binder/CLIToken.php
+++ b/app/Support/Binder/CLIToken.php
@@ -26,7 +26,6 @@ namespace FireflyIII\Support\Binder;
use FireflyIII\Exceptions\FireflyException;
use FireflyIII\Repositories\User\UserRepositoryInterface;
use Illuminate\Routing\Route;
-use Illuminate\Support\Facades\Log;
use Symfony\Component\HttpKernel\Exception\NotFoundHttpException;
/**
@@ -35,10 +34,8 @@ use Symfony\Component\HttpKernel\Exception\NotFoundHttpException;
class CLIToken implements BinderInterface
{
/**
- * @param string $value
- * @param Route $route
- *
* @return mixed
+ *
* @throws FireflyException
*/
public static function routeBinder(string $value, Route $route)
@@ -48,19 +45,20 @@ class CLIToken implements BinderInterface
$users = $repository->all();
// check for static token
- if ($value === config('firefly.static_cron_token') && 32 === strlen((string)config('firefly.static_cron_token'))) {
+ if ($value === config('firefly.static_cron_token') && 32 === strlen(config('firefly.static_cron_token'))) {
return $value;
}
foreach ($users as $user) {
$accessToken = app('preferences')->getForUser($user, 'access_token');
if (null !== $accessToken && $accessToken->data === $value) {
- Log::info(sprintf('Recognized user #%d (%s) from his acccess token.', $user->id, $user->email));
+ app('log')->info(sprintf('Recognized user #%d (%s) from his access token.', $user->id, $user->email));
return $value;
}
}
- Log::error(sprintf('Recognized no users by access token "%s"', $value));
+ app('log')->error(sprintf('Recognized no users by access token "%s"', $value));
+
throw new NotFoundHttpException();
}
}
diff --git a/app/Support/Binder/CategoryList.php b/app/Support/Binder/CategoryList.php
index f140cc7607..1275481fa3 100644
--- a/app/Support/Binder/CategoryList.php
+++ b/app/Support/Binder/CategoryList.php
@@ -34,31 +34,28 @@ use Symfony\Component\HttpKernel\Exception\NotFoundHttpException;
class CategoryList implements BinderInterface
{
/**
- * @param string $value
- * @param Route $route
- *
- * @return Collection
* @throws NotFoundHttpException
- *
*/
public static function routeBinder(string $value, Route $route): Collection
{
if (auth()->check()) {
if ('allCategories' === $value) {
return auth()->user()->categories()
- ->orderBy('name', 'ASC')
- ->get();
+ ->orderBy('name', 'ASC')
+ ->get()
+ ;
}
- $list = array_unique(array_map('\intval', explode(',', $value)));
- if (0 === count($list)) {
+ $list = array_unique(array_map('\intval', explode(',', $value)));
+ if (0 === count($list)) { // @phpstan-ignore-line
throw new NotFoundHttpException();
}
/** @var Collection $collection */
$collection = auth()->user()->categories()
- ->whereIn('id', $list)
- ->get();
+ ->whereIn('id', $list)
+ ->get()
+ ;
// add empty category if applicable.
if (in_array(0, $list, true)) {
@@ -69,6 +66,7 @@ class CategoryList implements BinderInterface
return $collection;
}
}
+
throw new NotFoundHttpException();
}
}
diff --git a/app/Support/Binder/CurrencyCode.php b/app/Support/Binder/CurrencyCode.php
index 2f8c141fa9..cc5000ede6 100644
--- a/app/Support/Binder/CurrencyCode.php
+++ b/app/Support/Binder/CurrencyCode.php
@@ -33,10 +33,6 @@ use Symfony\Component\HttpKernel\Exception\NotFoundHttpException;
class CurrencyCode implements BinderInterface
{
/**
- * @param string $value
- * @param Route $route
- *
- * @return TransactionCurrency
* @throws NotFoundHttpException
*/
public static function routeBinder(string $value, Route $route): TransactionCurrency
@@ -47,6 +43,7 @@ class CurrencyCode implements BinderInterface
return $currency;
}
}
+
throw new NotFoundHttpException();
}
}
diff --git a/app/Support/Binder/Date.php b/app/Support/Binder/Date.php
index 8ba226fbb5..99c0ce4c17 100644
--- a/app/Support/Binder/Date.php
+++ b/app/Support/Binder/Date.php
@@ -25,9 +25,9 @@ namespace FireflyIII\Support\Binder;
use Carbon\Carbon;
use Carbon\Exceptions\InvalidDateException;
+use Carbon\Exceptions\InvalidFormatException;
use FireflyIII\Helpers\Fiscal\FiscalHelperInterface;
use Illuminate\Routing\Route;
-use Illuminate\Support\Facades\Log;
use Symfony\Component\HttpKernel\Exception\NotFoundHttpException;
/**
@@ -36,10 +36,6 @@ use Symfony\Component\HttpKernel\Exception\NotFoundHttpException;
class Date implements BinderInterface
{
/**
- * @param string $value
- * @param Route $route
- *
- * @return Carbon
* @throws NotFoundHttpException
*/
public static function routeBinder(string $value, Route $route): Carbon
@@ -47,16 +43,16 @@ class Date implements BinderInterface
/** @var FiscalHelperInterface $fiscalHelper */
$fiscalHelper = app(FiscalHelperInterface::class);
- $magicWords = [
- 'currentMonthStart' => today(config('app.timezone'))->startOfMonth(),
- 'currentMonthEnd' => today(config('app.timezone'))->endOfMonth(),
- 'currentYearStart' => today(config('app.timezone'))->startOfYear(),
- 'currentYearEnd' => today(config('app.timezone'))->endOfYear(),
+ $magicWords = [
+ 'currentMonthStart' => today(config('app.timezone'))->startOfMonth(),
+ 'currentMonthEnd' => today(config('app.timezone'))->endOfMonth(),
+ 'currentYearStart' => today(config('app.timezone'))->startOfYear(),
+ 'currentYearEnd' => today(config('app.timezone'))->endOfYear(),
- 'previousMonthStart' => today(config('app.timezone'))->startOfMonth()->subDay()->startOfMonth(),
- 'previousMonthEnd' => today(config('app.timezone'))->startOfMonth()->subDay()->endOfMonth(),
- 'previousYearStart' => today(config('app.timezone'))->startOfYear()->subDay()->startOfYear(),
- 'previousYearEnd' => today(config('app.timezone'))->startOfYear()->subDay()->endOfYear(),
+ 'previousMonthStart' => today(config('app.timezone'))->startOfMonth()->subDay()->startOfMonth(),
+ 'previousMonthEnd' => today(config('app.timezone'))->startOfMonth()->subDay()->endOfMonth(),
+ 'previousYearStart' => today(config('app.timezone'))->startOfYear()->subDay()->startOfYear(),
+ 'previousYearEnd' => today(config('app.timezone'))->startOfYear()->subDay()->endOfYear(),
'currentFiscalYearStart' => $fiscalHelper->startOfFiscalYear(today(config('app.timezone'))),
'currentFiscalYearEnd' => $fiscalHelper->endOfFiscalYear(today(config('app.timezone'))),
@@ -65,17 +61,18 @@ class Date implements BinderInterface
];
if (array_key_exists($value, $magicWords)) {
$return = $magicWords[$value];
- Log::debug(sprintf('User requests "%s", so will return "%s"', $value, $return));
+ app('log')->debug(sprintf('User requests "%s", so will return "%s"', $value, $return));
return $return;
}
try {
$result = new Carbon($value);
- } catch (InvalidDateException $e) {
+ } catch (InvalidDateException|InvalidFormatException $e) { // @phpstan-ignore-line
$message = sprintf('Could not parse date "%s" for user #%d: %s', $value, auth()->user()->id, $e->getMessage());
- Log::error($message);
- throw new NotFoundHttpException($message, $e);
+ app('log')->error($message);
+
+ throw new NotFoundHttpException('Could not parse value', $e);
}
return $result;
diff --git a/app/Support/Binder/DynamicConfigKey.php b/app/Support/Binder/DynamicConfigKey.php
index e3fb1c608d..d277fc52f1 100644
--- a/app/Support/Binder/DynamicConfigKey.php
+++ b/app/Support/Binder/DynamicConfigKey.php
@@ -40,17 +40,16 @@ class DynamicConfigKey
];
/**
- * @param string $value
- * @param Route $route
- *
- * @return string
* @throws NotFoundHttpException
+ *
+ * @SuppressWarnings(PHPMD.UnusedFormalParameter)
*/
public static function routeBinder(string $value, Route $route): string
{
if (in_array($value, self::$accepted, true)) {
return $value;
}
+
throw new NotFoundHttpException();
}
}
diff --git a/app/Support/Binder/EitherConfigKey.php b/app/Support/Binder/EitherConfigKey.php
index f41db15cbf..719f98d481 100644
--- a/app/Support/Binder/EitherConfigKey.php
+++ b/app/Support/Binder/EitherConfigKey.php
@@ -57,17 +57,16 @@ class EitherConfigKey
];
/**
- * @param string $value
- * @param Route $route
- *
- * @return string
* @throws NotFoundHttpException
+ *
+ * @SuppressWarnings(PHPMD.UnusedFormalParameter)
*/
public static function routeBinder(string $value, Route $route): string
{
if (in_array($value, self::$static, true) || in_array($value, DynamicConfigKey::$accepted, true)) {
return $value;
}
+
throw new NotFoundHttpException();
}
}
diff --git a/app/Support/Binder/JournalList.php b/app/Support/Binder/JournalList.php
index a65f91df28..95b067a140 100644
--- a/app/Support/Binder/JournalList.php
+++ b/app/Support/Binder/JournalList.php
@@ -34,17 +34,12 @@ use Symfony\Component\HttpKernel\Exception\NotFoundHttpException;
class JournalList implements BinderInterface
{
/**
- * @param string $value
- * @param Route $route
- *
- * @return array
- *
* @throws NotFoundHttpException
*/
public static function routeBinder(string $value, Route $route): array
{
if (auth()->check()) {
- $list = self::parseList($value);
+ $list = self::parseList($value);
// get the journals by using the collector.
/** @var GroupCollectorInterface $collector */
@@ -52,25 +47,21 @@ class JournalList implements BinderInterface
$collector->setTypes([TransactionType::WITHDRAWAL, TransactionType::DEPOSIT, TransactionType::TRANSFER, TransactionType::RECONCILIATION]);
$collector->withCategoryInformation()->withBudgetInformation()->withTagInformation()->withAccountInformation();
$collector->setJournalIds($list);
- $result = $collector->getExtractedJournals();
+ $result = $collector->getExtractedJournals();
if (0 === count($result)) {
throw new NotFoundHttpException();
}
return $result;
}
+
throw new NotFoundHttpException();
}
- /**
- * @param string $value
- *
- * @return array
- */
protected static function parseList(string $value): array
{
$list = array_unique(array_map('\intval', explode(',', $value)));
- if (0 === count($list)) {
+ if (0 === count($list)) { // @phpstan-ignore-line
throw new NotFoundHttpException();
}
diff --git a/app/Support/Binder/TagList.php b/app/Support/Binder/TagList.php
index 4d1e92904e..d87c8c69b9 100644
--- a/app/Support/Binder/TagList.php
+++ b/app/Support/Binder/TagList.php
@@ -36,10 +36,6 @@ use Symfony\Component\HttpKernel\Exception\NotFoundHttpException;
class TagList implements BinderInterface
{
/**
- * @param string $value
- * @param Route $route
- *
- * @return Collection
* @throws NotFoundHttpException
*/
public static function routeBinder(string $value, Route $route): Collection
@@ -47,29 +43,34 @@ class TagList implements BinderInterface
if (auth()->check()) {
if ('allTags' === $value) {
return auth()->user()->tags()
- ->orderBy('tag', 'ASC')
- ->get();
+ ->orderBy('tag', 'ASC')
+ ->get()
+ ;
}
- $list = array_unique(array_map('\strtolower', explode(',', $value)));
- Log::debug('List of tags is', $list);
+ $list = array_unique(array_map('\strtolower', explode(',', $value)));
+ app('log')->debug('List of tags is', $list);
+
+ if (0 === count($list)) { // @phpstan-ignore-line
+ app('log')->error('Tag list is empty.');
- if (0 === count($list)) {
- Log::error('Tag list is empty.');
throw new NotFoundHttpException();
}
-
/** @var TagRepositoryInterface $repository */
$repository = app(TagRepositoryInterface::class);
$repository->setUser(auth()->user());
- $allTags = $repository->get();
+ $allTags = $repository->get();
$collection = $allTags->filter(
static function (Tag $tag) use ($list) {
if (in_array(strtolower($tag->tag), $list, true)) {
+ Log::debug(sprintf('TagList: (string) found tag #%d ("%s") in list.', $tag->id, $tag->tag));
+
return true;
}
if (in_array((string)$tag->id, $list, true)) {
+ Log::debug(sprintf('TagList: (id) found tag #%d ("%s") in list.', $tag->id, $tag->tag));
+
return true;
}
@@ -81,7 +82,8 @@ class TagList implements BinderInterface
return $collection;
}
}
- Log::error('TagList: user is not logged in.');
+ app('log')->error('TagList: user is not logged in.');
+
throw new NotFoundHttpException();
}
}
diff --git a/app/Support/Binder/TagOrId.php b/app/Support/Binder/TagOrId.php
index 8c79ec13a2..e742fb674d 100644
--- a/app/Support/Binder/TagOrId.php
+++ b/app/Support/Binder/TagOrId.php
@@ -26,7 +26,6 @@ namespace FireflyIII\Support\Binder;
use FireflyIII\Models\Tag;
use FireflyIII\Repositories\Tag\TagRepositoryInterface;
use Illuminate\Routing\Route;
-use Illuminate\Support\Facades\Log;
use Symfony\Component\HttpKernel\Exception\NotFoundHttpException;
/**
@@ -34,12 +33,6 @@ use Symfony\Component\HttpKernel\Exception\NotFoundHttpException;
*/
class TagOrId implements BinderInterface
{
- /**
- * @param string $value
- * @param Route $route
- *
- * @return Tag
- */
public static function routeBinder(string $value, Route $route): Tag
{
if (auth()->check()) {
@@ -47,17 +40,19 @@ class TagOrId implements BinderInterface
$repository = app(TagRepositoryInterface::class);
$repository->setUser(auth()->user());
- $result = $repository->findByTag($value);
+ $result = $repository->findByTag($value);
if (null === $result) {
$result = $repository->find((int)$value);
}
if (null !== $result) {
return $result;
}
- Log::error('TagOrId: tag not found.');
+ app('log')->error('TagOrId: tag not found.');
+
throw new NotFoundHttpException();
}
- Log::error('TagOrId: user is not logged in.');
+ app('log')->error('TagOrId: user is not logged in.');
+
throw new NotFoundHttpException();
}
}
diff --git a/app/Support/Binder/UserGroupAccount.php b/app/Support/Binder/UserGroupAccount.php
index b70d19183d..c395655e87 100644
--- a/app/Support/Binder/UserGroupAccount.php
+++ b/app/Support/Binder/UserGroupAccount.php
@@ -26,7 +26,6 @@ namespace FireflyIII\Support\Binder;
use FireflyIII\Models\Account;
use FireflyIII\User;
use Illuminate\Routing\Route;
-use Illuminate\Support\Collection;
use Symfony\Component\HttpKernel\Exception\NotFoundHttpException;
/**
@@ -35,25 +34,22 @@ use Symfony\Component\HttpKernel\Exception\NotFoundHttpException;
class UserGroupAccount implements BinderInterface
{
/**
- * @param string $value
- * @param Route $route
- *
- * @return Account
* @throws NotFoundHttpException
- *
*/
public static function routeBinder(string $value, Route $route): Account
{
if (auth()->check()) {
/** @var User $user */
- $user = auth()->user();
- $currency = Account::where('id', (int)$value)
- ->where('user_group_id', $user->user_group_id)
- ->first();
- if (null !== $currency) {
- return $currency;
+ $user = auth()->user();
+ $account = Account::where('id', (int)$value)
+ ->where('user_group_id', $user->user_group_id)
+ ->first()
+ ;
+ if (null !== $account) {
+ return $account;
}
}
+
throw new NotFoundHttpException();
}
}
diff --git a/app/Support/Binder/UserGroupBill.php b/app/Support/Binder/UserGroupBill.php
index 09530c1230..bd2489965e 100644
--- a/app/Support/Binder/UserGroupBill.php
+++ b/app/Support/Binder/UserGroupBill.php
@@ -34,12 +34,7 @@ use Symfony\Component\HttpKernel\Exception\NotFoundHttpException;
class UserGroupBill implements BinderInterface
{
/**
- * @param string $value
- * @param Route $route
- *
- * @return Bill
* @throws NotFoundHttpException
- *
*/
public static function routeBinder(string $value, Route $route): Bill
{
@@ -47,12 +42,14 @@ class UserGroupBill implements BinderInterface
/** @var User $user */
$user = auth()->user();
$currency = Bill::where('id', (int)$value)
- ->where('user_group_id', $user->user_group_id)
- ->first();
+ ->where('user_group_id', $user->user_group_id)
+ ->first()
+ ;
if (null !== $currency) {
return $currency;
}
}
+
throw new NotFoundHttpException();
}
}
diff --git a/app/Support/Binder/UserGroupTransaction.php b/app/Support/Binder/UserGroupTransaction.php
new file mode 100644
index 0000000000..fbbf5c1f43
--- /dev/null
+++ b/app/Support/Binder/UserGroupTransaction.php
@@ -0,0 +1,52 @@
+.
+ */
+declare(strict_types=1);
+
+namespace FireflyIII\Support\Binder;
+
+use FireflyIII\Models\TransactionGroup;
+use FireflyIII\User;
+use Illuminate\Routing\Route;
+use Symfony\Component\HttpKernel\Exception\NotFoundHttpException;
+
+/**
+ * Class UserGroupTransaction.
+ */
+class UserGroupTransaction implements BinderInterface
+{
+ public static function routeBinder(string $value, Route $route): TransactionGroup
+ {
+ if (auth()->check()) {
+ /** @var User $user */
+ $user = auth()->user();
+ $group = TransactionGroup::where('id', (int)$value)
+ ->where('user_group_id', $user->user_group_id)
+ ->first()
+ ;
+ if (null !== $group) {
+ return $group;
+ }
+ }
+
+ throw new NotFoundHttpException();
+ }
+}
diff --git a/app/Support/CacheProperties.php b/app/Support/CacheProperties.php
index 8156dc691a..dc1619bddf 100644
--- a/app/Support/CacheProperties.php
+++ b/app/Support/CacheProperties.php
@@ -23,23 +23,16 @@ declare(strict_types=1);
namespace FireflyIII\Support;
-use Cache;
use Illuminate\Support\Collection;
-use JsonException;
/**
* Class CacheProperties.
- *
-
*/
class CacheProperties
{
protected string $hash = '';
protected Collection $properties;
- /**
- *
- */
public function __construct()
{
$this->properties = new Collection();
@@ -62,20 +55,14 @@ class CacheProperties
*/
public function get()
{
- return Cache::get($this->hash);
+ return \Cache::get($this->hash);
}
- /**
- * @return string
- */
public function getHash(): string
{
return $this->hash;
}
- /**
- * @return bool
- */
public function has(): bool
{
if ('testing' === config('app.env')) {
@@ -83,18 +70,16 @@ class CacheProperties
}
$this->hash();
- return Cache::has($this->hash);
+ return \Cache::has($this->hash);
}
- /**
- */
private function hash(): void
{
- $content = '';
+ $content = '';
foreach ($this->properties as $property) {
try {
$content .= json_encode($property, JSON_THROW_ON_ERROR);
- } catch (JsonException $e) {
+ } catch (\JsonException $e) {
// @ignoreException
$content .= hash('sha256', (string)time());
}
@@ -107,6 +92,6 @@ class CacheProperties
*/
public function store($data): void
{
- Cache::forever($this->hash, $data);
+ \Cache::forever($this->hash, $data);
}
}
diff --git a/app/Support/Calendar/Calculator.php b/app/Support/Calendar/Calculator.php
index b09ba58c59..c8fc629934 100644
--- a/app/Support/Calendar/Calculator.php
+++ b/app/Support/Calendar/Calculator.php
@@ -1,6 +1,5 @@
offsetGet($periodicity);
$interval = $this->skipInterval($skipInterval);
+
return $periodicity->nextDate($epoch->clone(), $interval);
}
- /**
- * @param Periodicity $periodicity
- *
- * @return bool
- */
public function isAvailablePeriodicity(Periodicity $periodicity): bool
{
return self::containsInterval($periodicity);
}
- /**
- * @param Periodicity $periodicity
- *
- * @return bool
- */
private static function containsInterval(Periodicity $periodicity): bool
{
return self::loadIntervalMap()->contains($periodicity);
}
/**
- * @return SplObjectStorage
+ * @SuppressWarnings(PHPMD.MissingImport)
*/
- private static function loadIntervalMap(): SplObjectStorage
+ private static function loadIntervalMap(): \SplObjectStorage
{
- if (self::$intervalMap != null) {
+ if (null !== self::$intervalMap) {
return self::$intervalMap;
}
- self::$intervalMap = new SplObjectStorage();
+ self::$intervalMap = new \SplObjectStorage();
foreach (Periodicity::cases() as $interval) {
- $periodicityClass = __NAMESPACE__ . "\\Periodicity\\{$interval->name}";
+ $periodicityClass = __NAMESPACE__."\\Periodicity\\{$interval->name}";
self::$intervals[] = $interval->name;
self::$intervalMap->attach($interval, new $periodicityClass());
}
+
return self::$intervalMap;
}
- /**
- * @param int $skip
- *
- * @return int
- */
private function skipInterval(int $skip): int
{
return self::DEFAULT_INTERVAL + $skip;
}
-
}
diff --git a/app/Support/Calendar/Periodicity.php b/app/Support/Calendar/Periodicity.php
index 83803c2ce4..e7e37b0ca5 100644
--- a/app/Support/Calendar/Periodicity.php
+++ b/app/Support/Calendar/Periodicity.php
@@ -1,6 +1,5 @@
diff --git a/app/Support/Calendar/Periodicity/Bimonthly.php b/app/Support/Calendar/Periodicity/Bimonthly.php
index 849e7b19c4..ce89863100 100644
--- a/app/Support/Calendar/Periodicity/Bimonthly.php
+++ b/app/Support/Calendar/Periodicity/Bimonthly.php
@@ -1,6 +1,5 @@
@@ -30,5 +29,5 @@ namespace FireflyIII\Support\Calendar\Periodicity;
*/
final class Bimonthly extends Monthly
{
- public const INTERVAL = 2;
+ public const int INTERVAL = 2;
}
diff --git a/app/Support/Calendar/Periodicity/Daily.php b/app/Support/Calendar/Periodicity/Daily.php
index 5b9a661322..1b5811644b 100644
--- a/app/Support/Calendar/Periodicity/Daily.php
+++ b/app/Support/Calendar/Periodicity/Daily.php
@@ -1,6 +1,5 @@
@@ -32,14 +31,8 @@ use Carbon\Carbon;
*/
final class Daily extends Interval
{
- /**
- * @param Carbon $date
- * @param int $interval
- *
- * @return Carbon
- */
public function nextDate(Carbon $date, int $interval = 1): Carbon
{
- return ($date->clone())->addDays($this->skip($interval));
+ return $date->clone()->addDays($this->skip($interval));
}
}
diff --git a/app/Support/Calendar/Periodicity/Fortnightly.php b/app/Support/Calendar/Periodicity/Fortnightly.php
index 680d9d2341..99327e0276 100644
--- a/app/Support/Calendar/Periodicity/Fortnightly.php
+++ b/app/Support/Calendar/Periodicity/Fortnightly.php
@@ -1,6 +1,5 @@
@@ -30,5 +29,5 @@ namespace FireflyIII\Support\Calendar\Periodicity;
*/
final class Fortnightly extends Weekly
{
- public const INTERVAL = 2;
+ public const int INTERVAL = 2;
}
diff --git a/app/Support/Calendar/Periodicity/HalfYearly.php b/app/Support/Calendar/Periodicity/HalfYearly.php
index 5e34b92a93..4471a4f030 100644
--- a/app/Support/Calendar/Periodicity/HalfYearly.php
+++ b/app/Support/Calendar/Periodicity/HalfYearly.php
@@ -1,6 +1,5 @@
@@ -30,5 +29,5 @@ namespace FireflyIII\Support\Calendar\Periodicity;
*/
final class HalfYearly extends Monthly
{
- public const INTERVAL = 6;
+ public const int INTERVAL = 6;
}
diff --git a/app/Support/Calendar/Periodicity/Interspacable.php b/app/Support/Calendar/Periodicity/Interspacable.php
index 0e3281a4ba..b1d2ab5b42 100644
--- a/app/Support/Calendar/Periodicity/Interspacable.php
+++ b/app/Support/Calendar/Periodicity/Interspacable.php
@@ -1,6 +1,5 @@
@@ -32,11 +31,5 @@ use Carbon\Carbon;
*/
interface Interspacable
{
- /**
- * @param Carbon $date
- * @param int $interval
- *
- * @return Carbon
- */
public function nextDate(Carbon $date, int $interval = 1): Carbon;
}
diff --git a/app/Support/Calendar/Periodicity/Interval.php b/app/Support/Calendar/Periodicity/Interval.php
index c3a3a06805..ec34c1d43d 100644
--- a/app/Support/Calendar/Periodicity/Interval.php
+++ b/app/Support/Calendar/Periodicity/Interval.php
@@ -1,6 +1,5 @@
@@ -30,14 +29,9 @@ namespace FireflyIII\Support\Calendar\Periodicity;
*/
abstract class Interval implements Interspacable
{
- public const INTERVAL = 1;
+ public const int INTERVAL = 1;
- /**
- * @param int $skip
- *
- * @return int
- */
- public function skip(int $skip): int
+ final public function skip(int $skip): int
{
return static::INTERVAL * $skip;
}
diff --git a/app/Support/Calendar/Periodicity/Monthly.php b/app/Support/Calendar/Periodicity/Monthly.php
index 983383ab90..a2b1112d93 100644
--- a/app/Support/Calendar/Periodicity/Monthly.php
+++ b/app/Support/Calendar/Periodicity/Monthly.php
@@ -1,6 +1,5 @@
@@ -32,14 +31,8 @@ use Carbon\Carbon;
*/
class Monthly extends Interval
{
- /**
- * @param Carbon $date
- * @param int $interval
- *
- * @return Carbon
- */
public function nextDate(Carbon $date, int $interval = 1): Carbon
{
- return ($date->clone())->addMonthsNoOverflow($this->skip($interval));
+ return $date->clone()->addMonthsNoOverflow($this->skip($interval));
}
}
diff --git a/app/Support/Calendar/Periodicity/Quarterly.php b/app/Support/Calendar/Periodicity/Quarterly.php
index 839a7131f6..a9cd21b9a1 100644
--- a/app/Support/Calendar/Periodicity/Quarterly.php
+++ b/app/Support/Calendar/Periodicity/Quarterly.php
@@ -1,6 +1,5 @@
@@ -30,5 +29,5 @@ namespace FireflyIII\Support\Calendar\Periodicity;
*/
final class Quarterly extends Monthly
{
- public const INTERVAL = 3;
+ public const int INTERVAL = 3;
}
diff --git a/app/Support/Calendar/Periodicity/Weekly.php b/app/Support/Calendar/Periodicity/Weekly.php
index 54e33408a6..c4252eab93 100644
--- a/app/Support/Calendar/Periodicity/Weekly.php
+++ b/app/Support/Calendar/Periodicity/Weekly.php
@@ -1,6 +1,5 @@
@@ -32,14 +31,8 @@ use Carbon\Carbon;
*/
class Weekly extends Interval
{
- /**
- * @param Carbon $date
- * @param int $interval
- *
- * @return Carbon
- */
public function nextDate(Carbon $date, int $interval = 1): Carbon
{
- return ($date->clone())->addWeeks($this->skip($interval));
+ return $date->clone()->addWeeks($this->skip($interval));
}
}
diff --git a/app/Support/Calendar/Periodicity/Yearly.php b/app/Support/Calendar/Periodicity/Yearly.php
index 794bc111dd..1cf997c3fe 100644
--- a/app/Support/Calendar/Periodicity/Yearly.php
+++ b/app/Support/Calendar/Periodicity/Yearly.php
@@ -1,6 +1,5 @@
@@ -32,14 +31,8 @@ use Carbon\Carbon;
*/
final class Yearly extends Interval
{
- /**
- * @param Carbon $date
- * @param int $interval
- *
- * @return Carbon
- */
public function nextDate(Carbon $date, int $interval = 1): Carbon
{
- return ($date->clone())->addYearsNoOverflow($this->skip($interval));
+ return $date->clone()->addYearsNoOverflow($this->skip($interval));
}
}
diff --git a/app/Support/Chart/Budget/FrontpageChartGenerator.php b/app/Support/Chart/Budget/FrontpageChartGenerator.php
index 086092da0d..2e09e909a0 100644
--- a/app/Support/Chart/Budget/FrontpageChartGenerator.php
+++ b/app/Support/Chart/Budget/FrontpageChartGenerator.php
@@ -82,11 +82,6 @@ class FrontpageChartGenerator
* For each budget, gets all budget limits for the current time range.
* When no limits are present, the time range is used to collect information on money spent.
* If limits are present, each limit is processed individually.
- *
- * @param array $data
- * @param Budget $budget
- *
- * @return array
*/
private function processBudget(array $data, Budget $budget): array
{
@@ -104,15 +99,11 @@ class FrontpageChartGenerator
/**
* When no limits are present, the expenses of the whole period are collected and grouped.
* This is grouped per currency. Because there is no limit set, "left to spend" and "overspent" are empty.
- *
- * @param array $data
- * @param Budget $budget
- *
- * @return array
*/
private function noBudgetLimits(array $data, Budget $budget): array
{
$spent = $this->opsRepository->sumExpenses($this->start, $this->end, null, new Collection([$budget]));
+
/** @var array $entry */
foreach ($spent as $entry) {
$title = sprintf('%s (%s)', $budget->name, $entry['currency_name']);
@@ -126,12 +117,6 @@ class FrontpageChartGenerator
/**
* If a budget has budget limit, each limit is processed individually.
- *
- * @param array $data
- * @param Budget $budget
- * @param Collection $limits
- *
- * @return array
*/
private function budgetLimits(array $data, Budget $budget, Collection $limits): array
{
@@ -146,20 +131,15 @@ class FrontpageChartGenerator
/**
* For each limit, the expenses from the time range of the limit are collected. Each row from the result is
* processed individually.
- *
- * @param array $data
- * @param Budget $budget
- * @param BudgetLimit $limit
- *
- * @return array
*/
private function processLimit(array $data, Budget $budget, BudgetLimit $limit): array
{
$spent = $this->opsRepository->sumExpenses($limit->start_date, $limit->end_date, null, new Collection([$budget]), $limit->transactionCurrency);
+
/** @var array $entry */
foreach ($spent as $entry) {
// only spent the entry where the entry's currency matches the budget limit's currency
- if ($entry['currency_id'] === (int)$limit->transaction_currency_id) {
+ if ($entry['currency_id'] === $limit->transaction_currency_id) {
$data = $this->processRow($data, $budget, $limit, $entry);
}
}
@@ -172,17 +152,10 @@ class FrontpageChartGenerator
*
* Each one is added to the $data array. If the limit's date range is different from the global $start and $end
* dates, for example when a limit only partially falls into this month, the title is expanded to clarify.
- *
- * @param array $data
- * @param Budget $budget
- * @param BudgetLimit $limit
- * @param array $entry
- *
- * @return array
*/
private function processRow(array $data, Budget $budget, BudgetLimit $limit, array $entry): array
{
- $title = sprintf('%s (%s)', $budget->name, $entry['currency_name']);
+ $title = sprintf('%s (%s)', $budget->name, $entry['currency_name']);
if ($limit->start_date->startOfDay()->ne($this->start->startOfDay()) || $limit->end_date->startOfDay()->ne($this->end->startOfDay())) {
$title = sprintf(
'%s (%s) (%s - %s)',
@@ -192,7 +165,7 @@ class FrontpageChartGenerator
$limit->end_date->isoFormat($this->monthAndDayFormat)
);
}
- $sumSpent = bcmul($entry['sum'], '-1'); // spent
+ $sumSpent = bcmul($entry['sum'], '-1'); // spent
$data[0]['entries'][$title] = 1 === bccomp($sumSpent, $limit->amount) ? $limit->amount : $sumSpent; // spent
$data[1]['entries'][$title] = 1 === bccomp($limit->amount, $sumSpent) ? bcadd($entry['sum'], $limit->amount) : '0'; // left to spent
@@ -201,17 +174,11 @@ class FrontpageChartGenerator
return $data;
}
- /**
- * @param Carbon $end
- */
public function setEnd(Carbon $end): void
{
$this->end = $end;
}
- /**
- * @param Carbon $start
- */
public function setStart(Carbon $start): void
{
$this->start = $start;
@@ -219,8 +186,6 @@ class FrontpageChartGenerator
/**
* A basic setter for the user. Also updates the repositories with the right user.
- *
- * @param User $user
*/
public function setUser(User $user): void
{
diff --git a/app/Support/Chart/Category/FrontpageChartGenerator.php b/app/Support/Chart/Category/FrontpageChartGenerator.php
index c708797692..b570dd7552 100644
--- a/app/Support/Chart/Category/FrontpageChartGenerator.php
+++ b/app/Support/Chart/Category/FrontpageChartGenerator.php
@@ -51,9 +51,6 @@ class FrontpageChartGenerator
/**
* FrontpageChartGenerator constructor.
- *
- * @param Carbon $start
- * @param Carbon $end
*/
public function __construct(Carbon $start, Carbon $end)
{
@@ -66,18 +63,16 @@ class FrontpageChartGenerator
$this->noCatRepos = app(NoCategoryRepositoryInterface::class);
}
- /**
- * @return array
- */
public function generate(): array
{
- $categories = $this->repository->getCategories();
- $accounts = $this->accountRepos->getAccountsByType(
+ $categories = $this->repository->getCategories();
+ $accounts = $this->accountRepos->getAccountsByType(
[AccountType::DEBT, AccountType::LOAN, AccountType::MORTGAGE, AccountType::ASSET, AccountType::DEFAULT]
);
// get expenses + income per category:
- $collection = [];
+ $collection = [];
+
/** @var Category $category */
foreach ($categories as $category) {
// get expenses
@@ -87,10 +82,10 @@ class FrontpageChartGenerator
// collect for no-category:
$collection[] = $this->collectNoCatExpenses($accounts);
- $tempData = array_merge(...$collection);
+ $tempData = array_merge(...$collection);
// sort temp array by amount.
- $amounts = array_column($tempData, 'sum_float');
+ $amounts = array_column($tempData, 'sum_float');
array_multisort($amounts, SORT_ASC, $tempData);
$currencyData = $this->createCurrencyGroups($tempData);
@@ -98,12 +93,6 @@ class FrontpageChartGenerator
return $this->insertValues($currencyData, $tempData);
}
- /**
- * @param Category $category
- * @param Collection $accounts
- *
- * @return array
- */
private function collectExpenses(Category $category, Collection $accounts): array
{
$spent = $this->opsRepos->sumExpenses($this->start, $this->end, $accounts, new Collection([$category]));
@@ -121,14 +110,11 @@ class FrontpageChartGenerator
return $tempData;
}
- /**
- * @param array $currency
- */
private function addCurrency(array $currency): void
{
$currencyId = (int)$currency['currency_id'];
- $this->currencies[$currencyId] = $this->currencies[$currencyId] ?? [
+ $this->currencies[$currencyId] ??= [
'currency_id' => $currencyId,
'currency_name' => $currency['currency_name'],
'currency_symbol' => $currency['currency_symbol'],
@@ -137,11 +123,6 @@ class FrontpageChartGenerator
];
}
- /**
- * @param Collection $accounts
- *
- * @return array
- */
private function collectNoCatExpenses(Collection $accounts): array
{
$noCatExp = $this->noCatRepos->sumExpenses($this->start, $this->end, $accounts);
@@ -159,15 +140,11 @@ class FrontpageChartGenerator
return $tempData;
}
- /**
- * @param array $data
- *
- * @return array
- */
private function createCurrencyGroups(array $data): array
{
$return = [];
$names = $this->expandNames($data);
+
/**
* @var array $currency
*/
@@ -184,12 +161,6 @@ class FrontpageChartGenerator
return $return;
}
- /**
- * @param array $currencyData
- * @param array $monetaryData
- *
- * @return array
- */
private function insertValues(array $currencyData, array $monetaryData): array
{
/** @var array $array */
diff --git a/app/Support/Chart/Category/WholePeriodChartGenerator.php b/app/Support/Chart/Category/WholePeriodChartGenerator.php
index 808750a97a..e1765dbfc9 100644
--- a/app/Support/Chart/Category/WholePeriodChartGenerator.php
+++ b/app/Support/Chart/Category/WholePeriodChartGenerator.php
@@ -35,31 +35,24 @@ use Illuminate\Support\Collection;
*/
class WholePeriodChartGenerator
{
- /**
- * @param Category $category
- * @param Carbon $start
- * @param Carbon $end
- *
- * @return array
- */
public function generate(Category $category, Carbon $start, Carbon $end): array
{
- $collection = new Collection([$category]);
+ $collection = new Collection([$category]);
/** @var OperationsRepositoryInterface $opsRepository */
- $opsRepository = app(OperationsRepositoryInterface::class);
+ $opsRepository = app(OperationsRepositoryInterface::class);
/** @var AccountRepositoryInterface $accountRepository */
$accountRepository = app(AccountRepositoryInterface::class);
- $types = [AccountType::DEFAULT, AccountType::ASSET, AccountType::LOAN, AccountType::DEBT, AccountType::MORTGAGE];
- $accounts = $accountRepository->getAccountsByType($types);
- $step = $this->calculateStep($start, $end);
- $chartData = [];
- $spent = [];
- $earned = [];
+ $types = [AccountType::DEFAULT, AccountType::ASSET, AccountType::LOAN, AccountType::DEBT, AccountType::MORTGAGE];
+ $accounts = $accountRepository->getAccountsByType($types);
+ $step = $this->calculateStep($start, $end);
+ $chartData = [];
+ $spent = [];
+ $earned = [];
- $current = clone $start;
+ $current = clone $start;
while ($current <= $end) {
$key = $current->format('Y-m-d');
@@ -69,14 +62,14 @@ class WholePeriodChartGenerator
$current = app('navigation')->addPeriod($current, $step, 0);
}
- $currencies = $this->extractCurrencies($spent) + $this->extractCurrencies($earned);
+ $currencies = $this->extractCurrencies($spent) + $this->extractCurrencies($earned);
// generate chart data (for each currency)
/** @var array $currency */
foreach ($currencies as $currency) {
- $code = $currency['currency_code'];
- $name = $currency['currency_name'];
- $chartData[sprintf('spent-in-%s', $code)] = [
+ $code = $currency['currency_code'];
+ $name = $currency['currency_name'];
+ $chartData[sprintf('spent-in-%s', $code)] = [
'label' => (string)trans('firefly.box_spent_in_currency', ['currency' => $name]),
'entries' => [],
'type' => 'bar',
@@ -91,11 +84,11 @@ class WholePeriodChartGenerator
];
}
- $current = clone $start;
+ $current = clone $start;
while ($current <= $end) {
- $key = $current->format('Y-m-d');
- $label = app('navigation')->periodShow($current, $step);
+ $key = $current->format('Y-m-d');
+ $label = app('navigation')->periodShow($current, $step);
/** @var array $currency */
foreach ($currencies as $currency) {
@@ -116,11 +109,6 @@ class WholePeriodChartGenerator
/**
* TODO this method is duplicated
- *
- * @param Carbon $start
- * @param Carbon $end
- *
- * @return string
*/
protected function calculateStep(Carbon $start, Carbon $end): string
{
@@ -142,17 +130,13 @@ class WholePeriodChartGenerator
/**
* Loop array of spent/earned info, and extract which currencies are present.
* Key is the currency ID.
- *
- * @param array $array
- *
- * @return array
*/
private function extractCurrencies(array $array): array
{
$return = [];
foreach ($array as $block) {
foreach ($block as $currencyId => $currencyRow) {
- $return[$currencyId] = $return[$currencyId] ?? [
+ $return[$currencyId] ??= [
'currency_id' => $currencyId,
'currency_name' => $currencyRow['currency_name'],
'currency_symbol' => $currencyRow['currency_symbol'],
diff --git a/app/Support/ChartColour.php b/app/Support/ChartColour.php
index 54d64c32ea..9e938b9946 100644
--- a/app/Support/ChartColour.php
+++ b/app/Support/ChartColour.php
@@ -25,8 +25,6 @@ namespace FireflyIII\Support;
/**
* Class ChartColour.
- *
-
*/
class ChartColour
{
@@ -54,15 +52,10 @@ class ChartColour
[194, 24, 91],
];
- /**
- * @param int $index
- *
- * @return string
- */
public static function getColour(int $index): string
{
$index %= count(self::$colours);
- $row = self::$colours[$index];
+ $row = self::$colours[$index];
return sprintf('rgba(%d, %d, %d, 0.7)', $row[0], $row[1], $row[2]);
}
diff --git a/app/Support/Cronjobs/AbstractCronjob.php b/app/Support/Cronjobs/AbstractCronjob.php
index 581051e3db..35ccedfa44 100644
--- a/app/Support/Cronjobs/AbstractCronjob.php
+++ b/app/Support/Cronjobs/AbstractCronjob.php
@@ -27,8 +27,6 @@ use Carbon\Carbon;
/**
* Class AbstractCronjob
- *
-
*/
abstract class AbstractCronjob
{
@@ -53,23 +51,14 @@ abstract class AbstractCronjob
$this->message = null;
}
- /**
- *
- */
abstract public function fire(): void;
- /**
- * @param Carbon $date
- */
final public function setDate(Carbon $date): void
{
$newDate = clone $date;
$this->date = $newDate;
}
- /**
- * @param bool $force
- */
final public function setForce(bool $force): void
{
$this->force = $force;
diff --git a/app/Support/Cronjobs/AutoBudgetCronjob.php b/app/Support/Cronjobs/AutoBudgetCronjob.php
index bc540fa8b2..6ac8d0440a 100644
--- a/app/Support/Cronjobs/AutoBudgetCronjob.php
+++ b/app/Support/Cronjobs/AutoBudgetCronjob.php
@@ -27,16 +27,12 @@ namespace FireflyIII\Support\Cronjobs;
use Carbon\Carbon;
use FireflyIII\Jobs\CreateAutoBudgetLimits;
use FireflyIII\Models\Configuration;
-use Illuminate\Support\Facades\Log;
/**
* Class AutoBudgetCronjob
*/
class AutoBudgetCronjob extends AbstractCronjob
{
- /**
- * @inheritDoc
- */
public function fire(): void
{
/** @var Configuration $config */
@@ -45,40 +41,34 @@ class AutoBudgetCronjob extends AbstractCronjob
$diff = time() - $lastTime;
$diffForHumans = today(config('app.timezone'))->diffForHumans(Carbon::createFromTimestamp($lastTime), null, true);
if (0 === $lastTime) {
- Log::info('Auto budget cron-job has never fired before.');
+ app('log')->info('Auto budget cron-job has never fired before.');
}
// less than half a day ago:
if ($lastTime > 0 && $diff <= 43200) {
- Log::info(sprintf('It has been %s since the auto budget cron-job has fired.', $diffForHumans));
+ app('log')->info(sprintf('It has been %s since the auto budget cron-job has fired.', $diffForHumans));
if (false === $this->force) {
- Log::info('The auto budget cron-job will not fire now.');
+ app('log')->info('The auto budget cron-job will not fire now.');
$this->message = sprintf('It has been %s since the auto budget cron-job has fired. It will not fire now.', $diffForHumans);
return;
}
-
- // fire job regardless.
- if (true === $this->force) {
- Log::info('Execution of the auto budget cron-job has been FORCED.');
- }
+ app('log')->info('Execution of the auto budget cron-job has been FORCED.');
}
if ($lastTime > 0 && $diff > 43200) {
- Log::info(sprintf('It has been %s since the auto budget cron-job has fired. It will fire now!', $diffForHumans));
+ app('log')->info(sprintf('It has been %s since the auto budget cron-job has fired. It will fire now!', $diffForHumans));
}
$this->fireAutoBudget();
app('preferences')->mark();
}
- /**
- *
- */
private function fireAutoBudget(): void
{
- Log::info(sprintf('Will now fire auto budget cron job task for date "%s".', $this->date->format('Y-m-d')));
+ app('log')->info(sprintf('Will now fire auto budget cron job task for date "%s".', $this->date->format('Y-m-d')));
+
/** @var CreateAutoBudgetLimits $job */
- $job = app(CreateAutoBudgetLimits::class, [$this->date]);
+ $job = app(CreateAutoBudgetLimits::class, [$this->date]);
$job->setDate($this->date);
$job->handle();
@@ -89,6 +79,6 @@ class AutoBudgetCronjob extends AbstractCronjob
$this->message = 'Auto-budget cron job fired successfully.';
app('fireflyconfig')->set('last_ab_job', (int)$this->date->format('U'));
- Log::info('Done with auto budget cron job task.');
+ app('log')->info('Done with auto budget cron job task.');
}
}
diff --git a/app/Support/Cronjobs/BillWarningCronjob.php b/app/Support/Cronjobs/BillWarningCronjob.php
index 2b3c03f512..84362c2069 100644
--- a/app/Support/Cronjobs/BillWarningCronjob.php
+++ b/app/Support/Cronjobs/BillWarningCronjob.php
@@ -27,9 +27,6 @@ use Carbon\Carbon;
use FireflyIII\Exceptions\FireflyException;
use FireflyIII\Jobs\WarnAboutBills;
use FireflyIII\Models\Configuration;
-use Illuminate\Support\Facades\Log;
-use Psr\Container\ContainerExceptionInterface;
-use Psr\Container\NotFoundExceptionInterface;
/**
* Class BillWarningCronjob
@@ -38,12 +35,11 @@ class BillWarningCronjob extends AbstractCronjob
{
/**
* @throws FireflyException
- * @throws ContainerExceptionInterface
- * @throws NotFoundExceptionInterface
*/
public function fire(): void
{
- Log::debug(sprintf('Now in %s', __METHOD__));
+ app('log')->debug(sprintf('Now in %s', __METHOD__));
+
/** @var Configuration $config */
$config = app('fireflyconfig')->get('last_bw_job', 0);
$lastTime = (int)$config->data;
@@ -51,13 +47,13 @@ class BillWarningCronjob extends AbstractCronjob
$diffForHumans = today(config('app.timezone'))->diffForHumans(Carbon::createFromTimestamp($lastTime), null, true);
if (0 === $lastTime) {
- Log::info('The bill warning cron-job has never fired before.');
+ app('log')->info('The bill warning cron-job has never fired before.');
}
// less than half a day ago:
if ($lastTime > 0 && $diff <= 43200) {
- Log::info(sprintf('It has been %s since the bill warning cron-job has fired.', $diffForHumans));
+ app('log')->info(sprintf('It has been %s since the bill warning cron-job has fired.', $diffForHumans));
if (false === $this->force) {
- Log::info('The cron-job will not fire now.');
+ app('log')->info('The cron-job will not fire now.');
$this->message = sprintf('It has been %s since the bill warning cron-job has fired. It will not fire now.', $diffForHumans);
$this->jobFired = false;
$this->jobErrored = false;
@@ -66,14 +62,11 @@ class BillWarningCronjob extends AbstractCronjob
return;
}
- // fire job regardless.
- if (true === $this->force) {
- Log::info('Execution of the bill warning cron-job has been FORCED.');
- }
+ app('log')->info('Execution of the bill warning cron-job has been FORCED.');
}
if ($lastTime > 0 && $diff > 43200) {
- Log::info(sprintf('It has been %s since the bill warning cron-job has fired. It will fire now!', $diffForHumans));
+ app('log')->info(sprintf('It has been %s since the bill warning cron-job has fired. It will fire now!', $diffForHumans));
}
$this->fireWarnings();
@@ -81,14 +74,12 @@ class BillWarningCronjob extends AbstractCronjob
app('preferences')->mark();
}
- /**
- *
- */
private function fireWarnings(): void
{
- Log::info(sprintf('Will now fire bill warning job task for date "%s".', $this->date->format('Y-m-d H:i:s')));
+ app('log')->info(sprintf('Will now fire bill warning job task for date "%s".', $this->date->format('Y-m-d H:i:s')));
+
/** @var WarnAboutBills $job */
- $job = app(WarnAboutBills::class);
+ $job = app(WarnAboutBills::class);
$job->setDate($this->date);
$job->setForce($this->force);
$job->handle();
@@ -100,7 +91,7 @@ class BillWarningCronjob extends AbstractCronjob
$this->message = 'Bill warning cron job fired successfully.';
app('fireflyconfig')->set('last_bw_job', (int)$this->date->format('U'));
- Log::info(sprintf('Marked the last time this job has run as "%s" (%d)', $this->date->format('Y-m-d H:i:s'), (int)$this->date->format('U')));
- Log::info('Done with bill warning cron job task.');
+ app('log')->info(sprintf('Marked the last time this job has run as "%s" (%d)', $this->date->format('Y-m-d H:i:s'), (int)$this->date->format('U')));
+ app('log')->info('Done with bill warning cron job task.');
}
}
diff --git a/app/Support/Cronjobs/ExchangeRatesCronjob.php b/app/Support/Cronjobs/ExchangeRatesCronjob.php
index c76131777a..2572b8ba1e 100644
--- a/app/Support/Cronjobs/ExchangeRatesCronjob.php
+++ b/app/Support/Cronjobs/ExchangeRatesCronjob.php
@@ -27,16 +27,12 @@ namespace FireflyIII\Support\Cronjobs;
use Carbon\Carbon;
use FireflyIII\Jobs\DownloadExchangeRates;
use FireflyIII\Models\Configuration;
-use Illuminate\Support\Facades\Log;
/**
* Class ExchangeRatesCronjob
*/
class ExchangeRatesCronjob extends AbstractCronjob
{
- /**
- * @inheritDoc
- */
public function fire(): void
{
/** @var Configuration $config */
@@ -45,40 +41,35 @@ class ExchangeRatesCronjob extends AbstractCronjob
$diff = time() - $lastTime;
$diffForHumans = today(config('app.timezone'))->diffForHumans(Carbon::createFromTimestamp($lastTime), null, true);
if (0 === $lastTime) {
- Log::info('Exchange rates cron-job has never fired before.');
+ app('log')->info('Exchange rates cron-job has never fired before.');
}
// less than half a day ago:
if ($lastTime > 0 && $diff <= 43200) {
- Log::info(sprintf('It has been %s since the exchange rates cron-job has fired.', $diffForHumans));
+ app('log')->info(sprintf('It has been %s since the exchange rates cron-job has fired.', $diffForHumans));
if (false === $this->force) {
- Log::info('The exchange rates cron-job will not fire now.');
+ app('log')->info('The exchange rates cron-job will not fire now.');
$this->message = sprintf('It has been %s since the exchange rates cron-job has fired. It will not fire now.', $diffForHumans);
return;
}
- // fire job regardless.
- if (true === $this->force) {
- Log::info('Execution of the exchange rates cron-job has been FORCED.');
- }
+ app('log')->info('Execution of the exchange rates cron-job has been FORCED.');
}
if ($lastTime > 0 && $diff > 43200) {
- Log::info(sprintf('It has been %s since the exchange rates cron-job has fired. It will fire now!', $diffForHumans));
+ app('log')->info(sprintf('It has been %s since the exchange rates cron-job has fired. It will fire now!', $diffForHumans));
}
$this->fireExchangeRateJob();
app('preferences')->mark();
}
- /**
- *
- */
private function fireExchangeRateJob(): void
{
- Log::info(sprintf('Will now fire exchange rates cron job task for date "%s".', $this->date->format('Y-m-d')));
+ app('log')->info(sprintf('Will now fire exchange rates cron job task for date "%s".', $this->date->format('Y-m-d')));
+
/** @var DownloadExchangeRates $job */
- $job = app(DownloadExchangeRates::class);
+ $job = app(DownloadExchangeRates::class);
$job->setDate($this->date);
$job->handle();
@@ -89,6 +80,6 @@ class ExchangeRatesCronjob extends AbstractCronjob
$this->message = 'Exchange rates cron job fired successfully.';
app('fireflyconfig')->set('last_cer_job', (int)$this->date->format('U'));
- Log::info('Done with exchange rates job task.');
+ app('log')->info('Done with exchange rates job task.');
}
}
diff --git a/app/Support/Cronjobs/RecurringCronjob.php b/app/Support/Cronjobs/RecurringCronjob.php
index cdb2b989ff..6fd241104d 100644
--- a/app/Support/Cronjobs/RecurringCronjob.php
+++ b/app/Support/Cronjobs/RecurringCronjob.php
@@ -27,9 +27,6 @@ use Carbon\Carbon;
use FireflyIII\Exceptions\FireflyException;
use FireflyIII\Jobs\CreateRecurringTransactions;
use FireflyIII\Models\Configuration;
-use Illuminate\Support\Facades\Log;
-use Psr\Container\ContainerExceptionInterface;
-use Psr\Container\NotFoundExceptionInterface;
/**
* Class RecurringCronjob
@@ -38,12 +35,11 @@ class RecurringCronjob extends AbstractCronjob
{
/**
* @throws FireflyException
- * @throws ContainerExceptionInterface
- * @throws NotFoundExceptionInterface
*/
public function fire(): void
{
- Log::debug(sprintf('Now in %s', __METHOD__));
+ app('log')->debug(sprintf('Now in %s', __METHOD__));
+
/** @var Configuration $config */
$config = app('fireflyconfig')->get('last_rt_job', 0);
$lastTime = (int)$config->data;
@@ -51,13 +47,13 @@ class RecurringCronjob extends AbstractCronjob
$diffForHumans = today(config('app.timezone'))->diffForHumans(Carbon::createFromTimestamp($lastTime), null, true);
if (0 === $lastTime) {
- Log::info('Recurring transactions cron-job has never fired before.');
+ app('log')->info('Recurring transactions cron-job has never fired before.');
}
// less than half a day ago:
if ($lastTime > 0 && $diff <= 43200) {
- Log::info(sprintf('It has been %s since the recurring transactions cron-job has fired.', $diffForHumans));
+ app('log')->info(sprintf('It has been %s since the recurring transactions cron-job has fired.', $diffForHumans));
if (false === $this->force) {
- Log::info('The cron-job will not fire now.');
+ app('log')->info('The cron-job will not fire now.');
$this->message = sprintf('It has been %s since the recurring transactions cron-job has fired. It will not fire now.', $diffForHumans);
$this->jobFired = false;
$this->jobErrored = false;
@@ -65,15 +61,11 @@ class RecurringCronjob extends AbstractCronjob
return;
}
-
- // fire job regardless.
- if (true === $this->force) {
- Log::info('Execution of the recurring transaction cron-job has been FORCED.');
- }
+ app('log')->info('Execution of the recurring transaction cron-job has been FORCED.');
}
if ($lastTime > 0 && $diff > 43200) {
- Log::info(sprintf('It has been %s since the recurring transactions cron-job has fired. It will fire now!', $diffForHumans));
+ app('log')->info(sprintf('It has been %s since the recurring transactions cron-job has fired. It will fire now!', $diffForHumans));
}
$this->fireRecurring();
@@ -81,14 +73,12 @@ class RecurringCronjob extends AbstractCronjob
app('preferences')->mark();
}
- /**
- *
- */
private function fireRecurring(): void
{
- Log::info(sprintf('Will now fire recurring cron job task for date "%s".', $this->date->format('Y-m-d H:i:s')));
+ app('log')->info(sprintf('Will now fire recurring cron job task for date "%s".', $this->date->format('Y-m-d H:i:s')));
+
/** @var CreateRecurringTransactions $job */
- $job = app(CreateRecurringTransactions::class);
+ $job = app(CreateRecurringTransactions::class);
$job->setDate($this->date);
$job->setForce($this->force);
$job->handle();
@@ -100,7 +90,7 @@ class RecurringCronjob extends AbstractCronjob
$this->message = 'Recurring transactions cron job fired successfully.';
app('fireflyconfig')->set('last_rt_job', (int)$this->date->format('U'));
- Log::info(sprintf('Marked the last time this job has run as "%s" (%d)', $this->date->format('Y-m-d H:i:s'), (int)$this->date->format('U')));
- Log::info('Done with recurring cron job task.');
+ app('log')->info(sprintf('Marked the last time this job has run as "%s" (%d)', $this->date->format('Y-m-d H:i:s'), (int)$this->date->format('U')));
+ app('log')->info('Done with recurring cron job task.');
}
}
diff --git a/app/Support/Domain.php b/app/Support/Domain.php
index 42def30123..c37a70e431 100644
--- a/app/Support/Domain.php
+++ b/app/Support/Domain.php
@@ -25,30 +25,19 @@ namespace FireflyIII\Support;
/**
* Class Domain.
- *
-
*/
class Domain
{
- /**
- * @return array
- */
public static function getBindables(): array
{
return config('firefly.bindables');
}
- /**
- * @return array
- */
public static function getRuleActions(): array
{
return config('firefly.rule-actions');
}
- /**
- * @return array
- */
public static function getRuleTriggers(): array
{
return array_keys(config('search.operators'));
diff --git a/app/Support/ExpandedForm.php b/app/Support/ExpandedForm.php
index fc78951bea..74822444c4 100644
--- a/app/Support/ExpandedForm.php
+++ b/app/Support/ExpandedForm.php
@@ -27,30 +27,22 @@ use Eloquent;
use FireflyIII\Exceptions\FireflyException;
use FireflyIII\Support\Form\FormSupport;
use Illuminate\Support\Collection;
-use Illuminate\Support\Facades\Log;
-use Throwable;
/**
* Class ExpandedForm.
- *
- *
-
*/
class ExpandedForm
{
use FormSupport;
/**
- * @param string $name
- * @param mixed $value
- * @param array|null $options
+ * @param mixed $value
*
- * @return string
* @throws FireflyException
*/
public function amountNoCurrency(string $name, $value = null, array $options = null): string
{
- $options = $options ?? [];
+ $options ??= [];
$label = $this->label($name, $options);
$options = $this->expandOptionArray($name, $label, $options);
$classes = $this->getHolderClasses($name);
@@ -59,14 +51,15 @@ class ExpandedForm
unset($options['currency'], $options['placeholder']);
// make sure value is formatted nicely:
- //if (null !== $value && '' !== $value) {
- //$value = round((float)$value, 8);
- //}
+ // if (null !== $value && '' !== $value) {
+ // $value = round((float)$value, 8);
+ // }
try {
$html = view('form.amount-no-currency', compact('classes', 'name', 'label', 'value', 'options'))->render();
- } catch (Throwable $e) {
- Log::error(sprintf('Could not render amountNoCurrency(): %s', $e->getMessage()));
+ } catch (\Throwable $e) {
+ app('log')->error(sprintf('Could not render amountNoCurrency(): %s', $e->getMessage()));
$html = 'Could not render amountNoCurrency.';
+
throw new FireflyException($html, 0, $e);
}
@@ -74,18 +67,14 @@ class ExpandedForm
}
/**
- * @param string $name
- * @param int|null $value
- * @param mixed $checked
- * @param array|null $options
+ * @param mixed $checked
*
- * @return string
* @throws FireflyException
*/
public function checkbox(string $name, int $value = null, $checked = null, array $options = null): string
{
- $options = $options ?? [];
- $value = $value ?? 1;
+ $options ??= [];
+ $value ??= 1;
$options['checked'] = true === $checked;
if (app('session')->has('preFilled')) {
@@ -93,17 +82,19 @@ class ExpandedForm
$options['checked'] = $preFilled[$name] ?? $options['checked'];
}
- $label = $this->label($name, $options);
- $options = $this->expandOptionArray($name, $label, $options);
- $classes = $this->getHolderClasses($name);
- $value = $this->fillFieldValue($name, $value);
+ $label = $this->label($name, $options);
+ $options = $this->expandOptionArray($name, $label, $options);
+ $classes = $this->getHolderClasses($name);
+ $value = $this->fillFieldValue($name, $value);
unset($options['placeholder'], $options['autocomplete'], $options['class']);
+
try {
$html = view('form.checkbox', compact('classes', 'name', 'label', 'value', 'options'))->render();
- } catch (Throwable $e) {
- Log::debug(sprintf('Could not render checkbox(): %s', $e->getMessage()));
+ } catch (\Throwable $e) {
+ app('log')->debug(sprintf('Could not render checkbox(): %s', $e->getMessage()));
$html = 'Could not render checkbox.';
+
throw new FireflyException($html, 0, $e);
}
@@ -111,11 +102,8 @@ class ExpandedForm
}
/**
- * @param string $name
- * @param mixed $value
- * @param array|null $options
+ * @param mixed $value
*
- * @return string
* @throws FireflyException
*/
public function date(string $name, $value = null, array $options = null): string
@@ -125,11 +113,13 @@ class ExpandedForm
$classes = $this->getHolderClasses($name);
$value = $this->fillFieldValue($name, $value);
unset($options['placeholder']);
+
try {
$html = view('form.date', compact('classes', 'name', 'label', 'value', 'options'))->render();
- } catch (Throwable $e) {
- Log::debug(sprintf('Could not render date(): %s', $e->getMessage()));
+ } catch (\Throwable $e) {
+ app('log')->debug(sprintf('Could not render date(): %s', $e->getMessage()));
$html = 'Could not render date.';
+
throw new FireflyException($html, 0, $e);
}
@@ -137,23 +127,21 @@ class ExpandedForm
}
/**
- * @param string $name
- * @param array|null $options
- *
- * @return string
* @throws FireflyException
*/
public function file(string $name, array $options = null): string
{
- $options = $options ?? [];
+ $options ??= [];
$label = $this->label($name, $options);
$options = $this->expandOptionArray($name, $label, $options);
$classes = $this->getHolderClasses($name);
+
try {
$html = view('form.file', compact('classes', 'name', 'label', 'options'))->render();
- } catch (Throwable $e) {
- Log::debug(sprintf('Could not render file(): %s', $e->getMessage()));
+ } catch (\Throwable $e) {
+ app('log')->debug(sprintf('Could not render file(): %s', $e->getMessage()));
$html = 'Could not render file.';
+
throw new FireflyException($html, 0, $e);
}
@@ -161,52 +149,25 @@ class ExpandedForm
}
/**
- * @param string $name
- * @param mixed $value
- * @param array|null $options
+ * @param mixed $value
*
- * @return string
* @throws FireflyException
*/
public function integer(string $name, $value = null, array $options = null): string
{
- $options = $options ?? [];
- $label = $this->label($name, $options);
- $options = $this->expandOptionArray($name, $label, $options);
- $classes = $this->getHolderClasses($name);
- $value = $this->fillFieldValue($name, $value);
- $options['step'] = $options['step'] ?? '1';
- try {
- $html = view('form.integer', compact('classes', 'name', 'label', 'value', 'options'))->render();
- } catch (Throwable $e) {
- Log::debug(sprintf('Could not render integer(): %s', $e->getMessage()));
- $html = 'Could not render integer.';
- throw new FireflyException($html, 0, $e);
- }
-
- return $html;
- }
-
- /**
- * @param string $name
- * @param mixed $value
- * @param array|null $options
- *
- * @return string
- * @throws FireflyException
- */
- public function location(string $name, $value = null, array $options = null): string
- {
- $options = $options ?? [];
+ $options ??= [];
$label = $this->label($name, $options);
$options = $this->expandOptionArray($name, $label, $options);
$classes = $this->getHolderClasses($name);
$value = $this->fillFieldValue($name, $value);
+ $options['step'] ??= '1';
+
try {
- $html = view('form.location', compact('classes', 'name', 'label', 'value', 'options'))->render();
- } catch (Throwable $e) {
- Log::debug(sprintf('Could not render location(): %s', $e->getMessage()));
- $html = 'Could not render location.';
+ $html = view('form.integer', compact('classes', 'name', 'label', 'value', 'options'))->render();
+ } catch (\Throwable $e) {
+ app('log')->debug(sprintf('Could not render integer(): %s', $e->getMessage()));
+ $html = 'Could not render integer.';
+
throw new FireflyException($html, 0, $e);
}
@@ -214,22 +175,42 @@ class ExpandedForm
}
/**
- * @param Collection $set
- *
- * @return array
+ * @param mixed $value
*
+ * @throws FireflyException
*/
+ public function location(string $name, $value = null, array $options = null): string
+ {
+ $options ??= [];
+ $label = $this->label($name, $options);
+ $options = $this->expandOptionArray($name, $label, $options);
+ $classes = $this->getHolderClasses($name);
+ $value = $this->fillFieldValue($name, $value);
+
+ try {
+ $html = view('form.location', compact('classes', 'name', 'label', 'value', 'options'))->render();
+ } catch (\Throwable $e) {
+ app('log')->debug(sprintf('Could not render location(): %s', $e->getMessage()));
+ $html = 'Could not render location.';
+
+ throw new FireflyException($html, 0, $e);
+ }
+
+ return $html;
+ }
+
public function makeSelectListWithEmpty(Collection $set): array
{
$selectList = [];
$selectList[0] = '(none)';
$fields = ['title', 'name', 'description'];
- /** @var Eloquent $entry */
+
+ /** @var \Eloquent $entry */
foreach ($set as $entry) {
// All Eloquent models have an ID
- $entryId = (int)$entry->id; // @phpstan-ignore-line
- $current = $entry->toArray();
- $title = null;
+ $entryId = $entry->id; // @phpstan-ignore-line
+ $current = $entry->toArray();
+ $title = null;
foreach ($fields as $field) {
if (array_key_exists($field, $current) && null === $title) {
$title = $current[$field];
@@ -241,12 +222,9 @@ class ExpandedForm
return $selectList;
}
-
/**
- * @param null $value
- * @param array|null $options
+ * @param null $value
*
- * @return string
* @throws FireflyException
*/
public function objectGroup($value = null, array $options = null): string
@@ -264,9 +242,10 @@ class ExpandedForm
try {
$html = view('form.object_group', compact('classes', 'name', 'label', 'value', 'options'))->render();
- } catch (Throwable $e) {
- Log::debug(sprintf('Could not render objectGroup(): %s', $e->getMessage()));
+ } catch (\Throwable $e) {
+ app('log')->debug(sprintf('Could not render objectGroup(): %s', $e->getMessage()));
$html = 'Could not render objectGroup.';
+
throw new FireflyException($html, 0, $e);
}
@@ -274,19 +253,16 @@ class ExpandedForm
}
/**
- * @param string $type
- * @param string $name
- *
- * @return string
* @throws FireflyException
*/
public function optionsList(string $type, string $name): string
{
try {
$html = view('form.options', compact('type', 'name'))->render();
- } catch (Throwable $e) {
- Log::debug(sprintf('Could not render select(): %s', $e->getMessage()));
+ } catch (\Throwable $e) {
+ app('log')->debug(sprintf('Could not render select(): %s', $e->getMessage()));
$html = 'Could not render optionsList.';
+
throw new FireflyException($html, 0, $e);
}
@@ -294,10 +270,6 @@ class ExpandedForm
}
/**
- * @param string $name
- * @param array|null $options
- *
- * @return string
* @throws FireflyException
*/
public function password(string $name, array $options = null): string
@@ -305,11 +277,13 @@ class ExpandedForm
$label = $this->label($name, $options);
$options = $this->expandOptionArray($name, $label, $options);
$classes = $this->getHolderClasses($name);
+
try {
$html = view('form.password', compact('classes', 'name', 'label', 'options'))->render();
- } catch (Throwable $e) {
- Log::debug(sprintf('Could not render password(): %s', $e->getMessage()));
+ } catch (\Throwable $e) {
+ app('log')->debug(sprintf('Could not render password(): %s', $e->getMessage()));
$html = 'Could not render password.';
+
throw new FireflyException($html, 0, $e);
}
@@ -319,11 +293,8 @@ class ExpandedForm
/**
* Function to render a percentage.
*
- * @param string $name
- * @param mixed $value
- * @param array|null $options
+ * @param mixed $value
*
- * @return string
* @throws FireflyException
*/
public function percentage(string $name, $value = null, array $options = null): string
@@ -334,11 +305,13 @@ class ExpandedForm
$value = $this->fillFieldValue($name, $value);
$options['step'] = 'any';
unset($options['placeholder']);
+
try {
$html = view('form.percentage', compact('classes', 'name', 'label', 'value', 'options'))->render();
- } catch (Throwable $e) {
- Log::debug(sprintf('Could not render percentage(): %s', $e->getMessage()));
+ } catch (\Throwable $e) {
+ app('log')->debug(sprintf('Could not render percentage(): %s', $e->getMessage()));
$html = 'Could not render percentage.';
+
throw new FireflyException($html, 0, $e);
}
@@ -346,11 +319,8 @@ class ExpandedForm
}
/**
- * @param string $name
- * @param mixed $value
- * @param array|null $options
+ * @param mixed $value
*
- * @return string
* @throws FireflyException
*/
public function staticText(string $name, $value, array $options = null): string
@@ -358,11 +328,13 @@ class ExpandedForm
$label = $this->label($name, $options);
$options = $this->expandOptionArray($name, $label, $options);
$classes = $this->getHolderClasses($name);
+
try {
$html = view('form.static', compact('classes', 'name', 'label', 'value', 'options'))->render();
- } catch (Throwable $e) {
- Log::debug(sprintf('Could not render staticText(): %s', $e->getMessage()));
+ } catch (\Throwable $e) {
+ app('log')->debug(sprintf('Could not render staticText(): %s', $e->getMessage()));
$html = 'Could not render staticText.';
+
throw new FireflyException($html, 0, $e);
}
@@ -370,11 +342,8 @@ class ExpandedForm
}
/**
- * @param string $name
- * @param mixed $value
- * @param array|null $options
+ * @param mixed $value
*
- * @return string
* @throws FireflyException
*/
public function text(string $name, $value = null, array $options = null): string
@@ -383,11 +352,13 @@ class ExpandedForm
$options = $this->expandOptionArray($name, $label, $options);
$classes = $this->getHolderClasses($name);
$value = $this->fillFieldValue($name, $value);
+
try {
$html = view('form.text', compact('classes', 'name', 'label', 'value', 'options'))->render();
- } catch (Throwable $e) {
- Log::debug(sprintf('Could not render text(): %s', $e->getMessage()));
+ } catch (\Throwable $e) {
+ app('log')->debug(sprintf('Could not render text(): %s', $e->getMessage()));
$html = 'Could not render text.';
+
throw new FireflyException($html, 0, $e);
}
@@ -395,11 +366,8 @@ class ExpandedForm
}
/**
- * @param string $name
- * @param mixed $value
- * @param array|null $options
+ * @param mixed $value
*
- * @return string
* @throws FireflyException
*/
public function textarea(string $name, $value = null, array $options = null): string
@@ -416,9 +384,10 @@ class ExpandedForm
try {
$html = view('form.textarea', compact('classes', 'name', 'label', 'value', 'options'))->render();
- } catch (Throwable $e) {
- Log::debug(sprintf('Could not render textarea(): %s', $e->getMessage()));
+ } catch (\Throwable $e) {
+ app('log')->debug(sprintf('Could not render textarea(): %s', $e->getMessage()));
$html = 'Could not render textarea.';
+
throw new FireflyException($html, 0, $e);
}
diff --git a/app/Support/Export/ExportDataGenerator.php b/app/Support/Export/ExportDataGenerator.php
index 393ec30f08..2ac986eb7f 100644
--- a/app/Support/Export/ExportDataGenerator.php
+++ b/app/Support/Export/ExportDataGenerator.php
@@ -53,12 +53,9 @@ use FireflyIII\Repositories\TransactionGroup\TransactionGroupRepositoryInterface
use FireflyIII\Support\Request\ConvertsDataTypes;
use FireflyIII\User;
use Illuminate\Support\Collection;
-use Illuminate\Support\Facades\Log;
use League\Csv\CannotInsertRecord;
use League\Csv\Exception;
use League\Csv\Writer;
-use Psr\Container\ContainerExceptionInterface;
-use Psr\Container\NotFoundExceptionInterface;
/**
* Class ExportDataGenerator
@@ -67,8 +64,8 @@ class ExportDataGenerator
{
use ConvertsDataTypes;
- private const ADD_RECORD_ERR = 'Could not add record to set: %s';
- private const EXPORT_ERR = 'Could not export to string: %s';
+ private const string ADD_RECORD_ERR = 'Could not add record to set: %s';
+ private const string EXPORT_ERR = 'Could not export to string: %s';
private Collection $accounts;
private Carbon $end;
private bool $exportAccounts;
@@ -85,8 +82,8 @@ class ExportDataGenerator
public function __construct()
{
- $this->accounts = new Collection();
- $this->start = today(config('app.timezone'));
+ $this->accounts = new Collection();
+ $this->start = today(config('app.timezone'));
$this->start->subYear();
$this->end = today(config('app.timezone'));
$this->exportTransactions = false;
@@ -101,10 +98,7 @@ class ExportDataGenerator
}
/**
- * @return array
- * @throws ContainerExceptionInterface
* @throws FireflyException
- * @throws NotFoundExceptionInterface
*/
public function export(): array
{
@@ -141,14 +135,13 @@ class ExportDataGenerator
}
/**
- * @return string
* @throws CannotInsertRecord
* @throws Exception
* @throws FireflyException
*/
private function exportAccounts(): string
{
- $header = [
+ $header = [
'user_id',
'account_id',
'created_at',
@@ -167,11 +160,13 @@ class ExportDataGenerator
'interest',
'interest_period',
];
+
/** @var AccountRepositoryInterface $repository */
- $repository = app(AccountRepositoryInterface::class);
+ $repository = app(AccountRepositoryInterface::class);
$repository->setUser($this->user);
$allAccounts = $repository->getAccountsByType([]);
$records = [];
+
/** @var Account $account */
foreach ($allAccounts as $account) {
$currency = $repository->getAccountCurrency($account);
@@ -196,39 +191,36 @@ class ExportDataGenerator
];
}
- //load the CSV document from a string
- $csv = Writer::createFromString();
+ // load the CSV document from a string
+ $csv = Writer::createFromString();
- //insert the header
+ // insert the header
try {
$csv->insertOne($header);
} catch (CannotInsertRecord $e) {
throw new FireflyException(sprintf(self::ADD_RECORD_ERR, $e->getMessage()), 0, $e);
}
- //insert all the records
+ // insert all the records
$csv->insertAll($records);
try {
$string = $csv->toString();
} catch (Exception $e) { // intentional generic exception
- Log::error($e->getMessage());
+ app('log')->error($e->getMessage());
+
throw new FireflyException(sprintf(self::EXPORT_ERR, $e->getMessage()), 0, $e);
}
return $string;
}
- /**
- * @param User $user
- */
public function setUser(User $user): void
{
$this->user = $user;
}
/**
- * @return string
* @throws CannotInsertRecord
* @throws Exception
* @throws FireflyException
@@ -238,8 +230,8 @@ class ExportDataGenerator
/** @var BillRepositoryInterface $repository */
$repository = app(BillRepositoryInterface::class);
$repository->setUser($this->user);
- $bills = $repository->getBills();
- $header = [
+ $bills = $repository->getBills();
+ $header = [
'user_id',
'bill_id',
'created_at',
@@ -253,7 +245,7 @@ class ExportDataGenerator
'skip',
'active',
];
- $records = [];
+ $records = [];
/** @var Bill $bill */
foreach ($bills as $bill) {
@@ -273,23 +265,24 @@ class ExportDataGenerator
];
}
- //load the CSV document from a string
- $csv = Writer::createFromString();
+ // load the CSV document from a string
+ $csv = Writer::createFromString();
- //insert the header
+ // insert the header
try {
$csv->insertOne($header);
} catch (CannotInsertRecord $e) {
throw new FireflyException(sprintf(self::ADD_RECORD_ERR, $e->getMessage()), 0, $e);
}
- //insert all the records
+ // insert all the records
$csv->insertAll($records);
try {
$string = $csv->toString();
} catch (Exception $e) { // intentional generic exception
- Log::error($e->getMessage());
+ app('log')->error($e->getMessage());
+
throw new FireflyException(sprintf(self::EXPORT_ERR, $e->getMessage()), 0, $e);
}
@@ -297,14 +290,13 @@ class ExportDataGenerator
}
/**
- * @return string
* @throws CannotInsertRecord
* @throws Exception
* @throws FireflyException
*/
private function exportBudgets(): string
{
- $header = [
+ $header = [
'user_id',
'budget_id',
'name',
@@ -318,12 +310,14 @@ class ExportDataGenerator
$budgetRepos = app(BudgetRepositoryInterface::class);
$budgetRepos->setUser($this->user);
- $limitRepos = app(BudgetLimitRepositoryInterface::class);
- $budgets = $budgetRepos->getBudgets();
- $records = [];
+ $limitRepos = app(BudgetLimitRepositoryInterface::class);
+ $budgets = $budgetRepos->getBudgets();
+ $records = [];
+
/** @var Budget $budget */
foreach ($budgets as $budget) {
$limits = $limitRepos->getBudgetLimits($budget);
+
/** @var BudgetLimit $limit */
foreach ($limits as $limit) {
$records[] = [
@@ -340,23 +334,24 @@ class ExportDataGenerator
}
}
- //load the CSV document from a string
- $csv = Writer::createFromString();
+ // load the CSV document from a string
+ $csv = Writer::createFromString();
- //insert the header
+ // insert the header
try {
$csv->insertOne($header);
} catch (CannotInsertRecord $e) {
throw new FireflyException(sprintf(self::ADD_RECORD_ERR, $e->getMessage()), 0, $e);
}
- //insert all the records
+ // insert all the records
$csv->insertAll($records);
try {
$string = $csv->toString();
} catch (Exception $e) { // intentional generic exception
- Log::error($e->getMessage());
+ app('log')->error($e->getMessage());
+
throw new FireflyException(sprintf(self::EXPORT_ERR, $e->getMessage()), 0, $e);
}
@@ -364,17 +359,16 @@ class ExportDataGenerator
}
/**
- * @return string
* @throws CannotInsertRecord
* @throws Exception
* @throws FireflyException
*/
private function exportCategories(): string
{
- $header = ['user_id', 'category_id', 'created_at', 'updated_at', 'name'];
+ $header = ['user_id', 'category_id', 'created_at', 'updated_at', 'name'];
/** @var CategoryRepositoryInterface $catRepos */
- $catRepos = app(CategoryRepositoryInterface::class);
+ $catRepos = app(CategoryRepositoryInterface::class);
$catRepos->setUser($this->user);
$records = [];
@@ -391,23 +385,24 @@ class ExportDataGenerator
];
}
- //load the CSV document from a string
- $csv = Writer::createFromString();
+ // load the CSV document from a string
+ $csv = Writer::createFromString();
- //insert the header
+ // insert the header
try {
$csv->insertOne($header);
} catch (CannotInsertRecord $e) {
throw new FireflyException(sprintf(self::ADD_RECORD_ERR, $e->getMessage()), 0, $e);
}
- //insert all the records
+ // insert all the records
$csv->insertAll($records);
try {
$string = $csv->toString();
} catch (Exception $e) { // intentional generic exception
- Log::error($e->getMessage());
+ app('log')->error($e->getMessage());
+
throw new FireflyException(sprintf(self::EXPORT_ERR, $e->getMessage()), 0, $e);
}
@@ -415,7 +410,6 @@ class ExportDataGenerator
}
/**
- * @return string
* @throws CannotInsertRecord
* @throws Exception
* @throws FireflyException
@@ -423,14 +417,14 @@ class ExportDataGenerator
private function exportPiggies(): string
{
/** @var PiggyBankRepositoryInterface $piggyRepos */
- $piggyRepos = app(PiggyBankRepositoryInterface::class);
+ $piggyRepos = app(PiggyBankRepositoryInterface::class);
$piggyRepos->setUser($this->user);
/** @var AccountRepositoryInterface $accountRepos */
$accountRepos = app(AccountRepositoryInterface::class);
$accountRepos->setUser($this->user);
- $header = [
+ $header = [
'user_id',
'piggy_bank_id',
'created_at',
@@ -446,8 +440,8 @@ class ExportDataGenerator
'order',
'active',
];
- $records = [];
- $piggies = $piggyRepos->getPiggyBanks();
+ $records = [];
+ $piggies = $piggyRepos->getPiggyBanks();
/** @var PiggyBank $piggy */
foreach ($piggies as $piggy) {
@@ -471,23 +465,24 @@ class ExportDataGenerator
];
}
- //load the CSV document from a string
- $csv = Writer::createFromString();
+ // load the CSV document from a string
+ $csv = Writer::createFromString();
- //insert the header
+ // insert the header
try {
$csv->insertOne($header);
} catch (CannotInsertRecord $e) {
throw new FireflyException(sprintf(self::ADD_RECORD_ERR, $e->getMessage()), 0, $e);
}
- //insert all the records
+ // insert all the records
$csv->insertAll($records);
try {
$string = $csv->toString();
} catch (Exception $e) { // intentional generic exception
- Log::error($e->getMessage());
+ app('log')->error($e->getMessage());
+
throw new FireflyException(sprintf(self::EXPORT_ERR, $e->getMessage()), 0, $e);
}
@@ -495,7 +490,6 @@ class ExportDataGenerator
}
/**
- * @return string
* @throws CannotInsertRecord
* @throws Exception
* @throws FireflyException
@@ -505,63 +499,27 @@ class ExportDataGenerator
/** @var RecurringRepositoryInterface $recurringRepos */
$recurringRepos = app(RecurringRepositoryInterface::class);
$recurringRepos->setUser($this->user);
- $header = [
+ $header = [
// recurrence:
- 'user_id',
- 'recurrence_id',
- 'row_contains',
- 'created_at',
- 'updated_at',
- 'type',
- 'title',
- 'description',
- 'first_date',
- 'repeat_until',
- 'latest_date',
- 'repetitions',
- 'apply_rules',
- 'active',
+ 'user_id', 'recurrence_id', 'row_contains', 'created_at', 'updated_at', 'type', 'title', 'description', 'first_date', 'repeat_until', 'latest_date', 'repetitions', 'apply_rules', 'active',
// repetition info:
- 'type',
- 'moment',
- 'skip',
- 'weekend',
+ 'type', 'moment', 'skip', 'weekend',
// transactions + meta:
- 'currency_code',
- 'foreign_currency_code',
- 'source_name',
- 'source_type',
- 'destination_name',
- 'destination_type',
- 'amount',
- 'foreign_amount',
- 'category',
- 'budget',
- 'piggy_bank',
- 'tags',
+ 'currency_code', 'foreign_currency_code', 'source_name', 'source_type', 'destination_name', 'destination_type', 'amount', 'foreign_amount', 'category', 'budget', 'piggy_bank', 'tags',
];
- $records = [];
- $recurrences = $recurringRepos->getAll();
+ $records = [];
+ $recurrences = $recurringRepos->getAll();
+
/** @var Recurrence $recurrence */
foreach ($recurrences as $recurrence) {
// add recurrence:
$records[] = [
- $this->user->id,
- $recurrence->id,
+ $this->user->id, $recurrence->id,
'recurrence',
- $recurrence->created_at->toAtomString(),
- $recurrence->updated_at->toAtomString(),
- $recurrence->transactionType->type,
- $recurrence->title,
- $recurrence->description,
- $recurrence->first_date?->format('Y-m-d'),
- $recurrence->repeat_until?->format('Y-m-d'),
- $recurrence->latest_date?->format('Y-m-d'),
- $recurrence->repetitions,
- $recurrence->apply_rules,
- $recurrence->active,
+ $recurrence->created_at->toAtomString(), $recurrence->updated_at->toAtomString(), $recurrence->transactionType->type, $recurrence->title, $recurrence->description, $recurrence->first_date?->format('Y-m-d'), $recurrence->repeat_until?->format('Y-m-d'), $recurrence->latest_date?->format('Y-m-d'), $recurrence->repetitions, $recurrence->apply_rules, $recurrence->active,
];
+
// add new row for each repetition
/** @var RecurrenceRepetition $repetition */
foreach ($recurrence->recurrenceRepetitions as $repetition) {
@@ -570,25 +528,13 @@ class ExportDataGenerator
$this->user->id,
$recurrence->id,
'repetition',
- null,
- null,
- null,
- null,
- null,
- null,
- null,
- null,
- null,
- null,
- null,
+ null, null, null, null, null, null, null, null, null, null, null,
// repetition:
- $repetition->repetition_type,
- $repetition->repetition_moment,
- $repetition->repetition_skip,
- $repetition->weekend,
+ $repetition->repetition_type, $repetition->repetition_moment, $repetition->repetition_skip, $repetition->weekend,
];
}
+
/** @var RecurrenceTransaction $transaction */
foreach ($recurrence->recurrenceTransactions as $transaction) {
$categoryName = $recurringRepos->getCategoryName($transaction);
@@ -596,62 +542,39 @@ class ExportDataGenerator
$piggyBankId = $recurringRepos->getPiggyBank($transaction);
$tags = $recurringRepos->getTags($transaction);
- $records[] = [
+ $records[] = [
// recurrence
$this->user->id,
$recurrence->id,
'transaction',
- null,
- null,
- null,
- null,
- null,
- null,
- null,
- null,
- null,
- null,
- null,
+ null, null, null, null, null, null, null, null, null, null, null,
// repetition:
- null,
- null,
- null,
- null,
+ null, null, null, null,
// transaction:
- $transaction->transactionCurrency->code,
- $transaction->foreignCurrency?->code,
- $transaction->sourceAccount->name,
- $transaction->sourceAccount->accountType->type,
- $transaction->destinationAccount->name,
- $transaction->destinationAccount->accountType->type,
- $transaction->amount,
- $transaction->foreign_amount,
- $categoryName,
- $budgetId,
- $piggyBankId,
- implode(',', $tags),
+ $transaction->transactionCurrency->code, $transaction->foreignCurrency?->code, $transaction->sourceAccount->name, $transaction->sourceAccount->accountType->type, $transaction->destinationAccount->name, $transaction->destinationAccount->accountType->type, $transaction->amount, $transaction->foreign_amount, $categoryName, $budgetId, $piggyBankId, implode(',', $tags),
];
}
}
- //load the CSV document from a string
- $csv = Writer::createFromString();
+ // load the CSV document from a string
+ $csv = Writer::createFromString();
- //insert the header
+ // insert the header
try {
$csv->insertOne($header);
} catch (CannotInsertRecord $e) {
throw new FireflyException(sprintf(self::ADD_RECORD_ERR, $e->getMessage()), 0, $e);
}
- //insert all the records
+ // insert all the records
$csv->insertAll($records);
try {
$string = $csv->toString();
} catch (Exception $e) { // intentional generic exception
- Log::error($e->getMessage());
+ app('log')->error($e->getMessage());
+
throw new FireflyException(sprintf(self::EXPORT_ERR, $e->getMessage()), 0, $e);
}
@@ -659,7 +582,6 @@ class ExportDataGenerator
}
/**
- * @return string
* @throws CannotInsertRecord
* @throws Exception
* @throws FireflyException
@@ -667,122 +589,69 @@ class ExportDataGenerator
private function exportRules(): string
{
$header = [
- 'user_id',
- 'rule_id',
- 'row_contains',
- 'created_at',
- 'updated_at',
- 'group_id',
- 'group_name',
- 'title',
- 'description',
- 'order',
- 'active',
- 'stop_processing',
- 'strict',
- 'trigger_type',
- 'trigger_value',
- 'trigger_order',
- 'trigger_active',
- 'trigger_stop_processing',
- 'action_type',
- 'action_value',
- 'action_order',
- 'action_active',
- 'action_stop_processing',
- ];
+ 'user_id', 'rule_id', 'row_contains',
+ 'created_at', 'updated_at', 'group_id', 'title', 'description', 'order', 'active', 'stop_processing', 'strict',
+ 'trigger_type', 'trigger_value', 'trigger_order', 'trigger_active', 'trigger_stop_processing',
+ 'action_type', 'action_value', 'action_order', 'action_active', 'action_stop_processing'];
$ruleRepos = app(RuleRepositoryInterface::class);
$ruleRepos->setUser($this->user);
- $rules = $ruleRepos->getAll();
- $records = [];
+ $rules = $ruleRepos->getAll();
+ $records = [];
+
/** @var Rule $rule */
foreach ($rules as $rule) {
- $records[] = [
- $this->user->id,
- $rule->id,
+ $entry = [
+ $this->user->id, $rule->id,
'rule',
- $rule->created_at->toAtomString(),
- $rule->updated_at->toAtomString(),
- $rule->ruleGroup->id,
- $rule->ruleGroup->title,
- $rule->title,
- $rule->description,
- $rule->order,
- $rule->active,
- $rule->stop_processing,
- $rule->strict,
+ $rule->created_at->toAtomString(), $rule->updated_at->toAtomString(), $rule->ruleGroup->id, $rule->ruleGroup->title, $rule->title, $rule->description, $rule->order, $rule->active, $rule->stop_processing, $rule->strict,
+ null, null, null, null, null, null, null, null, null,
];
+ $records[] = $entry;
+
/** @var RuleTrigger $trigger */
foreach ($rule->ruleTriggers as $trigger) {
- $records[] = [
+ $entry = [
$this->user->id,
$rule->id,
'trigger',
- null,
- null,
- null,
- null,
- null,
- null,
- null,
- null,
- null,
- null,
- $trigger->trigger_type,
- $trigger->trigger_value,
- $trigger->order,
- $trigger->active,
- $trigger->stop_processing,
+ null, null, null, null, null, null, null, null, null,
+ $trigger->trigger_type, $trigger->trigger_value, $trigger->order, $trigger->active, $trigger->stop_processing,
+ null, null, null, null, null,
];
+ $records[] = $entry;
}
/** @var RuleAction $action */
foreach ($rule->ruleActions as $action) {
- $records[] = [
+ $entry = [
$this->user->id,
$rule->id,
'action',
- null,
- null,
- null,
- null,
- null,
- null,
- null,
- null,
- null,
- null,
- null,
- null,
- null,
- null,
- null,
- $action->action_type,
- $action->action_value,
- $action->order,
- $action->active,
- $action->stop_processing,
+ null, null, null, null, null, null, null, null, null, null, null, null, null, null,
+ $action->action_type, $action->action_value, $action->order, $action->active, $action->stop_processing,
];
+ $records[] = $entry;
}
}
- //load the CSV document from a string
- $csv = Writer::createFromString();
+ // load the CSV document from a string
+ $csv = Writer::createFromString();
- //insert the header
+ // insert the header
try {
$csv->insertOne($header);
} catch (CannotInsertRecord $e) {
throw new FireflyException(sprintf(self::ADD_RECORD_ERR, $e->getMessage()), 0, $e);
}
- //insert all the records
+ // insert all the records
$csv->insertAll($records);
try {
$string = $csv->toString();
} catch (Exception $e) { // intentional generic exception
- Log::error($e->getMessage());
+ app('log')->error($e->getMessage());
+
throw new FireflyException(sprintf(self::EXPORT_ERR, $e->getMessage()), 0, $e);
}
@@ -790,21 +659,19 @@ class ExportDataGenerator
}
/**
- * @return string
* @throws CannotInsertRecord
- * @throws ContainerExceptionInterface
* @throws Exception
* @throws FireflyException
- * @throws NotFoundExceptionInterface
*/
private function exportTags(): string
{
- $header = ['user_id', 'tag_id', 'created_at', 'updated_at', 'tag', 'date', 'description', 'latitude', 'longitude', 'zoom_level'];
+ $header = ['user_id', 'tag_id', 'created_at', 'updated_at', 'tag', 'date', 'description', 'latitude', 'longitude', 'zoom_level'];
$tagRepos = app(TagRepositoryInterface::class);
$tagRepos->setUser($this->user);
- $tags = $tagRepos->get();
- $records = [];
+ $tags = $tagRepos->get();
+ $records = [];
+
/** @var Tag $tag */
foreach ($tags as $tag) {
$records[] = [
@@ -821,23 +688,24 @@ class ExportDataGenerator
];
}
- //load the CSV document from a string
- $csv = Writer::createFromString();
+ // load the CSV document from a string
+ $csv = Writer::createFromString();
- //insert the header
+ // insert the header
try {
$csv->insertOne($header);
} catch (CannotInsertRecord $e) {
throw new FireflyException(sprintf(self::ADD_RECORD_ERR, $e->getMessage()), 0, $e);
}
- //insert all the records
+ // insert all the records
$csv->insertAll($records);
try {
$string = $csv->toString();
} catch (Exception $e) { // intentional generic exception
- Log::error($e->getMessage());
+ app('log')->error($e->getMessage());
+
throw new FireflyException(sprintf(self::EXPORT_ERR, $e->getMessage()), 0, $e);
}
@@ -845,7 +713,7 @@ class ExportDataGenerator
}
/**
- * @inheritDoc
+ * @SuppressWarnings(PHPMD.UnusedFormalParameter)
*/
public function get(string $key, mixed $default = null): mixed
{
@@ -853,7 +721,6 @@ class ExportDataGenerator
}
/**
- * @return string
* @throws CannotInsertRecord
* @throws Exception
* @throws FireflyException
@@ -861,155 +728,79 @@ class ExportDataGenerator
private function exportTransactions(): string
{
// TODO better place for keys?
- $header = [
- 'user_id',
- 'group_id',
- 'journal_id',
- 'created_at',
- 'updated_at',
- 'group_title',
- 'type',
- 'amount',
- 'foreign_amount',
- 'currency_code',
- 'foreign_currency_code',
- 'description',
- 'date',
- 'source_name',
- 'source_iban',
- 'source_type',
- 'destination_name',
- 'destination_iban',
- 'destination_type',
- 'reconciled',
- 'category',
- 'budget',
- 'bill',
- 'tags',
- 'notes',
- // all optional meta fields:
- ];
+ $header = ['user_id', 'group_id', 'journal_id', 'created_at', 'updated_at', 'group_title', 'type', 'amount', 'foreign_amount', 'currency_code', 'foreign_currency_code', 'description', 'date', 'source_name', 'source_iban', 'source_type', 'destination_name', 'destination_iban', 'destination_type', 'reconciled', 'category', 'budget', 'bill', 'tags', 'notes'];
$metaFields = config('firefly.journal_meta_fields');
$header = array_merge($header, $metaFields);
- $collector = app(GroupCollectorInterface::class);
+ $collector = app(GroupCollectorInterface::class);
$collector->setUser($this->user);
$collector->setRange($this->start, $this->end)->withAccountInformation()->withCategoryInformation()->withBillInformation()
- ->withBudgetInformation()->withTagInformation()->withNotes();
+ ->withBudgetInformation()->withTagInformation()->withNotes()
+ ;
if (0 !== $this->accounts->count()) {
$collector->setAccounts($this->accounts);
}
- $journals = $collector->getExtractedJournals();
+ $journals = $collector->getExtractedJournals();
// get repository for meta data:
$repository = app(TransactionGroupRepositoryInterface::class);
$repository->setUser($this->user);
- $records = [];
+ $records = [];
+
/** @var array $journal */
foreach ($journals as $journal) {
$metaData = $repository->getMetaFields($journal['transaction_journal_id'], $metaFields);
$records[] = [
- $journal['user_id'],
- $journal['transaction_group_id'],
- $journal['transaction_journal_id'],
- $journal['created_at']->toAtomString(),
- $journal['updated_at']->toAtomString(),
- $journal['transaction_group_title'],
- $journal['transaction_type_type'],
- $journal['amount'],
- $journal['foreign_amount'],
- $journal['currency_code'],
- $journal['foreign_currency_code'],
- $journal['description'],
- $journal['date']->toAtomString(),
- $journal['source_account_name'],
- $journal['source_account_iban'],
- $journal['source_account_type'],
- $journal['destination_account_name'],
- $journal['destination_account_iban'],
- $journal['destination_account_type'],
- $journal['reconciled'],
- $journal['category_name'],
- $journal['budget_name'],
- $journal['bill_name'],
+ $journal['user_id'], $journal['transaction_group_id'], $journal['transaction_journal_id'], $journal['created_at']->toAtomString(), $journal['updated_at']->toAtomString(), $journal['transaction_group_title'], $journal['transaction_type_type'], $journal['amount'], $journal['foreign_amount'], $journal['currency_code'], $journal['foreign_currency_code'], $journal['description'], $journal['date']->toAtomString(), $journal['source_account_name'], $journal['source_account_iban'], $journal['source_account_type'], $journal['destination_account_name'], $journal['destination_account_iban'], $journal['destination_account_type'], $journal['reconciled'], $journal['category_name'], $journal['budget_name'], $journal['bill_name'],
$this->mergeTags($journal['tags']),
- $this->clearString($journal['notes'], true),
-
- // export also the optional fields (ALL)
+ $this->clearStringKeepNewlines($journal['notes']),
// sepa
- $metaData['sepa_cc'],
- $metaData['sepa_ct_op'],
- $metaData['sepa_ct_id'],
- $metaData['sepa_db'],
- $metaData['sepa_country'],
- $metaData['sepa_ep'],
- $metaData['sepa_ci'],
- $metaData['sepa_batch_id'],
- $metaData['external_url'],
+ $metaData['sepa_cc'], $metaData['sepa_ct_op'], $metaData['sepa_ct_id'], $metaData['sepa_db'], $metaData['sepa_country'], $metaData['sepa_ep'], $metaData['sepa_ci'], $metaData['sepa_batch_id'], $metaData['external_url'],
// dates
- $metaData['interest_date'],
- $metaData['book_date'],
- $metaData['process_date'],
- $metaData['due_date'],
- $metaData['payment_date'],
- $metaData['invoice_date'],
+ $metaData['interest_date'], $metaData['book_date'], $metaData['process_date'], $metaData['due_date'], $metaData['payment_date'], $metaData['invoice_date'],
// others
- $metaData['recurrence_id'],
- $metaData['internal_reference'],
- $metaData['bunq_payment_id'],
- $metaData['import_hash'],
- $metaData['import_hash_v2'],
- $metaData['external_id'],
- $metaData['original_source'],
+ $metaData['recurrence_id'], $metaData['internal_reference'], $metaData['bunq_payment_id'], $metaData['import_hash'], $metaData['import_hash_v2'], $metaData['external_id'], $metaData['original_source'],
// recurring transactions
- $metaData['recurrence_total'],
- $metaData['recurrence_count'],
+ $metaData['recurrence_total'], $metaData['recurrence_count'],
];
}
- //load the CSV document from a string
- $csv = Writer::createFromString();
+ // load the CSV document from a string
+ $csv = Writer::createFromString();
- //insert the header
+ // insert the header
try {
$csv->insertOne($header);
} catch (CannotInsertRecord $e) {
throw new FireflyException(sprintf(self::ADD_RECORD_ERR, $e->getMessage()), 0, $e);
}
- //insert all the records
+ // insert all the records
$csv->insertAll($records);
try {
$string = $csv->toString();
} catch (Exception $e) { // intentional generic exception
- Log::error($e->getMessage());
+ app('log')->error($e->getMessage());
+
throw new FireflyException(sprintf(self::EXPORT_ERR, $e->getMessage()), 0, $e);
}
return $string;
}
- /**
- * @param Collection $accounts
- */
public function setAccounts(Collection $accounts): void
{
$this->accounts = $accounts;
}
- /**
- * @param array $tags
- *
- * @return string
- */
private function mergeTags(array $tags): string
{
if (0 === count($tags)) {
@@ -1024,96 +815,63 @@ class ExportDataGenerator
}
/**
- * @inheritDoc
+ * @SuppressWarnings(PHPMD.UnusedFormalParameter)
*/
public function has(mixed $key): mixed
{
return null;
}
- /**
- * @param Carbon $end
- */
public function setEnd(Carbon $end): void
{
$this->end = $end;
}
- /**
- * @param bool $exportAccounts
- */
public function setExportAccounts(bool $exportAccounts): void
{
$this->exportAccounts = $exportAccounts;
}
- /**
- * @param bool $exportBills
- */
public function setExportBills(bool $exportBills): void
{
$this->exportBills = $exportBills;
}
- /**
- * @param bool $exportBudgets
- */
public function setExportBudgets(bool $exportBudgets): void
{
$this->exportBudgets = $exportBudgets;
}
- /**
- * @param bool $exportCategories
- */
public function setExportCategories(bool $exportCategories): void
{
$this->exportCategories = $exportCategories;
}
- /**
- * @param bool $exportPiggies
- */
public function setExportPiggies(bool $exportPiggies): void
{
$this->exportPiggies = $exportPiggies;
}
- /**
- * @param bool $exportRecurring
- */
public function setExportRecurring(bool $exportRecurring): void
{
$this->exportRecurring = $exportRecurring;
}
- /**
- * @param bool $exportRules
- */
public function setExportRules(bool $exportRules): void
{
$this->exportRules = $exportRules;
}
- /**
- * @param bool $exportTags
- */
public function setExportTags(bool $exportTags): void
{
$this->exportTags = $exportTags;
}
- /**
- * @param bool $exportTransactions
- */
public function setExportTransactions(bool $exportTransactions): void
{
$this->exportTransactions = $exportTransactions;
}
- /**
- * @param Carbon $start
- */
public function setStart(Carbon $start): void
{
$this->start = $start;
diff --git a/app/Support/Facades/AccountForm.php b/app/Support/Facades/AccountForm.php
index 6681ad427c..2a44acd2bd 100644
--- a/app/Support/Facades/AccountForm.php
+++ b/app/Support/Facades/AccountForm.php
@@ -27,14 +27,11 @@ use Illuminate\Support\Facades\Facade;
/**
* Class AccountForm.
- *
*/
class AccountForm extends Facade
{
/**
* Get the registered name of the component.
- *
- * @return string
*/
protected static function getFacadeAccessor(): string
{
diff --git a/app/Support/Facades/Amount.php b/app/Support/Facades/Amount.php
index c11965dc7d..81abb85066 100644
--- a/app/Support/Facades/Amount.php
+++ b/app/Support/Facades/Amount.php
@@ -31,11 +31,11 @@ use Illuminate\Support\Facades\Facade;
/**
* Class Amount.
*
- * @method string formatAnything(TransactionCurrency $format, string $amount, bool $coloured = true)
- * @method Collection getAllCurrencies()
- * @method Collection getCurrencies()
- * @method string getCurrencyCode()
- * @method string getCurrencySymbol()
+ * @method string formatAnything(TransactionCurrency $format, string $amount, bool $coloured = true)
+ * @method Collection getAllCurrencies()
+ * @method Collection getCurrencies()
+ * @method string getCurrencyCode()
+ * @method string getCurrencySymbol()
* @method TransactionCurrency getDefaultCurrency()
* @method TransactionCurrency getDefaultCurrencyByUser(User $user)
*/
@@ -43,8 +43,6 @@ class Amount extends Facade
{
/**
* Get the registered name of the component.
- *
- * @return string
*/
protected static function getFacadeAccessor(): string
{
diff --git a/app/Support/Facades/CurrencyForm.php b/app/Support/Facades/CurrencyForm.php
index 08fdf6b78d..528ece371b 100644
--- a/app/Support/Facades/CurrencyForm.php
+++ b/app/Support/Facades/CurrencyForm.php
@@ -27,14 +27,11 @@ use Illuminate\Support\Facades\Facade;
/**
* Class CurrencyForm.
- *
*/
class CurrencyForm extends Facade
{
/**
* Get the registered name of the component.
- *
- * @return string
*/
protected static function getFacadeAccessor(): string
{
diff --git a/app/Support/Facades/ExpandedForm.php b/app/Support/Facades/ExpandedForm.php
index bd9c781816..9763269708 100644
--- a/app/Support/Facades/ExpandedForm.php
+++ b/app/Support/Facades/ExpandedForm.php
@@ -32,8 +32,6 @@ class ExpandedForm extends Facade
{
/**
* Get the registered name of the component.
- *
- * @return string
*/
protected static function getFacadeAccessor(): string
{
diff --git a/app/Support/Facades/FireflyConfig.php b/app/Support/Facades/FireflyConfig.php
index 3c5fc74e53..c5c3b505e2 100644
--- a/app/Support/Facades/FireflyConfig.php
+++ b/app/Support/Facades/FireflyConfig.php
@@ -28,18 +28,17 @@ use Illuminate\Support\Facades\Facade;
/**
* Class FireflyConfig.
+ *
* @method null|Configuration get($name, $default = null)
- * @method Configuration set(string $name, $value)
+ * @method Configuration set(string $name, $value)
* @method delete(string $name)
- * @method Configuration|null getFresh(string $name, $default = null)
- * @method Configuration put(string $name, $value)
+ * @method null|Configuration getFresh(string $name, $default = null)
+ * @method Configuration put(string $name, $value)
*/
class FireflyConfig extends Facade
{
/**
* Get the registered name of the component.
- *
- * @return string
*/
protected static function getFacadeAccessor(): string
{
diff --git a/app/Support/Facades/Navigation.php b/app/Support/Facades/Navigation.php
index 3e18b1568c..bb171321a6 100644
--- a/app/Support/Facades/Navigation.php
+++ b/app/Support/Facades/Navigation.php
@@ -30,10 +30,10 @@ use Illuminate\Support\Facades\Facade;
* Class Navigation.
*
* @method Carbon addPeriod(Carbon $theDate, string $repeatFreq, int $skip)
- * @method array blockPeriods(Carbon $start, Carbon $end, string $range)
+ * @method array blockPeriods(Carbon $start, Carbon $end, string $range)
* @method Carbon endOfPeriod(Carbon $end, string $repeatFreq)
* @method Carbon endOfX(Carbon $theCurrentEnd, string $repeatFreq, Carbon $maxDate = null)
- * @method array listOfPeriods(Carbon $start, Carbon $end)
+ * @method array listOfPeriods(Carbon $start, Carbon $end)
* @method string periodShow(Carbon $theDate, string $repeatFrequency)
* @method string preferredCarbonFormat(Carbon $start, Carbon $end)
* @method string preferredCarbonLocalizedFormat(Carbon $start, Carbon $end)
@@ -49,8 +49,6 @@ class Navigation extends Facade
{
/**
* Get the registered name of the component.
- *
- * @return string
*/
protected static function getFacadeAccessor(): string
{
diff --git a/app/Support/Facades/PiggyBankForm.php b/app/Support/Facades/PiggyBankForm.php
index bfb9bfe307..3dd4c84bda 100644
--- a/app/Support/Facades/PiggyBankForm.php
+++ b/app/Support/Facades/PiggyBankForm.php
@@ -27,14 +27,11 @@ use Illuminate\Support\Facades\Facade;
/**
* Class PiggyBankForm.
- *
*/
class PiggyBankForm extends Facade
{
/**
* Get the registered name of the component.
- *
- * @return string
*/
protected static function getFacadeAccessor(): string
{
diff --git a/app/Support/Facades/Preferences.php b/app/Support/Facades/Preferences.php
index 4fa1bb978e..207f5bf5a0 100644
--- a/app/Support/Facades/Preferences.php
+++ b/app/Support/Facades/Preferences.php
@@ -31,16 +31,16 @@ use Illuminate\Support\Facades\Facade;
/**
* Class Preferences.
*
- * @method Collection beginsWith(User $user, string $search)
- * @method bool delete(string $name)
- * @method Collection findByName(string $name)
- * @method Preference get(string $name, $value = null)
- * @method array getArrayForUser(User $user, array $list)
- * @method Preference|null getForUser(User $user, string $name, $default = null)
- * @method string lastActivity()
- * @method void mark()
- * @method Preference set(string $name, $value)
- * @method Preference setForUser(User $user, string $name, $value)
+ * @method Collection beginsWith(User $user, string $search)
+ * @method bool delete(string $name)
+ * @method Collection findByName(string $name)
+ * @method Preference get(string $name, $value = null)
+ * @method array getArrayForUser(User $user, array $list)
+ * @method null|Preference getForUser(User $user, string $name, $default = null)
+ * @method string lastActivity()
+ * @method void mark()
+ * @method Preference set(string $name, $value)
+ * @method Preference setForUser(User $user, string $name, $value)
*/
class Preferences extends Facade
{
@@ -51,8 +51,6 @@ class Preferences extends Facade
/**
* Get the registered name of the component.
- *
- * @return string
*/
protected static function getFacadeAccessor(): string
{
diff --git a/app/Support/Facades/RuleForm.php b/app/Support/Facades/RuleForm.php
index a13a626cac..b2aacf783f 100644
--- a/app/Support/Facades/RuleForm.php
+++ b/app/Support/Facades/RuleForm.php
@@ -27,14 +27,11 @@ use Illuminate\Support\Facades\Facade;
/**
* Class RuleForm.
- *
*/
class RuleForm extends Facade
{
/**
* Get the registered name of the component.
- *
- * @return string
*/
protected static function getFacadeAccessor(): string
{
diff --git a/app/Support/Facades/Steam.php b/app/Support/Facades/Steam.php
index 89ac24b108..747f990bf0 100644
--- a/app/Support/Facades/Steam.php
+++ b/app/Support/Facades/Steam.php
@@ -33,24 +33,20 @@ use Illuminate\Support\Facades\Facade;
*
* @method string balance(Account $account, Carbon $date)
* @method string balanceIgnoreVirtual(Account $account, Carbon $date)
- * @method array balanceInRange(Account $account, Carbon $start, Carbon $end)
- * @method array balancesByAccounts(Collection $accounts, Carbon $date)
+ * @method array balanceInRange(Account $account, Carbon $start, Carbon $end)
+ * @method array balancesByAccounts(Collection $accounts, Carbon $date)
* @method decrypt(int $isEncrypted, string $value)
- * @method array getLastActivities(array $accounts)
- * @method string negative(string $amount)
- * @method string|null opposite(string $amount = null)
- * @method int phpBytes(string $string)
- * @method string positive(string $amount)
- * @method array balancesPerCurrencyByAccounts(Collection $accounts, Carbon $date)
- *
-
+ * @method array getLastActivities(array $accounts)
+ * @method string negative(string $amount)
+ * @method null|string opposite(string $amount = null)
+ * @method int phpBytes(string $string)
+ * @method string positive(string $amount)
+ * @method array balancesPerCurrencyByAccounts(Collection $accounts, Carbon $date)
*/
class Steam extends Facade
{
/**
* Get the registered name of the component.
- *
- * @return string
*/
protected static function getFacadeAccessor(): string
{
diff --git a/app/Support/FireflyConfig.php b/app/Support/FireflyConfig.php
index 86dcd29dbf..c4078dbfd0 100644
--- a/app/Support/FireflyConfig.php
+++ b/app/Support/FireflyConfig.php
@@ -23,65 +23,50 @@ declare(strict_types=1);
namespace FireflyIII\Support;
-use Cache;
-use Exception;
use FireflyIII\Exceptions\FireflyException;
use FireflyIII\Models\Configuration;
use Illuminate\Database\QueryException;
-use Illuminate\Support\Facades\Log;
/**
* Class FireflyConfig.
- *
-
*/
class FireflyConfig
{
- /**
- * @param string $name
- */
public function delete(string $name): void
{
- $fullName = 'ff-config-' . $name;
- if (Cache::has($fullName)) {
- Cache::forget($fullName);
+ $fullName = 'ff-config-'.$name;
+ if (\Cache::has($fullName)) {
+ \Cache::forget($fullName);
}
Configuration::where('name', $name)->forceDelete();
}
- /**
- * @param string $name
- *
- * @return bool
- */
public function has(string $name): bool
{
- return Configuration::where('name', $name)->count() === 1;
+ return 1 === Configuration::where('name', $name)->count();
}
/**
- * @param string $name
- * @param bool|string|int|null $default
+ * @param null|bool|int|string $default
*
- * @return Configuration|null
* @throws FireflyException
*/
public function get(string $name, $default = null): ?Configuration
{
- $fullName = 'ff-config-' . $name;
- if (Cache::has($fullName)) {
- return Cache::get($fullName);
+ $fullName = 'ff-config-'.$name;
+ if (\Cache::has($fullName)) {
+ return \Cache::get($fullName);
}
try {
- /** @var Configuration|null $config */
+ /** @var null|Configuration $config */
$config = Configuration::where('name', $name)->first(['id', 'name', 'data']);
- } catch (QueryException | Exception $e) {
+ } catch (\Exception|QueryException $e) {
throw new FireflyException(sprintf('Could not poll the database: %s', $e->getMessage()), 0, $e);
}
if (null !== $config) {
- Cache::forever($fullName, $config);
+ \Cache::forever($fullName, $config);
return $config;
}
@@ -94,17 +79,14 @@ class FireflyConfig
}
/**
- * @param string $name
- * @param mixed $value
- *
- * @return Configuration
+ * @param mixed $value
*/
public function set(string $name, $value): Configuration
{
try {
$config = Configuration::whereName($name)->whereNull('deleted_at')->first();
} catch (QueryException $e) {
- Log::error($e->getMessage());
+ app('log')->error($e->getMessage());
$item = new Configuration();
$item->name = $name;
$item->data = $value;
@@ -117,27 +99,24 @@ class FireflyConfig
$item->name = $name;
$item->data = $value;
$item->save();
- Cache::forget('ff-config-' . $name);
+ \Cache::forget('ff-config-'.$name);
return $item;
}
$config->data = $value;
$config->save();
- Cache::forget('ff-config-' . $name);
+ \Cache::forget('ff-config-'.$name);
return $config;
}
/**
- * @param string $name
- * @param mixed $default
- *
- * @return Configuration|null
+ * @param mixed $default
*/
public function getFresh(string $name, $default = null): ?Configuration
{
$config = Configuration::where('name', $name)->first(['id', 'name', 'data']);
- if ($config) {
+ if (null !== $config) {
return $config;
}
// no preference found and default is null:
@@ -149,10 +128,7 @@ class FireflyConfig
}
/**
- * @param string $name
- * @param mixed $value
- *
- * @return Configuration
+ * @param mixed $value
*/
public function put(string $name, $value): Configuration
{
diff --git a/app/Support/Form/AccountForm.php b/app/Support/Form/AccountForm.php
index 0710bb6967..4a379117cb 100644
--- a/app/Support/Form/AccountForm.php
+++ b/app/Support/Form/AccountForm.php
@@ -27,8 +27,6 @@ use FireflyIII\Exceptions\FireflyException;
use FireflyIII\Models\Account;
use FireflyIII\Models\AccountType;
use FireflyIII\Repositories\Account\AccountRepositoryInterface;
-use Illuminate\Support\Facades\Log;
-use Throwable;
/**
* Class AccountForm
@@ -44,16 +42,10 @@ class AccountForm
/**
* Grouped dropdown list of all accounts that are valid as the destination of a withdrawal.
- *
- * @param string $name
- * @param mixed $value
- * @param array|null $options
- *
- * @return string
*/
public function activeDepositDestinations(string $name, mixed $value = null, array $options = null): string
{
- $types = [AccountType::MORTGAGE, AccountType::DEBT, AccountType::CREDITCARD, AccountType::LOAN, AccountType::REVENUE,];
+ $types = [AccountType::MORTGAGE, AccountType::DEBT, AccountType::CREDITCARD, AccountType::LOAN, AccountType::REVENUE];
$repository = $this->getAccountRepository();
$grouped = $this->getAccountsGrouped($types, $repository);
$cash = $repository->getCashAccount();
@@ -63,24 +55,18 @@ class AccountForm
return $this->select($name, $grouped, $value, $options);
}
- /**
- * @param array $types
- * @param AccountRepositoryInterface|null $repository
- *
- * @return array
- */
private function getAccountsGrouped(array $types, AccountRepositoryInterface $repository = null): array
{
if (null === $repository) {
$repository = $this->getAccountRepository();
}
$accountList = $repository->getActiveAccountsByType($types);
- $liabilityTypes = [AccountType::MORTGAGE, AccountType::DEBT, AccountType::CREDITCARD, AccountType::LOAN,];
+ $liabilityTypes = [AccountType::MORTGAGE, AccountType::DEBT, AccountType::CREDITCARD, AccountType::LOAN];
$grouped = [];
/** @var Account $account */
foreach ($accountList as $account) {
- $role = (string)$repository->getMetaValue($account, 'account_role');
+ $role = (string)$repository->getMetaValue($account, 'account_role');
if (in_array($account->accountType->type, $liabilityTypes, true)) {
$role = sprintf('l_%s', $account->accountType->type);
}
@@ -102,18 +88,12 @@ class AccountForm
/**
* Grouped dropdown list of all accounts that are valid as the destination of a withdrawal.
- *
- * @param string $name
- * @param mixed $value
- * @param array|null $options
- *
- * @return string
*/
public function activeWithdrawalDestinations(string $name, mixed $value = null, array $options = null): string
{
- $types = [AccountType::MORTGAGE, AccountType::DEBT, AccountType::CREDITCARD, AccountType::LOAN, AccountType::EXPENSE,];
- $repository = $this->getAccountRepository();
- $grouped = $this->getAccountsGrouped($types, $repository);
+ $types = [AccountType::MORTGAGE, AccountType::DEBT, AccountType::CREDITCARD, AccountType::LOAN, AccountType::EXPENSE];
+ $repository = $this->getAccountRepository();
+ $grouped = $this->getAccountsGrouped($types, $repository);
$cash = $repository->getCashAccount();
$key = (string)trans('firefly.cash_account_type');
@@ -125,30 +105,28 @@ class AccountForm
/**
* Check list of asset accounts.
*
- * @param string $name
- * @param array|null $options
- *
- * @return string
* @throws FireflyException
*/
public function assetAccountCheckList(string $name, array $options = null): string
{
- $options = $options ?? [];
+ $options ??= [];
$label = $this->label($name, $options);
$options = $this->expandOptionArray($name, $label, $options);
$classes = $this->getHolderClasses($name);
$selected = request()->old($name) ?? [];
// get all asset accounts:
- $types = [AccountType::ASSET, AccountType::DEFAULT, AccountType::LOAN, AccountType::MORTGAGE, AccountType::DEBT];
- $grouped = $this->getAccountsGrouped($types);
+ $types = [AccountType::ASSET, AccountType::DEFAULT, AccountType::LOAN, AccountType::MORTGAGE, AccountType::DEBT];
+ $grouped = $this->getAccountsGrouped($types);
unset($options['class']);
+
try {
$html = view('form.assetAccountCheckList', compact('classes', 'selected', 'name', 'label', 'options', 'grouped'))->render();
- } catch (Throwable $e) {
- Log::debug(sprintf('Could not render assetAccountCheckList(): %s', $e->getMessage()));
+ } catch (\Throwable $e) {
+ app('log')->debug(sprintf('Could not render assetAccountCheckList(): %s', $e->getMessage()));
$html = 'Could not render assetAccountCheckList.';
+
throw new FireflyException($html, 0, $e);
}
@@ -158,11 +136,7 @@ class AccountForm
/**
* Basic list of asset accounts.
*
- * @param string $name
- * @param mixed $value
- * @param array|null $options
- *
- * @return string
+ * @param mixed $value
*/
public function assetAccountList(string $name, $value = null, array $options = null): string
{
@@ -175,15 +149,11 @@ class AccountForm
/**
* Same list but all liabilities as well.
*
- * @param string $name
- * @param mixed $value
- * @param array|null $options
- *
- * @return string
+ * @param mixed $value
*/
public function longAccountList(string $name, $value = null, array $options = null): string
{
- $types = [AccountType::ASSET, AccountType::DEFAULT, AccountType::MORTGAGE, AccountType::DEBT, AccountType::CREDITCARD, AccountType::LOAN,];
+ $types = [AccountType::ASSET, AccountType::DEFAULT, AccountType::MORTGAGE, AccountType::DEBT, AccountType::CREDITCARD, AccountType::LOAN];
$grouped = $this->getAccountsGrouped($types);
return $this->select($name, $grouped, $value, $options);
diff --git a/app/Support/Form/CurrencyForm.php b/app/Support/Form/CurrencyForm.php
index ea44ade235..dd04390c74 100644
--- a/app/Support/Form/CurrencyForm.php
+++ b/app/Support/Form/CurrencyForm.php
@@ -23,13 +23,10 @@ declare(strict_types=1);
namespace FireflyIII\Support\Form;
-use Amount as Amt;
use FireflyIII\Exceptions\FireflyException;
use FireflyIII\Models\TransactionCurrency;
-use FireflyIII\Repositories\Currency\CurrencyRepositoryInterface;
+use FireflyIII\Repositories\UserGroups\Currency\CurrencyRepositoryInterface;
use Illuminate\Support\Collection;
-use Illuminate\Support\Facades\Log;
-use Throwable;
/**
* Class CurrencyForm
@@ -41,11 +38,8 @@ class CurrencyForm
use FormSupport;
/**
- * @param string $name
- * @param mixed $value
- * @param array|null $options
+ * @param mixed $value
*
- * @return string
* @throws FireflyException
*/
public function amount(string $name, $value = null, array $options = null): string
@@ -54,12 +48,6 @@ class CurrencyForm
}
/**
- * @param string $name
- * @param string $view
- * @param mixed $value
- * @param array|null $options
- *
- * @return string
* @throws FireflyException
*/
protected function currencyField(string $name, string $view, mixed $value = null, array $options = null): string
@@ -69,26 +57,27 @@ class CurrencyForm
$classes = $this->getHolderClasses($name);
$value = $this->fillFieldValue($name, $value);
$options['step'] = 'any';
- $defaultCurrency = $options['currency'] ?? Amt::getDefaultCurrency();
- /** @var Collection $currencies */
- $currencies = app('amount')->getCurrencies();
- unset($options['currency'], $options['placeholder']);
+ $defaultCurrency = $options['currency'] ?? app('amount')->getDefaultCurrency();
+ /** @var Collection $currencies */
+ $currencies = app('amount')->getCurrencies();
+ unset($options['currency'], $options['placeholder']);
// perhaps the currency has been sent to us in the field $amount_currency_id_$name (amount_currency_id_amount)
- $preFilled = session('preFilled');
+ $preFilled = session('preFilled');
if (!is_array($preFilled)) {
$preFilled = [];
}
- $key = 'amount_currency_id_' . $name;
- $sentCurrencyId = array_key_exists($key, $preFilled) ? (int)$preFilled[$key] : $defaultCurrency->id;
+ $key = 'amount_currency_id_'.$name;
+ $sentCurrencyId = array_key_exists($key, $preFilled) ? (int)$preFilled[$key] : $defaultCurrency->id;
- Log::debug(sprintf('Sent currency ID is %d', $sentCurrencyId));
+ app('log')->debug(sprintf('Sent currency ID is %d', $sentCurrencyId));
// find this currency in set of currencies:
foreach ($currencies as $currency) {
if ($currency->id === $sentCurrencyId) {
$defaultCurrency = $currency;
- Log::debug(sprintf('default currency is now %s', $defaultCurrency->code));
+ app('log')->debug(sprintf('default currency is now %s', $defaultCurrency->code));
+
break;
}
}
@@ -97,11 +86,13 @@ class CurrencyForm
if (null !== $value && '' !== $value) {
$value = app('steam')->bcround($value, $defaultCurrency->decimal_places);
}
+
try {
- $html = view('form.' . $view, compact('defaultCurrency', 'currencies', 'classes', 'name', 'label', 'value', 'options'))->render();
- } catch (Throwable $e) {
- Log::debug(sprintf('Could not render currencyField(): %s', $e->getMessage()));
+ $html = view('form.'.$view, compact('defaultCurrency', 'currencies', 'classes', 'name', 'label', 'value', 'options'))->render();
+ } catch (\Throwable $e) {
+ app('log')->debug(sprintf('Could not render currencyField(): %s', $e->getMessage()));
$html = 'Could not render currencyField.';
+
throw new FireflyException($html, 0, $e);
}
@@ -111,11 +102,8 @@ class CurrencyForm
/**
* TODO describe and cleanup.
*
- * @param string $name
- * @param mixed $value
- * @param array|null $options
+ * @param mixed $value
*
- * @return string
* @throws FireflyException
*/
public function balanceAll(string $name, $value = null, array $options = null): string
@@ -126,12 +114,8 @@ class CurrencyForm
/**
* TODO describe and cleanup
*
- * @param string $name
- * @param string $view
- * @param mixed $value
- * @param array|null $options
+ * @param mixed $value
*
- * @return string
* @throws FireflyException
*/
protected function allCurrencyField(string $name, string $view, $value = null, array $options = null): string
@@ -141,26 +125,28 @@ class CurrencyForm
$classes = $this->getHolderClasses($name);
$value = $this->fillFieldValue($name, $value);
$options['step'] = 'any';
- $defaultCurrency = $options['currency'] ?? Amt::getDefaultCurrency();
+ $defaultCurrency = $options['currency'] ?? app('amount')->getDefaultCurrency();
+
/** @var Collection $currencies */
- $currencies = app('amount')->getAllCurrencies();
+ $currencies = app('amount')->getAllCurrencies();
unset($options['currency'], $options['placeholder']);
// perhaps the currency has been sent to us in the field $amount_currency_id_$name (amount_currency_id_amount)
- $preFilled = session('preFilled');
+ $preFilled = session('preFilled');
if (!is_array($preFilled)) {
$preFilled = [];
}
- $key = 'amount_currency_id_' . $name;
- $sentCurrencyId = array_key_exists($key, $preFilled) ? (int)$preFilled[$key] : $defaultCurrency->id;
+ $key = 'amount_currency_id_'.$name;
+ $sentCurrencyId = array_key_exists($key, $preFilled) ? (int)$preFilled[$key] : $defaultCurrency->id;
- Log::debug(sprintf('Sent currency ID is %d', $sentCurrencyId));
+ app('log')->debug(sprintf('Sent currency ID is %d', $sentCurrencyId));
// find this currency in set of currencies:
foreach ($currencies as $currency) {
if ($currency->id === $sentCurrencyId) {
$defaultCurrency = $currency;
- Log::debug(sprintf('default currency is now %s', $defaultCurrency->code));
+ app('log')->debug(sprintf('default currency is now %s', $defaultCurrency->code));
+
break;
}
}
@@ -169,11 +155,13 @@ class CurrencyForm
if (null !== $value && '' !== $value) {
$value = app('steam')->bcround($value, $defaultCurrency->decimal_places);
}
+
try {
- $html = view('form.' . $view, compact('defaultCurrency', 'currencies', 'classes', 'name', 'label', 'value', 'options'))->render();
- } catch (Throwable $e) {
- Log::debug(sprintf('Could not render currencyField(): %s', $e->getMessage()));
+ $html = view('form.'.$view, compact('defaultCurrency', 'currencies', 'classes', 'name', 'label', 'value', 'options'))->render();
+ } catch (\Throwable $e) {
+ app('log')->debug(sprintf('Could not render currencyField(): %s', $e->getMessage()));
$html = 'Could not render currencyField.';
+
throw new FireflyException($html, 0, $e);
}
@@ -183,11 +171,7 @@ class CurrencyForm
/**
* TODO cleanup and describe
*
- * @param string $name
- * @param mixed $value
- * @param array|null $options
- *
- * @return string
+ * @param mixed $value
*/
public function currencyList(string $name, $value = null, array $options = null): string
{
@@ -195,11 +179,12 @@ class CurrencyForm
$currencyRepos = app(CurrencyRepositoryInterface::class);
// get all currencies:
- $list = $currencyRepos->get();
- $array = [];
+ $list = $currencyRepos->get();
+ $array = [];
+
/** @var TransactionCurrency $currency */
foreach ($list as $currency) {
- $array[$currency->id] = $currency->name . ' (' . $currency->symbol . ')';
+ $array[$currency->id] = $currency->name.' ('.$currency->symbol.')';
}
return $this->select($name, $array, $value, $options);
@@ -208,11 +193,7 @@ class CurrencyForm
/**
* TODO cleanup and describe
*
- * @param string $name
- * @param mixed $value
- * @param array|null $options
- *
- * @return string
+ * @param mixed $value
*/
public function currencyListEmpty(string $name, $value = null, array $options = null): string
{
@@ -220,13 +201,14 @@ class CurrencyForm
$currencyRepos = app(CurrencyRepositoryInterface::class);
// get all currencies:
- $list = $currencyRepos->get();
- $array = [
+ $list = $currencyRepos->get();
+ $array = [
0 => (string)trans('firefly.no_currency'),
];
+
/** @var TransactionCurrency $currency */
foreach ($list as $currency) {
- $array[$currency->id] = $currency->name . ' (' . $currency->symbol . ')';
+ $array[$currency->id] = $currency->name.' ('.$currency->symbol.')';
}
return $this->select($name, $array, $value, $options);
diff --git a/app/Support/Form/FormSupport.php b/app/Support/Form/FormSupport.php
index ebb78e43aa..41d5b0461e 100644
--- a/app/Support/Form/FormSupport.php
+++ b/app/Support/Form/FormSupport.php
@@ -26,9 +26,7 @@ namespace FireflyIII\Support\Form;
use Carbon\Carbon;
use Carbon\Exceptions\InvalidDateException;
use FireflyIII\Repositories\Account\AccountRepositoryInterface;
-use Illuminate\Support\Facades\Log;
use Illuminate\Support\MessageBag;
-use Throwable;
/**
* Trait FormSupport
@@ -36,76 +34,57 @@ use Throwable;
trait FormSupport
{
/**
- * @param string $name
- * @param array|null $list
- * @param mixed $selected
- * @param array|null $options
- *
- * @return string
+ * @param mixed $selected
*/
public function select(string $name, array $list = null, $selected = null, array $options = null): string
{
- $list = $list ?? [];
+ $list ??= [];
$label = $this->label($name, $options);
$options = $this->expandOptionArray($name, $label, $options);
$classes = $this->getHolderClasses($name);
$selected = $this->fillFieldValue($name, $selected);
unset($options['autocomplete'], $options['placeholder']);
+
try {
$html = view('form.select', compact('classes', 'name', 'label', 'selected', 'options', 'list'))->render();
- } catch (Throwable $e) {
- Log::debug(sprintf('Could not render select(): %s', $e->getMessage()));
+ } catch (\Throwable $e) {
+ app('log')->debug(sprintf('Could not render select(): %s', $e->getMessage()));
$html = 'Could not render select.';
}
return $html;
}
- /**
- * @param string $name
- * @param array|null $options
- *
- * @return string
- */
protected function label(string $name, array $options = null): string
{
- $options = $options ?? [];
+ $options ??= [];
if (array_key_exists('label', $options)) {
return $options['label'];
}
$name = str_replace('[]', '', $name);
- return (string)trans('form.' . $name);
+ return (string)trans('form.'.$name);
}
/**
- * @param string $name
- * @param mixed $label
- * @param array|null $options
- *
- * @return array
+ * @param mixed $label
*/
protected function expandOptionArray(string $name, $label, array $options = null): array
{
- $options = $options ?? [];
+ $options ??= [];
$name = str_replace('[]', '', $name);
$options['class'] = 'form-control';
- $options['id'] = 'ffInput_' . $name;
+ $options['id'] = 'ffInput_'.$name;
$options['autocomplete'] = 'off';
$options['placeholder'] = ucfirst($label);
return $options;
}
- /**
- * @param string $name
- *
- * @return string
- */
protected function getHolderClasses(string $name): string
{
// Get errors from session:
- /** @var MessageBag $errors */
+ /** @var null|MessageBag $errors */
$errors = session('errors');
$classes = 'form-group';
@@ -117,8 +96,7 @@ trait FormSupport
}
/**
- * @param string $name
- * @param mixed|null $value
+ * @param null|mixed $value
*
* @return mixed
*/
@@ -140,25 +118,20 @@ trait FormSupport
return $value;
}
- /**
- * @return AccountRepositoryInterface
- */
protected function getAccountRepository(): AccountRepositoryInterface
{
return app(AccountRepositoryInterface::class);
}
- /**
- * @return Carbon
- */
protected function getDate(): Carbon
{
/** @var Carbon $date */
$date = null;
+
try {
$date = today(config('app.timezone'));
- } catch (InvalidDateException $e) {
- Log::error($e->getMessage());
+ } catch (InvalidDateException $e) { // @phpstan-ignore-line
+ app('log')->error($e->getMessage());
}
return $date;
diff --git a/app/Support/Form/PiggyBankForm.php b/app/Support/Form/PiggyBankForm.php
index 2f7e865483..0bd0d3c311 100644
--- a/app/Support/Form/PiggyBankForm.php
+++ b/app/Support/Form/PiggyBankForm.php
@@ -38,11 +38,7 @@ class PiggyBankForm
/**
* TODO cleanup and describe
*
- * @param string $name
- * @param mixed $value
- * @param array|null $options
- *
- * @return string
+ * @param mixed $value
*/
public function piggyBankList(string $name, $value = null, array $options = null): string
{
@@ -62,16 +58,17 @@ class PiggyBankForm
],
],
];
+
/** @var PiggyBank $piggy */
foreach ($piggyBanks as $piggy) {
- $group = $piggy->objectGroups->first();
- $groupTitle = null;
- $groupOrder = 0;
+ $group = $piggy->objectGroups->first();
+ $groupTitle = null;
+ $groupOrder = 0;
if (null !== $group) {
$groupTitle = $group->title;
$groupOrder = $group->order;
}
- $subList[$groupOrder] = $subList[$groupOrder] ?? [
+ $subList[$groupOrder] ??= [
'group' => [
'title' => $groupTitle,
],
diff --git a/app/Support/Form/RuleForm.php b/app/Support/Form/RuleForm.php
index 577f34dc6b..4c58209f79 100644
--- a/app/Support/Form/RuleForm.php
+++ b/app/Support/Form/RuleForm.php
@@ -25,8 +25,6 @@ namespace FireflyIII\Support\Form;
use FireflyIII\Models\RuleGroup;
use FireflyIII\Repositories\RuleGroup\RuleGroupRepositoryInterface;
-use Form;
-use Illuminate\Support\HtmlString;
/**
* Class RuleForm
@@ -36,21 +34,15 @@ class RuleForm
{
use FormSupport;
- /**
- * @param string $name
- * @param mixed $value
- * @param array|null $options
- *
- * @return string
- */
public function ruleGroupList(string $name, mixed $value = null, array $options = null): string
{
/** @var RuleGroupRepositoryInterface $groupRepos */
$groupRepos = app(RuleGroupRepositoryInterface::class);
// get all currencies:
- $list = $groupRepos->get();
- $array = [];
+ $list = $groupRepos->get();
+ $array = [];
+
/** @var RuleGroup $group */
foreach ($list as $group) {
$array[$group->id] = $group->title;
@@ -60,24 +52,22 @@ class RuleForm
}
/**
- * @param string $name
- * @param null $value
- * @param array|null $options
- *
- * @return string
+ * @param null $value
*/
public function ruleGroupListWithEmpty(string $name, $value = null, array $options = null): string
{
- $options = $options ?? [];
+ $options ??= [];
$options['class'] = 'form-control';
+
/** @var RuleGroupRepositoryInterface $groupRepos */
- $groupRepos = app(RuleGroupRepositoryInterface::class);
+ $groupRepos = app(RuleGroupRepositoryInterface::class);
// get all currencies:
- $list = $groupRepos->get();
- $array = [
+ $list = $groupRepos->get();
+ $array = [
0 => (string)trans('firefly.none_in_select_list'),
];
+
/** @var RuleGroup $group */
foreach ($list as $group) {
if (array_key_exists('hidden', $options) && (int)$options['hidden'] !== $group->id) {
diff --git a/app/Support/Http/Api/AccountBalanceGrouped.php b/app/Support/Http/Api/AccountBalanceGrouped.php
new file mode 100644
index 0000000000..286620deef
--- /dev/null
+++ b/app/Support/Http/Api/AccountBalanceGrouped.php
@@ -0,0 +1,245 @@
+.
+ */
+
+declare(strict_types=1);
+
+namespace FireflyIII\Support\Http\Api;
+
+use Carbon\Carbon;
+use FireflyIII\Exceptions\FireflyException;
+use FireflyIII\Models\TransactionCurrency;
+use FireflyIII\Models\TransactionType;
+use Illuminate\Support\Collection;
+use Illuminate\Support\Facades\Log;
+
+/**
+ * Class AccountBalanceGrouped
+ */
+class AccountBalanceGrouped
+{
+ private array $accountIds;
+ private string $carbonFormat;
+ private array $currencies = [];
+ private array $data = [];
+ private TransactionCurrency $default;
+ private Carbon $end;
+ private array $journals = [];
+ private string $preferredRange;
+ private Carbon $start;
+
+ /**
+ * Convert the given input to a chart compatible array.
+ */
+ public function convertToChartData(): array
+ {
+ $chartData = [];
+
+ // loop2: loop this data, make chart bars for each currency:
+ /** @var array $currency */
+ foreach ($this->data as $currency) {
+ // income and expense array prepped:
+ $income = [
+ 'label' => 'earned',
+ 'currency_id' => (string)$currency['currency_id'],
+ 'currency_symbol' => $currency['currency_symbol'],
+ 'currency_code' => $currency['currency_code'],
+ 'currency_decimal_places' => $currency['currency_decimal_places'],
+ 'native_currency_id' => (string)$currency['native_currency_id'],
+ 'native_currency_symbol' => $currency['native_currency_symbol'],
+ 'native_currency_code' => $currency['native_currency_code'],
+ 'native_currency_decimal_places' => $currency['native_currency_decimal_places'],
+ 'start' => $this->start->toAtomString(),
+ 'end' => $this->end->toAtomString(),
+ 'period' => $this->preferredRange,
+ 'entries' => [],
+ 'native_entries' => [],
+ ];
+ $expense = [
+ 'label' => 'spent',
+ 'currency_id' => (string)$currency['currency_id'],
+ 'currency_symbol' => $currency['currency_symbol'],
+ 'currency_code' => $currency['currency_code'],
+ 'currency_decimal_places' => $currency['currency_decimal_places'],
+ 'native_currency_id' => (string)$currency['native_currency_id'],
+ 'native_currency_symbol' => $currency['native_currency_symbol'],
+ 'native_currency_code' => $currency['native_currency_code'],
+ 'native_currency_decimal_places' => $currency['native_currency_decimal_places'],
+ 'start' => $this->start->toAtomString(),
+ 'end' => $this->end->toAtomString(),
+ 'period' => $this->preferredRange,
+ 'entries' => [],
+ 'native_entries' => [],
+ ];
+ // loop all possible periods between $start and $end, and add them to the correct dataset.
+ $currentStart = clone $this->start;
+ while ($currentStart <= $this->end) {
+ $key = $currentStart->format($this->carbonFormat);
+ $label = $currentStart->toAtomString();
+ // normal entries
+ $income['entries'][$label] = app('steam')->bcround($currency[$key]['earned'] ?? '0', $currency['currency_decimal_places']);
+ $expense['entries'][$label] = app('steam')->bcround($currency[$key]['spent'] ?? '0', $currency['currency_decimal_places']);
+
+ // converted entries
+ $income['native_entries'][$label] = app('steam')->bcround($currency[$key]['native_earned'] ?? '0', $currency['native_currency_decimal_places']);
+ $expense['native_entries'][$label] = app('steam')->bcround($currency[$key]['native_spent'] ?? '0', $currency['native_currency_decimal_places']);
+
+ // next loop
+ $currentStart = app('navigation')->addPeriod($currentStart, $this->preferredRange, 0);
+ }
+
+ $chartData[] = $income;
+ $chartData[] = $expense;
+ }
+
+ return $chartData;
+ }
+
+ /**
+ * Group the given journals by currency and then by period.
+ * If they are part of a set of accounts this basically means it's balance chart.
+ */
+ public function groupByCurrencyAndPeriod(): void
+ {
+ Log::debug(sprintf('Created new ExchangeRateConverter in %s', __METHOD__));
+ $converter = new ExchangeRateConverter();
+
+ // loop. group by currency and by period.
+ /** @var array $journal */
+ foreach ($this->journals as $journal) {
+ // format the date according to the period
+ $period = $journal['date']->format($this->carbonFormat);
+ $currencyId = (int)$journal['currency_id'];
+ $currency = $this->currencies[$currencyId] ?? TransactionCurrency::find($currencyId);
+ $this->currencies[$currencyId] = $currency; // may just re-assign itself, don't mind.
+
+ // set the array with monetary info, if it does not exist.
+ $this->data[$currencyId] ??= [
+ 'currency_id' => (string)$currencyId,
+ 'currency_symbol' => $journal['currency_symbol'],
+ 'currency_code' => $journal['currency_code'],
+ 'currency_name' => $journal['currency_name'],
+ 'currency_decimal_places' => $journal['currency_decimal_places'],
+ // native currency info (could be the same)
+ 'native_currency_id' => (string)$this->default->id,
+ 'native_currency_code' => $this->default->code,
+ 'native_currency_symbol' => $this->default->symbol,
+ 'native_currency_decimal_places' => $this->default->decimal_places,
+ ];
+
+ // set the array (in monetary info) with spent/earned in this $period, if it does not exist.
+ $this->data[$currencyId][$period] ??= [
+ 'period' => $period,
+ 'spent' => '0',
+ 'earned' => '0',
+ 'native_spent' => '0',
+ 'native_earned' => '0',
+ ];
+ // is this journal's amount in- our outgoing?
+ $key = 'spent';
+ $amount = app('steam')->negative($journal['amount']);
+ // deposit = incoming
+ // transfer or reconcile or opening balance, and these accounts are the destination.
+ if (
+ TransactionType::DEPOSIT === $journal['transaction_type_type']
+
+ || (
+ (
+ TransactionType::TRANSFER === $journal['transaction_type_type']
+ || TransactionType::RECONCILIATION === $journal['transaction_type_type']
+ || TransactionType::OPENING_BALANCE === $journal['transaction_type_type']
+ )
+ && in_array($journal['destination_account_id'], $this->accountIds, true)
+ )
+ ) {
+ $key = 'earned';
+ $amount = app('steam')->positive($journal['amount']);
+ }
+
+ // get conversion rate
+ try {
+ $rate = $converter->getCurrencyRate($currency, $this->default, $journal['date']);
+ } catch (FireflyException $e) {
+ app('log')->error($e->getMessage());
+ $rate = '1';
+ }
+ $amountConverted = bcmul($amount, $rate);
+
+ // perhaps transaction already has the foreign amount in the native currency.
+ if ((int)$journal['foreign_currency_id'] === $this->default->id) {
+ $amountConverted = $journal['foreign_amount'] ?? '0';
+ $amountConverted = 'earned' === $key ? app('steam')->positive($amountConverted) : app('steam')->negative($amountConverted);
+ }
+
+ // add normal entry
+ $this->data[$currencyId][$period][$key] = bcadd($this->data[$currencyId][$period][$key], $amount);
+
+ // add converted entry
+ $convertedKey = sprintf('native_%s', $key);
+ $this->data[$currencyId][$period][$convertedKey] = bcadd($this->data[$currencyId][$period][$convertedKey], $amountConverted);
+ }
+ $converter->summarize();
+ }
+
+ public function setAccounts(Collection $accounts): void
+ {
+ $this->accountIds = $accounts->pluck('id')->toArray();
+ }
+
+ public function setDefault(TransactionCurrency $default): void
+ {
+ $this->default = $default;
+ $defaultCurrencyId = $default->id;
+ $this->currencies = [$default->id => $default]; // currency cache
+ $this->data[$defaultCurrencyId] = [
+ 'currency_id' => (string)$defaultCurrencyId,
+ 'currency_symbol' => $default->symbol,
+ 'currency_code' => $default->code,
+ 'currency_name' => $default->name,
+ 'currency_decimal_places' => $default->decimal_places,
+ 'native_currency_id' => (string)$defaultCurrencyId,
+ 'native_currency_symbol' => $default->symbol,
+ 'native_currency_code' => $default->code,
+ 'native_currency_name' => $default->name,
+ 'native_currency_decimal_places' => $default->decimal_places,
+ ];
+ }
+
+ public function setEnd(Carbon $end): void
+ {
+ $this->end = $end;
+ }
+
+ public function setJournals(array $journals): void
+ {
+ $this->journals = $journals;
+ }
+
+ public function setPreferredRange(string $preferredRange): void
+ {
+ $this->preferredRange = $preferredRange;
+ $this->carbonFormat = app('navigation')->preferredCarbonFormatByPeriod($preferredRange);
+ }
+
+ public function setStart(Carbon $start): void
+ {
+ $this->start = $start;
+ }
+}
diff --git a/app/Support/Http/Api/AccountFilter.php b/app/Support/Http/Api/AccountFilter.php
index 5aeeec5cd1..7c41a9d6c5 100644
--- a/app/Support/Http/Api/AccountFilter.php
+++ b/app/Support/Http/Api/AccountFilter.php
@@ -27,17 +27,11 @@ use FireflyIII\Models\AccountType;
/**
* Trait AccountFilter
- *
-
*/
trait AccountFilter
{
/**
* All the available types.
- *
- * @param string $type
- *
- * @return array
*/
protected function mapAccountTypes(string $type): array
{
@@ -56,11 +50,11 @@ trait AccountFilter
AccountType::DEBT,
AccountType::MORTGAGE,
],
- 'asset' => [AccountType::DEFAULT, AccountType::ASSET,],
- 'cash' => [AccountType::CASH,],
- 'expense' => [AccountType::EXPENSE, AccountType::BENEFICIARY,],
- 'revenue' => [AccountType::REVENUE,],
- 'special' => [AccountType::CASH, AccountType::INITIAL_BALANCE, AccountType::IMPORT, AccountType::RECONCILIATION,],
+ 'asset' => [AccountType::DEFAULT, AccountType::ASSET],
+ 'cash' => [AccountType::CASH],
+ 'expense' => [AccountType::EXPENSE, AccountType::BENEFICIARY],
+ 'revenue' => [AccountType::REVENUE],
+ 'special' => [AccountType::CASH, AccountType::INITIAL_BALANCE, AccountType::IMPORT, AccountType::RECONCILIATION],
'hidden' => [AccountType::INITIAL_BALANCE, AccountType::IMPORT, AccountType::RECONCILIATION],
'liability' => [AccountType::DEBT, AccountType::LOAN, AccountType::MORTGAGE, AccountType::CREDITCARD],
'liabilities' => [AccountType::DEBT, AccountType::LOAN, AccountType::MORTGAGE, AccountType::CREDITCARD],
diff --git a/app/Support/Http/Api/ApiSupport.php b/app/Support/Http/Api/ApiSupport.php
index 04a6037de2..76d371657e 100644
--- a/app/Support/Http/Api/ApiSupport.php
+++ b/app/Support/Http/Api/ApiSupport.php
@@ -28,17 +28,11 @@ use Illuminate\Support\Collection;
/**
* Trait ApiSupport
- *
-
*/
trait ApiSupport
{
/**
* Small helper function for the revenue and expense account charts.
- *
- * @param array $names
- *
- * @return array
*/
protected function expandNames(array $names): array
{
@@ -52,14 +46,11 @@ trait ApiSupport
/**
* Small helper function for the revenue and expense account charts.
- *
- * @param Collection $accounts
- *
- * @return array
*/
protected function extractNames(Collection $accounts): array
{
$return = [];
+
/** @var Account $account */
foreach ($accounts as $account) {
$return[$account->id] = $account->name;
diff --git a/app/Support/Http/Api/CleansChartData.php b/app/Support/Http/Api/CleansChartData.php
index bda87b5a7c..b4f1bb2bfe 100644
--- a/app/Support/Http/Api/CleansChartData.php
+++ b/app/Support/Http/Api/CleansChartData.php
@@ -1,6 +1,5 @@
enabled = false;
+ $this->enabled = false;
if (false === $this->enabled) {
$set['converted'] = false;
+
return $set;
}
$set['converted'] = true;
+
/** @var TransactionCurrency $native */
- $native = app('amount')->getDefaultCurrency();
- $currency = $this->getCurrency((int)$set['currency_id']);
+ $native = app('amount')->getDefaultCurrency();
+ $currency = $this->getCurrency((int)$set['currency_id']);
if ($native->id === $currency->id) {
- $set['native_id'] = (string)$currency->id;
- $set['native_code'] = $currency->code;
- $set['native_symbol'] = $currency->symbol;
- $set['native_decimal_places'] = $currency->decimal_places;
+ $set['native_currency_id'] = (string)$currency->id;
+ $set['native_currency_code'] = $currency->code;
+ $set['native_currency_symbol'] = $currency->symbol;
+ $set['native_currency_decimal_places'] = $currency->decimal_places;
+
return $set;
}
foreach ($set['entries'] as $date => $entry) {
- $carbon = Carbon::createFromFormat(DateTimeInterface::ATOM, $date);
- $rate = $this->getRate($currency, $native, $carbon);
- $rate = '0' === $rate ? '1' : $rate;
+ $carbon = Carbon::createFromFormat(\DateTimeInterface::ATOM, $date);
+ $rate = $this->getRate($currency, $native, $carbon);
+ $rate = '0' === $rate ? '1' : $rate;
app('log')->debug(sprintf('bcmul("%s", "%s")', (string)$entry, $rate));
$set['entries'][$date] = (float)bcmul((string)$entry, $rate);
}
+
return $set;
}
/**
- * @return void
* @deprecated
*/
private function getPreference(): void
@@ -89,9 +85,6 @@ trait ConvertsExchangeRates
}
/**
- * @param int $currencyId
- *
- * @return TransactionCurrency
* @deprecated
*/
private function getCurrency(int $currencyId): TransactionCurrency
@@ -100,17 +93,14 @@ trait ConvertsExchangeRates
if (null === $result) {
return app('amount')->getDefaultCurrency();
}
+
return $result;
}
-
/**
* For a sum of entries, get the exchange rate to the native currency of
* the user.
*
- * @param array $entries
- *
- * @return array
* @deprecated
*/
public function cerSum(array $entries): array
@@ -122,59 +112,55 @@ trait ConvertsExchangeRates
// if false, return the same array without conversion info
if (false === $this->enabled) {
$return = [];
+
/** @var array $entry */
foreach ($entries as $entry) {
$entry['converted'] = false;
$return[] = $entry;
}
+
return $return;
}
-
/** @var TransactionCurrency $native */
$native = app('amount')->getDefaultCurrency();
$return = [];
+
/** @var array $entry */
foreach ($entries as $entry) {
$currency = $this->getCurrency((int)$entry['id']);
if ($currency->id !== $native->id) {
- $amount = $this->convertAmount($entry['sum'], $currency, $native);
- $entry['converted'] = true;
- $entry['native_sum'] = $amount;
- $entry['native_id'] = (string)$native->id;
- $entry['native_name'] = $native->name;
- $entry['native_symbol'] = $native->symbol;
- $entry['native_code'] = $native->code;
- $entry['native_decimal_places'] = $native->decimal_places;
+ $amount = $this->convertAmount($entry['sum'], $currency, $native);
+ $entry['converted'] = true;
+ $entry['native_sum'] = $amount;
+ $entry['native_currency_id'] = (string)$native->id;
+ $entry['native_currency_name'] = $native->name;
+ $entry['native_currency_symbol'] = $native->symbol;
+ $entry['native_currency_code'] = $native->code;
+ $entry['native_currency_decimal_places'] = $native->decimal_places;
}
if ($currency->id === $native->id) {
- $entry['converted'] = false;
- $entry['native_sum'] = $entry['sum'];
- $entry['native_id'] = (string)$native->id;
- $entry['native_name'] = $native->name;
- $entry['native_symbol'] = $native->symbol;
- $entry['native_code'] = $native->code;
- $entry['native_decimal_places'] = $native->decimal_places;
+ $entry['converted'] = false;
+ $entry['native_sum'] = $entry['sum'];
+ $entry['native_currency_id'] = (string)$native->id;
+ $entry['native_currency_name'] = $native->name;
+ $entry['native_currency_symbol'] = $native->symbol;
+ $entry['native_currency_code'] = $native->code;
+ $entry['native_currency_decimal_places'] = $native->decimal_places;
}
$return[] = $entry;
}
+
return $return;
}
/**
- * @param string $amount
- * @param TransactionCurrency $from
- * @param TransactionCurrency $to
- * @param Carbon|null $date
- *
- * @return string
- *
* @deprecated
*/
private function convertAmount(string $amount, TransactionCurrency $from, TransactionCurrency $to, ?Carbon $date = null): string
{
app('log')->debug(sprintf('Converting %s from %s to %s', $amount, $from->code, $to->code));
- $date = $date ?? today(config('app.timezone'));
+ $date ??= today(config('app.timezone'));
$rate = $this->getRate($from, $to, $date);
return bcmul($amount, $rate);
diff --git a/app/Support/Http/Api/ExchangeRateConverter.php b/app/Support/Http/Api/ExchangeRateConverter.php
index 2051366405..05fa2e001d 100644
--- a/app/Support/Http/Api/ExchangeRateConverter.php
+++ b/app/Support/Http/Api/ExchangeRateConverter.php
@@ -1,6 +1,5 @@
getCurrencyRate($from, $to, $date);
+
return bcmul($amount, $rate);
}
/**
- * @param TransactionCurrency $from
- * @param TransactionCurrency $to
- * @param Carbon $date
- *
- * @return string
* @throws FireflyException
*/
public function getCurrencyRate(TransactionCurrency $from, TransactionCurrency $to, Carbon $date): string
{
+ Log::debug('getCurrencyRate()');
$rate = $this->getRate($from, $to, $date);
+
return '0' === $rate ? '1' : $rate;
}
/**
- * @param TransactionCurrency $from
- * @param TransactionCurrency $to
- * @param Carbon $date
- *
- * @return string
* @throws FireflyException
*/
private function getRate(TransactionCurrency $from, TransactionCurrency $to, Carbon $date): string
{
+ Log::debug('getRate()');
+ if ($this->isPrepared && $this->noPreparedRates) {
+ $fallback = $this->fallback[$from->id][$to->id] ?? '0';
+ Log::debug(sprintf('Return fallback rate from #%d to #%d on %s: %s', $from->id, $to->id, $date->format('Y-m-d'), $fallback));
+
+ return $fallback;
+ }
// first attempt:
- $rate = $this->getFromDB((int)$from->id, (int)$to->id, $date->format('Y-m-d'));
+ $rate = $this->getFromDB($from->id, $to->id, $date->format('Y-m-d'));
if (null !== $rate) {
return $rate;
}
// no result. perhaps the other way around?
- $rate = $this->getFromDB((int)$to->id, (int)$from->id, $date->format('Y-m-d'));
+ $rate = $this->getFromDB($to->id, $from->id, $date->format('Y-m-d'));
if (null !== $rate) {
return bcdiv('1', $rate);
}
@@ -93,108 +93,218 @@ class ExchangeRateConverter
$second = $this->getEuroRate($to, $date);
// combined (if present), they can be used to calculate the necessary conversion rate.
- if ('0' === $first || '0' === $second) {
+ if (0 === bccomp('0', $first) || 0 === bccomp('0', $second)) {
+ Log::warning(sprintf('$first is "%s" and $second is "%s"', $first, $second));
+
return '0';
}
$second = bcdiv('1', $second);
+
return bcmul($first, $second);
}
- /**
- * @param int $from
- * @param int $to
- * @param string $date
- *
- * @return string|null
- */
private function getFromDB(int $from, int $to, string $date): ?string
{
- $key = sprintf('cer-%d-%d-%s', $from, $to, $date);
+ Log::debug('getFromDB()');
+ if ($from === $to) {
+ return '1';
+ }
+ $key = sprintf('cer-%d-%d-%s', $from, $to, $date);
- $cache = new CacheProperties();
+ // perhaps the rate has been cached during this particular run
+ $preparedRate = $this->prepared[$date][$from][$to] ?? null;
+ if (null !== $preparedRate && 0 !== bccomp('0', $preparedRate)) {
+ Log::debug(sprintf('Found prepared rate from #%d to #%d on %s.', $from, $to, $date));
+
+ return $preparedRate;
+ }
+
+ $cache = new CacheProperties();
$cache->addProperty($key);
if ($cache->has()) {
$rate = $cache->get();
if ('' === $rate) {
return null;
}
+ Log::debug(sprintf('Found cached rate from #%d to #%d on %s.', $from, $to, $date));
+
return $rate;
}
- app('log')->debug(sprintf('Going to get rate #%d->#%d (%s) from DB.', $from, $to, $date));
- /** @var CurrencyExchangeRate $result */
- $result = auth()->user()
- ->currencyExchangeRates()
- ->where('from_currency_id', $from)
- ->where('to_currency_id', $to)
- ->where('date', '<=', $date)
- ->orderBy('date', 'DESC')
- ->first();
- $rate = (string)$result?->rate;
- $cache->store($rate);
+ /** @var null|CurrencyExchangeRate $result */
+ $result = auth()->user()
+ ->currencyExchangeRates()
+ ->where('from_currency_id', $from)
+ ->where('to_currency_id', $to)
+ ->where('date', '<=', $date)
+ ->orderBy('date', 'DESC')
+ ->first()
+ ;
+ ++$this->queryCount;
+ $rate = (string)$result?->rate;
+
if ('' === $rate) {
+ app('log')->debug(sprintf('Found no rate for #%d->#%d (%s) in the DB.', $from, $to, $date));
+
return null;
}
+ if (0 === bccomp('0', $rate)) {
+ app('log')->debug(sprintf('Found rate for #%d->#%d (%s) in the DB, but it\'s zero.', $from, $to, $date));
+
+ return null;
+ }
+ app('log')->debug(sprintf('Found rate for #%d->#%d (%s) in the DB: %s.', $from, $to, $date, $rate));
+ $cache->store($rate);
+
+ // if the rate has not been cached during this particular run, save it
+ $this->prepared[$date] ??= [
+ $from => [
+ $to => $rate,
+ ],
+ ];
+ // also save the exchange rate the other way around:
+ $this->prepared[$date] ??= [
+ $to => [
+ $from => bcdiv('1', $rate),
+ ],
+ ];
+
return $rate;
}
-
/**
- * @param TransactionCurrency $currency
- * @param Carbon $date
- *
- * @return string
* @throws FireflyException
- *
*/
private function getEuroRate(TransactionCurrency $currency, Carbon $date): string
{
+ Log::debug('getEuroRate()');
$euroId = $this->getEuroId();
- if ($euroId === (int)$currency->id) {
+ if ($euroId === $currency->id) {
return '1';
}
- $rate = $this->getFromDB((int)$currency->id, $euroId, $date->format('Y-m-d'));
+ $rate = $this->getFromDB($currency->id, $euroId, $date->format('Y-m-d'));
if (null !== $rate) {
// app('log')->debug(sprintf('Rate for %s to EUR is %s.', $currency->code, $rate));
return $rate;
}
- $rate = $this->getFromDB($euroId, (int)$currency->id, $date->format('Y-m-d'));
+ $rate = $this->getFromDB($euroId, $currency->id, $date->format('Y-m-d'));
if (null !== $rate) {
return bcdiv('1', $rate);
// app('log')->debug(sprintf('Inverted rate for %s to EUR is %s.', $currency->code, $rate));
- //return $rate;
+ // return $rate;
}
// grab backup values from config file:
$backup = config(sprintf('cer.rates.%s', $currency->code));
if (null !== $backup) {
return bcdiv('1', (string)$backup);
// app('log')->debug(sprintf('Backup rate for %s to EUR is %s.', $currency->code, $backup));
- //return $backup;
+ // return $backup;
}
// app('log')->debug(sprintf('No rate for %s to EUR.', $currency->code));
return '0';
}
-
/**
- * @return int
* @throws FireflyException
*/
private function getEuroId(): int
{
+ Log::debug('getEuroId()');
$cache = new CacheProperties();
$cache->addProperty('cer-euro-id');
if ($cache->has()) {
return (int)$cache->get();
}
- $euro = TransactionCurrency::whereCode('EUR')->first();
+ $euro = TransactionCurrency::whereCode('EUR')->first();
+ ++$this->queryCount;
if (null === $euro) {
throw new FireflyException('Cannot find EUR in system, cannot do currency conversion.');
}
- $cache->store((int)$euro->id);
- return (int)$euro->id;
+ $cache->store($euro->id);
+
+ return $euro->id;
+ }
+
+ /**
+ * @throws FireflyException
+ */
+ public function prepare(TransactionCurrency $from, TransactionCurrency $to, Carbon $start, Carbon $end): void
+ {
+ Log::debug('prepare()');
+ $start->startOfDay();
+ $end->endOfDay();
+ Log::debug(sprintf('Preparing for %s to %s between %s and %s', $from->code, $to->code, $start->format('Y-m-d'), $end->format('Y-m-d')));
+ $set = auth()->user()
+ ->currencyExchangeRates()
+ ->where('from_currency_id', $from->id)
+ ->where('to_currency_id', $to->id)
+ ->where('date', '<=', $end->format('Y-m-d'))
+ ->where('date', '>=', $start->format('Y-m-d'))
+ ->orderBy('date', 'DESC')->get()
+ ;
+ ++$this->queryCount;
+ if (0 === $set->count()) {
+ Log::debug('No prepared rates found in this period, use the fallback');
+ $this->fallback($from, $to, $start);
+ $this->noPreparedRates = true;
+ $this->isPrepared = true;
+ Log::debug('prepare DONE()');
+
+ return;
+ }
+ $this->isPrepared = true;
+
+ // so there is a fallback just in case. Now loop the set of rates we DO have.
+ $temp = [];
+ $count = 0;
+ foreach ($set as $rate) {
+ $date = $rate->date->format('Y-m-d');
+ $temp[$date] ??= [
+ $from->id => [
+ $to->id => $rate->rate,
+ ],
+ ];
+ ++$count;
+ }
+ Log::debug(sprintf('Found %d rates in this period.', $count));
+ $currentStart = clone $start;
+ while ($currentStart->lte($end)) {
+ $currentDate = $currentStart->format('Y-m-d');
+ $this->prepared[$currentDate] ??= [];
+ $fallback = $temp[$currentDate][$from->id][$to->id] ?? $this->fallback[$from->id][$to->id] ?? '0';
+ if (0 === count($this->prepared[$currentDate]) && 0 !== bccomp('0', $fallback)) {
+ // fill from temp or fallback or from temp (see before)
+ $this->prepared[$currentDate][$from->id][$to->id] = $fallback;
+ }
+ $currentStart->addDay();
+ }
+ }
+
+ /**
+ * If there are no exchange rate in the "prepare" array, future searches for any exchange rate
+ * will result in nothing: otherwise the preparation had been unnecessary. So, to fix this Firefly III
+ * will set two fallback currency exchange rates, A > B and B > A using the regular getCurrencyRate method.
+ *
+ * This method in turn will fall back on the default exchange rate (if present) or on "1" if necessary.
+ *
+ * @throws FireflyException
+ */
+ private function fallback(TransactionCurrency $from, TransactionCurrency $to, Carbon $date): void
+ {
+ Log::debug('fallback()');
+ $fallback = $this->getRate($from, $to, $date);
+ $fallback = 0 === bccomp('0', $fallback) ? '1' : $fallback;
+ $this->fallback[$from->id][$to->id] = $fallback;
+ $this->fallback[$to->id][$from->id] = bcdiv('1', $fallback);
+ Log::debug(sprintf('Fallback rate %s > %s = %s', $from->code, $to->code, $fallback));
+ Log::debug(sprintf('Fallback rate %s > %s = %s', $to->code, $from->code, bcdiv('1', $fallback)));
+ }
+
+ public function summarize(): void
+ {
+ Log::debug(sprintf('ExchangeRateConverter ran %d queries.', $this->queryCount));
}
}
diff --git a/app/Support/Http/Api/SummaryBalanceGrouped.php b/app/Support/Http/Api/SummaryBalanceGrouped.php
new file mode 100644
index 0000000000..ff807803b9
--- /dev/null
+++ b/app/Support/Http/Api/SummaryBalanceGrouped.php
@@ -0,0 +1,139 @@
+.
+ */
+
+declare(strict_types=1);
+
+namespace FireflyIII\Support\Http\Api;
+
+use FireflyIII\Models\TransactionCurrency;
+use FireflyIII\Repositories\UserGroups\Currency\CurrencyRepositoryInterface;
+use Illuminate\Support\Facades\Log;
+
+class SummaryBalanceGrouped
+{
+ private const string SUM = 'sum';
+ private array $amounts = [];
+ private array $currencies;
+ private CurrencyRepositoryInterface $currencyRepository;
+ private TransactionCurrency $default;
+ private array $keys;
+
+ public function __construct()
+ {
+ $this->keys = [self::SUM];
+ $this->currencies = [];
+ $this->currencyRepository = app(CurrencyRepositoryInterface::class);
+ }
+
+ public function groupData(): array
+ {
+ Log::debug('Now going to group data.');
+ $return = [];
+ foreach ($this->keys as $key) {
+ $title = match ($key) {
+ 'sum' => 'balance',
+ 'expense' => 'spent',
+ 'income' => 'earned',
+ default => 'something'
+ };
+
+ $return[] = [
+ 'key' => sprintf('%s-in-native', $title),
+ 'value' => $this->amounts[$key]['native'] ?? '0',
+ 'currency_id' => (string)$this->default->id,
+ 'currency_code' => $this->default->code,
+ 'currency_symbol' => $this->default->symbol,
+ 'currency_decimal_places' => $this->default->decimal_places,
+ ];
+ }
+ // loop 3: format amounts:
+ $currencyIds = array_keys($this->amounts[self::SUM] ?? []);
+ foreach ($currencyIds as $currencyId) {
+ if ('native' === $currencyId) {
+ // skip native entries.
+ continue;
+ }
+ $currencyId = (int)$currencyId;
+ $currency = $this->currencies[$currencyId] ?? $this->currencyRepository->find($currencyId);
+ $this->currencies[$currencyId] = $currency;
+ // create objects for big array.
+ foreach ($this->keys as $key) {
+ $title = match ($key) {
+ 'sum' => 'balance',
+ 'expense' => 'spent',
+ 'income' => 'earned',
+ default => 'something'
+ };
+ $return[] = [
+ 'key' => sprintf('%s-in-%s', $title, $currency->code),
+ 'value' => $this->amounts[$key][$currencyId] ?? '0',
+ 'currency_id' => (string)$currency->id,
+ 'currency_code' => $currency->code,
+ 'currency_symbol' => $currency->symbol,
+ 'currency_decimal_places' => $currency->decimal_places,
+ ];
+ }
+ }
+
+ return $return;
+ }
+
+ public function groupTransactions(string $key, array $journals): void
+ {
+ Log::debug(sprintf('Created new ExchangeRateConverter in %s', __METHOD__));
+ Log::debug(sprintf('Now in groupTransactions with key "%s" and %d journal(s)', $key, count($journals)));
+ $converter = new ExchangeRateConverter();
+ $this->keys[] = $key;
+ $multiplier = 'income' === $key ? '-1' : '1';
+
+ /** @var array $journal */
+ foreach ($journals as $journal) {
+ // transaction info:
+ $currencyId = (int)$journal['currency_id'];
+ $amount = bcmul($journal['amount'], $multiplier);
+ $currency = $this->currencies[$currencyId] ?? TransactionCurrency::find($currencyId);
+ $this->currencies[$currencyId] = $currency;
+ $nativeAmount = $converter->convert($currency, $this->default, $journal['date'], $amount);
+ if ((int)$journal['foreign_currency_id'] === $this->default->id) {
+ // use foreign amount instead
+ $nativeAmount = $journal['foreign_amount'];
+ }
+ // prep the arrays
+ $this->amounts[$key] ??= [];
+ $this->amounts[$key][$currencyId] ??= '0';
+ $this->amounts[$key]['native'] ??= '0';
+ $this->amounts[self::SUM][$currencyId] ??= '0';
+ $this->amounts[self::SUM]['native'] ??= '0';
+
+ // add values:
+ $this->amounts[$key][$currencyId] = bcadd($this->amounts[$key][$currencyId], $amount);
+ $this->amounts[self::SUM][$currencyId] = bcadd($this->amounts[self::SUM][$currencyId], $amount);
+ $this->amounts[$key]['native'] = bcadd($this->amounts[$key]['native'], $nativeAmount);
+ $this->amounts[self::SUM]['native'] = bcadd($this->amounts[self::SUM]['native'], $nativeAmount);
+ }
+ $converter->summarize();
+ }
+
+ public function setDefault(TransactionCurrency $default): void
+ {
+ $this->default = $default;
+ }
+}
diff --git a/app/Support/Http/Api/TransactionFilter.php b/app/Support/Http/Api/TransactionFilter.php
index 3542749cdd..0e5695c035 100644
--- a/app/Support/Http/Api/TransactionFilter.php
+++ b/app/Support/Http/Api/TransactionFilter.php
@@ -27,17 +27,11 @@ use FireflyIII\Models\TransactionType;
/**
* Trait TransactionFilter
- *
-
*/
trait TransactionFilter
{
/**
* All the types you can request.
- *
- * @param string $type
- *
- * @return array
*/
protected function mapTransactionTypes(string $type): array
{
@@ -49,27 +43,28 @@ trait TransactionFilter
TransactionType::OPENING_BALANCE,
TransactionType::RECONCILIATION,
],
- 'withdrawal' => [TransactionType::WITHDRAWAL,],
- 'withdrawals' => [TransactionType::WITHDRAWAL,],
- 'expense' => [TransactionType::WITHDRAWAL,],
- 'expenses' => [TransactionType::WITHDRAWAL,],
- 'income' => [TransactionType::DEPOSIT,],
- 'deposit' => [TransactionType::DEPOSIT,],
- 'deposits' => [TransactionType::DEPOSIT,],
- 'transfer' => [TransactionType::TRANSFER,],
- 'transfers' => [TransactionType::TRANSFER,],
- 'opening_balance' => [TransactionType::OPENING_BALANCE,],
- 'reconciliation' => [TransactionType::RECONCILIATION,],
- 'reconciliations' => [TransactionType::RECONCILIATION,],
- 'special' => [TransactionType::OPENING_BALANCE, TransactionType::RECONCILIATION,],
- 'specials' => [TransactionType::OPENING_BALANCE, TransactionType::RECONCILIATION,],
- 'default' => [TransactionType::WITHDRAWAL, TransactionType::DEPOSIT, TransactionType::TRANSFER,],
+ 'withdrawal' => [TransactionType::WITHDRAWAL],
+ 'withdrawals' => [TransactionType::WITHDRAWAL],
+ 'expense' => [TransactionType::WITHDRAWAL],
+ 'expenses' => [TransactionType::WITHDRAWAL],
+ 'income' => [TransactionType::DEPOSIT],
+ 'deposit' => [TransactionType::DEPOSIT],
+ 'deposits' => [TransactionType::DEPOSIT],
+ 'transfer' => [TransactionType::TRANSFER],
+ 'transfers' => [TransactionType::TRANSFER],
+ 'opening_balance' => [TransactionType::OPENING_BALANCE],
+ 'reconciliation' => [TransactionType::RECONCILIATION],
+ 'reconciliations' => [TransactionType::RECONCILIATION],
+ 'special' => [TransactionType::OPENING_BALANCE, TransactionType::RECONCILIATION],
+ 'specials' => [TransactionType::OPENING_BALANCE, TransactionType::RECONCILIATION],
+ 'default' => [TransactionType::WITHDRAWAL, TransactionType::DEPOSIT, TransactionType::TRANSFER],
];
$return = [];
$parts = explode(',', $type);
foreach ($parts as $part) {
$return = array_merge($return, $types[$part] ?? $types['default']);
}
+
return array_unique($return);
}
}
diff --git a/app/Support/Http/Api/ValidatesUserGroupTrait.php b/app/Support/Http/Api/ValidatesUserGroupTrait.php
index abc8666155..5a698ce75c 100644
--- a/app/Support/Http/Api/ValidatesUserGroupTrait.php
+++ b/app/Support/Http/Api/ValidatesUserGroupTrait.php
@@ -37,32 +37,35 @@ trait ValidatesUserGroupTrait
/**
* This check does not validate which rights the user has, that comes later.
*
- * @param Request $request
- *
- * @return UserGroup|null
* @throws FireflyException
*/
protected function validateUserGroup(Request $request): ?UserGroup
{
if (!auth()->check()) {
app('log')->debug('validateUserGroup: user is not logged in, return NULL.');
+
return null;
}
+
/** @var User $user */
- $user = auth()->user();
+ $user = auth()->user();
if (!$request->has('user_group_id')) {
$group = $user->userGroup;
- app('log')->debug(sprintf('validateUserGroup: no user group submitted, return default group #%d.', $group->id));
+ app('log')->debug(sprintf('validateUserGroup: no user group submitted, return default group #%d.', $group?->id));
+
return $group;
}
- $groupId = (int)$request->get('user_group_id');
- /** @var GroupMembership|null $membership */
+ $groupId = (int)$request->get('user_group_id');
+
+ /** @var null|GroupMembership $membership */
$membership = $user->groupMemberships()->where('user_group_id', $groupId)->first();
if (null === $membership) {
app('log')->debug('validateUserGroup: user has no access to this group.');
+
throw new FireflyException((string)trans('validation.belongs_user_or_user_group'));
}
app('log')->debug(sprintf('validateUserGroup: user has role "%s" in group #%d.', $membership->userRole->title, $membership->userGroup->id));
+
return $membership->userGroup;
}
}
diff --git a/app/Support/Http/Controllers/AugumentData.php b/app/Support/Http/Controllers/AugumentData.php
index c21eb7b3b5..489be0445f 100644
--- a/app/Support/Http/Controllers/AugumentData.php
+++ b/app/Support/Http/Controllers/AugumentData.php
@@ -40,28 +40,24 @@ use Illuminate\Support\Collection;
/**
* Trait AugumentData
- *
*/
trait AugumentData
{
/**
* Searches for the opposing account.
- *
- * @param Collection $accounts
- *
- * @return array
*/
protected function combineAccounts(Collection $accounts): array // filter + group data
{
/** @var AccountRepositoryInterface $repository */
$repository = app(AccountRepositoryInterface::class);
$combined = [];
+
/** @var Account $expenseAccount */
foreach ($accounts as $expenseAccount) {
- $collection = new Collection();
+ $collection = new Collection();
$collection->push($expenseAccount);
- $revenue = $repository->findByName($expenseAccount->name, [AccountType::REVENUE]);
+ $revenue = $repository->findByName($expenseAccount->name, [AccountType::REVENUE]);
if (null !== $revenue) {
$collection->push($revenue);
}
@@ -74,9 +70,7 @@ trait AugumentData
/**
* Small helper function for the revenue and expense account charts.
*
- * @param array $names
- *
- * @return array
+ * @param array $names
*/
protected function expandNames(array $names): array
{
@@ -90,14 +84,11 @@ trait AugumentData
/**
* Small helper function for the revenue and expense account charts.
- *
- * @param Collection $accounts
- *
- * @return array
*/
protected function extractNames(Collection $accounts): array
{
$return = [];
+
/** @var Account $account */
foreach ($accounts as $account) {
$return[$account->id] = $account->name;
@@ -108,10 +99,6 @@ trait AugumentData
/**
* Get the account names belonging to a bunch of account ID's.
- *
- * @param array $accountIds
- *
- * @return array
*/
protected function getAccountNames(array $accountIds): array // extract info from array.
{
@@ -127,17 +114,13 @@ trait AugumentData
$return[$accountId] = $grouped[$accountId][0]['name'];
}
}
- $return[0] = '(no name)';
+ $return[0] = '(no name)';
return $return;
}
/**
* Get the budget names from a set of budget ID's.
- *
- * @param array $budgetIds
- *
- * @return array
*/
protected function getBudgetNames(array $budgetIds): array // extract info from array.
{
@@ -151,17 +134,13 @@ trait AugumentData
$return[$budgetId] = $grouped[$budgetId][0]['name'];
}
}
- $return[0] = (string)trans('firefly.no_budget');
+ $return[0] = (string)trans('firefly.no_budget');
return $return;
}
/**
* Get the category names from a set of category ID's. Small helper function for some of the charts.
- *
- * @param array $categoryIds
- *
- * @return array
*/
protected function getCategoryNames(array $categoryIds): array // extract info from array.
{
@@ -177,29 +156,23 @@ trait AugumentData
$return[$categoryId] = $grouped[$categoryId][0]['name'];
}
}
- $return[0] = (string)trans('firefly.no_category');
+ $return[0] = (string)trans('firefly.no_category');
return $return;
}
/**
* Gets all budget limits for a budget.
- *
- * @param Budget $budget
- * @param Carbon $start
- * @param Carbon $end
- *
- * @return Collection
*/
protected function getLimits(Budget $budget, Carbon $start, Carbon $end): Collection // get data + augment with info
{
/** @var OperationsRepositoryInterface $opsRepository */
- $opsRepository = app(OperationsRepositoryInterface::class);
+ $opsRepository = app(OperationsRepositoryInterface::class);
/** @var BudgetLimitRepositoryInterface $blRepository */
- $blRepository = app(BudgetLimitRepositoryInterface::class);
+ $blRepository = app(BudgetLimitRepositoryInterface::class);
// properties for cache
- $cache = new CacheProperties();
+ $cache = new CacheProperties();
$cache->addProperty($start);
$cache->addProperty($end);
$cache->addProperty($budget->id);
@@ -215,12 +188,23 @@ trait AugumentData
/** @var BudgetLimit $entry */
foreach ($set as $entry) {
- $currency = $entry->transactionCurrency;
+ $currency = $entry->transactionCurrency;
+
+ if (null === $currency) {
+ $currency = app('amount')->getDefaultCurrency();
+ }
+
// clone because these objects change each other.
$currentStart = clone $entry->start_date;
- $currentEnd = clone $entry->end_date;
+ $currentEnd = null === $entry->end_date ? null : clone $entry->end_date;
+
+ if (null === $currentEnd) {
+ $currentEnd = clone $currentStart;
+ $currentEnd->addMonth();
+ }
+
$expenses = $opsRepository->sumExpenses($currentStart, $currentEnd, null, $budgetCollection, $currency);
- $spent = $expenses[(int)$currency->id]['sum'] ?? '0';
+ $spent = $expenses[$currency->id]['sum'] ?? '0';
$entry->spent = $spent;
$limits->push($entry);
@@ -232,18 +216,15 @@ trait AugumentData
/**
* Group set of transactions by name of opposing account.
- *
- * @param array $array
- *
- * @return array
*/
protected function groupByName(array $array): array // filter + group data
{
// group by opposing account name.
$grouped = [];
+
/** @var array $journal */
foreach ($array as $journal) {
- $name = '(no name)';
+ $name = '(no name)';
if (TransactionType::WITHDRAWAL === $journal['transaction_type_type']) {
$name = $journal['destination_account_name'];
}
@@ -251,7 +232,7 @@ trait AugumentData
$name = $journal['source_account_name'];
}
- $grouped[$name] = $grouped[$name] ?? '0';
+ $grouped[$name] ??= '0';
$grouped[$name] = bcadd($journal['amount'], $grouped[$name]);
}
@@ -260,29 +241,22 @@ trait AugumentData
/**
* Spent in a period.
- *
- * @param Collection $assets
- * @param Collection $opposing
- * @param Carbon $start
- * @param Carbon $end
- *
- * @return array
*/
protected function spentInPeriod(Collection $assets, Collection $opposing, Carbon $start, Carbon $end): array // get data + augment with info
{
/** @var GroupCollectorInterface $collector */
$collector = app(GroupCollectorInterface::class);
- $total = $assets->merge($opposing);
+ $total = $assets->merge($opposing);
$collector->setRange($start, $end)->setTypes([TransactionType::WITHDRAWAL])->setAccounts($total);
- $journals = $collector->getExtractedJournals();
- $sum = [
+ $journals = $collector->getExtractedJournals();
+ $sum = [
'grand_sum' => '0',
'per_currency' => [],
];
// loop to support multi currency
foreach ($journals as $journal) {
- $currencyId = (int)$journal['currency_id'];
+ $currencyId = (int)$journal['currency_id'];
// if not set, set to zero:
if (!array_key_exists($currencyId, $sum['per_currency'])) {
diff --git a/app/Support/Http/Controllers/BasicDataSupport.php b/app/Support/Http/Controllers/BasicDataSupport.php
index 360634330b..47d70225a7 100644
--- a/app/Support/Http/Controllers/BasicDataSupport.php
+++ b/app/Support/Http/Controllers/BasicDataSupport.php
@@ -27,16 +27,12 @@ use Carbon\Carbon;
/**
* Trait BasicDataSupport
- *
*/
trait BasicDataSupport
{
/**
* Find the ID in a given array. Return '0' if not there (amount).
*
- * @param array $array
- * @param int $entryId
- *
* @return null|mixed
*/
protected function isInArray(array $array, int $entryId)
@@ -46,11 +42,6 @@ trait BasicDataSupport
/**
* Find the ID in a given array. Return null if not there (amount).
- *
- * @param array $array
- * @param int $entryId
- *
- * @return null|Carbon
*/
protected function isInArrayDate(array $array, int $entryId): ?Carbon
{
diff --git a/app/Support/Http/Controllers/ChartGeneration.php b/app/Support/Http/Controllers/ChartGeneration.php
index 5b2cd7c6e6..cce65122fa 100644
--- a/app/Support/Http/Controllers/ChartGeneration.php
+++ b/app/Support/Http/Controllers/ChartGeneration.php
@@ -28,11 +28,8 @@ use FireflyIII\Exceptions\FireflyException;
use FireflyIII\Generator\Chart\Basic\GeneratorInterface;
use FireflyIII\Models\Account;
use FireflyIII\Repositories\Account\AccountRepositoryInterface;
-use FireflyIII\Repositories\Currency\CurrencyRepositoryInterface;
use FireflyIII\Support\CacheProperties;
use Illuminate\Support\Collection;
-use Illuminate\Support\Facades\Log;
-use JsonException;
/**
* Trait ChartGeneration
@@ -42,18 +39,12 @@ trait ChartGeneration
/**
* Shows an overview of the account balances for a set of accounts.
*
- * @param Collection $accounts
- * @param Carbon $start
- * @param Carbon $end
- *
- * @return array
* @throws FireflyException
- * @throws JsonException
*/
protected function accountBalanceChart(Collection $accounts, Carbon $start, Carbon $end): array // chart helper method.
{
// chart properties for cache:
- $cache = new CacheProperties();
+ $cache = new CacheProperties();
$cache->addProperty($start);
$cache->addProperty($end);
$cache->addProperty('chart.account.account-balance-chart');
@@ -61,26 +52,26 @@ trait ChartGeneration
if ($cache->has()) {
return $cache->get();
}
- Log::debug('Regenerate chart.account.account-balance-chart from scratch.');
- $locale = app('steam')->getLocale();
- /** @var GeneratorInterface $generator */
- $generator = app(GeneratorInterface::class);
+ app('log')->debug('Regenerate chart.account.account-balance-chart from scratch.');
+ $locale = app('steam')->getLocale();
+
+ /** @var GeneratorInterface $generator */
+ $generator = app(GeneratorInterface::class);
- /** @var CurrencyRepositoryInterface $repository */
- $repository = app(CurrencyRepositoryInterface::class);
/** @var AccountRepositoryInterface $accountRepos */
$accountRepos = app(AccountRepositoryInterface::class);
- $default = app('amount')->getDefaultCurrency();
- $chartData = [];
+ $default = app('amount')->getDefaultCurrency();
+ $chartData = [];
+
/** @var Account $account */
foreach ($accounts as $account) {
// TODO we can use getAccountCurrency instead.
- $currency = $repository->find((int)$accountRepos->getMetaValue($account, 'currency_id'));
+ $currency = $accountRepos->getAccountCurrency($account);
if (null === $currency) {
$currency = $default;
}
- $currentSet = [
+ $currentSet = [
'label' => $account->name,
'currency_symbol' => $currency->symbol,
'entries' => [],
@@ -90,16 +81,16 @@ trait ChartGeneration
$range = app('steam')->balanceInRange($account, $start, clone $end);
$previous = array_values($range)[0];
while ($currentStart <= $end) {
- $format = $currentStart->format('Y-m-d');
- $label = trim($currentStart->isoFormat((string)trans('config.month_and_day_js', [], $locale)));
- $balance = $range[$format] ?? $previous;
- $previous = $balance;
+ $format = $currentStart->format('Y-m-d');
+ $label = trim($currentStart->isoFormat((string)trans('config.month_and_day_js', [], $locale)));
+ $balance = $range[$format] ?? $previous;
+ $previous = $balance;
$currentStart->addDay();
$currentSet['entries'][$label] = $balance;
}
- $chartData[] = $currentSet;
+ $chartData[] = $currentSet;
}
- $data = $generator->multiSet($chartData);
+ $data = $generator->multiSet($chartData);
$cache->store($data);
return $data;
diff --git a/app/Support/Http/Controllers/CreateStuff.php b/app/Support/Http/Controllers/CreateStuff.php
index a856a2ea64..ebd702e5a2 100644
--- a/app/Support/Http/Controllers/CreateStuff.php
+++ b/app/Support/Http/Controllers/CreateStuff.php
@@ -34,17 +34,11 @@ use phpseclib3\Crypt\RSA;
/**
* Trait CreateStuff
- *
*/
trait CreateStuff
{
/**
* Creates an asset account.
- *
- * @param NewUserFormRequest $request
- * @param TransactionCurrency $currency
- *
- * @return bool
*/
protected function createAssetAccount(NewUserFormRequest $request, TransactionCurrency $currency): bool // create stuff
{
@@ -70,11 +64,6 @@ trait CreateStuff
/**
* Creates a cash wallet.
- *
- * @param TransactionCurrency $currency
- * @param string $language
- *
- * @return bool
*/
protected function createCashWalletAccount(TransactionCurrency $currency, string $language): bool // create stuff
{
@@ -112,22 +101,16 @@ trait CreateStuff
return;
}
- $keys = RSA::createKey(4096);
+ $key = RSA::createKey(4096);
Log::alert('NO OAuth keys were found. They have been created.');
- file_put_contents($publicKey, $keys['publickey']);
- file_put_contents($privateKey, $keys['privatekey']);
+ file_put_contents($publicKey, (string)$key->getPublicKey());
+ file_put_contents($privateKey, $key->toString('PKCS1'));
}
/**
* Create a savings account.
- *
- * @param NewUserFormRequest $request
- * @param TransactionCurrency $currency
- * @param string $language
- *
- * @return bool
*/
protected function createSavingsAccount(NewUserFormRequest $request, TransactionCurrency $currency, string $language): bool // create stuff
{
@@ -152,10 +135,6 @@ trait CreateStuff
/**
* Create a new user instance after a valid registration.
- *
- * @param array $data
- *
- * @return User
*/
protected function createUser(array $data): User // create object
{
diff --git a/app/Support/Http/Controllers/CronRunner.php b/app/Support/Http/Controllers/CronRunner.php
index dc0b337bd1..5fb7326bfa 100644
--- a/app/Support/Http/Controllers/CronRunner.php
+++ b/app/Support/Http/Controllers/CronRunner.php
@@ -29,28 +29,19 @@ use FireflyIII\Support\Cronjobs\AutoBudgetCronjob;
use FireflyIII\Support\Cronjobs\BillWarningCronjob;
use FireflyIII\Support\Cronjobs\ExchangeRatesCronjob;
use FireflyIII\Support\Cronjobs\RecurringCronjob;
-use Psr\Container\ContainerExceptionInterface;
-use Psr\Container\NotFoundExceptionInterface;
/**
* Trait CronRunner
*/
trait CronRunner
{
- /**
- * @param bool $force
- * @param Carbon $date
- *
- * @return array
- * @throws ContainerExceptionInterface
- * @throws NotFoundExceptionInterface
- */
protected function billWarningCronJob(bool $force, Carbon $date): array
{
/** @var BillWarningCronjob $billWarning */
$billWarning = app(BillWarningCronjob::class);
$billWarning->setForce($force);
$billWarning->setDate($date);
+
try {
$billWarning->fire();
} catch (FireflyException $e) {
@@ -70,18 +61,13 @@ trait CronRunner
];
}
- /**
- * @param bool $force
- * @param Carbon $date
- *
- * @return array
- */
protected function exchangeRatesCronJob(bool $force, Carbon $date): array
{
/** @var ExchangeRatesCronjob $exchangeRates */
$exchangeRates = app(ExchangeRatesCronjob::class);
$exchangeRates->setForce($force);
$exchangeRates->setDate($date);
+
try {
$exchangeRates->fire();
} catch (FireflyException $e) {
@@ -101,18 +87,13 @@ trait CronRunner
];
}
- /**
- * @param bool $force
- * @param Carbon $date
- *
- * @return array
- */
protected function runAutoBudget(bool $force, Carbon $date): array
{
/** @var AutoBudgetCronjob $autoBudget */
$autoBudget = app(AutoBudgetCronjob::class);
$autoBudget->setForce($force);
$autoBudget->setDate($date);
+
try {
$autoBudget->fire();
} catch (FireflyException $e) {
@@ -132,20 +113,13 @@ trait CronRunner
];
}
- /**
- * @param bool $force
- * @param Carbon $date
- *
- * @return array
- * @throws ContainerExceptionInterface
- * @throws NotFoundExceptionInterface
- */
protected function runRecurring(bool $force, Carbon $date): array
{
/** @var RecurringCronjob $recurring */
$recurring = app(RecurringCronjob::class);
$recurring->setForce($force);
$recurring->setDate($date);
+
try {
$recurring->fire();
} catch (FireflyException $e) {
diff --git a/app/Support/Http/Controllers/DateCalculation.php b/app/Support/Http/Controllers/DateCalculation.php
index ae01a4135e..320734d456 100644
--- a/app/Support/Http/Controllers/DateCalculation.php
+++ b/app/Support/Http/Controllers/DateCalculation.php
@@ -27,7 +27,6 @@ use Carbon\Carbon;
/**
* Trait DateCalculation
- *
*/
trait DateCalculation
{
@@ -37,11 +36,6 @@ trait DateCalculation
*
* If both are in the past OR both are in the future, simply return the number of days in the period with a minimum
* of 1
- *
- * @param Carbon $start
- * @param Carbon $end
- *
- * @return int
*/
public function activeDaysLeft(Carbon $start, Carbon $end): int
{
@@ -59,11 +53,6 @@ trait DateCalculation
* Calculate the number of days passed between two dates. Will take the current moment into consideration.
*
* If both are in the past OR both are in the future, simply return the period between them with a minimum of 1
- *
- * @param Carbon $start
- * @param Carbon $end
- *
- * @return int
*/
protected function activeDaysPassed(Carbon $start, Carbon $end): int
{
@@ -77,12 +66,6 @@ trait DateCalculation
return $difference;
}
- /**
- * @param Carbon $start
- * @param Carbon $end
- *
- * @return string
- */
protected function calculateStep(Carbon $start, Carbon $end): string
{
$step = '1D';
@@ -103,27 +86,23 @@ trait DateCalculation
/**
* Get a list of the periods that will occur after this date. For example,
* March 2018, April 2018, etc.
- *
- * @param Carbon $date
- * @param string $range
- *
- * @return array
*/
protected function getNextPeriods(Carbon $date, string $range): array
{
// select thing for next 12 periods:
- $loop = [];
+ $loop = [];
+
/** @var Carbon $current */
$current = app('navigation')->startOfPeriod($date, $range);
$current = app('navigation')->endOfPeriod($current, $range);
$current->addDay();
- $count = 0;
+ $count = 0;
while ($count < 12) {
$current = app('navigation')->endOfPeriod($current, $range);
$currentStart = app('navigation')->startOfPeriod($current, $range);
- $loop[] = [
+ $loop[] = [
'label' => $current->format('Y-m-d'),
'title' => app('navigation')->periodShow($current, $range),
'start' => clone $currentStart,
@@ -139,16 +118,12 @@ trait DateCalculation
/**
* Get a list of the periods that occurred before the start date. For example,
* March 2018, February 2018, etc.
- *
- * @param Carbon $date
- * @param string $range
- *
- * @return array
*/
protected function getPreviousPeriods(Carbon $date, string $range): array
{
// select thing for last 12 periods:
- $loop = [];
+ $loop = [];
+
/** @var Carbon $current */
$current = app('navigation')->startOfPeriod($date, $range);
$count = 0;
diff --git a/app/Support/Http/Controllers/GetConfigurationData.php b/app/Support/Http/Controllers/GetConfigurationData.php
index 0cfe7b8019..db23befbc2 100644
--- a/app/Support/Http/Controllers/GetConfigurationData.php
+++ b/app/Support/Http/Controllers/GetConfigurationData.php
@@ -25,22 +25,14 @@ namespace FireflyIII\Support\Http\Controllers;
use Carbon\Carbon;
use FireflyIII\Exceptions\FireflyException;
-use Illuminate\Support\Facades\Log;
-use Psr\Container\ContainerExceptionInterface;
-use Psr\Container\NotFoundExceptionInterface;
/**
* Trait GetConfigurationData
- *
*/
trait GetConfigurationData
{
/**
* Some common combinations.
- *
- * @param int $value
- *
- * @return string
*/
protected function errorReporting(int $value): string // get configuration
{
@@ -59,10 +51,6 @@ trait GetConfigurationData
/**
* Get the basic steps from config.
- *
- * @param string $route
- *
- * @return array
*/
protected function getBasicSteps(string $route): array // get config values
{
@@ -71,16 +59,16 @@ trait GetConfigurationData
$steps = [];
if (is_array($elements) && count($elements) > 0) {
foreach ($elements as $key => $options) {
- $currentStep = $options;
+ $currentStep = $options;
// get the text:
- $currentStep['intro'] = (string)trans('intro.' . $route . '_' . $key);
+ $currentStep['intro'] = (string)trans('intro.'.$route.'_'.$key);
// save in array:
- $steps[] = $currentStep;
+ $steps[] = $currentStep;
}
}
- Log::debug(sprintf('Total basic steps for %s is %d', $routeKey, count($steps)));
+ app('log')->debug(sprintf('Total basic steps for %s is %d', $routeKey, count($steps)));
return $steps;
}
@@ -88,24 +76,24 @@ trait GetConfigurationData
/**
* Get config for date range.
*
- * @return array
* @throws FireflyException
- * @throws ContainerExceptionInterface
- * @throws NotFoundExceptionInterface
*/
protected function getDateRangeConfig(): array // get configuration + get preferences.
{
- $viewRange = app('navigation')->getViewRange(false);
+ $viewRange = app('navigation')->getViewRange(false);
+
/** @var Carbon $start */
- $start = session('start');
+ $start = session('start');
+
/** @var Carbon $end */
- $end = session('end');
+ $end = session('end');
+
/** @var Carbon $first */
- $first = session('first');
- $title = sprintf('%s - %s', $start->isoFormat($this->monthAndDayFormat), $end->isoFormat($this->monthAndDayFormat));
- $isCustom = true === session('is_custom_range', false);
- $today = today(config('app.timezone'));
- $ranges = [
+ $first = session('first');
+ $title = sprintf('%s - %s', $start->isoFormat($this->monthAndDayFormat), $end->isoFormat($this->monthAndDayFormat));
+ $isCustom = true === session('is_custom_range', false);
+ $today = today(config('app.timezone'));
+ $ranges = [
// first range is the current range:
$title => [$start, $end],
];
@@ -134,9 +122,10 @@ trait GetConfigurationData
// today:
/** @var Carbon $todayStart */
- $todayStart = app('navigation')->startOfPeriod($today, $viewRange);
+ $todayStart = app('navigation')->startOfPeriod($today, $viewRange);
+
/** @var Carbon $todayEnd */
- $todayEnd = app('navigation')->endOfPeriod($todayStart, $viewRange);
+ $todayEnd = app('navigation')->endOfPeriod($todayStart, $viewRange);
if ($todayStart->ne($start) || $todayEnd->ne($end)) {
$ranges[ucfirst((string)trans('firefly.today'))] = [$todayStart, $todayEnd];
}
@@ -182,12 +171,6 @@ trait GetConfigurationData
/**
* Get specific info for special routes.
- *
- * @param string $route
- * @param string $specificPage
- *
- * @return array
- *
*/
protected function getSpecificSteps(string $route, string $specificPage): array // get config values
{
@@ -197,33 +180,30 @@ trait GetConfigurationData
// user is on page with specific instructions:
if ('' !== $specificPage) {
$routeKey = str_replace('.', '_', $route);
- $elements = config(sprintf('intro.%s', $routeKey . '_' . $specificPage));
+ $elements = config(sprintf('intro.%s', $routeKey.'_'.$specificPage));
if (is_array($elements) && count($elements) > 0) {
foreach ($elements as $key => $options) {
- $currentStep = $options;
+ $currentStep = $options;
// get the text:
- $currentStep['intro'] = (string)trans('intro.' . $route . '_' . $specificPage . '_' . $key);
+ $currentStep['intro'] = (string)trans('intro.'.$route.'_'.$specificPage.'_'.$key);
// save in array:
- $steps[] = $currentStep;
+ $steps[] = $currentStep;
}
}
}
- Log::debug(sprintf('Total specific steps for route "%s" and page "%s" (routeKey is "%s") is %d', $route, $specificPage, $routeKey, count($steps)));
+ app('log')->debug(sprintf('Total specific steps for route "%s" and page "%s" (routeKey is "%s") is %d', $route, $specificPage, $routeKey, count($steps)));
return $steps;
}
- /**
- *
- */
protected function verifyRecurringCronJob(): void
{
$config = app('fireflyconfig')->get('last_rt_job', 0);
- $lastTime = (int)$config->data;
+ $lastTime = (int)$config?->data;
$now = time();
- Log::debug(sprintf('verifyRecurringCronJob: last time is %d ("%s"), now is %d', $lastTime, $config->data, $now));
+ app('log')->debug(sprintf('verifyRecurringCronJob: last time is %d ("%s"), now is %d', $lastTime, $config?->data, $now));
if (0 === $lastTime) {
request()->session()->flash('info', trans('firefly.recurring_never_cron'));
diff --git a/app/Support/Http/Controllers/ModelInformation.php b/app/Support/Http/Controllers/ModelInformation.php
index 7d3d42e7ce..68a31bcc7a 100644
--- a/app/Support/Http/Controllers/ModelInformation.php
+++ b/app/Support/Http/Controllers/ModelInformation.php
@@ -30,24 +30,18 @@ use FireflyIII\Models\Tag;
use FireflyIII\Models\Transaction;
use FireflyIII\Models\TransactionJournal;
use FireflyIII\Repositories\Account\AccountRepositoryInterface;
-use Illuminate\Support\Facades\Log;
-use Throwable;
/**
* Trait ModelInformation
- *
*/
trait ModelInformation
{
/**
* Get actions based on a bill.
*
- * @param Bill $bill
- *
- * @return array
* @throws FireflyException
*/
- protected function getActionsForBill(Bill $bill): array // get info and augument
+ protected function getActionsForBill(Bill $bill): array // get info and argument
{
try {
$result = view(
@@ -59,10 +53,11 @@ trait ModelInformation
'count' => 1,
]
)->render();
- } catch (Throwable $e) {
- Log::error(sprintf('Throwable was thrown in getActionsForBill(): %s', $e->getMessage()));
- Log::error($e->getTraceAsString());
+ } catch (\Throwable $e) {
+ app('log')->error(sprintf('Throwable was thrown in getActionsForBill(): %s', $e->getMessage()));
+ app('log')->error($e->getTraceAsString());
$result = 'Could not render view. See log files.';
+
throw new FireflyException($result, 0, $e);
}
@@ -70,7 +65,6 @@ trait ModelInformation
}
/**
- *
* @return string[]
*
* @psalm-return array
@@ -78,10 +72,16 @@ trait ModelInformation
protected function getLiabilityTypes(): array
{
/** @var AccountRepositoryInterface $repository */
- $repository = app(AccountRepositoryInterface::class);
+ $repository = app(AccountRepositoryInterface::class);
+
// types of liability:
+ /** @var AccountType $debt */
$debt = $repository->getAccountTypeByType(AccountType::DEBT);
+
+ /** @var AccountType $loan */
$loan = $repository->getAccountTypeByType(AccountType::LOAN);
+
+ /** @var AccountType $mortgage */
$mortgage = $repository->getAccountTypeByType(AccountType::MORTGAGE);
$liabilityTypes = [
$debt->id => (string)trans(sprintf('firefly.account_type_%s', AccountType::DEBT)),
@@ -93,9 +93,6 @@ trait ModelInformation
return $liabilityTypes;
}
- /**
- * @return array
- */
protected function getRoles(): array
{
$roles = [];
@@ -109,16 +106,13 @@ trait ModelInformation
/**
* Create fake triggers to match the bill's properties
*
- * @param Bill $bill
- *
- * @return array
* @throws FireflyException
*/
- protected function getTriggersForBill(Bill $bill): array // get info and augument
+ protected function getTriggersForBill(Bill $bill): array // get info and argument
{
// TODO duplicate code
- $operators = config('search.operators');
- $triggers = [];
+ $operators = config('search.operators');
+ $triggers = [];
foreach ($operators as $key => $operator) {
if ('user_action' !== $key && false === $operator['alias']) {
$triggers[$key] = (string)trans(sprintf('firefly.rule_trigger_%s_choice', $key));
@@ -129,7 +123,7 @@ trait ModelInformation
$result = [];
$billTriggers = ['currency_is', 'amount_more', 'amount_less', 'description_contains'];
$values = [
- $bill->transactionCurrency()->first()->name,
+ $bill->transactionCurrency()->first()?->name,
$bill->amount_min,
$bill->amount_max,
$bill->name,
@@ -146,11 +140,11 @@ trait ModelInformation
'triggers' => $triggers,
]
)->render();
- } catch (Throwable $e) {
- Log::debug(sprintf('Throwable was thrown in getTriggersForBill(): %s', $e->getMessage()));
- Log::debug($e->getTraceAsString());
- $string = '';
- throw new FireflyException('Could not render trigger', 0, $e);
+ } catch (\Throwable $e) {
+ app('log')->debug(sprintf('Throwable was thrown in getTriggersForBill(): %s', $e->getMessage()));
+ app('log')->debug($e->getTraceAsString());
+
+ throw new FireflyException(sprintf('Could not render trigger: %s', $e->getMessage()), 0, $e);
}
if ('' !== $string) {
$result[] = $string;
@@ -161,16 +155,15 @@ trait ModelInformation
}
/**
- * @param TransactionJournal $journal
- *
- * @return array
* @throws FireflyException
+ *
+ * @SuppressWarnings(PHPMD.ExcessiveMethodLength)
*/
private function getTriggersForJournal(TransactionJournal $journal): array
{
- // See reference nr. 40
- $operators = config('search.operators');
- $triggers = [];
+ // TODO duplicated code.
+ $operators = config('search.operators');
+ $triggers = [];
foreach ($operators as $key => $operator) {
if ('user_action' !== $key && false === $operator['alias']) {
$triggers[$key] = (string)trans(sprintf('firefly.rule_trigger_%s_choice', $key));
@@ -178,95 +171,96 @@ trait ModelInformation
}
asort($triggers);
- $result = [];
- $journalTriggers = [];
- $values = [];
- $index = 0;
+ $result = [];
+ $journalTriggers = [];
+ $values = [];
+ $index = 0;
+
// amount, description, category, budget, tags, source, destination, notes, currency type
- //,type
- /** @var Transaction|null $source */
- $source = $journal->transactions()->where('amount', '<', 0)->first();
- /** @var Transaction|null $destination */
- $destination = $journal->transactions()->where('amount', '>', 0)->first();
+ // ,type
+ /** @var null|Transaction $source */
+ $source = $journal->transactions()->where('amount', '<', 0)->first();
+
+ /** @var null|Transaction $destination */
+ $destination = $journal->transactions()->where('amount', '>', 0)->first();
if (null === $destination || null === $source) {
return $result;
}
// type
$journalTriggers[$index] = 'transaction_type';
$values[$index] = $journal->transactionType->type;
- $index++;
+ ++$index;
// currency
$journalTriggers[$index] = 'currency_is';
- $values[$index] = sprintf('%s (%s)', $journal->transactionCurrency->name, $journal->transactionCurrency->code);
- $index++;
+ $values[$index] = sprintf('%s (%s)', $journal->transactionCurrency?->name, $journal->transactionCurrency?->code);
+ ++$index;
// amount_exactly:
$journalTriggers[$index] = 'amount_exactly';
$values[$index] = $destination->amount;
- $index++;
+ ++$index;
// description_is:
$journalTriggers[$index] = 'description_is';
$values[$index] = $journal->description;
- $index++;
+ ++$index;
// from_account_is
$journalTriggers[$index] = 'source_account_is';
$values[$index] = $source->account->name;
- $index++;
+ ++$index;
// to_account_is
$journalTriggers[$index] = 'destination_account_is';
$values[$index] = $destination->account->name;
- $index++;
+ ++$index;
// category (if)
- $category = $journal->categories()->first();
+ $category = $journal->categories()->first();
if (null !== $category) {
$journalTriggers[$index] = 'category_is';
$values[$index] = $category->name;
- $index++;
+ ++$index;
}
// budget (if)
- $budget = $journal->budgets()->first();
+ $budget = $journal->budgets()->first();
if (null !== $budget) {
$journalTriggers[$index] = 'budget_is';
$values[$index] = $budget->name;
- $index++;
+ ++$index;
}
// tags (if)
- $tags = $journal->tags()->get();
+ $tags = $journal->tags()->get();
+
/** @var Tag $tag */
foreach ($tags as $tag) {
$journalTriggers[$index] = 'tag_is';
$values[$index] = $tag->tag;
- $index++;
+ ++$index;
}
// notes (if)
- $notes = $journal->notes()->first();
+ $notes = $journal->notes()->first();
if (null !== $notes) {
$journalTriggers[$index] = 'notes_are';
$values[$index] = $notes->text;
}
- foreach ($journalTriggers as $index => $trigger) {
+ foreach ($journalTriggers as $ii => $trigger) {
try {
- $string = view(
- 'rules.partials.trigger',
- [
- 'oldTrigger' => $trigger,
- 'oldValue' => $values[$index],
- 'oldChecked' => false,
- 'count' => $index + 1,
- 'triggers' => $triggers,
- ]
- )->render();
- } catch (Throwable $e) {
- Log::debug(sprintf('Throwable was thrown in getTriggersForJournal(): %s', $e->getMessage()));
- Log::debug($e->getTraceAsString());
- $string = '';
- throw new FireflyException('Could not render trigger', 0, $e);
+ $renderInfo = [
+ 'oldTrigger' => $trigger,
+ 'oldValue' => $values[$ii],
+ 'oldChecked' => false,
+ 'count' => $ii + 1,
+ 'triggers' => $triggers,
+ ];
+ $string = view('rules.partials.trigger', $renderInfo)->render();
+ } catch (\Throwable $e) {
+ app('log')->debug(sprintf('Throwable was thrown in getTriggersForJournal(): %s', $e->getMessage()));
+ app('log')->debug($e->getTraceAsString());
+
+ throw new FireflyException(sprintf('Could not render trigger: %s', $e->getMessage()), 0, $e);
}
if ('' !== $string) {
$result[] = $string;
diff --git a/app/Support/Http/Controllers/PeriodOverview.php b/app/Support/Http/Controllers/PeriodOverview.php
index 8bdacc157d..c35213211a 100644
--- a/app/Support/Http/Controllers/PeriodOverview.php
+++ b/app/Support/Http/Controllers/PeriodOverview.php
@@ -33,9 +33,6 @@ use FireflyIII\Models\TransactionType;
use FireflyIII\Repositories\Journal\JournalRepositoryInterface;
use FireflyIII\Support\CacheProperties;
use Illuminate\Support\Collection;
-use Illuminate\Support\Facades\Log;
-use Psr\Container\ContainerExceptionInterface;
-use Psr\Container\NotFoundExceptionInterface;
/**
* Trait PeriodOverview.
@@ -63,7 +60,6 @@ use Psr\Container\NotFoundExceptionInterface;
* amount: -1234 (str)
* count: 23
* ]
- *
*/
trait PeriodOverview
{
@@ -74,22 +70,15 @@ trait PeriodOverview
* and for each period, the amount of money spent and earned. This is a complex operation which is cached for
* performance reasons.
*
- * @param Account $account
- * @param Carbon $start
- * @param Carbon $end
- *
- * @return array
* @throws FireflyException
- * @throws ContainerExceptionInterface
- * @throws NotFoundExceptionInterface
*/
protected function getAccountPeriodOverview(Account $account, Carbon $start, Carbon $end): array
{
- $range = app('navigation')->getViewRange(true);
+ $range = app('navigation')->getViewRange(true);
[$start, $end] = $end < $start ? [$end, $start] : [$start, $end];
// properties for cache
- $cache = new CacheProperties();
+ $cache = new CacheProperties();
$cache->addProperty($start);
$cache->addProperty($end);
$cache->addProperty('account-show-period-entries');
@@ -97,33 +86,34 @@ trait PeriodOverview
if ($cache->has()) {
return $cache->get();
}
+
/** @var array $dates */
- $dates = app('navigation')->blockPeriods($start, $end, $range);
- $entries = [];
+ $dates = app('navigation')->blockPeriods($start, $end, $range);
+ $entries = [];
// collect all expenses in this period:
/** @var GroupCollectorInterface $collector */
- $collector = app(GroupCollectorInterface::class);
+ $collector = app(GroupCollectorInterface::class);
$collector->setAccounts(new Collection([$account]));
$collector->setRange($start, $end);
$collector->setTypes([TransactionType::DEPOSIT]);
- $earnedSet = $collector->getExtractedJournals();
+ $earnedSet = $collector->getExtractedJournals();
// collect all income in this period:
/** @var GroupCollectorInterface $collector */
- $collector = app(GroupCollectorInterface::class);
+ $collector = app(GroupCollectorInterface::class);
$collector->setAccounts(new Collection([$account]));
$collector->setRange($start, $end);
$collector->setTypes([TransactionType::WITHDRAWAL]);
- $spentSet = $collector->getExtractedJournals();
+ $spentSet = $collector->getExtractedJournals();
// collect all transfers in this period:
/** @var GroupCollectorInterface $collector */
- $collector = app(GroupCollectorInterface::class);
+ $collector = app(GroupCollectorInterface::class);
$collector->setAccounts(new Collection([$account]));
$collector->setRange($start, $end);
$collector->setTypes([TransactionType::TRANSFER]);
- $transferSet = $collector->getExtractedJournals();
+ $transferSet = $collector->getExtractedJournals();
// loop dates
foreach ($dates as $currentDate) {
@@ -134,16 +124,15 @@ trait PeriodOverview
$transferredIn = $this->filterTransferredIn($account, $this->filterJournalsByDate($transferSet, $currentDate['start'], $currentDate['end']));
$entries[]
= [
- 'title' => $title,
- 'route' =>
- route('accounts.show', [$account->id, $currentDate['start']->format('Y-m-d'), $currentDate['end']->format('Y-m-d')]),
+ 'title' => $title,
+ 'route' => route('accounts.show', [$account->id, $currentDate['start']->format('Y-m-d'), $currentDate['end']->format('Y-m-d')]),
- 'total_transactions' => count($spent) + count($earned) + count($transferredAway) + count($transferredIn),
- 'spent' => $this->groupByCurrency($spent),
- 'earned' => $this->groupByCurrency($earned),
- 'transferred_away' => $this->groupByCurrency($transferredAway),
- 'transferred_in' => $this->groupByCurrency($transferredIn),
- ];
+ 'total_transactions' => count($spent) + count($earned) + count($transferredAway) + count($transferredIn),
+ 'spent' => $this->groupByCurrency($spent),
+ 'earned' => $this->groupByCurrency($earned),
+ 'transferred_away' => $this->groupByCurrency($transferredAway),
+ 'transferred_in' => $this->groupByCurrency($transferredIn),
+ ];
}
$cache->store($entries);
@@ -152,16 +141,11 @@ trait PeriodOverview
/**
* Filter a list of journals by a set of dates, and then group them by currency.
- *
- * @param array $array
- * @param Carbon $start
- * @param Carbon $end
- *
- * @return array
*/
private function filterJournalsByDate(array $array, Carbon $start, Carbon $end): array
{
$result = [];
+
/** @var array $journal */
foreach ($array as $journal) {
if ($journal['date'] <= $end && $journal['date'] >= $start) {
@@ -174,15 +158,11 @@ trait PeriodOverview
/**
* Return only transactions where $account is the source.
- *
- * @param Account $account
- * @param array $journals
- *
- * @return array
*/
private function filterTransferredAway(Account $account, array $journals): array
{
$return = [];
+
/** @var array $journal */
foreach ($journals as $journal) {
if ($account->id === (int)$journal['source_account_id']) {
@@ -195,15 +175,11 @@ trait PeriodOverview
/**
* Return only transactions where $account is the source.
- *
- * @param Account $account
- * @param array $journals
- *
- * @return array
*/
private function filterTransferredIn(Account $account, array $journals): array
{
$return = [];
+
/** @var array $journal */
foreach ($journals as $journal) {
if ($account->id === (int)$journal['destination_account_id']) {
@@ -214,18 +190,14 @@ trait PeriodOverview
return $return;
}
- /**
- * @param array $journals
- *
- * @return array
- */
private function groupByCurrency(array $journals): array
{
$return = [];
+
/** @var array $journal */
foreach ($journals as $journal) {
- $currencyId = (int)$journal['currency_id'];
- $foreignCurrencyId = $journal['foreign_currency_id'];
+ $currencyId = (int)$journal['currency_id'];
+ $foreignCurrencyId = $journal['foreign_currency_id'];
if (!array_key_exists($currencyId, $return)) {
$return[$currencyId] = [
'amount' => '0',
@@ -238,7 +210,7 @@ trait PeriodOverview
];
}
$return[$currencyId]['amount'] = bcadd($return[$currencyId]['amount'], $journal['amount'] ?? '0');
- $return[$currencyId]['count']++;
+ ++$return[$currencyId]['count'];
if (null !== $foreignCurrencyId && null !== $journal['foreign_amount']) {
if (!array_key_exists($foreignCurrencyId, $return)) {
@@ -252,7 +224,7 @@ trait PeriodOverview
'currency_decimal_places' => $journal['foreign_currency_decimal_places'],
];
}
- $return[$foreignCurrencyId]['count']++;
+ ++$return[$foreignCurrencyId]['count'];
$return[$foreignCurrencyId]['amount'] = bcadd($return[$foreignCurrencyId]['amount'], $journal['foreign_amount']);
}
}
@@ -263,22 +235,15 @@ trait PeriodOverview
/**
* Overview for single category. Has been refactored recently.
*
- * @param Category $category
- * @param Carbon $start
- * @param Carbon $end
- *
- * @return array
* @throws FireflyException
- * @throws ContainerExceptionInterface
- * @throws NotFoundExceptionInterface
*/
protected function getCategoryPeriodOverview(Category $category, Carbon $start, Carbon $end): array
{
- $range = app('navigation')->getViewRange(true);
+ $range = app('navigation')->getViewRange(true);
[$start, $end] = $end < $start ? [$end, $start] : [$start, $end];
// properties for entries with their amounts.
- $cache = new CacheProperties();
+ $cache = new CacheProperties();
$cache->addProperty($start);
$cache->addProperty($end);
$cache->addProperty($range);
@@ -288,33 +253,34 @@ trait PeriodOverview
if ($cache->has()) {
return $cache->get();
}
+
/** @var array $dates */
- $dates = app('navigation')->blockPeriods($start, $end, $range);
- $entries = [];
+ $dates = app('navigation')->blockPeriods($start, $end, $range);
+ $entries = [];
// collect all expenses in this period:
/** @var GroupCollectorInterface $collector */
- $collector = app(GroupCollectorInterface::class);
+ $collector = app(GroupCollectorInterface::class);
$collector->setCategory($category);
$collector->setRange($start, $end);
$collector->setTypes([TransactionType::DEPOSIT]);
- $earnedSet = $collector->getExtractedJournals();
+ $earnedSet = $collector->getExtractedJournals();
// collect all income in this period:
/** @var GroupCollectorInterface $collector */
- $collector = app(GroupCollectorInterface::class);
+ $collector = app(GroupCollectorInterface::class);
$collector->setCategory($category);
$collector->setRange($start, $end);
$collector->setTypes([TransactionType::WITHDRAWAL]);
- $spentSet = $collector->getExtractedJournals();
+ $spentSet = $collector->getExtractedJournals();
// collect all transfers in this period:
/** @var GroupCollectorInterface $collector */
- $collector = app(GroupCollectorInterface::class);
+ $collector = app(GroupCollectorInterface::class);
$collector->setCategory($category);
$collector->setRange($start, $end);
$collector->setTypes([TransactionType::TRANSFER]);
- $transferSet = $collector->getExtractedJournals();
+ $transferSet = $collector->getExtractedJournals();
foreach ($dates as $currentDate) {
$spent = $this->filterJournalsByDate($spentSet, $currentDate['start'], $currentDate['end']);
$earned = $this->filterJournalsByDate($earnedSet, $currentDate['start'], $currentDate['end']);
@@ -322,17 +288,17 @@ trait PeriodOverview
$title = app('navigation')->periodShow($currentDate['end'], $currentDate['period']);
$entries[]
= [
- 'transactions' => 0,
- 'title' => $title,
- 'route' => route(
- 'categories.show',
- [$category->id, $currentDate['start']->format('Y-m-d'), $currentDate['end']->format('Y-m-d')]
- ),
- 'total_transactions' => count($spent) + count($earned) + count($transferred),
- 'spent' => $this->groupByCurrency($spent),
- 'earned' => $this->groupByCurrency($earned),
- 'transferred' => $this->groupByCurrency($transferred),
- ];
+ 'transactions' => 0,
+ 'title' => $title,
+ 'route' => route(
+ 'categories.show',
+ [$category->id, $currentDate['start']->format('Y-m-d'), $currentDate['end']->format('Y-m-d')]
+ ),
+ 'total_transactions' => count($spent) + count($earned) + count($transferred),
+ 'spent' => $this->groupByCurrency($spent),
+ 'earned' => $this->groupByCurrency($earned),
+ 'transferred' => $this->groupByCurrency($transferred),
+ ];
}
$cache->store($entries);
@@ -344,21 +310,15 @@ trait PeriodOverview
*
* This method has been refactored recently.
*
- * @param Carbon $start
- * @param Carbon $end
- *
- * @return array
* @throws FireflyException
- * @throws ContainerExceptionInterface
- * @throws NotFoundExceptionInterface
*/
protected function getNoBudgetPeriodOverview(Carbon $start, Carbon $end): array
{
- $range = app('navigation')->getViewRange(true);
+ $range = app('navigation')->getViewRange(true);
[$start, $end] = $end < $start ? [$end, $start] : [$start, $end];
- $cache = new CacheProperties();
+ $cache = new CacheProperties();
$cache->addProperty($start);
$cache->addProperty($end);
$cache->addProperty('no-budget-period-entries');
@@ -368,27 +328,28 @@ trait PeriodOverview
}
/** @var array $dates */
- $dates = app('navigation')->blockPeriods($start, $end, $range);
- $entries = [];
+ $dates = app('navigation')->blockPeriods($start, $end, $range);
+ $entries = [];
+
// get all expenses without a budget.
/** @var GroupCollectorInterface $collector */
- $collector = app(GroupCollectorInterface::class);
+ $collector = app(GroupCollectorInterface::class);
$collector->setRange($start, $end)->withoutBudget()->withAccountInformation()->setTypes([TransactionType::WITHDRAWAL]);
- $journals = $collector->getExtractedJournals();
+ $journals = $collector->getExtractedJournals();
foreach ($dates as $currentDate) {
$set = $this->filterJournalsByDate($journals, $currentDate['start'], $currentDate['end']);
$title = app('navigation')->periodShow($currentDate['end'], $currentDate['period']);
$entries[]
= [
- 'title' => $title,
- 'route' => route('budgets.no-budget', [$currentDate['start']->format('Y-m-d'), $currentDate['end']->format('Y-m-d')]),
- 'total_transactions' => count($set),
- 'spent' => $this->groupByCurrency($set),
- 'earned' => [],
- 'transferred_away' => [],
- 'transferred_in' => [],
- ];
+ 'title' => $title,
+ 'route' => route('budgets.no-budget', [$currentDate['start']->format('Y-m-d'), $currentDate['end']->format('Y-m-d')]),
+ 'total_transactions' => count($set),
+ 'spent' => $this->groupByCurrency($set),
+ 'earned' => [],
+ 'transferred_away' => [],
+ 'transferred_in' => [],
+ ];
}
$cache->store($entries);
@@ -400,47 +361,42 @@ trait PeriodOverview
*
* Show period overview for no category view.
*
- * @param Carbon $theDate
- *
- * @return array
* @throws FireflyException
- * @throws ContainerExceptionInterface
- * @throws NotFoundExceptionInterface
*/
protected function getNoCategoryPeriodOverview(Carbon $theDate): array
{
- Log::debug(sprintf('Now in getNoCategoryPeriodOverview(%s)', $theDate->format('Y-m-d')));
- $range = app('navigation')->getViewRange(true);
- $first = $this->journalRepos->firstNull();
- $start = null === $first ? new Carbon() : $first->date;
- $end = clone $theDate;
+ app('log')->debug(sprintf('Now in getNoCategoryPeriodOverview(%s)', $theDate->format('Y-m-d')));
+ $range = app('navigation')->getViewRange(true);
+ $first = $this->journalRepos->firstNull();
+ $start = null === $first ? new Carbon() : $first->date;
+ $end = clone $theDate;
- Log::debug(sprintf('Start for getNoCategoryPeriodOverview() is %s', $start->format('Y-m-d')));
- Log::debug(sprintf('End for getNoCategoryPeriodOverview() is %s', $end->format('Y-m-d')));
+ app('log')->debug(sprintf('Start for getNoCategoryPeriodOverview() is %s', $start->format('Y-m-d')));
+ app('log')->debug(sprintf('End for getNoCategoryPeriodOverview() is %s', $end->format('Y-m-d')));
// properties for cache
- $dates = app('navigation')->blockPeriods($start, $end, $range);
- $entries = [];
+ $dates = app('navigation')->blockPeriods($start, $end, $range);
+ $entries = [];
// collect all expenses in this period:
/** @var GroupCollectorInterface $collector */
- $collector = app(GroupCollectorInterface::class);
+ $collector = app(GroupCollectorInterface::class);
$collector->withoutCategory();
$collector->setRange($start, $end);
$collector->setTypes([TransactionType::DEPOSIT]);
- $earnedSet = $collector->getExtractedJournals();
+ $earnedSet = $collector->getExtractedJournals();
// collect all income in this period:
/** @var GroupCollectorInterface $collector */
- $collector = app(GroupCollectorInterface::class);
+ $collector = app(GroupCollectorInterface::class);
$collector->withoutCategory();
$collector->setRange($start, $end);
$collector->setTypes([TransactionType::WITHDRAWAL]);
- $spentSet = $collector->getExtractedJournals();
+ $spentSet = $collector->getExtractedJournals();
// collect all transfers in this period:
/** @var GroupCollectorInterface $collector */
- $collector = app(GroupCollectorInterface::class);
+ $collector = app(GroupCollectorInterface::class);
$collector->withoutCategory();
$collector->setRange($start, $end);
$collector->setTypes([TransactionType::TRANSFER]);
@@ -454,15 +410,15 @@ trait PeriodOverview
$title = app('navigation')->periodShow($currentDate['end'], $currentDate['period']);
$entries[]
= [
- 'title' => $title,
- 'route' => route('categories.no-category', [$currentDate['start']->format('Y-m-d'), $currentDate['end']->format('Y-m-d')]),
- 'total_transactions' => count($spent) + count($earned) + count($transferred),
- 'spent' => $this->groupByCurrency($spent),
- 'earned' => $this->groupByCurrency($earned),
- 'transferred' => $this->groupByCurrency($transferred),
- ];
+ 'title' => $title,
+ 'route' => route('categories.no-category', [$currentDate['start']->format('Y-m-d'), $currentDate['end']->format('Y-m-d')]),
+ 'total_transactions' => count($spent) + count($earned) + count($transferred),
+ 'spent' => $this->groupByCurrency($spent),
+ 'earned' => $this->groupByCurrency($earned),
+ 'transferred' => $this->groupByCurrency($transferred),
+ ];
}
- Log::debug('End of loops');
+ app('log')->debug('End of loops');
return $entries;
}
@@ -470,56 +426,55 @@ trait PeriodOverview
/**
* This shows a period overview for a tag. It goes back in time and lists all relevant transactions and sums.
*
- * @param Tag $tag
- * @param Carbon $start
- * @param Carbon $end
- *
- * @return array
* @throws FireflyException
- * @throws ContainerExceptionInterface
- * @throws NotFoundExceptionInterface
*/
protected function getTagPeriodOverview(Tag $tag, Carbon $start, Carbon $end): array // period overview for tags.
{
- $range = app('navigation')->getViewRange(true);
+ $range = app('navigation')->getViewRange(true);
[$start, $end] = $end < $start ? [$end, $start] : [$start, $end];
// properties for cache
- $cache = new CacheProperties();
+ $cache = new CacheProperties();
$cache->addProperty($start);
$cache->addProperty($end);
$cache->addProperty('tag-period-entries');
$cache->addProperty($tag->id);
if ($cache->has()) {
- return $cache->get();
+ // return $cache->get();
}
+
/** @var array $dates */
- $dates = app('navigation')->blockPeriods($start, $end, $range);
- $entries = [];
+ $dates = app('navigation')->blockPeriods($start, $end, $range);
+ $entries = [];
// collect all expenses in this period:
/** @var GroupCollectorInterface $collector */
- $collector = app(GroupCollectorInterface::class);
+ $collector = app(GroupCollectorInterface::class);
$collector->setTag($tag);
$collector->setRange($start, $end);
$collector->setTypes([TransactionType::DEPOSIT]);
- $earnedSet = $collector->getExtractedJournals();
+ $earnedSet = $collector->getExtractedJournals();
// collect all income in this period:
/** @var GroupCollectorInterface $collector */
- $collector = app(GroupCollectorInterface::class);
+ $collector = app(GroupCollectorInterface::class);
$collector->setTag($tag);
$collector->setRange($start, $end);
$collector->setTypes([TransactionType::WITHDRAWAL]);
- $spentSet = $collector->getExtractedJournals();
+ $spentSet = $collector->getExtractedJournals();
// collect all transfers in this period:
/** @var GroupCollectorInterface $collector */
- $collector = app(GroupCollectorInterface::class);
+ $collector = app(GroupCollectorInterface::class);
$collector->setTag($tag);
$collector->setRange($start, $end);
$collector->setTypes([TransactionType::TRANSFER]);
- $transferSet = $collector->getExtractedJournals();
+ $transferSet = $collector->getExtractedJournals();
+
+ // filer all of them:
+ $earnedSet = $this->filterJournalsByTag($earnedSet, $tag);
+ $spentSet = $this->filterJournalsByTag($spentSet, $tag);
+ $transferSet = $this->filterJournalsByTag($transferSet, $tag);
foreach ($dates as $currentDate) {
$spent = $this->filterJournalsByDate($spentSet, $currentDate['start'], $currentDate['end']);
@@ -528,40 +483,54 @@ trait PeriodOverview
$title = app('navigation')->periodShow($currentDate['end'], $currentDate['period']);
$entries[]
= [
- 'transactions' => 0,
- 'title' => $title,
- 'route' => route(
- 'tags.show',
- [$tag->id, $currentDate['start']->format('Y-m-d'), $currentDate['end']->format('Y-m-d')]
- ),
- 'total_transactions' => count($spent) + count($earned) + count($transferred),
- 'spent' => $this->groupByCurrency($spent),
- 'earned' => $this->groupByCurrency($earned),
- 'transferred' => $this->groupByCurrency($transferred),
- ];
+ 'transactions' => 0,
+ 'title' => $title,
+ 'route' => route(
+ 'tags.show',
+ [$tag->id, $currentDate['start']->format('Y-m-d'), $currentDate['end']->format('Y-m-d')]
+ ),
+ 'total_transactions' => count($spent) + count($earned) + count($transferred),
+ 'spent' => $this->groupByCurrency($spent),
+ 'earned' => $this->groupByCurrency($earned),
+ 'transferred' => $this->groupByCurrency($transferred),
+ ];
}
return $entries;
}
+ private function filterJournalsByTag(array $set, Tag $tag): array
+ {
+ $return = [];
+ foreach ($set as $entry) {
+ $found = false;
+
+ /** @var array $localTag */
+ foreach ($entry['tags'] as $localTag) {
+ if ($localTag['id'] === $tag->id) {
+ $found = true;
+ }
+ }
+ if (false === $found) {
+ continue;
+ }
+ $return[] = $entry;
+ }
+
+ return $return;
+ }
+
/**
- * @param string $transactionType
- * @param Carbon $start
- * @param Carbon $end
- *
- * @return array
* @throws FireflyException
- * @throws ContainerExceptionInterface
- * @throws NotFoundExceptionInterface
*/
protected function getTransactionPeriodOverview(string $transactionType, Carbon $start, Carbon $end): array
{
- $range = app('navigation')->getViewRange(true);
- $types = config(sprintf('firefly.transactionTypesByType.%s', $transactionType));
+ $range = app('navigation')->getViewRange(true);
+ $types = config(sprintf('firefly.transactionTypesByType.%s', $transactionType));
[$start, $end] = $end < $start ? [$end, $start] : [$start, $end];
// properties for cache
- $cache = new CacheProperties();
+ $cache = new CacheProperties();
$cache->addProperty($start);
$cache->addProperty($end);
$cache->addProperty('transactions-period-entries');
@@ -569,14 +538,15 @@ trait PeriodOverview
if ($cache->has()) {
return $cache->get();
}
+
/** @var array $dates */
- $dates = app('navigation')->blockPeriods($start, $end, $range);
- $entries = [];
+ $dates = app('navigation')->blockPeriods($start, $end, $range);
+ $entries = [];
// collect all journals in this period (regardless of type)
- $collector = app(GroupCollectorInterface::class);
+ $collector = app(GroupCollectorInterface::class);
$collector->setTypes($types)->setRange($start, $end);
- $genericSet = $collector->getExtractedJournals();
+ $genericSet = $collector->getExtractedJournals();
foreach ($dates as $currentDate) {
$spent = [];
@@ -595,15 +565,14 @@ trait PeriodOverview
$transferred = $this->filterJournalsByDate($genericSet, $currentDate['start'], $currentDate['end']);
}
$entries[]
- = [
- 'title' => $title,
- 'route' =>
- route('transactions.index', [$transactionType, $currentDate['start']->format('Y-m-d'), $currentDate['end']->format('Y-m-d')]),
- 'total_transactions' => count($spent) + count($earned) + count($transferred),
- 'spent' => $this->groupByCurrency($spent),
- 'earned' => $this->groupByCurrency($earned),
- 'transferred' => $this->groupByCurrency($transferred),
- ];
+ = [
+ 'title' => $title,
+ 'route' => route('transactions.index', [$transactionType, $currentDate['start']->format('Y-m-d'), $currentDate['end']->format('Y-m-d')]),
+ 'total_transactions' => count($spent) + count($earned) + count($transferred),
+ 'spent' => $this->groupByCurrency($spent),
+ 'earned' => $this->groupByCurrency($earned),
+ 'transferred' => $this->groupByCurrency($transferred),
+ ];
}
return $entries;
diff --git a/app/Support/Http/Controllers/RenderPartialViews.php b/app/Support/Http/Controllers/RenderPartialViews.php
index c68c358255..d03ecb2835 100644
--- a/app/Support/Http/Controllers/RenderPartialViews.php
+++ b/app/Support/Http/Controllers/RenderPartialViews.php
@@ -36,42 +36,41 @@ use FireflyIII\Repositories\Budget\BudgetRepositoryInterface;
use FireflyIII\Repositories\Category\CategoryRepositoryInterface;
use FireflyIII\Repositories\Tag\TagRepositoryInterface;
use FireflyIII\Support\Search\OperatorQuerySearch;
-use Illuminate\Support\Facades\Log;
-use Throwable;
/**
* Trait RenderPartialViews
- *
*/
trait RenderPartialViews
{
/**
* View for transactions in a budget for an account.
*
- * @param array $attributes
- *
- * @return string
* @throws FireflyException
*/
protected function budgetEntry(array $attributes): string // generate view for report.
{
/** @var PopupReportInterface $popupHelper */
- $popupHelper = app(PopupReportInterface::class);
+ $popupHelper = app(PopupReportInterface::class);
/** @var BudgetRepositoryInterface $budgetRepository */
$budgetRepository = app(BudgetRepositoryInterface::class);
$budget = $budgetRepository->find((int)$attributes['budgetId']);
- $accountRepos = app(AccountRepositoryInterface::class);
- $account = $accountRepos->find((int)$attributes['accountId']);
+ $accountRepos = app(AccountRepositoryInterface::class);
+ $account = $accountRepos->find((int)$attributes['accountId']);
- $journals = $popupHelper->balanceForBudget($budget, $account, $attributes);
+ if (null === $budget || null === $account) {
+ throw new FireflyException('Could not render popup.report.balance-amount because budget or account is null.');
+ }
+
+ $journals = $popupHelper->balanceForBudget($budget, $account, $attributes);
try {
$view = view('popup.report.balance-amount', compact('journals', 'budget', 'account'))->render();
- } catch (Throwable $e) {
- Log::error(sprintf('Could not render: %s', $e->getMessage()));
+ } catch (\Throwable $e) {
+ app('log')->error(sprintf('Could not render: %s', $e->getMessage()));
$view = 'Firefly III could not render the view. Please see the log files.';
+
throw new FireflyException($view, 0, $e);
}
@@ -81,7 +80,6 @@ trait RenderPartialViews
/**
* Get options for budget report.
*
- * @return string
* @throws FireflyException
*/
protected function budgetReportOptions(): string // render a view
@@ -92,9 +90,10 @@ trait RenderPartialViews
try {
$result = view('reports.options.budget', compact('budgets'))->render();
- } catch (Throwable $e) {
- Log::error(sprintf('Cannot render reports.options.tag: %s', $e->getMessage()));
+ } catch (\Throwable $e) {
+ app('log')->error(sprintf('Cannot render reports.options.tag: %s', $e->getMessage()));
$result = 'Could not render view.';
+
throw new FireflyException($result, 0, $e);
}
@@ -104,9 +103,6 @@ trait RenderPartialViews
/**
* View for spent in a single budget.
*
- * @param array $attributes
- *
- * @return string
* @throws FireflyException
*/
protected function budgetSpentAmount(array $attributes): string // generate view for report.
@@ -115,19 +111,20 @@ trait RenderPartialViews
$budgetRepository = app(BudgetRepositoryInterface::class);
/** @var PopupReportInterface $popupHelper */
- $popupHelper = app(PopupReportInterface::class);
+ $popupHelper = app(PopupReportInterface::class);
- $budget = $budgetRepository->find((int)$attributes['budgetId']);
+ $budget = $budgetRepository->find((int)$attributes['budgetId']);
if (null === $budget) {
$budget = new Budget();
}
- $journals = $popupHelper->byBudget($budget, $attributes);
+ $journals = $popupHelper->byBudget($budget, $attributes);
try {
$view = view('popup.report.budget-spent-amount', compact('journals', 'budget'))->render();
- } catch (Throwable $e) {
- Log::error(sprintf('Could not render: %s', $e->getMessage()));
+ } catch (\Throwable $e) {
+ app('log')->error(sprintf('Could not render: %s', $e->getMessage()));
$view = 'Firefly III could not render the view. Please see the log files.';
+
throw new FireflyException($view, 0, $e);
}
@@ -137,15 +134,12 @@ trait RenderPartialViews
/**
* View for transactions in a category.
*
- * @param array $attributes
- *
- * @return string
* @throws FireflyException
*/
protected function categoryEntry(array $attributes): string // generate view for report.
{
/** @var PopupReportInterface $popupHelper */
- $popupHelper = app(PopupReportInterface::class);
+ $popupHelper = app(PopupReportInterface::class);
/** @var CategoryRepositoryInterface $categoryRepository */
$categoryRepository = app(CategoryRepositoryInterface::class);
@@ -154,9 +148,10 @@ trait RenderPartialViews
try {
$view = view('popup.report.category-entry', compact('journals', 'category'))->render();
- } catch (Throwable $e) {
- Log::error(sprintf('Could not render: %s', $e->getMessage()));
+ } catch (\Throwable $e) {
+ app('log')->error(sprintf('Could not render: %s', $e->getMessage()));
$view = 'Firefly III could not render the view. Please see the log files.';
+
throw new FireflyException($view, 0, $e);
}
@@ -166,7 +161,6 @@ trait RenderPartialViews
/**
* Get options for category report.
*
- * @return string
* @throws FireflyException
*/
protected function categoryReportOptions(): string // render a view
@@ -177,9 +171,10 @@ trait RenderPartialViews
try {
$result = view('reports.options.category', compact('categories'))->render();
- } catch (Throwable $e) {
- Log::error(sprintf('Cannot render reports.options.category: %s', $e->getMessage()));
+ } catch (\Throwable $e) {
+ app('log')->error(sprintf('Cannot render reports.options.category: %s', $e->getMessage()));
$result = 'Could not render view.';
+
throw new FireflyException($result, 0, $e);
}
@@ -189,7 +184,6 @@ trait RenderPartialViews
/**
* Get options for double report.
*
- * @return string
* @throws FireflyException
*/
protected function doubleReportOptions(): string // render a view
@@ -217,12 +211,12 @@ trait RenderPartialViews
}
}
-
try {
$result = view('reports.options.double', compact('set'))->render();
- } catch (Throwable $e) {
- Log::error(sprintf('Cannot render reports.options.tag: %s', $e->getMessage()));
+ } catch (\Throwable $e) {
+ app('log')->error(sprintf('Cannot render reports.options.tag: %s', $e->getMessage()));
$result = 'Could not render view.';
+
throw new FireflyException($result, 0, $e);
}
@@ -232,9 +226,6 @@ trait RenderPartialViews
/**
* Returns all the expenses that went to the given expense account.
*
- * @param array $attributes
- *
- * @return string
* @throws FireflyException
*/
protected function expenseEntry(array $attributes): string // generate view for report.
@@ -243,21 +234,22 @@ trait RenderPartialViews
$accountRepository = app(AccountRepositoryInterface::class);
/** @var PopupReportInterface $popupHelper */
- $popupHelper = app(PopupReportInterface::class);
+ $popupHelper = app(PopupReportInterface::class);
- $account = $accountRepository->find((int)$attributes['accountId']);
+ $account = $accountRepository->find((int)$attributes['accountId']);
if (null === $account) {
return 'This is an unknown account. Apologies.';
}
- $journals = $popupHelper->byExpenses($account, $attributes);
+ $journals = $popupHelper->byExpenses($account, $attributes);
try {
$view = view('popup.report.expense-entry', compact('journals', 'account'))->render();
- } catch (Throwable $e) {
- Log::error(sprintf('Could not render: %s', $e->getMessage()));
+ } catch (\Throwable $e) {
+ app('log')->error(sprintf('Could not render: %s', $e->getMessage()));
$view = 'Firefly III could not render the view. Please see the log files.';
+
throw new FireflyException($view, 0, $e);
}
@@ -267,20 +259,19 @@ trait RenderPartialViews
/**
* Get current (from system) rule actions.
*
- * @param Rule $rule
- *
- * @return array
* @throws FireflyException
*/
protected function getCurrentActions(Rule $rule): array // get info from object and present.
{
- $index = 0;
- $actions = [];
+ $index = 0;
+ $actions = [];
// must be repos
$currentActions = $rule->ruleActions()->orderBy('order', 'ASC')->get();
+
/** @var RuleAction $entry */
foreach ($currentActions as $entry) {
$count = ($index + 1);
+
try {
$actions[] = view(
'rules.partials.action',
@@ -291,9 +282,10 @@ trait RenderPartialViews
'count' => $count,
]
)->render();
- } catch (Throwable $e) {
- Log::debug(sprintf('Throwable was thrown in getCurrentActions(): %s', $e->getMessage()));
- Log::error($e->getTraceAsString());
+ } catch (\Throwable $e) {
+ app('log')->debug(sprintf('Throwable was thrown in getCurrentActions(): %s', $e->getMessage()));
+ app('log')->error($e->getTraceAsString());
+
throw new FireflyException(sprintf('Could not render: %s', $e->getMessage()), 0, $e);
}
@@ -306,16 +298,13 @@ trait RenderPartialViews
/**
* Get current (from DB) rule triggers.
*
- * @param Rule $rule
- *
- * @return array
* @throws FireflyException
*/
protected function getCurrentTriggers(Rule $rule): array // get info from object and present.
{
// TODO duplicated code.
- $operators = config('search.operators');
- $triggers = [];
+ $operators = config('search.operators');
+ $triggers = [];
foreach ($operators as $key => $operator) {
if ('user_action' !== $key && false === $operator['alias']) {
$triggers[$key] = (string)trans(sprintf('firefly.rule_trigger_%s_choice', $key));
@@ -326,12 +315,14 @@ trait RenderPartialViews
$renderedEntries = [];
// must be repos
$currentTriggers = $rule->ruleTriggers()->orderBy('order', 'ASC')->get();
+
/** @var RuleTrigger $entry */
foreach ($currentTriggers as $entry) {
if ('user_action' !== $entry->trigger_type) {
$count = ($index + 1);
+
try {
- $rootOperator = OperatorQuerySearch::getRootOperator($entry->trigger_type);
+ $rootOperator = OperatorQuerySearch::getRootOperator((string)$entry->trigger_type);
if (str_starts_with($rootOperator, '-')) {
$rootOperator = substr($rootOperator, 1);
}
@@ -341,14 +332,15 @@ trait RenderPartialViews
'oldTrigger' => $rootOperator,
'oldValue' => $entry->trigger_value,
'oldChecked' => $entry->stop_processing,
- 'oldProhibited' => str_starts_with($entry->trigger_type, '-'),
+ 'oldProhibited' => str_starts_with((string)$entry->trigger_type, '-'),
'count' => $count,
'triggers' => $triggers,
]
)->render();
- } catch (Throwable $e) {
- Log::debug(sprintf('Throwable was thrown in getCurrentTriggers(): %s', $e->getMessage()));
- Log::error($e->getTraceAsString());
+ } catch (\Throwable $e) {
+ app('log')->debug(sprintf('Throwable was thrown in getCurrentTriggers(): %s', $e->getMessage()));
+ app('log')->error($e->getTraceAsString());
+
throw new FireflyException(sprintf('Could not render: %s', $e->getMessage()), 0, $e);
}
@@ -362,9 +354,6 @@ trait RenderPartialViews
/**
* Returns all the incomes that went to the given asset account.
*
- * @param array $attributes
- *
- * @return string
* @throws FireflyException
*/
protected function incomeEntry(array $attributes): string // generate view for report.
@@ -373,20 +362,21 @@ trait RenderPartialViews
$accountRepository = app(AccountRepositoryInterface::class);
/** @var PopupReportInterface $popupHelper */
- $popupHelper = app(PopupReportInterface::class);
- $account = $accountRepository->find((int)$attributes['accountId']);
+ $popupHelper = app(PopupReportInterface::class);
+ $account = $accountRepository->find((int)$attributes['accountId']);
if (null === $account) {
return 'This is an unknown category. Apologies.';
}
- $journals = $popupHelper->byIncome($account, $attributes);
+ $journals = $popupHelper->byIncome($account, $attributes);
try {
$view = view('popup.report.income-entry', compact('journals', 'account'))->render();
- } catch (Throwable $e) {
- Log::error(sprintf('Could not render: %s', $e->getMessage()));
+ } catch (\Throwable $e) {
+ app('log')->error(sprintf('Could not render: %s', $e->getMessage()));
$view = 'Firefly III could not render the view. Please see the log files.';
+
throw new FireflyException($view, 0, $e);
}
@@ -396,16 +386,16 @@ trait RenderPartialViews
/**
* Get options for default report.
*
- * @return string
* @throws FireflyException
*/
protected function noReportOptions(): string // render a view
{
try {
$result = view('reports.options.no-options')->render();
- } catch (Throwable $e) {
- Log::error(sprintf('Cannot render reports.options.no-options: %s', $e->getMessage()));
+ } catch (\Throwable $e) {
+ app('log')->error(sprintf('Cannot render reports.options.no-options: %s', $e->getMessage()));
$result = 'Could not render view.';
+
throw new FireflyException($result, 0, $e);
}
@@ -415,7 +405,6 @@ trait RenderPartialViews
/**
* Get options for tag report.
*
- * @return string
* @throws FireflyException
*/
protected function tagReportOptions(): string // render a view
@@ -424,12 +413,12 @@ trait RenderPartialViews
$repository = app(TagRepositoryInterface::class);
$tags = $repository->get();
-
try {
$result = view('reports.options.tag', compact('tags'))->render();
- } catch (Throwable $e) {
- Log::error(sprintf('Cannot render reports.options.tag: %s', $e->getMessage()));
+ } catch (\Throwable $e) {
+ app('log')->error(sprintf('Cannot render reports.options.tag: %s', $e->getMessage()));
$result = 'Could not render view.';
+
throw new FireflyException($result, 0, $e);
}
diff --git a/app/Support/Http/Controllers/RequestInformation.php b/app/Support/Http/Controllers/RequestInformation.php
index 28780e340f..96fdcd2ef7 100644
--- a/app/Support/Http/Controllers/RequestInformation.php
+++ b/app/Support/Http/Controllers/RequestInformation.php
@@ -25,46 +25,33 @@ namespace FireflyIII\Support\Http\Controllers;
use Carbon\Carbon;
use FireflyIII\Exceptions\ValidationException;
-use FireflyIII\Helpers\Help\HelpInterface;
use FireflyIII\Http\Requests\RuleFormRequest;
use FireflyIII\Http\Requests\TestRuleFormRequest;
use FireflyIII\Support\Binder\AccountList;
use FireflyIII\User;
-use Hash;
use Illuminate\Contracts\Validation\Validator as ValidatorContract;
use Illuminate\Routing\Route;
-use Illuminate\Support\Facades\Log;
use Illuminate\Support\Facades\Validator;
-use InvalidArgumentException;
-use Psr\Container\ContainerExceptionInterface;
-use Psr\Container\NotFoundExceptionInterface;
use Route as RouteFacade;
/**
* Trait RequestInformation
- *
*/
trait RequestInformation
{
/**
* Get the domain of FF system.
- *
- * @return string
*/
final protected function getDomain(): string // get request info
{
$url = url()->to('/');
$parts = parse_url($url);
- return $parts['host'];
+ return $parts['host'] ?? '';
}
/**
* Get a list of triggers.
- *
- * @param TestRuleFormRequest $request
- *
- * @return array
*/
final protected function getValidTriggerList(TestRuleFormRequest $request): array // process input
{
@@ -82,28 +69,25 @@ trait RequestInformation
$triggers[] = $current;
}
}
+
return $triggers;
}
/**
* Returns if user has seen demo.
- *
- * @return bool
- * @throws ContainerExceptionInterface
- * @throws NotFoundExceptionInterface
*/
final protected function hasSeenDemo(): bool // get request info + get preference
{
$page = $this->getPageName();
$specificPage = $this->getSpecificPageName();
// indicator if user has seen the help for this page ( + special page):
- $key = sprintf('shown_demo_%s%s', $page, $specificPage);
+ $key = sprintf('shown_demo_%s%s', $page, $specificPage);
// is there an intro for this route?
$intro = config(sprintf('intro.%s', $page)) ?? [];
$specialIntro = config(sprintf('intro.%s%s', $page, $specificPage)) ?? [];
// some routes have a "what" parameter, which indicates a special page:
- $shownDemo = true;
+ $shownDemo = true;
// both must be array and either must be > 0
if (count($intro) > 0 || count($specialIntro) > 0) {
$shownDemo = app('preferences')->get($key, false)->data;
@@ -115,9 +99,6 @@ trait RequestInformation
return $shownDemo;
}
- /**
- * @return string
- */
final protected function getPageName(): string // get request info
{
return str_replace('.', '_', RouteFacade::currentRouteName());
@@ -125,26 +106,23 @@ trait RequestInformation
/**
* Get the specific name of a page for intro.
- *
- * @return string
*/
final protected function getSpecificPageName(): string // get request info
{
- return null === RouteFacade::current()->parameter('objectType') ? '' : '_' . RouteFacade::current()->parameter('objectType');
+ /** @var null|string $param */
+ $param = RouteFacade::current()->parameter('objectType');
+
+ return null === $param ? '' : sprintf('_%s', $param);
}
/**
* Check if date is outside session range.
- *
- * @param Carbon $date
- *
- * @return bool
- *
*/
final protected function notInSessionRange(Carbon $date): bool // Validate a preference
{
/** @var Carbon $start */
- $start = session('start', today(config('app.timezone'))->startOfMonth());
+ $start = session('start', today(config('app.timezone'))->startOfMonth());
+
/** @var Carbon $end */
$end = session('end', today(config('app.timezone'))->endOfMonth());
$result = false;
@@ -161,30 +139,24 @@ trait RequestInformation
/**
* Parses attributes from URL
- *
- * @param array $attributes
- *
- * @return array
*/
final protected function parseAttributes(array $attributes): array // parse input + return result
{
- $attributes['location'] = $attributes['location'] ?? '';
- $attributes['accounts'] = AccountList::routeBinder($attributes['accounts'] ?? '', new Route('get', '', []));
- try {
- $attributes['startDate'] = Carbon::createFromFormat('Ymd', $attributes['startDate'])->startOfDay();
- } catch (InvalidArgumentException $e) {
- Log::debug(sprintf('Not important error message: %s', $e->getMessage()));
- $date = today(config('app.timezone'))->startOfMonth();
- $attributes['startDate'] = $date;
+ $attributes['location'] ??= '';
+ $attributes['accounts'] = AccountList::routeBinder($attributes['accounts'] ?? '', new Route('get', '', []));
+ $date = Carbon::createFromFormat('Ymd', $attributes['startDate']);
+ if (false === $date) {
+ $date = today(config('app.timezone'));
}
+ $date->startOfMonth();
+ $attributes['startDate'] = $date;
- try {
- $attributes['endDate'] = Carbon::createFromFormat('Ymd', $attributes['endDate'])->endOfDay();
- } catch (InvalidArgumentException $e) {
- Log::debug(sprintf('Not important error message: %s', $e->getMessage()));
- $date = today(config('app.timezone'))->startOfMonth();
- $attributes['endDate'] = $date;
+ $date2 = Carbon::createFromFormat('Ymd', $attributes['endDate']);
+ if (false === $date2) {
+ $date2 = today(config('app.timezone'));
}
+ $date2->endOfDay();
+ $attributes['endDate'] = $date2;
return $attributes;
}
@@ -192,17 +164,11 @@ trait RequestInformation
/**
* Validate users new password.
*
- * @param User $user
- * @param string $current
- * @param string $new
- *
- * @return bool
- *
* @throws ValidationException
*/
- final protected function validatePassword(User $user, string $current, string $new): bool //get request info
+ final protected function validatePassword(User $user, string $current, string $new): bool // get request info
{
- if (!Hash::check($current, $user->password)) {
+ if (!\Hash::check($current, $user->password)) {
throw new ValidationException((string)trans('firefly.invalid_current_password'));
}
@@ -215,10 +181,6 @@ trait RequestInformation
/**
* Get a validator for an incoming registration request.
- *
- * @param array $data
- *
- * @return ValidatorContract
*/
final protected function validator(array $data): ValidatorContract
{
diff --git a/app/Support/Http/Controllers/RuleManagement.php b/app/Support/Http/Controllers/RuleManagement.php
index 874829cc6d..8a6b527bfd 100644
--- a/app/Support/Http/Controllers/RuleManagement.php
+++ b/app/Support/Http/Controllers/RuleManagement.php
@@ -27,19 +27,13 @@ use FireflyIII\Exceptions\FireflyException;
use FireflyIII\Repositories\RuleGroup\RuleGroupRepositoryInterface;
use FireflyIII\Support\Search\OperatorQuerySearch;
use Illuminate\Http\Request;
-use Illuminate\Support\Facades\Log;
-use Throwable;
/**
* Trait RuleManagement
- *
*/
trait RuleManagement
{
/**
- * @param Request $request
- *
- * @return array
* @throws FireflyException
*/
protected function getPreviousActions(Request $request): array
@@ -59,12 +53,13 @@ trait RuleManagement
'count' => $index + 1,
]
)->render();
- } catch (Throwable $e) {
- Log::error(sprintf('Throwable was thrown in getPreviousActions(): %s', $e->getMessage()));
- Log::error($e->getTraceAsString());
+ } catch (\Throwable $e) {
+ app('log')->error(sprintf('Throwable was thrown in getPreviousActions(): %s', $e->getMessage()));
+ app('log')->error($e->getTraceAsString());
+
throw new FireflyException(sprintf('Could not render: %s', $e->getMessage()), 0, $e);
}
- $index++;
+ ++$index;
}
}
@@ -72,16 +67,13 @@ trait RuleManagement
}
/**
- * @param Request $request
- *
- * @return array
* @throws FireflyException
*/
protected function getPreviousTriggers(Request $request): array
{
// TODO duplicated code.
- $operators = config('search.operators');
- $triggers = [];
+ $operators = config('search.operators');
+ $triggers = [];
foreach ($operators as $key => $operator) {
if ('user_action' !== $key && false === $operator['alias']) {
$triggers[$key] = (string)trans(sprintf('firefly.rule_trigger_%s_choice', $key));
@@ -99,19 +91,20 @@ trait RuleManagement
'rules.partials.trigger',
[
'oldTrigger' => OperatorQuerySearch::getRootOperator($oldTrigger['type']),
- 'oldValue' => $oldTrigger['value'],
+ 'oldValue' => $oldTrigger['value'] ?? '',
'oldChecked' => 1 === (int)($oldTrigger['stop_processing'] ?? '0'),
'oldProhibited' => 1 === (int)($oldTrigger['prohibited'] ?? '0'),
'count' => $index + 1,
'triggers' => $triggers,
]
)->render();
- } catch (Throwable $e) {
- Log::debug(sprintf('Throwable was thrown in getPreviousTriggers(): %s', $e->getMessage()));
- Log::error($e->getTraceAsString());
+ } catch (\Throwable $e) {
+ app('log')->debug(sprintf('Throwable was thrown in getPreviousTriggers(): %s', $e->getMessage()));
+ app('log')->error($e->getTraceAsString());
+
throw new FireflyException(sprintf('Could not render: %s', $e->getMessage()), 0, $e);
}
- $index++;
+ ++$index;
}
}
@@ -119,9 +112,6 @@ trait RuleManagement
}
/**
- * @param array $submittedOperators
- *
- * @return array
* @throws FireflyException
*/
protected function parseFromOperators(array $submittedOperators): array
@@ -137,34 +127,35 @@ trait RuleManagement
}
asort($triggers);
- $index = 0;
+ $index = 0;
foreach ($submittedOperators as $operator) {
+ $rootOperator = OperatorQuerySearch::getRootOperator($operator['type']);
+ $needsContext = (bool)config(sprintf('search.operators.%s.needs_context', $rootOperator));
+
try {
$renderedEntries[] = view(
'rules.partials.trigger',
[
- 'oldTrigger' => OperatorQuerySearch::getRootOperator($operator['type']),
- 'oldValue' => $operator['value'],
+ 'oldTrigger' => $rootOperator,
+ 'oldValue' => $needsContext ? $operator['value'] : '',
'oldChecked' => false,
'oldProhibited' => $operator['prohibited'] ?? false,
'count' => $index + 1,
'triggers' => $triggers,
]
)->render();
- } catch (Throwable $e) {
- Log::debug(sprintf('Throwable was thrown in getPreviousTriggers(): %s', $e->getMessage()));
- Log::error($e->getTraceAsString());
+ } catch (\Throwable $e) {
+ app('log')->debug(sprintf('Throwable was thrown in getPreviousTriggers(): %s', $e->getMessage()));
+ app('log')->error($e->getTraceAsString());
+
throw new FireflyException(sprintf('Could not render: %s', $e->getMessage()), 0, $e);
}
- $index++;
+ ++$index;
}
return $renderedEntries;
}
- /**
- *
- */
private function createDefaultRuleGroup(): void
{
/** @var RuleGroupRepositoryInterface $repository */
diff --git a/app/Support/Http/Controllers/TransactionCalculation.php b/app/Support/Http/Controllers/TransactionCalculation.php
index c17c26a7a5..db847dad41 100644
--- a/app/Support/Http/Controllers/TransactionCalculation.php
+++ b/app/Support/Http/Controllers/TransactionCalculation.php
@@ -30,44 +30,29 @@ use Illuminate\Support\Collection;
/**
* Trait TransactionCalculation
- *
*/
trait TransactionCalculation
{
/**
* Get all expenses for a set of accounts.
- *
- * @param Collection $accounts
- * @param Collection $opposing
- * @param Carbon $start
- * @param Carbon $end
- *
- * @return array
*/
protected function getExpensesForOpposing(Collection $accounts, Collection $opposing, Carbon $start, Carbon $end): array
{
- $total = $accounts->merge($opposing);
+ $total = $accounts->merge($opposing);
/** @var GroupCollectorInterface $collector */
$collector = app(GroupCollectorInterface::class);
$collector->setAccounts($total)
- ->setRange($start, $end)
- ->withAccountInformation()
- ->setTypes([TransactionType::WITHDRAWAL]);
+ ->setRange($start, $end)
+ ->withAccountInformation()
+ ->setTypes([TransactionType::WITHDRAWAL])
+ ;
return $collector->getExtractedJournals();
}
/**
* Get all expenses by tags.
- *
- * @param Collection $accounts
- * @param Collection $tags
- * @param Carbon $start
- * @param Carbon $end
- *
- * @return array
- *
*/
protected function getExpensesForTags(Collection $accounts, Collection $tags, Carbon $start, Carbon $end): array
{
@@ -75,40 +60,28 @@ trait TransactionCalculation
$collector = app(GroupCollectorInterface::class);
$collector->setAccounts($accounts)->setRange($start, $end)->setTypes([TransactionType::WITHDRAWAL, TransactionType::TRANSFER])
- ->setTags($tags)->withAccountInformation();
+ ->setTags($tags)->withAccountInformation()
+ ;
return $collector->getExtractedJournals();
}
/**
* Helper function that collects expenses for the given budgets.
- *
- * @param Collection $accounts
- * @param Collection $budgets
- * @param Carbon $start
- * @param Carbon $end
- *
- * @return array
*/
protected function getExpensesInBudgets(Collection $accounts, Collection $budgets, Carbon $start, Carbon $end): array
{
/** @var GroupCollectorInterface $collector */
$collector = app(GroupCollectorInterface::class);
$collector->setAccounts($accounts)->setRange($start, $end)->setTypes([TransactionType::WITHDRAWAL, TransactionType::TRANSFER])
- ->setBudgets($budgets)->withAccountInformation();
+ ->setBudgets($budgets)->withAccountInformation()
+ ;
return $collector->getExtractedJournals();
}
/**
* Get all expenses in a period for categories.
- *
- * @param Collection $accounts
- * @param Collection $categories
- * @param Carbon $start
- * @param Carbon $end
- *
- * @return array
*/
protected function getExpensesInCategories(Collection $accounts, Collection $categories, Carbon $start, Carbon $end): array
{
@@ -119,44 +92,33 @@ trait TransactionCalculation
->setRange($start, $end)
->setTypes([TransactionType::WITHDRAWAL, TransactionType::TRANSFER])
->setCategories($categories)
- ->withAccountInformation();
+ ->withAccountInformation()
+ ;
return $collector->getExtractedJournals();
}
/**
* Get all income for a period and a bunch of categories.
- *
- * @param Collection $accounts
- * @param Collection $categories
- * @param Carbon $start
- * @param Carbon $end
- *
- * @return array
*/
protected function getIncomeForCategories(Collection $accounts, Collection $categories, Carbon $start, Carbon $end): array
{
/** @var GroupCollectorInterface $collector */
$collector = app(GroupCollectorInterface::class);
$collector->setAccounts($accounts)->setRange($start, $end)->setTypes([TransactionType::DEPOSIT, TransactionType::TRANSFER])
- ->setCategories($categories)->withAccountInformation();
+ ->setCategories($categories)->withAccountInformation()
+ ;
return $collector->getExtractedJournals();
}
/**
* Get the income for a set of accounts.
- *
- * @param Collection $accounts
- * @param Collection $opposing
- * @param Carbon $start
- * @param Carbon $end
- *
- * @return array
*/
protected function getIncomeForOpposing(Collection $accounts, Collection $opposing, Carbon $start, Carbon $end): array
{
- $total = $accounts->merge($opposing);
+ $total = $accounts->merge($opposing);
+
/** @var GroupCollectorInterface $collector */
$collector = app(GroupCollectorInterface::class);
$collector->setAccounts($total)->setRange($start, $end)->withAccountInformation()->setTypes([TransactionType::DEPOSIT]);
@@ -166,20 +128,14 @@ trait TransactionCalculation
/**
* Get all income by tag.
- *
- * @param Collection $accounts
- * @param Collection $tags
- * @param Carbon $start
- * @param Carbon $end
- *
- * @return array
*/
protected function getIncomeForTags(Collection $accounts, Collection $tags, Carbon $start, Carbon $end): array
{
/** @var GroupCollectorInterface $collector */
$collector = app(GroupCollectorInterface::class);
$collector->setAccounts($accounts)->setRange($start, $end)->setTypes([TransactionType::DEPOSIT, TransactionType::TRANSFER])
- ->setTags($tags)->withAccountInformation();
+ ->setTags($tags)->withAccountInformation()
+ ;
return $collector->getExtractedJournals();
}
diff --git a/app/Support/Http/Controllers/UserNavigation.php b/app/Support/Http/Controllers/UserNavigation.php
index 6fffe00a08..22065bb0c0 100644
--- a/app/Support/Http/Controllers/UserNavigation.php
+++ b/app/Support/Http/Controllers/UserNavigation.php
@@ -31,11 +31,9 @@ use FireflyIII\Models\TransactionJournal;
use FireflyIII\Models\TransactionType;
use Illuminate\Http\RedirectResponse;
use Illuminate\Routing\Redirector;
-use Illuminate\Support\Facades\Log;
/**
* Trait UserNavigation
- *
*/
trait UserNavigation
{
@@ -46,26 +44,18 @@ trait UserNavigation
* returned but instead the index (/) will be returned.
* - If the remembered url contains "jscript/" the remembered url will not be returned but instead the index (/)
* will be returned.
- *
- * @param string $identifier
- *
- * @return string
*/
final protected function getPreviousUrl(string $identifier): string
{
- Log::debug(sprintf('Trying to retrieve URL stored under "%s"', $identifier));
+ app('log')->debug(sprintf('Trying to retrieve URL stored under "%s"', $identifier));
$url = (string)session($identifier);
- Log::debug(sprintf('The URL is %s', $url));
+ app('log')->debug(sprintf('The URL is %s', $url));
return app('steam')->getSafeUrl($url, route('index'));
}
/**
* Will return false if you cant edit this account type.
- *
- * @param Account $account
- *
- * @return bool
*/
final protected function isEditableAccount(Account $account): bool
{
@@ -75,15 +65,10 @@ trait UserNavigation
return in_array($type, $editable, true);
}
- /**
- * @param TransactionGroup $group
- *
- * @return bool
- */
final protected function isEditableGroup(TransactionGroup $group): bool
{
- /** @var TransactionJournal|null $journal */
- $journal = $group->transactionJournals()->first();
+ /** @var null|TransactionJournal $journal */
+ $journal = $group->transactionJournals()->first();
if (null === $journal) {
return false;
}
@@ -94,9 +79,7 @@ trait UserNavigation
}
/**
- * @param Account $account
- *
- * @return RedirectResponse|Redirector
+ * @return Redirector|RedirectResponse
*/
final protected function redirectAccountToAccount(Account $account)
{
@@ -104,19 +87,20 @@ trait UserNavigation
if (AccountType::RECONCILIATION === $type || AccountType::INITIAL_BALANCE === $type || AccountType::LIABILITY_CREDIT === $type) {
// reconciliation must be stored somewhere in this account's transactions.
- /** @var Transaction|null $transaction */
+ /** @var null|Transaction $transaction */
$transaction = $account->transactions()->first();
if (null === $transaction) {
- Log::error(sprintf('Account #%d has no transactions. Dont know where it belongs.', $account->id));
+ app('log')->error(sprintf('Account #%d has no transactions. Dont know where it belongs.', $account->id));
session()->flash('error', trans('firefly.cant_find_redirect_account'));
return redirect(route('index'));
}
- $journal = $transaction->transactionJournal;
- /** @var Transaction|null $other */
- $other = $journal->transactions()->where('id', '!=', $transaction->id)->first();
+ $journal = $transaction->transactionJournal;
+
+ /** @var null|Transaction $other */
+ $other = $journal->transactions()->where('id', '!=', $transaction->id)->first();
if (null === $other) {
- Log::error(sprintf('Account #%d has no valid journals. Dont know where it belongs.', $account->id));
+ app('log')->error(sprintf('Account #%d has no valid journals. Dont know where it belongs.', $account->id));
session()->flash('error', trans('firefly.cant_find_redirect_account'));
return redirect(route('index'));
@@ -129,22 +113,21 @@ trait UserNavigation
}
/**
- * @param TransactionGroup $group
- *
- * @return RedirectResponse|Redirector
+ * @return Redirector|RedirectResponse
*/
final protected function redirectGroupToAccount(TransactionGroup $group)
{
- /** @var TransactionJournal|null $journal */
- $journal = $group->transactionJournals()->first();
+ /** @var null|TransactionJournal $journal */
+ $journal = $group->transactionJournals()->first();
if (null === $journal) {
- Log::error(sprintf('No journals in group #%d', $group->id));
+ app('log')->error(sprintf('No journals in group #%d', $group->id));
return redirect(route('index'));
}
// prefer redirect to everything but expense and revenue:
$transactions = $journal->transactions;
$ignore = [AccountType::REVENUE, AccountType::EXPENSE, AccountType::RECONCILIATION, AccountType::INITIAL_BALANCE];
+
/** @var Transaction $transaction */
foreach ($transactions as $transaction) {
$type = $transaction->account->accountType->type;
@@ -156,17 +139,12 @@ trait UserNavigation
return redirect(route('index'));
}
- /**
- * @param string $identifier
- *
- * @return string|null
- */
final protected function rememberPreviousUrl(string $identifier): ?string
{
$return = app('steam')->getSafePreviousUrl();
session()->put($identifier, $return);
- Log::debug(sprintf('rememberPreviousUrl: %s: "%s"', $identifier, $return));
+ app('log')->debug(sprintf('rememberPreviousUrl: %s: "%s"', $identifier, $return));
return $return;
}
diff --git a/app/Support/Logging/AuditLogger.php b/app/Support/Logging/AuditLogger.php
index eeac766f53..56bd255554 100644
--- a/app/Support/Logging/AuditLogger.php
+++ b/app/Support/Logging/AuditLogger.php
@@ -30,24 +30,19 @@ use Monolog\Handler\AbstractProcessingHandler;
/**
* Class AuditLogger
- *
-
*/
class AuditLogger
{
/**
* Customize the given logger instance.
- *
- * @param Logger $logger
- *
- * @return void
*/
- public function __invoke(Logger $logger)
+ public function __invoke(Logger $logger): void
{
$processor = new AuditProcessor();
+
/** @var AbstractProcessingHandler $handler */
foreach ($logger->getHandlers() as $handler) {
- $formatter = new LineFormatter("[%datetime%] %channel%.%level_name%: %message% %context% %extra%\n");
+ $formatter = new LineFormatter("[%datetime%] %channel%.%level_name%: %message% %context% %extra%\n", 'Y-m-d H:i:s', false, true);
$handler->setFormatter($formatter);
$handler->pushProcessor($processor);
}
diff --git a/app/Support/Logging/AuditProcessor.php b/app/Support/Logging/AuditProcessor.php
index 8e64183298..5f8f823c13 100644
--- a/app/Support/Logging/AuditProcessor.php
+++ b/app/Support/Logging/AuditProcessor.php
@@ -28,33 +28,27 @@ use Monolog\LogRecord;
/**
* Class AuditProcessor
- *
-
*/
class AuditProcessor
{
- /**
- * @param LogRecord $record
- *
- * @return LogRecord
- */
public function __invoke(LogRecord $record): LogRecord
{
if (auth()->check()) {
$message = sprintf(
'AUDIT: %s (%s (%s) -> %s:%s)',
- $record['message'],
+ $record['message'], // @phpstan-ignore-line
app('request')->ip(),
auth()->user()->email,
request()->method(),
request()->url()
);
+
return new LogRecord($record->datetime, $record->channel, $record->level, $message, $record->context, $record->extra, $record->formatted);
}
$message = sprintf(
'AUDIT: %s (%s -> %s:%s)',
- $record['message'],
+ $record['message'], // @phpstan-ignore-line
app('request')->ip(),
request()->method(),
request()->url()
diff --git a/app/Support/Models/BillDateCalculator.php b/app/Support/Models/BillDateCalculator.php
new file mode 100644
index 0000000000..0be61d49aa
--- /dev/null
+++ b/app/Support/Models/BillDateCalculator.php
@@ -0,0 +1,160 @@
+.
+ */
+
+declare(strict_types=1);
+
+namespace FireflyIII\Support\Models;
+
+use Carbon\Carbon;
+use Illuminate\Support\Collection;
+use Illuminate\Support\Facades\Log;
+
+class BillDateCalculator
+{
+ // #8401 we start keeping track of the diff in periods, because if it can't jump over a period (happens often in February)
+ // we can force the process along.
+ private int $diffInMonths = 0;
+
+ /**
+ * Returns the dates a bill needs to be paid.
+ *
+ * @SuppressWarnings(PHPMD.ExcessiveParameterList)
+ */
+ public function getPayDates(Carbon $earliest, Carbon $latest, Carbon $billStart, string $period, int $skip, ?Carbon $lastPaid): array
+ {
+ $this->diffInMonths = 0;
+ $earliest->startOfDay();
+ $latest->endOfDay();
+ $billStart->startOfDay();
+ Log::debug('Now in BillDateCalculator::getPayDates()');
+ Log::debug(sprintf('Dates must be between %s and %s.', $earliest->format('Y-m-d'), $latest->format('Y-m-d')));
+ Log::debug(sprintf('Bill started on %s, period is "%s", skip is %d, last paid = "%s".', $billStart->format('Y-m-d'), $period, $skip, $lastPaid?->format('Y-m-d')));
+
+ $daysUntilEOM = app('navigation')->daysUntilEndOfMonth($billStart);
+ Log::debug(sprintf('For bill start, days until end of month is %d', $daysUntilEOM));
+
+ $set = new Collection();
+ $currentStart = clone $earliest;
+
+ // 2023-06-23 subDay to fix 7655
+ $currentStart->subDay();
+ $loop = 0;
+
+ Log::debug('Start of loop');
+ while ($currentStart <= $latest) {
+ Log::debug(sprintf('Current start is %s', $currentStart->format('Y-m-d')));
+ $nextExpectedMatch = $this->nextDateMatch(clone $currentStart, clone $billStart, $period, $skip);
+ Log::debug(sprintf('Next expected match is %s', $nextExpectedMatch->format('Y-m-d')));
+
+ // If nextExpectedMatch is after end, we stop looking:
+ if ($nextExpectedMatch->gt($latest)) {
+ Log::debug('Next expected match is after $latest.');
+ if ($set->count() > 0) {
+ Log::debug(sprintf('Already have %d date(s), so we can safely break.', $set->count()));
+
+ break;
+ }
+ Log::debug('Add date to set anyway, since we had no dates yet.');
+ $set->push(clone $nextExpectedMatch);
+
+ continue;
+ }
+
+ // add to set, if the date is ON or after the start parameter
+ // AND date is after last paid date
+ if (
+ $nextExpectedMatch->gte($earliest) // date is after "earliest possible date"
+ && (null === $lastPaid || $nextExpectedMatch->gt($lastPaid)) // date is after last paid date, if that date is not NULL
+ ) {
+ Log::debug('Add date to set, because it is after earliest possible date and after last paid date.');
+ $set->push(clone $nextExpectedMatch);
+ }
+
+ // #8401
+ // a little check for when the day of the bill (ie 30th of the month) is not possible in
+ // the next expected month because that month has only 28 days (i.e. february).
+ // this applies to leap years as well.
+ if ($daysUntilEOM < 4) {
+ $nextUntilEOM = app('navigation')->daysUntilEndOfMonth($nextExpectedMatch);
+ $diffEOM = $daysUntilEOM - $nextUntilEOM;
+ if ($diffEOM > 0) {
+ Log::debug(sprintf('Bill start is %d days from the end of the month. nextExceptedMatch is %d days from the end of the month.', $daysUntilEOM, $nextUntilEOM));
+ $nextExpectedMatch->subDays(1);
+ Log::debug(sprintf('Subtract %d days from next expected match, which is now %s', $diffEOM, $nextExpectedMatch->format('Y-m-d')));
+ }
+ }
+
+ // 2023-10
+ // for the next loop, go to end of period, THEN add day.
+ Log::debug('Add one day to nextExpectedMatch/currentStart.');
+ $nextExpectedMatch->addDay();
+ $currentStart = clone $nextExpectedMatch;
+
+ ++$loop;
+ if ($loop > 12) {
+ Log::debug('Loop is more than 12, so we break.');
+
+ break;
+ }
+ }
+ Log::debug('end of loop');
+ $simple = $set->map(
+ static function (Carbon $date) {
+ return $date->format('Y-m-d');
+ }
+ );
+ Log::debug(sprintf('Found %d pay dates', $set->count()), $simple->toArray());
+
+ return $simple->toArray();
+ }
+
+ /**
+ * Given a bill and a date, this method will tell you at which moment this bill expects its next
+ * transaction given the earliest date this could happen.
+ *
+ * That date must be AFTER $billStartDate, as a sanity check.
+ */
+ protected function nextDateMatch(Carbon $earliest, Carbon $billStartDate, string $period, int $skip): Carbon
+ {
+ Log::debug(sprintf('Bill start date is %s', $billStartDate->format('Y-m-d')));
+ if ($earliest->lt($billStartDate)) {
+ Log::debug('Earliest possible date is after bill start, so just return bill start date.');
+
+ return $billStartDate;
+ }
+
+ $steps = app('navigation')->diffInPeriods($period, $skip, $earliest, $billStartDate);
+ if ($steps === $this->diffInMonths) {
+ Log::debug(sprintf('Steps is %d, which is the same as diffInMonths (%d), so we add another 1.', $steps, $this->diffInMonths));
+ ++$steps;
+ }
+ $this->diffInMonths = $steps;
+ $result = clone $billStartDate;
+ if ($steps > 0) {
+ --$steps;
+ Log::debug(sprintf('Steps is %d, because addPeriod already adds 1.', $steps));
+ $result = app('navigation')->addPeriod($billStartDate, $period, $steps);
+ }
+ Log::debug(sprintf('Number of steps is %d, added to %s, result is %s', $steps, $billStartDate->format('Y-m-d'), $result->format('Y-m-d')));
+
+ return $result;
+ }
+}
diff --git a/frontend/src/api/rule-groups/get.js b/app/Support/Models/ReturnsIntegerIdTrait.php
similarity index 60%
rename from frontend/src/api/rule-groups/get.js
rename to app/Support/Models/ReturnsIntegerIdTrait.php
index b63ba19027..5d0d501b53 100644
--- a/frontend/src/api/rule-groups/get.js
+++ b/app/Support/Models/ReturnsIntegerIdTrait.php
@@ -1,6 +1,7 @@
+.
*/
-import {api} from "boot/axios";
+declare(strict_types=1);
-export default class Get {
- get(identifier, date) {
- let url = '/api/v1/rule_groups/' + identifier;
- if (!date) {
- return api.get(url);
+namespace FireflyIII\Support\Models;
+
+use Illuminate\Database\Eloquent\Casts\Attribute;
+
+/**
+ * Trait ReturnsIntegerIdTrait
+ */
+trait ReturnsIntegerIdTrait
+{
+ /**
+ * Get the ID
+ *
+ * @SuppressWarnings(PHPMD.ShortMethodName)
+ */
+ protected function id(): Attribute
+ {
+ return Attribute::make(
+ get: static fn ($value) => (int)$value,
+ );
}
- return api.get(url, {params: {date: date}});
- }
-
- rules(identifier, page, cacheKey) {
- let url = '/api/v1/rule_groups/' + identifier + '/rules';
- return api.get(url, {params: {page: page, cache: cacheKey}});
- }
}
diff --git a/frontend/src/stores/index.js b/app/Support/Models/ReturnsIntegerUserIdTrait.php
similarity index 55%
rename from frontend/src/stores/index.js
rename to app/Support/Models/ReturnsIntegerUserIdTrait.php
index 637bd95b24..77f1d8d18f 100644
--- a/frontend/src/stores/index.js
+++ b/app/Support/Models/ReturnsIntegerUserIdTrait.php
@@ -1,6 +1,7 @@
+.
*/
-import {store} from 'quasar/wrappers'
-import {createPinia} from 'pinia'
+declare(strict_types=1);
-/*
- * If not building with SSR mode, you can
- * directly export the Store instantiation;
- *
- * The function below can be async too; either use
- * async/await or return a Promise which resolves
- * with the Store instance.
+namespace FireflyIII\Support\Models;
+
+use Illuminate\Database\Eloquent\Casts\Attribute;
+
+/**
+ * Trait ReturnsIntegerUserIdTrait
*/
+trait ReturnsIntegerUserIdTrait
+{
+ /**
+ * Get the user group ID
+ */
+ protected function userGroupId(): Attribute
+ {
+ return Attribute::make(
+ get: static fn ($value) => (int)$value,
+ );
+ }
-export default store((/* { ssrContext } */) => {
- const pinia = createPinia()
-
- // You can add Pinia plugins here
- // pinia.use(SomePiniaPlugin)
-
- return pinia
-})
+ protected function userId(): Attribute
+ {
+ return Attribute::make(
+ get: static fn ($value) => (int)$value,
+ );
+ }
+}
diff --git a/app/Support/Navigation.php b/app/Support/Navigation.php
index 0cd95afc07..9eac3bebe9 100644
--- a/app/Support/Navigation.php
+++ b/app/Support/Navigation.php
@@ -25,14 +25,11 @@ namespace FireflyIII\Support;
use Carbon\Carbon;
use FireflyIII\Exceptions\FireflyException;
+use FireflyIII\Exceptions\IntervalException;
use FireflyIII\Helpers\Fiscal\FiscalHelperInterface;
use FireflyIII\Support\Calendar\Calculator;
-use FireflyIII\Support\Calendar\Exceptions\IntervalException;
use FireflyIII\Support\Calendar\Periodicity;
use Illuminate\Support\Facades\Log;
-use Psr\Container\ContainerExceptionInterface;
-use Psr\Container\NotFoundExceptionInterface;
-use Throwable;
/**
* Class Navigation.
@@ -41,23 +38,14 @@ class Navigation
{
private Calculator $calculator;
- /**
- * @param Calculator|null $calculator
- */
public function __construct(Calculator $calculator = null)
{
- $this->calculator = ($calculator instanceof Calculator) ?: new Calculator();
+ $this->calculator = $calculator instanceof Calculator ? $calculator : new Calculator();
}
- /**
- * @param Carbon $theDate
- * @param string $repeatFreq
- * @param int $skip
- *
- * @return Carbon
- */
public function addPeriod(Carbon $theDate, string $repeatFreq, int $skip = 0): Carbon
{
+ $date = clone $theDate;
$functionMap = [
'1D' => Periodicity::Daily,
'daily' => Periodicity::Daily,
@@ -90,28 +78,22 @@ class Navigation
Log::error(sprintf(
'The periodicity %s is unknown. Choose one of available periodicity: %s',
$repeatFreq,
- join(', ', array_keys($functionMap))
+ implode(', ', array_keys($functionMap))
));
+
return $theDate;
}
- return $this->nextDateByInterval($theDate, $functionMap[$repeatFreq], $skip);
+ return $this->nextDateByInterval($date, $functionMap[$repeatFreq], $skip);
}
- /**
- * @param Carbon $epoch
- * @param Periodicity $periodicity
- * @param int $skipInterval
- *
- * @return Carbon
- */
public function nextDateByInterval(Carbon $epoch, Periodicity $periodicity, int $skipInterval = 0): Carbon
{
try {
return $this->calculator->nextDateByInterval($epoch, $periodicity, $skipInterval);
} catch (IntervalException $exception) {
Log::warning($exception->getMessage(), ['exception' => $exception]);
- } catch (Throwable $exception) {
+ } catch (\Throwable $exception) { // @phpstan-ignore-line
Log::error($exception->getMessage(), ['exception' => $exception]);
}
@@ -123,20 +105,12 @@ class Navigation
return $epoch;
}
- /**
- * @param Carbon $start
- * @param Carbon $end
- * @param string $range
- *
- * @return array
- *
- */
public function blockPeriods(Carbon $start, Carbon $end, string $range): array
{
if ($end < $start) {
[$start, $end] = [$end, $start];
}
- $periods = [];
+ $periods = [];
// first, 13 periods of [range]
$loopCount = 0;
$loopDate = clone $end;
@@ -144,8 +118,8 @@ class Navigation
$workEnd = clone $loopDate;
while ($loopCount < 13) {
// make range:
- $workStart = \Navigation::startOfPeriod($workStart, $range);
- $workEnd = \Navigation::endOfPeriod($workStart, $range);
+ $workStart = $this->startOfPeriod($workStart, $range);
+ $workEnd = $this->endOfPeriod($workStart, $range);
// make sure we don't go overboard
if ($workEnd->gt($start)) {
@@ -157,7 +131,7 @@ class Navigation
}
// skip to the next period:
$workStart->subDay()->startOfDay();
- $loopCount++;
+ ++$loopCount;
}
// if $workEnd is still before $start, continue on a yearly basis:
$loopCount = 0;
@@ -177,22 +151,16 @@ class Navigation
}
// skip to the next period:
$workStart->subDay()->startOfDay();
- $loopCount++;
+ ++$loopCount;
}
}
return $periods;
}
- /**
- * @param Carbon $theDate
- * @param string $repeatFreq
- *
- * @return Carbon
- */
public function startOfPeriod(Carbon $theDate, string $repeatFreq): Carbon
{
- $date = clone $theDate;
+ $date = clone $theDate;
$functionMap = [
'1D' => 'startOfDay',
@@ -212,7 +180,7 @@ class Navigation
];
if (array_key_exists($repeatFreq, $functionMap)) {
$function = $functionMap[$repeatFreq];
- $date->$function();
+ $date->{$function}(); // @phpstan-ignore-line
return $date;
}
@@ -223,7 +191,7 @@ class Navigation
return $date;
}
- $result = match ($repeatFreq) {
+ $result = match ($repeatFreq) {
'last7' => $date->subDays(7)->startOfDay(),
'last30' => $date->subDays(30)->startOfDay(),
'last90' => $date->subDays(90)->startOfDay(),
@@ -237,7 +205,6 @@ class Navigation
return $result;
}
-
if ('custom' === $repeatFreq) {
return $date; // the date is already at the start.
}
@@ -246,15 +213,9 @@ class Navigation
return $theDate;
}
- /**
- * @param Carbon $end
- * @param string $repeatFreq
- *
- * @return Carbon
- */
public function endOfPeriod(Carbon $end, string $repeatFreq): Carbon
{
- $currentEnd = clone $end;
+ $currentEnd = clone $end;
$functionMap = [
'1D' => 'endOfDay',
@@ -275,32 +236,31 @@ class Navigation
'yearly' => 'addYear',
'1Y' => 'addYear',
];
- $modifierMap = [
- 'quarter' => 3,
- '3M' => 3,
- 'quarterly' => 3,
- 'half-year' => 6,
- 'half_year' => 6,
- '6M' => 6,
- ];
+ $modifierMap = ['quarter' => 3, '3M' => 3, 'quarterly' => 3, 'half-year' => 6, 'half_year' => 6, '6M' => 6];
+ $subDay = ['week', 'weekly', '1W', 'month', 'monthly', '1M', '3M', 'quarter', 'quarterly', '6M', 'half-year', 'half_year', '1Y', 'year', 'yearly'];
- $subDay = ['week', 'weekly', '1W', 'month', 'monthly', '1M', '3M', 'quarter', 'quarterly', '6M', 'half-year', 'half_year', '1Y', 'year', 'yearly'];
-
- // if the range is custom, the end of the period
- // is another X days (x is the difference between start)
- // and end added to $theCurrentEnd
if ('custom' === $repeatFreq) {
- /** @var Carbon $tStart */
- $tStart = session('start', today(config('app.timezone'))->startOfMonth());
- /** @var Carbon $tEnd */
- $tEnd = session('end', today(config('app.timezone'))->endOfMonth());
- $diffInDays = $tStart->diffInDays($tEnd);
+ // if the repeat frequency is "custom", use the current session start/end to see how large the range is,
+ // and use that to "add" another period.
+ // if there is no session data available use "30 days" as a default.
+ $diffInDays = 30;
+ if (null !== session('start') && null !== session('end')) {
+ Log::debug('Session data available.');
+
+ /** @var Carbon $tStart */
+ $tStart = session('start', today(config('app.timezone'))->startOfMonth());
+
+ /** @var Carbon $tEnd */
+ $tEnd = session('end', today(config('app.timezone'))->endOfMonth());
+ $diffInDays = $tStart->diffInDays($tEnd);
+ }
+ Log::debug(sprintf('Diff in days is %d', $diffInDays));
$currentEnd->addDays($diffInDays);
return $currentEnd;
}
- $result = match ($repeatFreq) {
+ $result = match ($repeatFreq) {
'last7' => $currentEnd->addDays(7)->startOfDay(),
'last30' => $currentEnd->addDays(30)->startOfDay(),
'last90' => $currentEnd->addDays(90)->startOfDay(),
@@ -315,16 +275,15 @@ class Navigation
}
unset($result);
-
if (!array_key_exists($repeatFreq, $functionMap)) {
Log::error(sprintf('Cannot do endOfPeriod for $repeat_freq "%s"', $repeatFreq));
return $end;
}
- $function = $functionMap[$repeatFreq];
+ $function = $functionMap[$repeatFreq];
if (array_key_exists($repeatFreq, $modifierMap)) {
- $currentEnd->$function($modifierMap[$repeatFreq]);
+ $currentEnd->{$function}($modifierMap[$repeatFreq]); // @phpstan-ignore-line
if (in_array($repeatFreq, $subDay, true)) {
$currentEnd->subDay();
}
@@ -332,7 +291,7 @@ class Navigation
return $currentEnd;
}
- $currentEnd->$function();
+ $currentEnd->{$function}(); // @phpstan-ignore-line
$currentEnd->endOfDay();
if (in_array($repeatFreq, $subDay, true)) {
$currentEnd->subDay();
@@ -341,42 +300,68 @@ class Navigation
return $currentEnd;
}
- /**
- * @param string $period
- * @param Carbon $beginning
- * @param Carbon $end
- *
- * @return int
- */
- public function diffInPeriods(string $period, Carbon $beginning, Carbon $end): int
+ public function daysUntilEndOfMonth(Carbon $date): int
{
- $map = [
- 'daily' => 'diffInDays',
- 'weekly' => 'diffInWeeks',
- 'monthly' => 'diffInMonths',
- 'quarterly' => 'diffInQuarters',
- 'half-year' => 'diffInQuarters',
- 'yearly' => 'diffInYears',
+ $endOfMonth = $date->copy()->endOfMonth();
+
+ return $date->diffInDays($endOfMonth);
+ }
+
+ public function diffInPeriods(string $period, int $skip, Carbon $beginning, Carbon $end): int
+ {
+ Log::debug(sprintf(
+ 'diffInPeriods: %s (skip: %d), between %s and %s.',
+ $period,
+ $skip,
+ $beginning->format('Y-m-d'),
+ $end->format('Y-m-d')
+ ));
+ $map = [
+ 'daily' => 'floatDiffInDays',
+ 'weekly' => 'floatDiffInWeeks',
+ 'monthly' => 'floatDiffInMonths',
+ 'quarterly' => 'floatDiffInMonths',
+ 'half-year' => 'floatDiffInMonths',
+ 'yearly' => 'floatDiffInYears',
];
if (!array_key_exists($period, $map)) {
- app('log')->warning(sprintf('No diffInPeriods for period "%s"', $period));
+ Log::warning(sprintf('No diffInPeriods for period "%s"', $period));
+
return 1;
}
- $func = $map[$period];
- $diff = $beginning->$func($end);
- if ('half-year' === $period) {
- $diff = ceil($diff / 2);
+ $func = $map[$period];
+ // first do the diff
+ $floatDiff = $beginning->{$func}($end); // @phpstan-ignore-line
+
+ // then correct for quarterly or half-year
+ if ('quarterly' === $period) {
+ Log::debug(sprintf('Q: Corrected %f to %f', $floatDiff, $floatDiff / 3));
+ $floatDiff /= 3;
}
+ if ('half-year' === $period) {
+ Log::debug(sprintf('H: Corrected %f to %f', $floatDiff, $floatDiff / 6));
+ $floatDiff /= 6;
+ }
+
+ // then do ceil()
+ $diff = ceil($floatDiff);
+
+ Log::debug(sprintf('Diff is %f periods (%d rounded up)', $floatDiff, $diff));
+
+ if ($skip > 0) {
+ $parameter = $skip + 1;
+ $diff = ceil($diff / $parameter) * $parameter;
+ Log::debug(sprintf(
+ 'diffInPeriods: skip is %d, so param is %d, and diff becomes %d',
+ $skip,
+ $parameter,
+ $diff
+ ));
+ }
+
return (int)$diff;
}
- /**
- * @param Carbon $theCurrentEnd
- * @param string $repeatFreq
- * @param Carbon|null $maxDate
- *
- * @return Carbon
- */
public function endOfX(Carbon $theCurrentEnd, string $repeatFreq, ?Carbon $maxDate): Carbon
{
$functionMap = [
@@ -396,11 +381,11 @@ class Navigation
'yearly' => 'endOfYear',
];
- $currentEnd = clone $theCurrentEnd;
+ $currentEnd = clone $theCurrentEnd;
if (array_key_exists($repeatFreq, $functionMap)) {
$function = $functionMap[$repeatFreq];
- $currentEnd->$function();
+ $currentEnd->{$function}(); // @phpstan-ignore-line
}
if (null !== $maxDate && $currentEnd > $maxDate) {
@@ -413,30 +398,33 @@ class Navigation
/**
* Returns the user's view range and if necessary, corrects the dynamic view
* range to a normal range.
- *
- * @param bool $correct
- *
- * @return string
- * @throws ContainerExceptionInterface
- * @throws NotFoundExceptionInterface
*/
public function getViewRange(bool $correct): string
{
- $range = (string)app('preferences')->get('viewRange', '1M')?->data ?? '1M';
+ $range = app('preferences')->get('viewRange', '1M')?->data ?? '1M';
+ if (is_array($range)) {
+ $range = '1M';
+ }
+ $range = (string)$range;
if (!$correct) {
return $range;
}
+
switch ($range) {
default:
return $range;
+
case 'last7':
return '1W';
+
case 'last30':
case 'MTD':
return '1M';
+
case 'last90':
case 'QTD':
return '3M';
+
case 'last365':
case 'YTD':
return '1Y';
@@ -444,15 +432,11 @@ class Navigation
}
/**
- * @param Carbon $start
- * @param Carbon $end
- *
- * @return array
* @throws FireflyException
*/
public function listOfPeriods(Carbon $start, Carbon $end): array
{
- $locale = app('steam')->getLocale();
+ $locale = app('steam')->getLocale();
// define period to increment
$increment = 'addDay';
$format = $this->preferredCarbonFormat($start, $end);
@@ -468,13 +452,13 @@ class Navigation
$increment = 'addYear';
$displayFormat = (string)trans('config.year_js');
}
- $begin = clone $start;
- $entries = [];
+ $begin = clone $start;
+ $entries = [];
while ($begin < $end) {
$formatted = $begin->format($format);
$displayed = $begin->isoFormat($displayFormat);
$entries[$formatted] = $displayed;
- $begin->$increment();
+ $begin->{$increment}(); // @phpstan-ignore-line
}
return $entries;
@@ -483,11 +467,6 @@ class Navigation
/**
* If the date difference between start and end is less than a month, method returns "Y-m-d". If the difference is
* less than a year, method returns "Y-m". If the date difference is larger, method returns "Y".
- *
- * @param Carbon $start
- * @param Carbon $end
- *
- * @return string
*/
public function preferredCarbonFormat(Carbon $start, Carbon $end): string
{
@@ -503,12 +482,6 @@ class Navigation
return $format;
}
- /**
- * @param Carbon $theDate
- * @param string $repeatFrequency
- *
- * @return string
- */
public function periodShow(Carbon $theDate, string $repeatFrequency): string
{
$date = clone $theDate;
@@ -529,7 +502,7 @@ class Navigation
];
if (array_key_exists($repeatFrequency, $formatMap)) {
- return $date->isoFormat((string)$formatMap[$repeatFrequency]);
+ return $date->isoFormat($formatMap[$repeatFrequency]);
}
if ('3M' === $repeatFrequency || 'quarter' === $repeatFrequency) {
$quarter = ceil($theDate->month / 3);
@@ -545,16 +518,12 @@ class Navigation
/**
* Same as preferredCarbonFormat but by string
- *
- * @param string $period
- *
- * @return string
*/
public function preferredCarbonFormatByPeriod(string $period): string
{
return match ($period) {
default => 'Y-m-d',
- //'1D' => 'Y-m-d',
+ // '1D' => 'Y-m-d',
'1W' => '\WW,Y',
'1M' => 'Y-m',
'3M', '6M' => '\QQ,Y',
@@ -566,11 +535,6 @@ class Navigation
* If the date difference between start and end is less than a month, method returns trans(config.month_and_day).
* If the difference is less than a year, method returns "config.month". If the date difference is larger, method
* returns "config.year".
- *
- * @param Carbon $start
- * @param Carbon $end
- *
- * @return string
*/
public function preferredCarbonLocalizedFormat(Carbon $start, Carbon $end): string
{
@@ -590,11 +554,6 @@ class Navigation
/**
* If the date difference between start and end is less than a month, method returns "endOfDay". If the difference
* is less than a year, method returns "endOfMonth". If the date difference is larger, method returns "endOfYear".
- *
- * @param Carbon $start
- * @param Carbon $end
- *
- * @return string
*/
public function preferredEndOfPeriod(Carbon $start, Carbon $end): string
{
@@ -613,11 +572,6 @@ class Navigation
/**
* If the date difference between start and end is less than a month, method returns "1D". If the difference is
* less than a year, method returns "1M". If the date difference is larger, method returns "1Y".
- *
- * @param Carbon $start
- * @param Carbon $end
- *
- * @return string
*/
public function preferredRangeFormat(Carbon $start, Carbon $end): string
{
@@ -636,11 +590,6 @@ class Navigation
/**
* If the date difference between start and end is less than a month, method returns "%Y-%m-%d". If the difference
* is less than a year, method returns "%Y-%m". If the date difference is larger, method returns "%Y".
- *
- * @param Carbon $start
- * @param Carbon $end
- *
- * @return string
*/
public function preferredSqlFormat(Carbon $start, Carbon $end): string
{
@@ -657,18 +606,12 @@ class Navigation
}
/**
- * @param Carbon $theDate
- * @param string $repeatFreq
- * @param int|null $subtract
- *
- * @return Carbon
- *
* @throws FireflyException
*/
public function subtractPeriod(Carbon $theDate, string $repeatFreq, int $subtract = null): Carbon
{
- $subtract = $subtract ?? 1;
- $date = clone $theDate;
+ $subtract ??= 1;
+ $date = clone $theDate;
// 1D 1W 1M 3M 6M 1Y
$functionMap = [
'1D' => 'subDays',
@@ -692,7 +635,7 @@ class Navigation
];
if (array_key_exists($repeatFreq, $functionMap)) {
$function = $functionMap[$repeatFreq];
- $date->$function($subtract);
+ $date->{$function}($subtract); // @phpstan-ignore-line
return $date;
}
@@ -707,7 +650,8 @@ class Navigation
// this is then subtracted from $theDate (* $subtract).
if ('custom' === $repeatFreq) {
/** @var Carbon $tStart */
- $tStart = session('start', today(config('app.timezone'))->startOfMonth());
+ $tStart = session('start', today(config('app.timezone'))->startOfMonth());
+
/** @var Carbon $tEnd */
$tEnd = session('end', today(config('app.timezone'))->endOfMonth());
$diffInDays = $tStart->diffInDays($tEnd);
@@ -715,42 +659,51 @@ class Navigation
return $date;
}
+
switch ($repeatFreq) {
default:
break;
+
case 'last7':
$date->subDays(7);
+
return $date;
+
case 'last30':
$date->subDays(30);
+
return $date;
+
case 'last90':
$date->subDays(90);
+
return $date;
+
case 'last365':
$date->subDays(365);
+
return $date;
+
case 'YTD':
$date->subYear();
+
return $date;
+
case 'QTD':
$date->subQuarter();
+
return $date;
+
case 'MTD':
$date->subMonth();
+
return $date;
}
-
throw new FireflyException(sprintf('Cannot do subtractPeriod for $repeat_freq "%s"', $repeatFreq));
}
/**
- * @param string $range
- * @param Carbon $start
- *
- * @return Carbon
- *
* @throws FireflyException
*/
public function updateEndDate(string $range, Carbon $start): Carbon
@@ -767,7 +720,7 @@ class Navigation
if (array_key_exists($range, $functionMap)) {
$function = $functionMap[$range];
- $end->$function();
+ $end->{$function}(); // @phpstan-ignore-line
return $end;
}
@@ -789,7 +742,7 @@ class Navigation
return $fiscalHelper->endOfFiscalYear($end);
}
- $list = [
+ $list = [
'last7',
'last30',
'last90',
@@ -802,6 +755,7 @@ class Navigation
$end = today(config('app.timezone'));
$end->endOfDay();
Log::debug(sprintf('updateEndDate returns "%s"', $end->format('Y-m-d')));
+
return $end;
}
@@ -809,11 +763,6 @@ class Navigation
}
/**
- * @param string $range
- * @param Carbon $start
- *
- * @return Carbon
- *
* @throws FireflyException
*/
public function updateStartDate(string $range, Carbon $start): Carbon
@@ -828,7 +777,7 @@ class Navigation
];
if (array_key_exists($range, $functionMap)) {
$function = $functionMap[$range];
- $start->$function();
+ $start->{$function}(); // @phpstan-ignore-line
return $start;
}
@@ -850,31 +799,47 @@ class Navigation
return $fiscalHelper->startOfFiscalYear($start);
}
+
switch ($range) {
default:
break;
+
case 'last7':
$start->subDays(7);
+
return $start;
+
case 'last30':
$start->subDays(30);
+
return $start;
+
case 'last90':
$start->subDays(90);
+
return $start;
+
case 'last365':
$start->subDays(365);
+
return $start;
+
case 'YTD':
$start->startOfYear();
+
return $start;
+
case 'QTD':
$start->startOfQuarter();
+
return $start;
+
case 'MTD':
$start->startOfMonth();
+
return $start;
}
+
throw new FireflyException(sprintf('updateStartDate cannot handle range "%s"', $range));
}
}
diff --git a/app/Support/Notifications/UrlValidator.php b/app/Support/Notifications/UrlValidator.php
index 5f6106ce9d..355f45e4ad 100644
--- a/app/Support/Notifications/UrlValidator.php
+++ b/app/Support/Notifications/UrlValidator.php
@@ -1,6 +1,5 @@
debug(sprintf('parseDate("%s")', $date));
+ $date = strtolower($date);
// parse keywords:
if (in_array($date, $this->keywords, true)) {
return $this->parseKeyword($date);
}
// if regex for YYYY-MM-DD:
- $pattern = '/^(19|20)\d\d-(0[1-9]|1[012])-(0[1-9]|[12]\d|3[01])$/';
- if (preg_match($pattern, $date)) {
+ $pattern = '/^(19|20)\d\d-(0[1-9]|1[012])-(0[1-9]|[12]\d|3[01])$/';
+ $result = preg_match($pattern, $date);
+ if (false !== $result && 0 !== $result) {
return $this->parseDefaultDate($date);
}
@@ -108,7 +104,8 @@ class ParseDateString
// maybe a date range
if (10 === strlen($date) && (str_contains($date, 'xx') || str_contains($date, 'xxxx'))) {
- Log::debug(sprintf('[c] Detected a date range ("%s"), return a fake date.', $date));
+ app('log')->debug(sprintf('[c] Detected a date range ("%s"), return a fake date.', $date));
+
// very lazy way to parse the date without parsing it, because this specific function
// cant handle date ranges.
return new Carbon('1984-09-17');
@@ -121,11 +118,6 @@ class ParseDateString
throw new FireflyException(sprintf('[d] Not a recognised date format: "%s"', $date));
}
- /**
- * @param string $keyword
- *
- * @return Carbon
- */
protected function parseKeyword(string $keyword): Carbon
{
$today = today(config('app.timezone'))->startOfDay();
@@ -145,24 +137,25 @@ class ParseDateString
};
}
- /**
- * @param string $date
- *
- * @return Carbon
- */
protected function parseDefaultDate(string $date): Carbon
{
- return Carbon::createFromFormat('Y-m-d', $date);
+ $result = false;
+
+ try {
+ $result = Carbon::createFromFormat('Y-m-d', $date);
+ } catch (InvalidFormatException $e) { // @phpstan-ignore-line
+ Log::error(sprintf('parseDefaultDate("%s") ran into an error, but dont mind: %s', $date, $e->getMessage()));
+ }
+ if (false === $result) {
+ $result = today(config('app.timezone'))->startOfDay();
+ }
+
+ return $result;
}
- /**
- * @param string $date
- *
- * @return Carbon
- */
protected function parseRelativeDate(string $date): Carbon
{
- Log::debug(sprintf('Now in parseRelativeDate("%s")', $date));
+ app('log')->debug(sprintf('Now in parseRelativeDate("%s")', $date));
$parts = explode(' ', $date);
$today = today(config('app.timezone'))->startOfDay();
$functions = [
@@ -183,63 +176,73 @@ class ParseDateString
];
foreach ($parts as $part) {
- Log::debug(sprintf('Now parsing part "%s"', $part));
- $part = trim($part);
+ app('log')->debug(sprintf('Now parsing part "%s"', $part));
+ $part = trim($part);
// verify if correct
- $pattern = '/[+-]\d+[wqmdy]/';
- $res = preg_match($pattern, $part);
- if (0 === $res || false === $res) {
- Log::error(sprintf('Part "%s" does not match regular expression. Will be skipped.', $part));
+ $pattern = '/[+-]\d+[wqmdy]/';
+ $result = preg_match($pattern, $part);
+ if (0 === $result || false === $result) {
+ app('log')->error(sprintf('Part "%s" does not match regular expression. Will be skipped.', $part));
+
continue;
}
$direction = str_starts_with($part, '+') ? 1 : 0;
$period = $part[strlen($part) - 1];
$number = (int)substr($part, 1, -1);
if (!array_key_exists($period, $functions[$direction])) {
- Log::error(sprintf('No method for direction %d and period "%s".', $direction, $period));
+ app('log')->error(sprintf('No method for direction %d and period "%s".', $direction, $period));
+
continue;
}
- $func = $functions[$direction][$period];
- Log::debug(sprintf('Will now do %s(%d) on %s', $func, $number, $today->format('Y-m-d')));
- $today->$func($number);
- Log::debug(sprintf('Resulting date is %s', $today->format('Y-m-d')));
+ $func = $functions[$direction][$period];
+ app('log')->debug(sprintf('Will now do %s(%d) on %s', $func, $number, $today->format('Y-m-d')));
+ $today->{$func}($number); // @phpstan-ignore-line
+ app('log')->debug(sprintf('Resulting date is %s', $today->format('Y-m-d')));
}
return $today;
}
- /**
- * @param string $date
- *
- * @return array
- */
public function parseRange(string $date): array
{
// several types of range can be submitted
$result = [
'exact' => new Carbon('1984-09-17'),
];
+
switch (true) {
default:
break;
+
case $this->isDayRange($date):
$result = $this->parseDayRange($date);
+
break;
+
case $this->isMonthRange($date):
$result = $this->parseMonthRange($date);
+
break;
+
case $this->isYearRange($date):
$result = $this->parseYearRange($date);
+
break;
+
case $this->isMonthDayRange($date):
$result = $this->parseMonthDayRange($date);
+
break;
+
case $this->isDayYearRange($date):
$result = $this->parseDayYearRange($date);
+
break;
+
case $this->isMonthYearRange($date):
$result = $this->parseMonthYearRange($date);
+
break;
}
@@ -247,30 +250,24 @@ class ParseDateString
}
/**
- * @param string $date
- *
- * @return bool
+ * Returns true if this matches regex for xxxx-xx-DD:
*/
protected function isDayRange(string $date): bool
{
- // if regex for xxxx-xx-DD:
$pattern = '/^xxxx-xx-(0[1-9]|[12]\d|3[01])$/';
- if (preg_match($pattern, $date)) {
- Log::debug(sprintf('"%s" is a day range.', $date));
+ $result = preg_match($pattern, $date);
+ if (false !== $result && 0 !== $result) {
+ app('log')->debug(sprintf('"%s" is a day range.', $date));
return true;
}
- Log::debug(sprintf('"%s" is not a day range.', $date));
+ app('log')->debug(sprintf('"%s" is not a day range.', $date));
return false;
}
/**
* format of string is xxxx-xx-DD
- *
- * @param string $date
- *
- * @return array
*/
protected function parseDayRange(string $date): array
{
@@ -281,35 +278,27 @@ class ParseDateString
];
}
- /**
- * @param string $date
- *
- * @return bool
- */
protected function isMonthRange(string $date): bool
{
// if regex for xxxx-MM-xx:
$pattern = '/^xxxx-(0[1-9]|1[012])-xx$/';
- if (preg_match($pattern, $date)) {
- Log::debug(sprintf('"%s" is a month range.', $date));
+ $result = preg_match($pattern, $date);
+ if (false !== $result && 0 !== $result) {
+ app('log')->debug(sprintf('"%s" is a month range.', $date));
return true;
}
- Log::debug(sprintf('"%s" is not a month range.', $date));
+ app('log')->debug(sprintf('"%s" is not a month range.', $date));
return false;
}
/**
* format of string is xxxx-MM-xx
- *
- * @param string $date
- *
- * @return array
*/
protected function parseMonthRange(string $date): array
{
- Log::debug(sprintf('parseMonthRange: Parsed "%s".', $date));
+ app('log')->debug(sprintf('parseMonthRange: Parsed "%s".', $date));
$parts = explode('-', $date);
return [
@@ -317,35 +306,27 @@ class ParseDateString
];
}
- /**
- * @param string $date
- *
- * @return bool
- */
protected function isYearRange(string $date): bool
{
// if regex for YYYY-xx-xx:
$pattern = '/^(19|20)\d\d-xx-xx$/';
- if (preg_match($pattern, $date)) {
- Log::debug(sprintf('"%s" is a year range.', $date));
+ $result = preg_match($pattern, $date);
+ if (false !== $result && 0 !== $result) {
+ app('log')->debug(sprintf('"%s" is a year range.', $date));
return true;
}
- Log::debug(sprintf('"%s" is not a year range.', $date));
+ app('log')->debug(sprintf('"%s" is not a year range.', $date));
return false;
}
/**
* format of string is YYYY-xx-xx
- *
- * @param string $date
- *
- * @return array
*/
protected function parseYearRange(string $date): array
{
- Log::debug(sprintf('parseYearRange: Parsed "%s"', $date));
+ app('log')->debug(sprintf('parseYearRange: Parsed "%s"', $date));
$parts = explode('-', $date);
return [
@@ -353,35 +334,27 @@ class ParseDateString
];
}
- /**
- * @param string $date
- *
- * @return bool
- */
protected function isMonthDayRange(string $date): bool
{
// if regex for xxxx-MM-DD:
$pattern = '/^xxxx-(0[1-9]|1[012])-(0[1-9]|[12]\d|3[01])$/';
- if (preg_match($pattern, $date)) {
- Log::debug(sprintf('"%s" is a month/day range.', $date));
+ $result = preg_match($pattern, $date);
+ if (false !== $result && 0 !== $result) {
+ app('log')->debug(sprintf('"%s" is a month/day range.', $date));
return true;
}
- Log::debug(sprintf('"%s" is not a month/day range.', $date));
+ app('log')->debug(sprintf('"%s" is not a month/day range.', $date));
return false;
}
/**
* format of string is xxxx-MM-DD
- *
- * @param string $date
- *
- * @return array
*/
private function parseMonthDayRange(string $date): array
{
- Log::debug(sprintf('parseMonthDayRange: Parsed "%s".', $date));
+ app('log')->debug(sprintf('parseMonthDayRange: Parsed "%s".', $date));
$parts = explode('-', $date);
return [
@@ -390,35 +363,27 @@ class ParseDateString
];
}
- /**
- * @param string $date
- *
- * @return bool
- */
protected function isDayYearRange(string $date): bool
{
// if regex for YYYY-xx-DD:
$pattern = '/^(19|20)\d\d-xx-(0[1-9]|[12]\d|3[01])$/';
- if (preg_match($pattern, $date)) {
- Log::debug(sprintf('"%s" is a day/year range.', $date));
+ $result = preg_match($pattern, $date);
+ if (false !== $result && 0 !== $result) {
+ app('log')->debug(sprintf('"%s" is a day/year range.', $date));
return true;
}
- Log::debug(sprintf('"%s" is not a day/year range.', $date));
+ app('log')->debug(sprintf('"%s" is not a day/year range.', $date));
return false;
}
/**
* format of string is YYYY-xx-DD
- *
- * @param string $date
- *
- * @return array
*/
private function parseDayYearRange(string $date): array
{
- Log::debug(sprintf('parseDayYearRange: Parsed "%s".', $date));
+ app('log')->debug(sprintf('parseDayYearRange: Parsed "%s".', $date));
$parts = explode('-', $date);
return [
@@ -427,35 +392,27 @@ class ParseDateString
];
}
- /**
- * @param string $date
- *
- * @return bool
- */
protected function isMonthYearRange(string $date): bool
{
// if regex for YYYY-MM-xx:
$pattern = '/^(19|20)\d\d-(0[1-9]|1[012])-xx$/';
- if (preg_match($pattern, $date)) {
- Log::debug(sprintf('"%s" is a month/year range.', $date));
+ $result = preg_match($pattern, $date);
+ if (false !== $result && 0 !== $result) {
+ app('log')->debug(sprintf('"%s" is a month/year range.', $date));
return true;
}
- Log::debug(sprintf('"%s" is not a month/year range.', $date));
+ app('log')->debug(sprintf('"%s" is not a month/year range.', $date));
return false;
}
/**
* format of string is YYYY-MM-xx
- *
- * @param string $date
- *
- * @return array
*/
protected function parseMonthYearRange(string $date): array
{
- Log::debug(sprintf('parseMonthYearRange: Parsed "%s".', $date));
+ app('log')->debug(sprintf('parseMonthYearRange: Parsed "%s".', $date));
$parts = explode('-', $date);
return [
diff --git a/app/Support/Preferences.php b/app/Support/Preferences.php
index c519a992ee..4b7c326a79 100644
--- a/app/Support/Preferences.php
+++ b/app/Support/Preferences.php
@@ -23,24 +23,16 @@ declare(strict_types=1);
namespace FireflyIII\Support;
-use Cache;
use FireflyIII\Exceptions\FireflyException;
use FireflyIII\Models\Preference;
use FireflyIII\User;
use Illuminate\Support\Collection;
-use PDOException;
-use Session;
/**
* Class Preferences.
- *
-
*/
class Preferences
{
- /**
- * @return Collection
- */
public function all(): Collection
{
$user = auth()->user();
@@ -52,15 +44,17 @@ class Preferences
}
/**
- * @param string $name
- * @param mixed $default
+ * @param mixed $default
*
- * @return Preference|null
* @throws FireflyException
*/
public function get(string $name, $default = null): ?Preference
{
- /** @var User|null $user */
+ if ('currencyPreference' === $name) {
+ throw new FireflyException('No longer supports "currencyPreference", please refactor me.');
+ }
+
+ /** @var null|User $user */
$user = auth()->user();
if (null === $user) {
$preference = new Preference();
@@ -73,15 +67,13 @@ class Preferences
}
/**
- * @param User $user
- * @param string $name
- * @param null|string|int $default
- *
- * @return Preference|null
* @throws FireflyException
*/
- public function getForUser(User $user, string $name, $default = null): ?Preference
+ public function getForUser(User $user, string $name, null|array|bool|int|string $default = null): ?Preference
{
+ if ('currencyPreference' === $name) {
+ throw new FireflyException('No longer supports "currencyPreference", please refactor me.');
+ }
$preference = Preference::where('user_id', $user->id)->where('name', $name)->first(['id', 'user_id', 'name', 'data', 'updated_at', 'created_at']);
if (null !== $preference && null === $preference->data) {
$preference->delete();
@@ -101,47 +93,47 @@ class Preferences
}
/**
- * @param string $name
- *
- * @return bool
* @throws FireflyException
*/
public function delete(string $name): bool
{
+ if ('currencyPreference' === $name) {
+ throw new FireflyException('No longer supports "currencyPreference", please refactor me.');
+ }
$fullName = sprintf('preference%s%s', auth()->user()->id, $name);
- if (Cache::has($fullName)) {
- Cache::forget($fullName);
+ if (\Cache::has($fullName)) {
+ \Cache::forget($fullName);
}
Preference::where('user_id', auth()->user()->id)->where('name', $name)->delete();
return true;
}
- /**
- * @param User $user
- * @param string $name
- */
public function forget(User $user, string $name): void
{
+ if ('currencyPreference' === $name) {
+ throw new FireflyException('No longer supports "currencyPreference", please refactor me.');
+ }
$key = sprintf('preference%s%s', $user->id, $name);
- Cache::forget($key);
- Cache::put($key, '', 5);
+ \Cache::forget($key);
+ \Cache::put($key, '', 5);
}
/**
- * @param User $user
- * @param string $name
- * @param mixed $value
+ * @param mixed $value
*
- * @return Preference
* @throws FireflyException
*/
public function setForUser(User $user, string $name, $value): Preference
{
- $fullName = sprintf('preference%s%s', $user->id, $name);
- Cache::forget($fullName);
- /** @var Preference|null $pref */
- $pref = Preference::where('user_id', $user->id)->where('name', $name)->first(['id', 'name', 'data', 'updated_at', 'created_at']);
+ if ('currencyPreference' === $name) {
+ throw new FireflyException('No longer supports "currencyPreference", please refactor me.');
+ }
+ $fullName = sprintf('preference%s%s', $user->id, $name);
+ \Cache::forget($fullName);
+
+ /** @var null|Preference $pref */
+ $pref = Preference::where('user_id', $user->id)->where('name', $name)->first(['id', 'name', 'data', 'updated_at', 'created_at']);
if (null !== $pref && null === $value) {
$pref->delete();
@@ -153,51 +145,40 @@ class Preferences
}
if (null === $pref) {
$pref = new Preference();
- $pref->user_id = $user->id;
+ $pref->user_id = (int)$user->id;
$pref->name = $name;
}
$pref->data = $value;
+
try {
$pref->save();
- } catch (PDOException $e) {
+ } catch (\PDOException $e) {
throw new FireflyException(sprintf('Could not save preference: %s', $e->getMessage()), 0, $e);
}
- Cache::forever($fullName, $pref);
+ \Cache::forever($fullName, $pref);
return $pref;
}
- /**
- * @param User $user
- * @param string $search
- *
- * @return Collection
- */
public function beginsWith(User $user, string $search): Collection
{
- return Preference::where('user_id', $user->id)->where('name', 'LIKE', $search . '%')->get();
+ return Preference::where('user_id', $user->id)->where('name', 'LIKE', $search.'%')->get();
}
- /**
- * @param string $name
- *
- * @return Collection
- */
public function findByName(string $name): Collection
{
+ if ('currencyPreference' === $name) {
+ throw new FireflyException('No longer supports "currencyPreference", please refactor me.');
+ }
+
return Preference::where('name', $name)->get();
}
- /**
- * @param User $user
- * @param array $list
- *
- * @return array
- */
public function getArrayForUser(User $user, array $list): array
{
$result = [];
$preferences = Preference::where('user_id', $user->id)->whereIn('name', $list)->get(['id', 'name', 'data']);
+
/** @var Preference $preference */
foreach ($preferences as $preference) {
$result[$preference->name] = $preference->data;
@@ -212,15 +193,17 @@ class Preferences
}
/**
- * @param string $name
- * @param mixed $default
+ * @param mixed $default
*
- * @return Preference|null
* @throws FireflyException
*/
public function getFresh(string $name, $default = null): ?Preference
{
- /** @var User|null $user */
+ if ('currencyPreference' === $name) {
+ throw new FireflyException('No longer supports "currencyPreference", please refactor me.');
+ }
+
+ /** @var null|User $user */
$user = auth()->user();
if (null === $user) {
$preference = new Preference();
@@ -233,21 +216,22 @@ class Preferences
}
/**
- * @param User $user
- * @param string $name
- * @param null $default
- *
- * @return Preference|null
* TODO remove me.
+ *
+ * @param null $default
+ *
* @throws FireflyException
*/
public function getFreshForUser(User $user, string $name, $default = null): ?Preference
{
+ if ('currencyPreference' === $name) {
+ throw new FireflyException('No longer supports "currencyPreference", please refactor me.');
+ }
+
return $this->getForUser($user, $name, $default);
}
/**
- * @return string
* @throws FireflyException
*/
public function lastActivity(): string
@@ -262,27 +246,25 @@ class Preferences
$lastActivity = implode(',', $lastActivity);
}
- return hash('sha256', $lastActivity);
+ return hash('sha256', (string)$lastActivity);
}
- /**
- *
- */
public function mark(): void
{
$this->set('lastActivity', microtime());
- Session::forget('first');
+ \Session::forget('first');
}
/**
- * @param string $name
- * @param mixed $value
+ * @param mixed $value
*
- * @return Preference
* @throws FireflyException
*/
public function set(string $name, $value): Preference
{
+ if ('currencyPreference' === $name) {
+ throw new FireflyException('No longer supports "currencyPreference", please refactor me.');
+ }
$user = auth()->user();
if (null === $user) {
// make new preference, return it:
diff --git a/app/Support/Report/Budget/BudgetReportGenerator.php b/app/Support/Report/Budget/BudgetReportGenerator.php
index 739a0c3a25..7059886943 100644
--- a/app/Support/Report/Budget/BudgetReportGenerator.php
+++ b/app/Support/Report/Budget/BudgetReportGenerator.php
@@ -35,7 +35,6 @@ use FireflyIII\Repositories\Budget\NoBudgetRepositoryInterface;
use FireflyIII\Repositories\Budget\OperationsRepositoryInterface;
use FireflyIII\User;
use Illuminate\Support\Collection;
-use JsonException;
/**
* Class BudgetReportGenerator
@@ -74,10 +73,11 @@ class BudgetReportGenerator
{
$spent = $this->opsRepository->listExpenses($this->start, $this->end, $this->accounts, $this->budgets);
$this->report = [];
+
/** @var Account $account */
foreach ($this->accounts as $account) {
- $accountId = $account->id;
- $this->report[$accountId] = $this->report[$accountId] ?? [
+ $accountId = $account->id;
+ $this->report[$accountId] ??= [
'name' => $account->name,
'id' => $account->id,
'iban' => $account->iban,
@@ -93,8 +93,6 @@ class BudgetReportGenerator
/**
* Process each row of expenses collected for the "Account per budget" partial
- *
- * @param array $expenses
*/
private function processExpenses(array $expenses): void
{
@@ -105,9 +103,6 @@ class BudgetReportGenerator
/**
* Process each set of transactions for each row of expenses.
- *
- * @param array $expenses
- * @param array $budget
*/
private function processBudgetExpenses(array $expenses, array $budget): void
{
@@ -117,19 +112,19 @@ class BudgetReportGenerator
$sourceAccountId = $journal['source_account_id'];
$this->report[$sourceAccountId]['currencies'][$currencyId]
- = $this->report[$sourceAccountId]['currencies'][$currencyId] ?? [
- 'currency_id' => $expenses['currency_id'],
- 'currency_symbol' => $expenses['currency_symbol'],
- 'currency_name' => $expenses['currency_name'],
- 'currency_decimal_places' => $expenses['currency_decimal_places'],
- 'budgets' => [],
- ];
+ ??= [
+ 'currency_id' => $expenses['currency_id'],
+ 'currency_symbol' => $expenses['currency_symbol'],
+ 'currency_name' => $expenses['currency_name'],
+ 'currency_decimal_places' => $expenses['currency_decimal_places'],
+ 'budgets' => [],
+ ];
$this->report[$sourceAccountId]['currencies'][$currencyId]['budgets'][$budgetId]
- = $this->report[$sourceAccountId]['currencies'][$currencyId]['budgets'][$budgetId] ?? '0';
+ ??= '0';
$this->report[$sourceAccountId]['currencies'][$currencyId]['budgets'][$budgetId]
- = bcadd($this->report[$sourceAccountId]['currencies'][$currencyId]['budgets'][$budgetId], $journal['amount']);
+ = bcadd($this->report[$sourceAccountId]['currencies'][$currencyId]['budgets'][$budgetId], $journal['amount']);
}
}
@@ -155,6 +150,7 @@ class BudgetReportGenerator
private function generalBudgetReport(): void
{
$budgetList = $this->repository->getBudgets();
+
/** @var Budget $budget */
foreach ($budgetList as $budget) {
$this->processBudget($budget);
@@ -163,13 +159,11 @@ class BudgetReportGenerator
/**
* Process expenses etc. for a single budget for the budgets block on the default report.
- *
- * @param Budget $budget
*/
private function processBudget(Budget $budget): void
{
- $budgetId = (int)$budget->id;
- $this->report['budgets'][$budgetId] = $this->report['budgets'][$budgetId] ?? [
+ $budgetId = $budget->id;
+ $this->report['budgets'][$budgetId] ??= [
'budget_id' => $budgetId,
'budget_name' => $budget->name,
'no_budget' => false,
@@ -177,7 +171,8 @@ class BudgetReportGenerator
];
// get all budget limits for budget in period:
- $limits = $this->blRepository->getBudgetLimits($budget, $this->start, $this->end);
+ $limits = $this->blRepository->getBudgetLimits($budget, $this->start, $this->end);
+
/** @var BudgetLimit $limit */
foreach ($limits as $limit) {
$this->processLimit($budget, $limit);
@@ -186,22 +181,19 @@ class BudgetReportGenerator
/**
* Process a single budget limit for the budgets block on the default report.
- *
- * @param Budget $budget
- * @param BudgetLimit $limit
*/
private function processLimit(Budget $budget, BudgetLimit $limit): void
{
- $budgetId = (int)$budget->id;
- $limitId = (int)$limit->id;
- $limitCurrency = $limit->transactionCurrency ?? $this->currency;
- $currencyId = (int)$limitCurrency->id;
- $expenses = $this->opsRepository->sumExpenses($limit->start_date, $limit->end_date, $this->accounts, new Collection([$budget]));
- $spent = $expenses[$currencyId]['sum'] ?? '0';
- $left = -1 === bccomp(bcadd($limit->amount, $spent), '0') ? '0' : bcadd($limit->amount, $spent);
- $overspent = 1 === bccomp(bcmul($spent, '-1'), $limit->amount) ? bcadd($spent, $limit->amount) : '0';
+ $budgetId = $budget->id;
+ $limitId = $limit->id;
+ $limitCurrency = $limit->transactionCurrency ?? $this->currency;
+ $currencyId = $limitCurrency->id;
+ $expenses = $this->opsRepository->sumExpenses($limit->start_date, $limit->end_date, $this->accounts, new Collection([$budget]));
+ $spent = $expenses[$currencyId]['sum'] ?? '0';
+ $left = -1 === bccomp(bcadd($limit->amount, $spent), '0') ? '0' : bcadd($limit->amount, $spent);
+ $overspent = 1 === bccomp(bcmul($spent, '-1'), $limit->amount) ? bcadd($spent, $limit->amount) : '0';
- $this->report['budgets'][$budgetId]['budget_limits'][$limitId] = $this->report['budgets'][$budgetId]['budget_limits'][$limitId] ?? [
+ $this->report['budgets'][$budgetId]['budget_limits'][$limitId] ??= [
'budget_limit_id' => $limitId,
'start_date' => $limit->start_date,
'end_date' => $limit->end_date,
@@ -220,17 +212,17 @@ class BudgetReportGenerator
// make sum information:
$this->report['sums'][$currencyId]
- = $this->report['sums'][$currencyId] ?? [
- 'budgeted' => '0',
- 'spent' => '0',
- 'left' => '0',
- 'overspent' => '0',
- 'currency_id' => $currencyId,
- 'currency_code' => $limitCurrency->code,
- 'currency_name' => $limitCurrency->name,
- 'currency_symbol' => $limitCurrency->symbol,
- 'currency_decimal_places' => $limitCurrency->decimal_places,
- ];
+ ??= [
+ 'budgeted' => '0',
+ 'spent' => '0',
+ 'left' => '0',
+ 'overspent' => '0',
+ 'currency_id' => $currencyId,
+ 'currency_code' => $limitCurrency->code,
+ 'currency_name' => $limitCurrency->name,
+ 'currency_symbol' => $limitCurrency->symbol,
+ 'currency_decimal_places' => $limitCurrency->decimal_places,
+ ];
$this->report['sums'][$currencyId]['budgeted'] = bcadd($this->report['sums'][$currencyId]['budgeted'], $limit->amount);
$this->report['sums'][$currencyId]['spent'] = bcadd($this->report['sums'][$currencyId]['spent'], $spent);
$this->report['sums'][$currencyId]['left'] = bcadd($this->report['sums'][$currencyId]['left'], bcadd($limit->amount, $spent));
@@ -250,16 +242,16 @@ class BudgetReportGenerator
'budget_limits' => [],
];
- $noBudget = $this->nbRepository->sumExpenses($this->start, $this->end, $this->accounts);
+ $noBudget = $this->nbRepository->sumExpenses($this->start, $this->end, $this->accounts);
foreach ($noBudget as $noBudgetEntry) {
// currency information:
- $nbCurrencyId = (int)($noBudgetEntry['currency_id'] ?? $this->currency->id);
- $nbCurrencyCode = $noBudgetEntry['currency_code'] ?? $this->currency->code;
- $nbCurrencyName = $noBudgetEntry['currency_name'] ?? $this->currency->name;
- $nbCurrencySymbol = $noBudgetEntry['currency_symbol'] ?? $this->currency->symbol;
- $nbCurrencyDp = $noBudgetEntry['currency_decimal_places'] ?? $this->currency->decimal_places;
+ $nbCurrencyId = (int)($noBudgetEntry['currency_id'] ?? $this->currency->id);
+ $nbCurrencyCode = $noBudgetEntry['currency_code'] ?? $this->currency->code;
+ $nbCurrencyName = $noBudgetEntry['currency_name'] ?? $this->currency->name;
+ $nbCurrencySymbol = $noBudgetEntry['currency_symbol'] ?? $this->currency->symbol;
+ $nbCurrencyDp = $noBudgetEntry['currency_decimal_places'] ?? $this->currency->decimal_places;
- $this->report['budgets'][0]['budget_limits'][] = [
+ $this->report['budgets'][0]['budget_limits'][] = [
'budget_limit_id' => null,
'start_date' => $this->start,
'end_date' => $this->end,
@@ -275,7 +267,7 @@ class BudgetReportGenerator
'currency_symbol' => $nbCurrencySymbol,
'currency_decimal_places' => $nbCurrencyDp,
];
- $this->report['sums'][$nbCurrencyId]['spent'] = bcadd($this->report['sums'][$nbCurrencyId]['spent'] ?? '0', $noBudgetEntry['sum']);
+ $this->report['sums'][$nbCurrencyId]['spent'] = bcadd($this->report['sums'][$nbCurrencyId]['spent'] ?? '0', $noBudgetEntry['sum']);
// append currency info because it may be missing:
$this->report['sums'][$nbCurrencyId]['currency_id'] = $nbCurrencyId;
$this->report['sums'][$nbCurrencyId]['currency_code'] = $nbCurrencyCode;
@@ -284,9 +276,9 @@ class BudgetReportGenerator
$this->report['sums'][$nbCurrencyId]['currency_decimal_places'] = $nbCurrencyDp;
// append other sums because they might be missing:
- $this->report['sums'][$nbCurrencyId]['overspent'] = $this->report['sums'][$nbCurrencyId]['overspent'] ?? '0';
- $this->report['sums'][$nbCurrencyId]['left'] = $this->report['sums'][$nbCurrencyId]['left'] ?? '0';
- $this->report['sums'][$nbCurrencyId]['budgeted'] = $this->report['sums'][$nbCurrencyId]['budgeted'] ?? '0';
+ $this->report['sums'][$nbCurrencyId]['overspent'] ??= '0';
+ $this->report['sums'][$nbCurrencyId]['left'] ??= '0';
+ $this->report['sums'][$nbCurrencyId]['budgeted'] ??= '0';
}
}
@@ -298,15 +290,15 @@ class BudgetReportGenerator
// make percentages based on total amount.
foreach ($this->report['budgets'] as $budgetId => $data) {
foreach ($data['budget_limits'] as $limitId => $entry) {
- $budgetId = (int)$budgetId;
- $limitId = (int)$limitId;
- $currencyId = (int)$entry['currency_id'];
- $spent = $entry['spent'];
- $totalSpent = $this->report['sums'][$currencyId]['spent'] ?? '0';
- $spentPct = '0';
- $budgeted = $entry['budgeted'];
- $totalBudgeted = $this->report['sums'][$currencyId]['budgeted'] ?? '0';
- $budgetedPct = '0';
+ $budgetId = (int)$budgetId;
+ $limitId = (int)$limitId;
+ $currencyId = (int)$entry['currency_id'];
+ $spent = $entry['spent'];
+ $totalSpent = $this->report['sums'][$currencyId]['spent'] ?? '0';
+ $spentPct = '0';
+ $budgeted = $entry['budgeted'];
+ $totalBudgeted = $this->report['sums'][$currencyId]['budgeted'] ?? '0';
+ $budgetedPct = '0';
if (0 !== bccomp($spent, '0') && 0 !== bccomp($totalSpent, '0')) {
$spentPct = round((float)bcmul(bcdiv($spent, $totalSpent), '100'));
@@ -314,58 +306,40 @@ class BudgetReportGenerator
if (0 !== bccomp($budgeted, '0') && 0 !== bccomp($totalBudgeted, '0')) {
$budgetedPct = round((float)bcmul(bcdiv($budgeted, $totalBudgeted), '100'));
}
- $this->report['sums'][$currencyId]['budgeted'] = $this->report['sums'][$currencyId]['budgeted'] ?? '0';
+ $this->report['sums'][$currencyId]['budgeted'] ??= '0';
$this->report['budgets'][$budgetId]['budget_limits'][$limitId]['spent_pct'] = $spentPct;
$this->report['budgets'][$budgetId]['budget_limits'][$limitId]['budgeted_pct'] = $budgetedPct;
}
}
}
- /**
- * @return array
- */
public function getReport(): array
{
return $this->report;
}
- /**
- * @param Collection $accounts
- */
public function setAccounts(Collection $accounts): void
{
$this->accounts = $accounts;
}
- /**
- * @param Collection $budgets
- */
public function setBudgets(Collection $budgets): void
{
$this->budgets = $budgets;
}
- /**
- * @param Carbon $end
- */
public function setEnd(Carbon $end): void
{
$this->end = $end;
}
- /**
- * @param Carbon $start
- */
public function setStart(Carbon $start): void
{
$this->start = $start;
}
/**
- * @param User $user
- *
* @throws FireflyException
- * @throws JsonException
*/
public function setUser(User $user): void
{
@@ -373,6 +347,6 @@ class BudgetReportGenerator
$this->blRepository->setUser($user);
$this->opsRepository->setUser($user);
$this->nbRepository->setUser($user);
- $this->currency = app('amount')->getDefaultCurrencyByUser($user);
+ $this->currency = app('amount')->getDefaultCurrencyByUserGroup($user->userGroup);
}
}
diff --git a/app/Support/Report/Category/CategoryReportGenerator.php b/app/Support/Report/Category/CategoryReportGenerator.php
index f8e85f9cb4..67a3d872f6 100644
--- a/app/Support/Report/Category/CategoryReportGenerator.php
+++ b/app/Support/Report/Category/CategoryReportGenerator.php
@@ -50,9 +50,6 @@ class CategoryReportGenerator
$this->noCatRepository = app(NoCategoryRepositoryInterface::class);
}
- /**
- * @return array
- */
public function getReport(): array
{
return $this->report;
@@ -64,17 +61,17 @@ class CategoryReportGenerator
*/
public function operations(): void
{
- $earnedWith = $this->opsRepository->listIncome($this->start, $this->end, $this->accounts);
- $spentWith = $this->opsRepository->listExpenses($this->start, $this->end, $this->accounts);
+ $earnedWith = $this->opsRepository->listIncome($this->start, $this->end, $this->accounts);
+ $spentWith = $this->opsRepository->listExpenses($this->start, $this->end, $this->accounts);
// also transferred out and transferred into these accounts in this category:
$transferredIn = $this->opsRepository->listTransferredIn($this->start, $this->end, $this->accounts);
$transferredOut = $this->opsRepository->listTransferredOut($this->start, $this->end, $this->accounts);
- $earnedWithout = $this->noCatRepository->listIncome($this->start, $this->end, $this->accounts);
- $spentWithout = $this->noCatRepository->listExpenses($this->start, $this->end, $this->accounts);
+ $earnedWithout = $this->noCatRepository->listIncome($this->start, $this->end, $this->accounts);
+ $spentWithout = $this->noCatRepository->listExpenses($this->start, $this->end, $this->accounts);
- $this->report = [
+ $this->report = [
'categories' => [],
'sums' => [],
];
@@ -87,8 +84,6 @@ class CategoryReportGenerator
/**
* Process one of the spent arrays from the operations method.
- *
- * @param array $data
*/
private function processOpsArray(array $data): void
{
@@ -101,13 +96,9 @@ class CategoryReportGenerator
}
}
- /**
- * @param int $currencyId
- * @param array $currencyRow
- */
private function processCurrencyArray(int $currencyId, array $currencyRow): void
{
- $this->report['sums'][$currencyId] = $this->report['sums'][$currencyId] ?? [
+ $this->report['sums'][$currencyId] ??= [
'spent' => '0',
'earned' => '0',
'sum' => '0',
@@ -127,16 +118,10 @@ class CategoryReportGenerator
}
}
- /**
- * @param int $currencyId
- * @param array $currencyRow
- * @param int $categoryId
- * @param array $categoryRow
- */
private function processCategoryRow(int $currencyId, array $currencyRow, int $categoryId, array $categoryRow): void
{
- $key = sprintf('%s-%s', $currencyId, $categoryId);
- $this->report['categories'][$key] = $this->report['categories'][$key] ?? [
+ $key = sprintf('%s-%s', $currencyId, $categoryId);
+ $this->report['categories'][$key] ??= [
'id' => $categoryId,
'title' => $categoryRow['name'],
'currency_id' => $currencyRow['currency_id'],
@@ -151,9 +136,9 @@ class CategoryReportGenerator
// loop journals:
foreach ($categoryRow['transaction_journals'] as $journal) {
// sum of sums
- $this->report['sums'][$currencyId]['sum'] = bcadd($this->report['sums'][$currencyId]['sum'], $journal['amount']);
+ $this->report['sums'][$currencyId]['sum'] = bcadd($this->report['sums'][$currencyId]['sum'], $journal['amount']);
// sum of spent:
- $this->report['sums'][$currencyId]['spent'] = -1 === bccomp($journal['amount'], '0') ? bcadd(
+ $this->report['sums'][$currencyId]['spent'] = -1 === bccomp($journal['amount'], '0') ? bcadd(
$this->report['sums'][$currencyId]['spent'],
$journal['amount']
) : $this->report['sums'][$currencyId]['spent'];
@@ -164,47 +149,35 @@ class CategoryReportGenerator
) : $this->report['sums'][$currencyId]['earned'];
// sum of category
- $this->report['categories'][$key]['sum'] = bcadd($this->report['categories'][$key]['sum'], $journal['amount']);
+ $this->report['categories'][$key]['sum'] = bcadd($this->report['categories'][$key]['sum'], $journal['amount']);
// total spent in category
- $this->report['categories'][$key]['spent'] = -1 === bccomp($journal['amount'], '0') ? bcadd(
+ $this->report['categories'][$key]['spent'] = -1 === bccomp($journal['amount'], '0') ? bcadd(
$this->report['categories'][$key]['spent'],
$journal['amount']
) : $this->report['categories'][$key]['spent'];
// total earned in category
- $this->report['categories'][$key]['earned'] = 1 === bccomp($journal['amount'], '0') ? bcadd(
+ $this->report['categories'][$key]['earned'] = 1 === bccomp($journal['amount'], '0') ? bcadd(
$this->report['categories'][$key]['earned'],
$journal['amount']
) : $this->report['categories'][$key]['earned'];
}
}
- /**
- * @param Collection $accounts
- */
public function setAccounts(Collection $accounts): void
{
$this->accounts = $accounts;
}
- /**
- * @param Carbon $end
- */
public function setEnd(Carbon $end): void
{
$this->end = $end;
}
- /**
- * @param Carbon $start
- */
public function setStart(Carbon $start): void
{
$this->start = $start;
}
- /**
- * @param User $user
- */
public function setUser(User $user): void
{
$this->noCatRepository->setUser($user);
diff --git a/app/Support/Repositories/Recurring/CalculateRangeOccurrences.php b/app/Support/Repositories/Recurring/CalculateRangeOccurrences.php
index 89588bd41b..df73a72f60 100644
--- a/app/Support/Repositories/Recurring/CalculateRangeOccurrences.php
+++ b/app/Support/Repositories/Recurring/CalculateRangeOccurrences.php
@@ -25,7 +25,6 @@ declare(strict_types=1);
namespace FireflyIII\Support\Repositories\Recurring;
use Carbon\Carbon;
-use Illuminate\Support\Facades\Log;
/**
* Trait CalculateRangeOccurrences
@@ -35,12 +34,6 @@ trait CalculateRangeOccurrences
/**
* Get the number of daily occurrences for a recurring transaction until date $end is reached. Will skip every
* $skipMod-1 occurrences.
- *
- * @param Carbon $start
- * @param Carbon $end
- * @param int $skipMod
- *
- * @return array
*/
protected function getDailyInRange(Carbon $start, Carbon $end, int $skipMod): array
{
@@ -51,7 +44,7 @@ trait CalculateRangeOccurrences
$return[] = clone $start;
}
$start->addDay();
- $attempts++;
+ ++$attempts;
}
return $return;
@@ -60,14 +53,6 @@ trait CalculateRangeOccurrences
/**
* Get the number of daily occurrences for a recurring transaction until date $end is reached. Will skip every
* $skipMod-1 occurrences.
- *
- * @param Carbon $start
- * @param Carbon $end
- * @param int $skipMod
- * @param string $moment
- *
- * @return array
- *
*/
protected function getMonthlyInRange(Carbon $start, Carbon $end, int $skipMod, string $moment): array
{
@@ -84,7 +69,7 @@ trait CalculateRangeOccurrences
if (0 === $attempts % $skipMod && $start->lte($start) && $end->gte($start)) {
$return[] = clone $start;
}
- $attempts++;
+ ++$attempts;
$start->endOfMonth()->startOfDay()->addDay();
}
@@ -94,22 +79,15 @@ trait CalculateRangeOccurrences
/**
* Get the number of daily occurrences for a recurring transaction until date $end is reached. Will skip every
* $skipMod-1 occurrences.
- *
- * @param Carbon $start
- * @param Carbon $end
- * @param int $skipMod
- * @param string $moment
- *
- * @return array
*/
protected function getNdomInRange(Carbon $start, Carbon $end, int $skipMod, string $moment): array
{
- $return = [];
- $attempts = 0;
+ $return = [];
+ $attempts = 0;
$start->startOfMonth();
// this feels a bit like a cop out but why reinvent the wheel?
- $counters = [1 => 'first', 2 => 'second', 3 => 'third', 4 => 'fourth', 5 => 'fifth',];
- $daysOfWeek = [1 => 'Monday', 2 => 'Tuesday', 3 => 'Wednesday', 4 => 'Thursday', 5 => 'Friday', 6 => 'Saturday', 7 => 'Sunday',];
+ $counters = [1 => 'first', 2 => 'second', 3 => 'third', 4 => 'fourth', 5 => 'fifth'];
+ $daysOfWeek = [1 => 'Monday', 2 => 'Tuesday', 3 => 'Wednesday', 4 => 'Thursday', 5 => 'Friday', 6 => 'Saturday', 7 => 'Sunday'];
$parts = explode(',', $moment);
while ($start <= $end) {
$string = sprintf('%s %s of %s %s', $counters[$parts[0]], $daysOfWeek[$parts[1]], $start->format('F'), $start->format('Y'));
@@ -117,7 +95,7 @@ trait CalculateRangeOccurrences
if (0 === $attempts % $skipMod) {
$return[] = clone $newCarbon;
}
- $attempts++;
+ ++$attempts;
$start->endOfMonth()->addDay();
}
@@ -127,43 +105,35 @@ trait CalculateRangeOccurrences
/**
* Get the number of daily occurrences for a recurring transaction until date $end is reached. Will skip every
* $skipMod-1 occurrences.
- *
- * @param Carbon $start
- * @param Carbon $end
- * @param int $skipMod
- * @param string $moment
- *
- * @return array
- *
*/
protected function getWeeklyInRange(Carbon $start, Carbon $end, int $skipMod, string $moment): array
{
- $return = [];
- $attempts = 0;
- Log::debug('Rep is weekly.');
+ $return = [];
+ $attempts = 0;
+ app('log')->debug('Rep is weekly.');
// monday = 1
// sunday = 7
- $dayOfWeek = (int)$moment;
- Log::debug(sprintf('DoW in repetition is %d, in mutator is %d', $dayOfWeek, $start->dayOfWeekIso));
+ $dayOfWeek = (int)$moment;
+ app('log')->debug(sprintf('DoW in repetition is %d, in mutator is %d', $dayOfWeek, $start->dayOfWeekIso));
if ($start->dayOfWeekIso > $dayOfWeek) {
// day has already passed this week, add one week:
$start->addWeek();
- Log::debug(sprintf('Jump to next week, so mutator is now: %s', $start->format('Y-m-d')));
+ app('log')->debug(sprintf('Jump to next week, so mutator is now: %s', $start->format('Y-m-d')));
}
// today is wednesday (3), expected is friday (5): add two days.
// today is friday (5), expected is monday (1), subtract four days.
- Log::debug(sprintf('Mutator is now: %s', $start->format('Y-m-d')));
+ app('log')->debug(sprintf('Mutator is now: %s', $start->format('Y-m-d')));
$dayDifference = $dayOfWeek - $start->dayOfWeekIso;
$start->addDays($dayDifference);
- Log::debug(sprintf('Mutator is now: %s', $start->format('Y-m-d')));
+ app('log')->debug(sprintf('Mutator is now: %s', $start->format('Y-m-d')));
while ($start <= $end) {
if (0 === $attempts % $skipMod && $start->lte($start) && $end->gte($start)) {
- Log::debug('Date is in range of start+end, add to set.');
+ app('log')->debug('Date is in range of start+end, add to set.');
$return[] = clone $start;
}
- $attempts++;
+ ++$attempts;
$start->addWeek();
- Log::debug(sprintf('Mutator is now (end of loop): %s', $start->format('Y-m-d')));
+ app('log')->debug(sprintf('Mutator is now (end of loop): %s', $start->format('Y-m-d')));
}
return $return;
@@ -172,14 +142,6 @@ trait CalculateRangeOccurrences
/**
* Get the number of daily occurrences for a recurring transaction until date $end is reached. Will skip every
* $skipMod-1 occurrences.
- *
- * @param Carbon $start
- * @param Carbon $end
- * @param int $skipMod
- * @param string $moment
- *
- * @return array
- *
*/
protected function getYearlyInRange(Carbon $start, Carbon $end, int $skipMod, string $moment): array
{
@@ -192,15 +154,15 @@ trait CalculateRangeOccurrences
}
// is $date between $start and $end?
- $obj = clone $date;
- $count = 0;
+ $obj = clone $date;
+ $count = 0;
while ($obj <= $end && $obj >= $start && $count < 10) {
if (0 === $attempts % $skipMod) {
$return[] = clone $obj;
}
$obj->addYears();
- $count++;
- $attempts++;
+ ++$count;
+ ++$attempts;
}
return $return;
diff --git a/app/Support/Repositories/Recurring/CalculateXOccurrences.php b/app/Support/Repositories/Recurring/CalculateXOccurrences.php
index eae0b5eaa5..f31171810f 100644
--- a/app/Support/Repositories/Recurring/CalculateXOccurrences.php
+++ b/app/Support/Repositories/Recurring/CalculateXOccurrences.php
@@ -34,12 +34,6 @@ trait CalculateXOccurrences
/**
* Calculates the number of daily occurrences for a recurring transaction, starting at the date, until $count is
* reached. It will skip over $skipMod -1 recurrences.
- *
- * @param Carbon $date
- * @param int $count
- * @param int $skipMod
- *
- * @return array
*/
protected function getXDailyOccurrences(Carbon $date, int $count, int $skipMod): array
{
@@ -51,9 +45,9 @@ trait CalculateXOccurrences
$mutator->addDay();
if (0 === $attempts % $skipMod) {
$return[] = clone $mutator;
- $total++;
+ ++$total;
}
- $attempts++;
+ ++$attempts;
}
return $return;
@@ -62,13 +56,6 @@ trait CalculateXOccurrences
/**
* Calculates the number of monthly occurrences for a recurring transaction, starting at the date, until $count is
* reached. It will skip over $skipMod -1 recurrences.
- *
- * @param Carbon $date
- * @param int $count
- * @param int $skipMod
- * @param string $moment
- *
- * @return array
*/
protected function getXMonthlyOccurrences(Carbon $date, int $count, int $skipMod, string $moment): array
{
@@ -87,9 +74,9 @@ trait CalculateXOccurrences
$mutator->day = $domCorrected;
if (0 === $attempts % $skipMod) {
$return[] = clone $mutator;
- $total++;
+ ++$total;
}
- $attempts++;
+ ++$attempts;
$mutator->endOfMonth()->addDay();
}
@@ -99,25 +86,18 @@ trait CalculateXOccurrences
/**
* Calculates the number of NDOM occurrences for a recurring transaction, starting at the date, until $count is
* reached. It will skip over $skipMod -1 recurrences.
- *
- * @param Carbon $date
- * @param int $count
- * @param int $skipMod
- * @param string $moment
- *
- * @return array
*/
protected function getXNDomOccurrences(Carbon $date, int $count, int $skipMod, string $moment): array
{
- $return = [];
- $total = 0;
- $attempts = 0;
- $mutator = clone $date;
+ $return = [];
+ $total = 0;
+ $attempts = 0;
+ $mutator = clone $date;
$mutator->addDay(); // always assume today has passed.
$mutator->startOfMonth();
// this feels a bit like a cop out but why reinvent the wheel?
- $counters = [1 => 'first', 2 => 'second', 3 => 'third', 4 => 'fourth', 5 => 'fifth',];
- $daysOfWeek = [1 => 'Monday', 2 => 'Tuesday', 3 => 'Wednesday', 4 => 'Thursday', 5 => 'Friday', 6 => 'Saturday', 7 => 'Sunday',];
+ $counters = [1 => 'first', 2 => 'second', 3 => 'third', 4 => 'fourth', 5 => 'fifth'];
+ $daysOfWeek = [1 => 'Monday', 2 => 'Tuesday', 3 => 'Wednesday', 4 => 'Thursday', 5 => 'Friday', 6 => 'Saturday', 7 => 'Sunday'];
$parts = explode(',', $moment);
while ($total < $count) {
@@ -125,9 +105,9 @@ trait CalculateXOccurrences
$newCarbon = new Carbon($string);
if (0 === $attempts % $skipMod) {
$return[] = clone $newCarbon;
- $total++;
+ ++$total;
}
- $attempts++;
+ ++$attempts;
$mutator->endOfMonth()->addDay();
}
@@ -137,24 +117,17 @@ trait CalculateXOccurrences
/**
* Calculates the number of weekly occurrences for a recurring transaction, starting at the date, until $count is
* reached. It will skip over $skipMod -1 recurrences.
- *
- * @param Carbon $date
- * @param int $count
- * @param int $skipMod
- * @param string $moment
- *
- * @return array
*/
protected function getXWeeklyOccurrences(Carbon $date, int $count, int $skipMod, string $moment): array
{
- $return = [];
- $total = 0;
- $attempts = 0;
- $mutator = clone $date;
+ $return = [];
+ $total = 0;
+ $attempts = 0;
+ $mutator = clone $date;
// monday = 1
// sunday = 7
$mutator->addDay(); // always assume today has passed.
- $dayOfWeek = (int)$moment;
+ $dayOfWeek = (int)$moment;
if ($mutator->dayOfWeekIso > $dayOfWeek) {
// day has already passed this week, add one week:
$mutator->addWeek();
@@ -167,9 +140,9 @@ trait CalculateXOccurrences
while ($total < $count) {
if (0 === $attempts % $skipMod) {
$return[] = clone $mutator;
- $total++;
+ ++$total;
}
- $attempts++;
+ ++$attempts;
$mutator->addWeek();
}
@@ -179,13 +152,6 @@ trait CalculateXOccurrences
/**
* Calculates the number of yearly occurrences for a recurring transaction, starting at the date, until $count is
* reached. It will skip over $skipMod -1 recurrences.
- *
- * @param Carbon $date
- * @param int $count
- * @param int $skipMod
- * @param string $moment
- *
- * @return array
*/
protected function getXYearlyOccurrences(Carbon $date, int $count, int $skipMod, string $moment): array
{
@@ -198,14 +164,14 @@ trait CalculateXOccurrences
if ($mutator > $date) {
$date->addYear();
}
- $obj = clone $date;
+ $obj = clone $date;
while ($total < $count) {
if (0 === $attempts % $skipMod) {
$return[] = clone $obj;
- $total++;
+ ++$total;
}
$obj->addYears();
- $attempts++;
+ ++$attempts;
}
return $return;
diff --git a/app/Support/Repositories/Recurring/CalculateXOccurrencesSince.php b/app/Support/Repositories/Recurring/CalculateXOccurrencesSince.php
index f4c52b5580..26eb8b8b98 100644
--- a/app/Support/Repositories/Recurring/CalculateXOccurrencesSince.php
+++ b/app/Support/Repositories/Recurring/CalculateXOccurrencesSince.php
@@ -25,7 +25,6 @@ declare(strict_types=1);
namespace FireflyIII\Support\Repositories\Recurring;
use Carbon\Carbon;
-use Illuminate\Support\Facades\Log;
/**
* Class CalculateXOccurrencesSince
@@ -35,17 +34,10 @@ trait CalculateXOccurrencesSince
/**
* Calculates the number of daily occurrences for a recurring transaction, starting at the date, until $count is
* reached. It will skip over $skipMod -1 recurrences.
- *
- * @param Carbon $date
- * @param Carbon $afterDate
- * @param int $count
- * @param int $skipMod
- *
- * @return array
*/
protected function getXDailyOccurrencesSince(Carbon $date, Carbon $afterDate, int $count, int $skipMod): array
{
- Log::debug(sprintf('Now in %s', __METHOD__));
+ app('log')->debug(sprintf('Now in %s', __METHOD__));
$return = [];
$mutator = clone $date;
$total = 0;
@@ -53,10 +45,10 @@ trait CalculateXOccurrencesSince
while ($total < $count) {
if (0 === $attempts % $skipMod && $mutator->gt($afterDate)) {
$return[] = clone $mutator;
- $total++;
+ ++$total;
}
$mutator->addDay();
- $attempts++;
+ ++$attempts;
}
return $return;
@@ -66,17 +58,11 @@ trait CalculateXOccurrencesSince
* Calculates the number of monthly occurrences for a recurring transaction, starting at the date, until $count is
* reached. It will skip over $skipMod -1 recurrences.
*
- * @param Carbon $date
- * @param Carbon $afterDate
- * @param int $count
- * @param int $skipMod
- * @param string $moment
- *
- * @return array
+ * @SuppressWarnings(PHPMD.ExcessiveParameterList)
*/
protected function getXMonthlyOccurrencesSince(Carbon $date, Carbon $afterDate, int $count, int $skipMod, string $moment): array
{
- Log::debug(sprintf('Now in %s(%s, %s, %d)', __METHOD__, $date->format('Y-m-d'), $afterDate->format('Y-m-d'), $count));
+ app('log')->debug(sprintf('Now in %s(%s, %s, %d)', __METHOD__, $date->format('Y-m-d'), $afterDate->format('Y-m-d'), $count));
$return = [];
$mutator = clone $date;
$total = 0;
@@ -84,10 +70,10 @@ trait CalculateXOccurrencesSince
$dayOfMonth = (int)$moment;
$dayOfMonth = 0 === $dayOfMonth ? 1 : $dayOfMonth;
if ($mutator->day > $dayOfMonth) {
- Log::debug(sprintf('%d is after %d, add a month. Mutator is now', $mutator->day, $dayOfMonth));
+ app('log')->debug(sprintf('%d is after %d, add a month. Mutator is now', $mutator->day, $dayOfMonth));
// day has passed already, add a month.
$mutator->addMonth();
- Log::debug(sprintf('%s', $mutator->format('Y-m-d')));
+ app('log')->debug(sprintf('%s', $mutator->format('Y-m-d')));
}
while ($total < $count) {
@@ -95,11 +81,11 @@ trait CalculateXOccurrencesSince
$mutator->day = $domCorrected;
if (0 === $attempts % $skipMod && $mutator->gte($afterDate)) {
$return[] = clone $mutator;
- $total++;
+ ++$total;
}
- $attempts++;
- $mutator = $mutator->endOfMonth()->addDay();
- Log::debug(sprintf('Mutator is now %s', $mutator->format('Y-m-d')));
+ ++$attempts;
+ $mutator = $mutator->endOfMonth()->addDay();
+ app('log')->debug(sprintf('Mutator is now %s', $mutator->format('Y-m-d')));
}
return $return;
@@ -109,26 +95,20 @@ trait CalculateXOccurrencesSince
* Calculates the number of NDOM occurrences for a recurring transaction, starting at the date, until $count is
* reached. It will skip over $skipMod -1 recurrences.
*
- * @param Carbon $date
- * @param Carbon $afterDate
- * @param int $count
- * @param int $skipMod
- * @param string $moment
- *
- * @return array
+ * @SuppressWarnings(PHPMD.ExcessiveParameterList)
*/
protected function getXNDomOccurrencesSince(Carbon $date, Carbon $afterDate, int $count, int $skipMod, string $moment): array
{
- Log::debug(sprintf('Now in %s', __METHOD__));
- $return = [];
- $total = 0;
- $attempts = 0;
- $mutator = clone $date;
+ app('log')->debug(sprintf('Now in %s', __METHOD__));
+ $return = [];
+ $total = 0;
+ $attempts = 0;
+ $mutator = clone $date;
$mutator->addDay(); // always assume today has passed.
$mutator->startOfMonth();
// this feels a bit like a cop out but why reinvent the wheel?
- $counters = [1 => 'first', 2 => 'second', 3 => 'third', 4 => 'fourth', 5 => 'fifth',];
- $daysOfWeek = [1 => 'Monday', 2 => 'Tuesday', 3 => 'Wednesday', 4 => 'Thursday', 5 => 'Friday', 6 => 'Saturday', 7 => 'Sunday',];
+ $counters = [1 => 'first', 2 => 'second', 3 => 'third', 4 => 'fourth', 5 => 'fifth'];
+ $daysOfWeek = [1 => 'Monday', 2 => 'Tuesday', 3 => 'Wednesday', 4 => 'Thursday', 5 => 'Friday', 6 => 'Saturday', 7 => 'Sunday'];
$parts = explode(',', $moment);
while ($total < $count) {
@@ -136,9 +116,9 @@ trait CalculateXOccurrencesSince
$newCarbon = new Carbon($string);
if (0 === $attempts % $skipMod && $mutator->gte($afterDate)) {
$return[] = clone $newCarbon;
- $total++;
+ ++$total;
}
- $attempts++;
+ ++$attempts;
$mutator->endOfMonth()->addDay();
}
@@ -149,26 +129,20 @@ trait CalculateXOccurrencesSince
* Calculates the number of weekly occurrences for a recurring transaction, starting at the date, until $count is
* reached. It will skip over $skipMod -1 recurrences.
*
- * @param Carbon $date
- * @param Carbon $afterDate
- * @param int $count
- * @param int $skipMod
- * @param string $moment
- *
- * @return array
+ * @SuppressWarnings(PHPMD.ExcessiveParameterList)
*/
protected function getXWeeklyOccurrencesSince(Carbon $date, Carbon $afterDate, int $count, int $skipMod, string $moment): array
{
- Log::debug(sprintf('Now in %s', __METHOD__));
- $return = [];
- $total = 0;
- $attempts = 0;
- $mutator = clone $date;
+ app('log')->debug(sprintf('Now in %s', __METHOD__));
+ $return = [];
+ $total = 0;
+ $attempts = 0;
+ $mutator = clone $date;
// monday = 1
// sunday = 7
// Removed assumption today has passed, see issue https://github.com/firefly-iii/firefly-iii/issues/4798
- //$mutator->addDay(); // always assume today has passed.
- $dayOfWeek = (int)$moment;
+ // $mutator->addDay(); // always assume today has passed.
+ $dayOfWeek = (int)$moment;
if ($mutator->dayOfWeekIso > $dayOfWeek) {
// day has already passed this week, add one week:
$mutator->addWeek();
@@ -181,9 +155,9 @@ trait CalculateXOccurrencesSince
while ($total < $count) {
if (0 === $attempts % $skipMod && $mutator->gte($afterDate)) {
$return[] = clone $mutator;
- $total++;
+ ++$total;
}
- $attempts++;
+ ++$attempts;
$mutator->addWeek();
}
@@ -194,17 +168,11 @@ trait CalculateXOccurrencesSince
* Calculates the number of yearly occurrences for a recurring transaction, starting at the date, until $count is
* reached. It will skip over $skipMod -1 recurrences.
*
- * @param Carbon $date
- * @param Carbon $afterDate
- * @param int $count
- * @param int $skipMod
- * @param string $moment
- *
- * @return array
+ * @SuppressWarnings(PHPMD.ExcessiveParameterList)
*/
protected function getXYearlyOccurrencesSince(Carbon $date, Carbon $afterDate, int $count, int $skipMod, string $moment): array
{
- Log::debug(sprintf('Now in %s(%s, %d, %d, %s)', __METHOD__, $date->format('Y-m-d'), $date->format('Y-m-d'), $count, $skipMod));
+ app('log')->debug(sprintf('Now in %s(%s, %d, %d, %s)', __METHOD__, $date->format('Y-m-d'), $date->format('Y-m-d'), $count, $skipMod));
$return = [];
$mutator = clone $date;
$total = 0;
@@ -212,24 +180,24 @@ trait CalculateXOccurrencesSince
$date = new Carbon($moment);
$date->year = $mutator->year;
if ($mutator > $date) {
- Log::debug(
+ app('log')->debug(
sprintf('mutator (%s) > date (%s), so add a year to date (%s)', $mutator->format('Y-m-d'), $date->format('Y-m-d'), $date->format('Y-m-d'))
);
$date->addYear();
- Log::debug(sprintf('Date is now %s', $date->format('Y-m-d')));
+ app('log')->debug(sprintf('Date is now %s', $date->format('Y-m-d')));
}
- $obj = clone $date;
+ $obj = clone $date;
while ($total < $count) {
- Log::debug(sprintf('total (%d) < count (%d) so go.', $total, $count));
- Log::debug(sprintf('attempts (%d) %% skipmod (%d) === %d', $attempts, $skipMod, $attempts % $skipMod));
- Log::debug(sprintf('Obj (%s) gte afterdate (%s)? %s', $obj->format('Y-m-d'), $afterDate->format('Y-m-d'), var_export($obj->gte($afterDate), true)));
+ app('log')->debug(sprintf('total (%d) < count (%d) so go.', $total, $count));
+ app('log')->debug(sprintf('attempts (%d) %% skipmod (%d) === %d', $attempts, $skipMod, $attempts % $skipMod));
+ app('log')->debug(sprintf('Obj (%s) gte afterdate (%s)? %s', $obj->format('Y-m-d'), $afterDate->format('Y-m-d'), var_export($obj->gte($afterDate), true)));
if (0 === $attempts % $skipMod && $obj->gte($afterDate)) {
- Log::debug('All conditions true, add obj.');
+ app('log')->debug('All conditions true, add obj.');
$return[] = clone $obj;
- $total++;
+ ++$total;
}
$obj->addYears();
- $attempts++;
+ ++$attempts;
}
return $return;
diff --git a/app/Support/Repositories/Recurring/FiltersWeekends.php b/app/Support/Repositories/Recurring/FiltersWeekends.php
index 58da6897ba..e5b4108c93 100644
--- a/app/Support/Repositories/Recurring/FiltersWeekends.php
+++ b/app/Support/Repositories/Recurring/FiltersWeekends.php
@@ -27,7 +27,6 @@ namespace FireflyIII\Support\Repositories\Recurring;
use Carbon\Carbon;
use FireflyIII\Models\RecurrenceRepetition;
use Illuminate\Support\Collection;
-use Illuminate\Support\Facades\Log;
/**
* Trait FiltersWeekends
@@ -36,62 +35,60 @@ trait FiltersWeekends
{
/**
* Filters out all weekend entries, if necessary.
- *
- * @param RecurrenceRepetition $repetition
- * @param array $dates
- *
- * @return array
- *
*/
protected function filterWeekends(RecurrenceRepetition $repetition, array $dates): array
{
- Log::debug(sprintf('Now in %s', __METHOD__));
- if ((int)$repetition->weekend === RecurrenceRepetition::WEEKEND_DO_NOTHING) {
- Log::debug('Repetition will not be filtered on weekend days.');
+ app('log')->debug(sprintf('Now in %s', __METHOD__));
+ if (RecurrenceRepetition::WEEKEND_DO_NOTHING === $repetition->weekend) {
+ app('log')->debug('Repetition will not be filtered on weekend days.');
return $dates;
}
- $return = [];
+ $return = [];
+
/** @var Carbon $date */
foreach ($dates as $date) {
$isWeekend = $date->isWeekend();
if (!$isWeekend) {
$return[] = clone $date;
- //Log::debug(sprintf('Date is %s, not a weekend date.', $date->format('D d M Y')));
+
+ // app('log')->debug(sprintf('Date is %s, not a weekend date.', $date->format('D d M Y')));
continue;
}
// is weekend and must set back to Friday?
- if ($repetition->weekend === RecurrenceRepetition::WEEKEND_TO_FRIDAY) {
- $clone = clone $date;
+ if (RecurrenceRepetition::WEEKEND_TO_FRIDAY === $repetition->weekend) {
+ $clone = clone $date;
$clone->addDays(5 - $date->dayOfWeekIso);
- Log::debug(
+ app('log')->debug(
sprintf('Date is %s, and this is in the weekend, so corrected to %s (Friday).', $date->format('D d M Y'), $clone->format('D d M Y'))
);
$return[] = clone $clone;
+
continue;
}
// postpone to Monday?
- if ($repetition->weekend === RecurrenceRepetition::WEEKEND_TO_MONDAY) {
- $clone = clone $date;
+ if (RecurrenceRepetition::WEEKEND_TO_MONDAY === $repetition->weekend) {
+ $clone = clone $date;
$clone->addDays(8 - $date->dayOfWeekIso);
- Log::debug(
+ app('log')->debug(
sprintf('Date is %s, and this is in the weekend, so corrected to %s (Monday).', $date->format('D d M Y'), $clone->format('D d M Y'))
);
$return[] = $clone;
+
continue;
}
- //Log::debug(sprintf('Date is %s, removed from final result', $date->format('D d M Y')));
+ // app('log')->debug(sprintf('Date is %s, removed from final result', $date->format('D d M Y')));
}
// filter unique dates
- Log::debug(sprintf('Count before filtering: %d', count($dates)));
+ app('log')->debug(sprintf('Count before filtering: %d', count($dates)));
$collection = new Collection($return);
$filtered = $collection->unique();
$return = $filtered->toArray();
- Log::debug(sprintf('Count after filtering: %d', count($return)));
+ app('log')->debug(sprintf('Count after filtering: %d', count($return)));
return $return;
}
diff --git a/app/Support/Repositories/UserGroup/UserGroupTrait.php b/app/Support/Repositories/UserGroup/UserGroupTrait.php
index 87e18cb43c..72559775ec 100644
--- a/app/Support/Repositories/UserGroup/UserGroupTrait.php
+++ b/app/Support/Repositories/UserGroup/UserGroupTrait.php
@@ -1,6 +1,5 @@
userGroup;
@@ -49,10 +45,6 @@ trait UserGroupTrait
/**
* TODO This method does not check if the user has access to this particular user group.
- *
- * @param UserGroup $userGroup
- *
- * @return void
*/
public function setUserGroup(UserGroup $userGroup): void
{
@@ -60,38 +52,37 @@ trait UserGroupTrait
}
/**
- * @param Authenticatable|User|null $user
- *
- * @return void
+ * @throws FireflyException
*/
- public function setUser(Authenticatable | User | null $user): void
+ public function setUser(null|Authenticatable|User $user): void
{
- if (null !== $user) {
+ if ($user instanceof User) {
$this->user = $user;
+ if (null === $user->userGroup) {
+ throw new FireflyException(sprintf('User #%d has no user group.', $user->id));
+ }
$this->userGroup = $user->userGroup;
}
}
/**
- * @param int $userGroupId
- *
* @throws FireflyException
*/
public function setUserGroupById(int $userGroupId): void
{
- $memberships = GroupMembership::where('user_id', $this->user->id)
- ->where('user_group_id', $userGroupId)
- ->count();
+ $memberships = GroupMembership::where('user_id', $this->user->id)
+ ->where('user_group_id', $userGroupId)
+ ->count()
+ ;
if (0 === $memberships) {
throw new FireflyException(sprintf('User #%d has no access to administration #%d', $this->user->id, $userGroupId));
}
- /** @var UserGroup|null $userGroup */
- $userGroup = UserGroup::find($userGroupId);
+
+ /** @var null|UserGroup $userGroup */
+ $userGroup = UserGroup::find($userGroupId);
if (null === $userGroup) {
throw new FireflyException(sprintf('Cannot find administration for user #%d', $this->user->id));
}
$this->userGroup = $userGroup;
}
-
-
}
diff --git a/app/Support/Request/AppendsLocationData.php b/app/Support/Request/AppendsLocationData.php
index 5d126ffb17..eeba807830 100644
--- a/app/Support/Request/AppendsLocationData.php
+++ b/app/Support/Request/AppendsLocationData.php
@@ -23,17 +23,46 @@ declare(strict_types=1);
namespace FireflyIII\Support\Request;
-use Illuminate\Support\Facades\Log;
-
/**
* Trait AppendsLocationData
*/
trait AppendsLocationData
{
+ public function addFromromTransactionStore(array $information, array $return): array
+ {
+ $return['store_location'] = false;
+ if (true === $information['store_location']) {
+ $long = array_key_exists('longitude', $information) ? $information['longitude'] : null;
+ $lat = array_key_exists('latitude', $information) ? $information['latitude'] : null;
+ if (null !== $long && null !== $lat && $this->validLongitude($long) && $this->validLatitude($lat)) {
+ $return['store_location'] = true;
+ $return['longitude'] = $information['longitude'];
+ $return['latitude'] = $information['latitude'];
+ $return['zoom_level'] = $information['zoom_level'];
+ }
+ }
+
+ return $return;
+ }
+
+ private function validLongitude(string $longitude): bool
+ {
+ $number = (float)$longitude;
+
+ return $number >= -180 && $number <= 180;
+ }
+
+ private function validLatitude(string $latitude): bool
+ {
+ $number = (float)$latitude;
+
+ return $number >= -90 && $number <= 90;
+ }
+
/**
* Abstract method.
*
- * @param $key
+ * @param mixed $key
*
* @return bool
*/
@@ -41,16 +70,10 @@ trait AppendsLocationData
/**
* Read the submitted Request data and add new or updated Location data to the array.
- *
- * @param array $data
- *
- * @param string|null $prefix
- *
- * @return array
*/
protected function appendLocationData(array $data, ?string $prefix): array
{
- Log::debug(sprintf('Now in appendLocationData("%s")', $prefix), $data);
+ app('log')->debug(sprintf('Now in appendLocationData("%s")', $prefix), $data);
$data['store_location'] = false;
$data['update_location'] = false;
$data['remove_location'] = false;
@@ -58,16 +81,16 @@ trait AppendsLocationData
$data['latitude'] = null;
$data['zoom_level'] = null;
- $longitudeKey = $this->getLocationKey($prefix, 'longitude');
- $latitudeKey = $this->getLocationKey($prefix, 'latitude');
- $zoomLevelKey = $this->getLocationKey($prefix, 'zoom_level');
- $isValidPOST = $this->isValidPost($prefix);
- $isValidPUT = $this->isValidPUT($prefix);
- $isValidEmptyPUT = $this->isValidEmptyPUT($prefix);
+ $longitudeKey = $this->getLocationKey($prefix, 'longitude');
+ $latitudeKey = $this->getLocationKey($prefix, 'latitude');
+ $zoomLevelKey = $this->getLocationKey($prefix, 'zoom_level');
+ $isValidPOST = $this->isValidPost($prefix);
+ $isValidPUT = $this->isValidPUT($prefix);
+ $isValidEmptyPUT = $this->isValidEmptyPUT($prefix);
// for a POST (store), all fields must be present and not NULL.
if ($isValidPOST) {
- Log::debug('Method is POST and all fields present and not NULL.');
+ app('log')->debug('Method is POST and all fields present and not NULL.');
$data['store_location'] = true;
$data['longitude'] = $this->convertString($longitudeKey);
$data['latitude'] = $this->convertString($latitudeKey);
@@ -76,18 +99,18 @@ trait AppendsLocationData
// for a PUT (api update) or POST update (UI)
if ($isValidPUT) {
- Log::debug('Method is PUT and all fields present and not NULL.');
+ app('log')->debug('Method is PUT and all fields present and not NULL.');
$data['update_location'] = true;
$data['longitude'] = $this->convertString($longitudeKey);
$data['latitude'] = $this->convertString($latitudeKey);
$data['zoom_level'] = $this->convertString($zoomLevelKey);
}
if ($isValidEmptyPUT) {
- Log::debug('Method is PUT and all fields present and NULL.');
+ app('log')->debug('Method is PUT and all fields present and NULL.');
$data['remove_location'] = true;
}
- Log::debug(sprintf('Returning longitude: "%s", latitude: "%s", zoom level: "%s"', $data['longitude'], $data['latitude'], $data['zoom_level']));
- Log::debug(
+ app('log')->debug(sprintf('Returning longitude: "%s", latitude: "%s", zoom level: "%s"', $data['longitude'], $data['latitude'], $data['zoom_level']));
+ app('log')->debug(
sprintf(
'Returning actions: store: %s, update: %s, delete: %s',
var_export($data['store_location'], true),
@@ -99,12 +122,6 @@ trait AppendsLocationData
return $data;
}
- /**
- * @param string|null $prefix
- * @param string $key
- *
- * @return string
- */
private function getLocationKey(?string $prefix, string $key): string
{
if (null === $prefix) {
@@ -114,45 +131,40 @@ trait AppendsLocationData
return sprintf('%s_%s', $prefix, $key);
}
- /**
- * @param string|null $prefix
- *
- * @return bool
- */
- private function isValidPOST(?string $prefix): bool
+ private function isValidPost(?string $prefix): bool
{
- Log::debug('Now in isValidPOST()');
+ app('log')->debug('Now in isValidPost()');
$longitudeKey = $this->getLocationKey($prefix, 'longitude');
$latitudeKey = $this->getLocationKey($prefix, 'latitude');
$zoomLevelKey = $this->getLocationKey($prefix, 'zoom_level');
$hasLocationKey = $this->getLocationKey($prefix, 'has_location');
// fields must not be null:
if (null !== $this->get($longitudeKey) && null !== $this->get($latitudeKey) && null !== $this->get($zoomLevelKey)) {
- Log::debug('All fields present');
+ app('log')->debug('All fields present');
// if is POST and route contains API, this is enough:
if ('POST' === $this->method() && $this->routeIs('api.v1.*')) {
- Log::debug('Is API location');
+ app('log')->debug('Is API location');
return true;
}
// if is POST and route does not contain API, must also have "has_location" = true
- if ('POST' === $this->method() && $this->routeIs('*.store') && !$this->routeIs('api.v1.*') && $hasLocationKey) {
- Log::debug('Is POST + store route.');
+ if ('POST' === $this->method() && $this->routeIs('*.store') && !$this->routeIs('api.v1.*') && '' !== $hasLocationKey) {
+ app('log')->debug('Is POST + store route.');
$hasLocation = $this->boolean($hasLocationKey);
if (true === $hasLocation) {
- Log::debug('Has form form location');
+ app('log')->debug('Has form form location');
return true;
}
- Log::debug('Does not have form location');
+ app('log')->debug('Does not have form location');
return false;
}
- Log::debug('Is not POST API or POST form');
+ app('log')->debug('Is not POST API or POST form');
return false;
}
- Log::debug('Fields not present');
+ app('log')->debug('Fields not present');
return false;
}
@@ -180,59 +192,51 @@ trait AppendsLocationData
* @param bool $default
*
* @return mixed
+ *
+ * @SuppressWarnings(PHPMD.BooleanArgumentFlag)
*/
abstract public function boolean($key = null, $default = false);
- /**
- * @param string|null $prefix
- *
- * @return bool
- */
private function isValidPUT(?string $prefix): bool
{
$longitudeKey = $this->getLocationKey($prefix, 'longitude');
$latitudeKey = $this->getLocationKey($prefix, 'latitude');
$zoomLevelKey = $this->getLocationKey($prefix, 'zoom_level');
$hasLocationKey = $this->getLocationKey($prefix, 'has_location');
- Log::debug('Now in isValidPUT()');
+ app('log')->debug('Now in isValidPUT()');
// all fields must be set:
if (null !== $this->get($longitudeKey) && null !== $this->get($latitudeKey) && null !== $this->get($zoomLevelKey)) {
- Log::debug('All fields present.');
+ app('log')->debug('All fields present.');
// must be PUT and API route:
if ('PUT' === $this->method() && $this->routeIs('api.v1.*')) {
- Log::debug('Is API location');
+ app('log')->debug('Is API location');
return true;
}
// if POST and not API route, must also have "has_location"
// if is POST and route does not contain API, must also have "has_location" = true
- if ('POST' === $this->method() && $this->routeIs('*.update') && !$this->routeIs('api.v1.*') && $hasLocationKey) {
- Log::debug('Is POST + store route.');
+ if ('POST' === $this->method() && $this->routeIs('*.update') && !$this->routeIs('api.v1.*') && '' !== $hasLocationKey) {
+ app('log')->debug('Is POST + store route.');
$hasLocation = $this->boolean($hasLocationKey);
if (true === $hasLocation) {
- Log::debug('Has form location data + has_location');
+ app('log')->debug('Has form location data + has_location');
return true;
}
- Log::debug('Does not have form location');
+ app('log')->debug('Does not have form location');
return false;
}
- Log::debug('Is not POST API or POST form');
+ app('log')->debug('Is not POST API or POST form');
return false;
}
- Log::debug('Fields not present');
+ app('log')->debug('Fields not present');
return false;
}
- /**
- * @param string|null $prefix
- *
- * @return bool
- */
private function isValidEmptyPUT(?string $prefix): bool
{
$longitudeKey = $this->getLocationKey($prefix, 'longitude');
diff --git a/app/Support/Request/ChecksLogin.php b/app/Support/Request/ChecksLogin.php
index e0d236f993..af635bac7e 100644
--- a/app/Support/Request/ChecksLogin.php
+++ b/app/Support/Request/ChecksLogin.php
@@ -26,7 +26,6 @@ namespace FireflyIII\Support\Request;
use FireflyIII\Enums\UserRoleEnum;
use FireflyIII\Models\UserGroup;
use FireflyIII\User;
-use Illuminate\Support\Facades\Log;
/**
* Trait ChecksLogin
@@ -35,52 +34,54 @@ trait ChecksLogin
{
/**
* Verify the request.
- *
- * @return bool
*/
public function authorize(): bool
{
- Log::debug(sprintf('Now in %s', __METHOD__));
+ app('log')->debug(sprintf('Now in %s', __METHOD__));
// Only allow logged-in users
- $check = auth()->check();
+ $check = auth()->check();
if (!$check) {
return false;
}
- if (!property_exists($this, 'acceptedRoles')) {
+ if (!property_exists($this, 'acceptedRoles')) { // @phpstan-ignore-line
app('log')->debug('Request class has no acceptedRoles array');
+
return true; // check for false already took place.
}
+
/** @var User $user */
$user = auth()->user();
$userGroup = $this->getUserGroup();
if (null === $userGroup) {
app('log')->error('User has no valid user group submitted or otherwise.');
+
return false;
}
/** @var UserRoleEnum $role */
foreach ($this->acceptedRoles as $role) {
// system owner cannot overrule this, MUST be member of the group.
- if ($user->hasRoleInGroup($userGroup, $role, true, false)) {
+ $access = $user->hasRoleInGroupOrOwner($userGroup, $role);
+ if ($access) {
return true;
}
}
+
return false;
}
/**
* Return the user group or NULL if none is set.
* Will throw exception if invalid.
- *
- * @return UserGroup|null
*/
public function getUserGroup(): ?UserGroup
{
/** @var User $user */
- $user = auth()->user();
+ $user = auth()->user();
app('log')->debug('Now in getUserGroup()');
- /** @var UserGroup $userGroup */
- $userGroup = $this->route()->parameter('userGroup');
+
+ /** @var null|UserGroup $userGroup */
+ $userGroup = $this->route()?->parameter('userGroup');
if (null === $userGroup) {
app('log')->debug('Request class has no userGroup parameter, but perhaps there is a parameter.');
$userGroupId = (int)$this->get('user_group_id');
@@ -88,13 +89,15 @@ trait ChecksLogin
app('log')->debug(sprintf('Request class has no user_group_id parameter, grab default from user (group #%d).', $user->user_group_id));
$userGroupId = (int)$user->user_group_id;
}
- $userGroup = UserGroup::find($userGroupId);
+ $userGroup = UserGroup::find($userGroupId);
if (null === $userGroup) {
app('log')->error(sprintf('Request class has user_group_id (#%d), but group does not exist.', $userGroupId));
+
return null;
}
app('log')->debug('Request class has valid user_group_id.');
}
+
return $userGroup;
}
}
diff --git a/app/Support/Request/ConvertAPIDataTypes.php b/app/Support/Request/ConvertAPIDataTypes.php
index 837e906847..0c9732e80c 100644
--- a/app/Support/Request/ConvertAPIDataTypes.php
+++ b/app/Support/Request/ConvertAPIDataTypes.php
@@ -26,6 +26,4 @@ namespace FireflyIII\Support\Request;
/**
* Trait ConvertAPIDataTypes
*/
-trait ConvertAPIDataTypes
-{
-}
+trait ConvertAPIDataTypes {}
diff --git a/app/Support/Request/ConvertsDataTypes.php b/app/Support/Request/ConvertsDataTypes.php
index 89c7d4b70c..0e1db9ab00 100644
--- a/app/Support/Request/ConvertsDataTypes.php
+++ b/app/Support/Request/ConvertsDataTypes.php
@@ -28,67 +28,14 @@ use Carbon\Exceptions\InvalidDateException;
use Carbon\Exceptions\InvalidFormatException;
use FireflyIII\Repositories\UserGroups\Account\AccountRepositoryInterface;
use Illuminate\Support\Collection;
-use Illuminate\Support\Facades\Log;
/**
* Trait ConvertsDataTypes
*/
trait ConvertsDataTypes
{
- /**
- * Return integer value.
- *
- * @param string $field
- *
- * @return int
- */
- public function convertInteger(string $field): int
- {
- return (int)$this->get($field);
- }
-
- /**
- * Abstract method that always exists in the Request classes that use this
- * trait, OR a stub needs to be added by any other class that uses this train.
- *
- * @param string $key
- * @param mixed|null $default
- *
- * @return mixed
- */
- abstract public function get(string $key, mixed $default = null): mixed;
-
- /**
- * Return string value.
- *
- * @param string $field
- *
- * @return string
- */
- public function convertString(string $field): string
- {
- $entry = $this->get($field);
- if (!is_scalar($entry)) {
- return '';
- }
- return $this->clearString((string)$entry, false);
- }
-
- /**
- * @param string|null $string
- * @param bool $keepNewlines
- *
- * @return string|null
- */
- public function clearString(?string $string, bool $keepNewlines = true): ?string
- {
- if (null === $string) {
- return null;
- }
- if ('' === $string) {
- return '';
- }
- $search = [
+ private array $characters
+ = [
"\0", // NUL
"\f", // form feed
"\v", // vertical tab
@@ -137,37 +84,80 @@ trait ConvertsDataTypes
"\u{202F}", // narrow no-break space
"\u{3000}", // ideographic space
"\u{FEFF}", // zero width no -break space
+ "\r", // carriage return
];
- $replace = "\x20"; // plain old normal space
- $string = str_replace($search, $replace, $string);
- $secondSearch = $keepNewlines ? ["\r"] : ["\r", "\n", "\t", "\036", "\025"];
- $string = str_replace($secondSearch, '', $string);
+ /**
+ * Return integer value.
+ */
+ public function convertInteger(string $field): int
+ {
+ return (int)$this->get($field);
+ }
+
+ /**
+ * Abstract method that always exists in the Request classes that use this
+ * trait, OR a stub needs to be added by any other class that uses this train.
+ */
+ abstract public function get(string $key, mixed $default = null): mixed;
+
+ /**
+ * Return string value.
+ */
+ public function convertString(string $field): string
+ {
+ $entry = $this->get($field);
+ if (!is_scalar($entry)) {
+ return '';
+ }
+
+ return (string)$this->clearString((string)$entry);
+ }
+
+ public function clearString(?string $string): ?string
+ {
+ $string = $this->clearStringKeepNewlines($string);
- // clear zalgo text (TODO also in API v2)
- $string = preg_replace('/(\pM{2})\pM+/u', '\1', $string);
if (null === $string) {
return null;
}
if ('' === $string) {
return '';
}
+
+ // then remove newlines too:
+ $string = str_replace(["\r", "\n", "\t", "\036", "\025"], '', $string);
+
return trim($string);
}
+ public function clearStringKeepNewlines(?string $string): ?string
+ {
+ if (null === $string) {
+ return null;
+ }
+ if ('' === $string) {
+ return '';
+ }
+ $string = str_replace($this->characters, "\x20", $string);
+
+ // clear zalgo text (TODO also in API v2)
+ $string = preg_replace('/(\pM{2})\pM+/u', '\1', $string);
+
+ return trim((string)$string);
+ }
+
/**
* TODO duplicate, see SelectTransactionsRequest
*
* Validate list of accounts. This one is for V2 endpoints, so it searches for groups, not users.
- *
- * @return Collection
*/
public function getAccountList(): Collection
{
/** @var AccountRepositoryInterface $repository */
$repository = app(AccountRepositoryInterface::class);
- if (method_exists($this, 'validateUserGroup')) {
+ if (method_exists($this, 'validateUserGroup')) { // @phpstan-ignore-line
$userGroup = $this->validateUserGroup($this);
if (null !== $userGroup) {
$repository->setUserGroup($userGroup);
@@ -193,20 +183,14 @@ trait ConvertsDataTypes
/**
* Return string value with newlines.
- *
- * @param string $field
- *
- * @return string
*/
public function stringWithNewlines(string $field): string
{
- return $this->clearString((string)($this->get($field) ?? ''));
+ return (string)$this->clearStringKeepNewlines((string)($this->get($field) ?? ''));
}
/**
* @param mixed $array
- *
- * @return array|null
*/
protected function arrayFromValue($array): ?array
{
@@ -223,11 +207,6 @@ trait ConvertsDataTypes
return null;
}
- /**
- * @param string|null $value
- *
- * @return bool
- */
protected function convertBoolean(?string $value): bool
{
if (null === $value) {
@@ -249,14 +228,9 @@ trait ConvertsDataTypes
return false;
}
- /**
- * @param string|null $string
- *
- * @return Carbon|null
- */
protected function convertDateTime(?string $string): ?Carbon
{
- $value = $this->get($string);
+ $value = $this->get((string)$string);
if (null === $value) {
return null;
}
@@ -267,37 +241,42 @@ trait ConvertsDataTypes
// probably a date format.
try {
$carbon = Carbon::createFromFormat('Y-m-d', $value);
- } catch (InvalidDateException $e) {
- Log::error(sprintf('[1] "%s" is not a valid date: %s', $value, $e->getMessage()));
+ } catch (InvalidDateException $e) { // @phpstan-ignore-line
+ app('log')->error(sprintf('[1] "%s" is not a valid date: %s', $value, $e->getMessage()));
+
return null;
- } catch (InvalidFormatException $e) {
- Log::error(sprintf('[2] "%s" is of an invalid format: %s', $value, $e->getMessage()));
+ } catch (InvalidFormatException $e) { // @phpstan-ignore-line
+ app('log')->error(sprintf('[2] "%s" is of an invalid format: %s', $value, $e->getMessage()));
return null;
}
+ if (false === $carbon) {
+ app('log')->error(sprintf('[2] "%s" is of an invalid format.', $value));
+
+ return null;
+ }
+
return $carbon;
}
+
// is an atom string, I hope?
try {
$carbon = Carbon::parse($value);
- } catch (InvalidDateException $e) {
- Log::error(sprintf('[3] "%s" is not a valid date or time: %s', $value, $e->getMessage()));
+ } catch (InvalidDateException $e) { // @phpstan-ignore-line
+ app('log')->error(sprintf('[3] "%s" is not a valid date or time: %s', $value, $e->getMessage()));
return null;
} catch (InvalidFormatException $e) {
- Log::error(sprintf('[4] "%s" is of an invalid format: %s', $value, $e->getMessage()));
+ app('log')->error(sprintf('[4] "%s" is of an invalid format: %s', $value, $e->getMessage()));
return null;
}
+
return $carbon;
}
/**
* Return floating value.
- *
- * @param string $field
- *
- * @return float|null
*/
protected function convertFloat(string $field): ?float
{
@@ -309,11 +288,6 @@ trait ConvertsDataTypes
return (float)$res;
}
- /**
- * @param string|null $string
- *
- * @return Carbon|null
- */
protected function dateFromValue(?string $string): ?Carbon
{
if (null === $string) {
@@ -323,17 +297,18 @@ trait ConvertsDataTypes
return null;
}
$carbon = null;
+
try {
$carbon = new Carbon($string, config('app.timezone'));
} catch (InvalidFormatException $e) {
// @ignoreException
}
if (null === $carbon) {
- Log::debug(sprintf('Invalid date: %s', $string));
+ app('log')->debug(sprintf('Invalid date: %s', $string));
return null;
}
- Log::debug(sprintf('Date object: %s (%s)', $carbon->toW3cString(), $carbon->getTimezone()));
+ app('log')->debug(sprintf('Date object: %s (%s)', $carbon->toW3cString(), $carbon->getTimezone()));
return $carbon;
}
@@ -341,18 +316,14 @@ trait ConvertsDataTypes
/**
* Returns all data in the request, or omits the field if not set,
* according to the config from the request. This is the way.
- *
- * @param array $fields
- *
- * @return array
*/
protected function getAllData(array $fields): array
{
$return = [];
foreach ($fields as $field => $info) {
- if ($this->has($info[0])) {
+ if (true === $this->has($info[0])) {
$method = $info[1];
- $return[$field] = $this->$method($info[0]);
+ $return[$field] = $this->{$method}($info[0]); // @phpstan-ignore-line
}
}
@@ -371,21 +342,18 @@ trait ConvertsDataTypes
/**
* Return date or NULL.
- *
- * @param string $field
- *
- * @return Carbon|null
*/
protected function getCarbonDate(string $field): ?Carbon
{
$result = null;
+
try {
- $result = $this->get($field) ? new Carbon($this->get($field), config('app.timezone')) : null;
+ $result = '' !== (string)$this->get($field) ? new Carbon((string)$this->get($field), config('app.timezone')) : null;
} catch (InvalidFormatException $e) {
// @ignoreException
}
if (null === $result) {
- Log::debug(sprintf('Exception when parsing date "%s".', $this->get($field)));
+ app('log')->debug(sprintf('Exception when parsing date "%s".', $this->get($field)));
}
return $result;
@@ -393,10 +361,6 @@ trait ConvertsDataTypes
/**
* Parse to integer
- *
- * @param string|null $string
- *
- * @return int|null
*/
protected function integerFromValue(?string $string): ?int
{
@@ -412,14 +376,10 @@ trait ConvertsDataTypes
/**
* Return integer value, or NULL when it's not set.
- *
- * @param string $field
- *
- * @return int|null
*/
protected function nullableInteger(string $field): ?int
{
- if (!$this->has($field)) {
+ if (false === $this->has($field)) {
return null;
}
diff --git a/app/Support/Request/GetRecurrenceData.php b/app/Support/Request/GetRecurrenceData.php
index d26b9e702e..a687cf3215 100644
--- a/app/Support/Request/GetRecurrenceData.php
+++ b/app/Support/Request/GetRecurrenceData.php
@@ -28,67 +28,27 @@ namespace FireflyIII\Support\Request;
*/
trait GetRecurrenceData
{
- /**
- * @param array $transaction
- *
- * @return array
- */
protected function getSingleTransactionData(array $transaction): array
{
- $return = [];
+ $return = [];
+ $stringKeys = ['id'];
+ $intKeys = ['currency_id', 'foreign_currency_id', 'source_id', 'destination_id', 'bill_id', 'piggy_bank_id', 'bill_id', 'budget_id', 'category_id'];
+ $keys = ['amount', 'currency_code', 'foreign_amount', 'foreign_currency_code', 'description', 'tags'];
- if (array_key_exists('id', $transaction)) {
- $return['id'] = (string)$transaction['id'];
+ foreach ($stringKeys as $key) {
+ if (array_key_exists($key, $transaction)) {
+ $return[$key] = (string)$transaction[$key];
+ }
}
-
- // amount + currency
- if (array_key_exists('amount', $transaction)) {
- $return['amount'] = $transaction['amount'];
+ foreach ($intKeys as $key) {
+ if (array_key_exists($key, $transaction)) {
+ $return[$key] = (int)$transaction[$key];
+ }
}
- if (array_key_exists('currency_id', $transaction)) {
- $return['currency_id'] = (int)$transaction['currency_id'];
- }
- if (array_key_exists('currency_code', $transaction)) {
- $return['currency_code'] = $transaction['currency_code'];
- }
-
- // foreign amount + currency
- if (array_key_exists('foreign_amount', $transaction)) {
- $return['foreign_amount'] = $transaction['foreign_amount'];
- }
- if (array_key_exists('foreign_currency_id', $transaction)) {
- $return['foreign_currency_id'] = (int)$transaction['foreign_currency_id'];
- }
- if (array_key_exists('foreign_currency_code', $transaction)) {
- $return['foreign_currency_code'] = $transaction['foreign_currency_code'];
- }
- // source + dest
- if (array_key_exists('source_id', $transaction)) {
- $return['source_id'] = (int)$transaction['source_id'];
- }
- if (array_key_exists('destination_id', $transaction)) {
- $return['destination_id'] = (int)$transaction['destination_id'];
- }
- // description
- if (array_key_exists('description', $transaction)) {
- $return['description'] = $transaction['description'];
- }
-
- if (array_key_exists('piggy_bank_id', $transaction)) {
- $return['piggy_bank_id'] = (int)$transaction['piggy_bank_id'];
- }
- if (array_key_exists('bill_id', $transaction)) {
- $return['bill_id'] = (int)$transaction['bill_id'];
- }
-
- if (array_key_exists('tags', $transaction)) {
- $return['tags'] = $transaction['tags'];
- }
- if (array_key_exists('budget_id', $transaction)) {
- $return['budget_id'] = (int)$transaction['budget_id'];
- }
- if (array_key_exists('category_id', $transaction)) {
- $return['category_id'] = (int)$transaction['category_id'];
+ foreach ($keys as $key) {
+ if (array_key_exists($key, $transaction)) {
+ $return[$key] = $transaction[$key];
+ }
}
return $return;
diff --git a/app/Support/Request/GetRuleConfiguration.php b/app/Support/Request/GetRuleConfiguration.php
index 776d966ea6..d1fa61edc2 100644
--- a/app/Support/Request/GetRuleConfiguration.php
+++ b/app/Support/Request/GetRuleConfiguration.php
@@ -28,17 +28,11 @@ namespace FireflyIII\Support\Request;
*/
trait GetRuleConfiguration
{
- /**
- * @return array
- */
protected function getTriggers(): array
{
return array_keys(config('search.operators'));
}
- /**
- * @return array
- */
protected function getTriggersWithContext(): array
{
$list = config('search.operators');
diff --git a/app/Support/Search/AccountSearch.php b/app/Support/Search/AccountSearch.php
index 7ca86aa79e..60214a1290 100644
--- a/app/Support/Search/AccountSearch.php
+++ b/app/Support/Search/AccountSearch.php
@@ -35,15 +35,19 @@ use Illuminate\Support\Collection;
class AccountSearch implements GenericSearchInterface
{
/** @var string */
- public const SEARCH_ALL = 'all';
+ public const string SEARCH_ALL = 'all';
+
/** @var string */
- public const SEARCH_IBAN = 'iban';
+ public const string SEARCH_IBAN = 'iban';
+
/** @var string */
- public const SEARCH_ID = 'id';
+ public const string SEARCH_ID = 'id';
+
/** @var string */
- public const SEARCH_NAME = 'name';
+ public const string SEARCH_NAME = 'name';
+
/** @var string */
- public const SEARCH_NUMBER = 'number';
+ public const string SEARCH_NUMBER = 'number';
private string $field;
private string $query;
private array $types;
@@ -54,22 +58,21 @@ class AccountSearch implements GenericSearchInterface
$this->types = [];
}
- /**
- * @return Collection
- */
public function search(): Collection
{
$searchQuery = $this->user->accounts()
- ->leftJoin('account_types', 'accounts.account_type_id', '=', 'account_types.id')
- ->leftJoin('account_meta', 'accounts.id', '=', 'account_meta.account_id')
- ->whereIn('account_types.type', $this->types);
+ ->leftJoin('account_types', 'accounts.account_type_id', '=', 'account_types.id')
+ ->leftJoin('account_meta', 'accounts.id', '=', 'account_meta.account_id')
+ ->whereIn('account_types.type', $this->types)
+ ;
$like = sprintf('%%%s%%', $this->query);
$originalQuery = $this->query;
+
switch ($this->field) {
default:
case self::SEARCH_ALL:
$searchQuery->where(
- static function (Builder $q) use ($like) {
+ static function (Builder $q) use ($like): void { // @phpstan-ignore-line
$q->where('accounts.id', 'LIKE', $like);
$q->orWhere('accounts.name', 'LIKE', $like);
$q->orWhere('accounts.iban', 'LIKE', $like);
@@ -77,69 +80,64 @@ class AccountSearch implements GenericSearchInterface
);
// meta data:
$searchQuery->orWhere(
- static function (Builder $q) use ($originalQuery) {
+ static function (Builder $q) use ($originalQuery): void { // @phpstan-ignore-line
$json = json_encode($originalQuery, JSON_THROW_ON_ERROR);
$q->where('account_meta.name', '=', 'account_number');
$q->where('account_meta.data', 'LIKE', $json);
}
);
+
break;
+
case self::SEARCH_ID:
$searchQuery->where('accounts.id', '=', (int)$originalQuery);
+
break;
+
case self::SEARCH_NAME:
$searchQuery->where('accounts.name', 'LIKE', $like);
+
break;
+
case self::SEARCH_IBAN:
$searchQuery->where('accounts.iban', 'LIKE', $like);
+
break;
+
case self::SEARCH_NUMBER:
// meta data:
$searchQuery->Where(
- static function (Builder $q) use ($originalQuery) {
+ static function (Builder $q) use ($originalQuery): void { // @phpstan-ignore-line
$json = json_encode($originalQuery, JSON_THROW_ON_ERROR);
$q->where('account_meta.name', 'account_number');
$q->where('account_meta.data', $json);
}
);
+
break;
}
return $searchQuery->distinct()->get(['accounts.*']);
}
- /**
- * @param string $field
- */
public function setField(string $field): void
{
$this->field = $field;
}
- /**
- * @param string $query
- */
public function setQuery(string $query): void
{
$this->query = $query;
}
- /**
- * @param array $types
- */
public function setTypes(array $types): void
{
$this->types = $types;
}
- /**
- * @param User|Authenticatable|null $user
- *
- * @return void
- */
- public function setUser(User | Authenticatable | null $user): void
+ public function setUser(null|Authenticatable|User $user): void
{
- if (null !== $user) {
+ if ($user instanceof User) {
$this->user = $user;
}
}
diff --git a/app/Support/Search/GenericSearchInterface.php b/app/Support/Search/GenericSearchInterface.php
index e7bb9005c3..1c765b459e 100644
--- a/app/Support/Search/GenericSearchInterface.php
+++ b/app/Support/Search/GenericSearchInterface.php
@@ -31,8 +31,5 @@ use Illuminate\Support\Collection;
*/
interface GenericSearchInterface
{
- /**
- * @return Collection
- */
public function search(): Collection;
}
diff --git a/app/Support/Search/OperatorQuerySearch.php b/app/Support/Search/OperatorQuerySearch.php
index b0a64829fc..dcac60ceda 100644
--- a/app/Support/Search/OperatorQuerySearch.php
+++ b/app/Support/Search/OperatorQuerySearch.php
@@ -24,6 +24,8 @@ declare(strict_types=1);
namespace FireflyIII\Support\Search;
use Carbon\Carbon;
+use FireflyIII\Enums\SearchDirection;
+use FireflyIII\Enums\StringPosition;
use FireflyIII\Exceptions\FireflyException;
use FireflyIII\Helpers\Collector\GroupCollectorInterface;
use FireflyIII\Models\Account;
@@ -34,8 +36,8 @@ 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\Tag\TagRepositoryInterface;
+use FireflyIII\Repositories\UserGroups\Currency\CurrencyRepositoryInterface;
use FireflyIII\Support\ParseDateString;
use FireflyIII\User;
use Gdbots\QueryParser\Enum\BoolOperator;
@@ -54,12 +56,11 @@ use Gdbots\QueryParser\Node\Word;
use Gdbots\QueryParser\QueryParser;
use Illuminate\Pagination\LengthAwarePaginator;
use Illuminate\Support\Collection;
-use Illuminate\Support\Facades\Log;
-use LogicException;
-use TypeError;
/**
* Class OperatorQuerySearch
+ *
+ * @SuppressWarnings(PHPMD.CouplingBetweenObjects)
*/
class OperatorQuerySearch implements SearchInterface
{
@@ -70,6 +71,8 @@ class OperatorQuerySearch implements SearchInterface
private CategoryRepositoryInterface $categoryRepository;
private GroupCollectorInterface $collector;
private CurrencyRepositoryInterface $currencyRepository;
+ private array $excludeTags;
+ private array $includeTags;
private array $invalidOperators;
private int $limit;
private Collection $operators;
@@ -82,15 +85,15 @@ class OperatorQuerySearch implements SearchInterface
/**
* OperatorQuerySearch constructor.
- *
-
*/
public function __construct()
{
- Log::debug('Constructed OperatorQuerySearch');
+ app('log')->debug('Constructed OperatorQuerySearch');
$this->operators = new Collection();
$this->page = 1;
$this->words = [];
+ $this->excludeTags = [];
+ $this->includeTags = [];
$this->prohibitedWords = [];
$this->invalidOperators = [];
$this->limit = 25;
@@ -104,40 +107,27 @@ class OperatorQuerySearch implements SearchInterface
$this->currencyRepository = app(CurrencyRepositoryInterface::class);
}
- /**
- * @return array
- */
public function getInvalidOperators(): array
{
return $this->invalidOperators;
}
- /**
- * @inheritDoc
- */
public function getModifiers(): Collection
{
return $this->getOperators();
}
- /**
- * @inheritDoc
- */
public function getOperators(): Collection
{
return $this->operators;
}
- /**
- * @inheritDoc
- */
public function getWordsAsString(): string
{
return implode(' ', $this->words);
}
/**
- * @inheritDoc
* @throws FireflyException
*/
public function hasModifiers(): bool
@@ -146,49 +136,54 @@ class OperatorQuerySearch implements SearchInterface
}
/**
- * @inheritDoc
* @throws FireflyException
*/
- public function parseQuery(string $query)
+ public function parseQuery(string $query): void
{
- Log::debug(sprintf('Now in parseQuery(%s)', $query));
+ app('log')->debug(sprintf('Now in parseQuery(%s)', $query));
$parser = new QueryParser();
+
try {
$query1 = $parser->parse($query);
- } catch (TypeError | LogicException $e) {
- Log::error($e->getMessage());
- Log::error(sprintf('Could not parse search: "%s".', $query));
+ } catch (\LogicException|\TypeError $e) {
+ app('log')->error($e->getMessage());
+ app('log')->error(sprintf('Could not parse search: "%s".', $query));
+
throw new FireflyException(sprintf('Invalid search value "%s". See the logs.', e($query)), 0, $e);
}
- Log::debug(sprintf('Found %d node(s)', count($query1->getNodes())));
+ app('log')->debug(sprintf('Found %d node(s)', count($query1->getNodes())));
foreach ($query1->getNodes() as $searchNode) {
$this->handleSearchNode($searchNode);
}
-
$this->collector->setSearchWords($this->words);
$this->collector->excludeSearchWords($this->prohibitedWords);
}
/**
- * @param Node $searchNode
- *
* @throws FireflyException
+ *
+ * @SuppressWarnings(PHPMD.CyclomaticComplexity)
*/
private function handleSearchNode(Node $searchNode): void
{
$class = get_class($searchNode);
- Log::debug(sprintf('Now in handleSearchNode(%s)', $class));
+ app('log')->debug(sprintf('Now in handleSearchNode(%s)', $class));
+
switch ($class) {
default:
- Log::error(sprintf('Cannot handle node %s', $class));
+ app('log')->error(sprintf('Cannot handle node %s', $class));
+
throw new FireflyException(sprintf('Firefly III search cant handle "%s"-nodes', $class));
+
case Subquery::class:
// loop all notes in subquery:
foreach ($searchNode->getNodes() as $subNode) { // @phpstan-ignore-line PHPStan thinks getNodes() does not exist but it does.
$this->handleSearchNode($subNode); // let's hope it's not too recursive
}
+
break;
+
case Word::class:
case Phrase::class:
case Numbr::class:
@@ -198,28 +193,37 @@ class OperatorQuerySearch implements SearchInterface
case Emoticon::class:
case Emoji::class:
case Mention::class:
- $allWords = (string)$searchNode->getValue();
- Log::debug(sprintf('Add words "%s" to search string, because Node class is "%s"', $allWords, $class));
+ $allWords = (string)$searchNode->getValue();
+ app('log')->debug(sprintf('Add words "%s" to search string, because Node class is "%s"', $allWords, $class));
$this->words[] = $allWords;
+
break;
+
case Field::class:
- Log::debug(sprintf('Now handle Node class %s', $class));
+ app('log')->debug(sprintf('Now handle Node class %s', $class));
+
/** @var Field $searchNode */
// used to search for x:y
- $operator = strtolower($searchNode->getValue());
- $value = $searchNode->getNode()->getValue();
- $prohibited = $searchNode->getBoolOperator() === BoolOperator::PROHIBITED;
- $context = config(sprintf('search.operators.%s.needs_context', $operator));
+ $operator = strtolower($searchNode->getValue());
+ $value = $searchNode->getNode()->getValue();
+ $prohibited = BoolOperator::PROHIBITED === $searchNode->getBoolOperator();
+ $context = config(sprintf('search.operators.%s.needs_context', $operator));
// is an operator that needs no context, and value is false, then prohibited = true.
- if ('false' === $value && in_array($operator, $this->validOperators, true) && false === $context) {
+ if ('false' === $value && in_array($operator, $this->validOperators, true) && false === $context && !$prohibited) {
$prohibited = true;
+ $value = 'true';
+ }
+ // if the operator is prohibited, but the value is false, do an uno reverse
+ if ('false' === $value && $prohibited && in_array($operator, $this->validOperators, true) && false === $context) {
+ $prohibited = false;
+ $value = 'true';
}
// must be valid operator:
if (
- in_array($operator, $this->validOperators, true) &&
- $this->updateCollector($operator, (string)$value, $prohibited)) {
+ in_array($operator, $this->validOperators, true)
+ && $this->updateCollector($operator, (string)$value, $prohibited)) {
$this->operators->push(
[
'type' => self::getRootOperator($operator),
@@ -227,10 +231,10 @@ class OperatorQuerySearch implements SearchInterface
'prohibited' => $prohibited,
]
);
- Log::debug(sprintf('Added operator type "%s"', $operator));
+ app('log')->debug(sprintf('Added operator type "%s"', $operator));
}
if (!in_array($operator, $this->validOperators, true)) {
- Log::debug(sprintf('Added INVALID operator type "%s"', $operator));
+ app('log')->debug(sprintf('Added INVALID operator type "%s"', $operator));
$this->invalidOperators[] = [
'type' => $operator,
'value' => (string)$value,
@@ -240,131 +244,200 @@ class OperatorQuerySearch implements SearchInterface
}
/**
- *
* @throws FireflyException
+ *
+ * @SuppressWarnings(PHPMD.ExcessiveMethodLength)
+ * @SuppressWarnings(PHPMD.CyclomaticComplexity)
*/
private function updateCollector(string $operator, string $value, bool $prohibited): bool
{
if ($prohibited) {
- Log::debug(sprintf('Operator "%s" is now "%s"', $operator, sprintf('-%s', $operator)));
+ app('log')->debug(sprintf('Operator "%s" is now "%s"', $operator, sprintf('-%s', $operator)));
$operator = sprintf('-%s', $operator);
}
- Log::debug(sprintf('Now in updateCollector("%s", "%s")', $operator, $value));
+ app('log')->debug(sprintf('Now in updateCollector("%s", "%s")', $operator, $value));
// check if alias, replace if necessary:
$operator = self::getRootOperator($operator);
switch ($operator) {
default:
- Log::error(sprintf('No such operator: %s', $operator));
+ app('log')->error(sprintf('No such operator: %s', $operator));
+
throw new FireflyException(sprintf('Unsupported search operator: "%s"', $operator));
+
// some search operators are ignored, basically:
case 'user_action':
- Log::info(sprintf('Ignore search operator "%s"', $operator));
+ app('log')->info(sprintf('Ignore search operator "%s"', $operator));
return false;
+
//
// all account related searches:
//
case 'account_is':
- $this->searchAccount($value, 3, 4);
+ $this->searchAccount($value, SearchDirection::BOTH, StringPosition::IS);
+
break;
+
case '-account_is':
- $this->searchAccount($value, 3, 4, true);
+ $this->searchAccount($value, SearchDirection::BOTH, StringPosition::IS, true);
+
break;
+
case 'account_contains':
- $this->searchAccount($value, 3, 3);
+ $this->searchAccount($value, SearchDirection::BOTH, StringPosition::CONTAINS);
+
break;
+
case '-account_contains':
- $this->searchAccount($value, 3, 3, true);
+ $this->searchAccount($value, SearchDirection::BOTH, StringPosition::CONTAINS, true);
+
break;
+
case 'account_ends':
- $this->searchAccount($value, 3, 2);
+ $this->searchAccount($value, SearchDirection::BOTH, StringPosition::ENDS);
+
break;
+
case '-account_ends':
- $this->searchAccount($value, 3, 2, true);
+ $this->searchAccount($value, SearchDirection::BOTH, StringPosition::ENDS, true);
+
break;
+
case 'account_starts':
- $this->searchAccount($value, 3, 1);
+ $this->searchAccount($value, SearchDirection::BOTH, StringPosition::STARTS);
+
break;
+
case '-account_starts':
- $this->searchAccount($value, 3, 1, true);
+ $this->searchAccount($value, SearchDirection::BOTH, StringPosition::STARTS, true);
+
break;
+
case 'account_nr_is':
- $this->searchAccountNr($value, 3, 4);
+ $this->searchAccountNr($value, SearchDirection::BOTH, StringPosition::IS);
+
break;
+
case '-account_nr_is':
- $this->searchAccountNr($value, 3, 4, true);
+ $this->searchAccountNr($value, SearchDirection::BOTH, StringPosition::IS, true);
+
break;
+
case 'account_nr_contains':
- $this->searchAccountNr($value, 3, 3);
+ $this->searchAccountNr($value, SearchDirection::BOTH, StringPosition::CONTAINS);
+
break;
+
case '-account_nr_contains':
- $this->searchAccountNr($value, 3, 3, true);
+ $this->searchAccountNr($value, SearchDirection::BOTH, StringPosition::CONTAINS, true);
+
break;
+
case 'account_nr_ends':
- $this->searchAccountNr($value, 3, 2);
+ $this->searchAccountNr($value, SearchDirection::BOTH, StringPosition::ENDS);
+
break;
+
case '-account_nr_ends':
- $this->searchAccountNr($value, 3, 2, true);
+ $this->searchAccountNr($value, SearchDirection::BOTH, StringPosition::ENDS, true);
+
break;
+
case 'account_nr_starts':
- $this->searchAccountNr($value, 3, 1);
+ $this->searchAccountNr($value, SearchDirection::BOTH, StringPosition::STARTS);
+
break;
+
case '-account_nr_starts':
- $this->searchAccountNr($value, 3, 1, true);
+ $this->searchAccountNr($value, SearchDirection::BOTH, StringPosition::STARTS, true);
+
break;
+
case 'source_account_starts':
- $this->searchAccount($value, 1, 1);
+ $this->searchAccount($value, SearchDirection::SOURCE, StringPosition::STARTS);
+
break;
+
case '-source_account_starts':
- $this->searchAccount($value, 1, 1, true);
+ $this->searchAccount($value, SearchDirection::SOURCE, StringPosition::STARTS, true);
+
break;
+
case 'source_account_ends':
- $this->searchAccount($value, 1, 2);
+ $this->searchAccount($value, SearchDirection::SOURCE, StringPosition::ENDS);
+
break;
+
case '-source_account_ends':
- $this->searchAccount($value, 1, 2, true);
+ $this->searchAccount($value, SearchDirection::SOURCE, StringPosition::ENDS, true);
+
break;
+
case 'source_account_is':
- $this->searchAccount($value, 1, 4);
+ $this->searchAccount($value, SearchDirection::SOURCE, StringPosition::IS);
+
break;
+
case '-source_account_is':
- $this->searchAccount($value, 1, 4, true);
+ $this->searchAccount($value, SearchDirection::SOURCE, StringPosition::IS, true);
+
break;
+
case 'source_account_nr_starts':
- $this->searchAccountNr($value, 1, 1);
+ $this->searchAccountNr($value, SearchDirection::SOURCE, StringPosition::STARTS);
+
break;
+
case '-source_account_nr_starts':
- $this->searchAccountNr($value, 1, 1, true);
+ $this->searchAccountNr($value, SearchDirection::SOURCE, StringPosition::STARTS, true);
+
break;
+
case 'source_account_nr_ends':
- $this->searchAccountNr($value, 1, 2);
+ $this->searchAccountNr($value, SearchDirection::SOURCE, StringPosition::ENDS);
+
break;
+
case '-source_account_nr_ends':
- $this->searchAccountNr($value, 1, 2, true);
+ $this->searchAccountNr($value, SearchDirection::SOURCE, StringPosition::ENDS, true);
+
break;
+
case 'source_account_nr_is':
- $this->searchAccountNr($value, 1, 4);
+ $this->searchAccountNr($value, SearchDirection::SOURCE, StringPosition::IS);
+
break;
+
case '-source_account_nr_is':
- $this->searchAccountNr($value, 1, 4, true);
+ $this->searchAccountNr($value, SearchDirection::SOURCE, StringPosition::IS, true);
+
break;
+
case 'source_account_nr_contains':
- $this->searchAccountNr($value, 1, 3);
+ $this->searchAccountNr($value, SearchDirection::SOURCE, StringPosition::CONTAINS);
+
break;
+
case '-source_account_nr_contains':
- $this->searchAccountNr($value, 1, 3, true);
+ $this->searchAccountNr($value, SearchDirection::SOURCE, StringPosition::CONTAINS, true);
+
break;
+
case 'source_account_contains':
- $this->searchAccount($value, 1, 3);
+ $this->searchAccount($value, SearchDirection::SOURCE, StringPosition::CONTAINS);
+
break;
+
case '-source_account_contains':
- $this->searchAccount($value, 1, 3, true);
+ $this->searchAccount($value, SearchDirection::SOURCE, StringPosition::CONTAINS, true);
+
break;
+
case 'source_account_id':
- $account = $this->accountRepository->find((int)$value);
+ $account = $this->accountRepository->find((int)$value);
if (null !== $account) {
$this->collector->setSourceAccounts(new Collection([$account]));
}
@@ -372,9 +445,11 @@ class OperatorQuerySearch implements SearchInterface
// since the source does not exist, cannot return results:
$this->collector->findNothing();
}
+
break;
+
case '-source_account_id':
- $account = $this->accountRepository->find((int)$value);
+ $account = $this->accountRepository->find((int)$value);
if (null !== $account) {
$this->collector->excludeSourceAccounts(new Collection([$account]));
}
@@ -382,92 +457,138 @@ class OperatorQuerySearch implements SearchInterface
// since the source does not exist, cannot return results:
$this->collector->findNothing();
}
+
break;
+
case 'journal_id':
- $parts = explode(',', $value);
+ $parts = explode(',', $value);
$this->collector->setJournalIds($parts);
+
break;
+
case '-journal_id':
- $parts = explode(',', $value);
+ $parts = explode(',', $value);
$this->collector->excludeJournalIds($parts);
+
break;
+
case 'id':
- $parts = explode(',', $value);
+ $parts = explode(',', $value);
$this->collector->setIds($parts);
+
break;
+
case '-id':
- $parts = explode(',', $value);
+ $parts = explode(',', $value);
$this->collector->excludeIds($parts);
+
break;
+
case 'destination_account_starts':
- $this->searchAccount($value, 2, 1);
+ $this->searchAccount($value, SearchDirection::DESTINATION, StringPosition::STARTS);
+
break;
+
case '-destination_account_starts':
- $this->searchAccount($value, 2, 1, true);
+ $this->searchAccount($value, SearchDirection::DESTINATION, StringPosition::STARTS, true);
+
break;
+
case 'destination_account_ends':
- $this->searchAccount($value, 2, 2);
+ $this->searchAccount($value, SearchDirection::DESTINATION, StringPosition::ENDS);
+
break;
+
case '-destination_account_ends':
- $this->searchAccount($value, 2, 2, true);
+ $this->searchAccount($value, SearchDirection::DESTINATION, StringPosition::ENDS, true);
+
break;
+
case 'destination_account_nr_starts':
- $this->searchAccountNr($value, 2, 1);
+ $this->searchAccountNr($value, SearchDirection::DESTINATION, StringPosition::STARTS);
+
break;
+
case '-destination_account_nr_starts':
- $this->searchAccountNr($value, 2, 1, true);
+ $this->searchAccountNr($value, SearchDirection::DESTINATION, StringPosition::STARTS, true);
+
break;
+
case 'destination_account_nr_ends':
- $this->searchAccountNr($value, 2, 2);
+ $this->searchAccountNr($value, SearchDirection::DESTINATION, StringPosition::ENDS);
+
break;
+
case '-destination_account_nr_ends':
- $this->searchAccountNr($value, 2, 2, true);
+ $this->searchAccountNr($value, SearchDirection::DESTINATION, StringPosition::ENDS, true);
+
break;
+
case 'destination_account_nr_is':
- $this->searchAccountNr($value, 2, 4);
+ $this->searchAccountNr($value, SearchDirection::DESTINATION, StringPosition::IS);
+
break;
+
case '-destination_account_nr_is':
- $this->searchAccountNr($value, 2, 4, true);
+ $this->searchAccountNr($value, SearchDirection::DESTINATION, StringPosition::IS, true);
+
break;
+
case 'destination_account_is':
- $this->searchAccount($value, 2, 4);
+ $this->searchAccount($value, SearchDirection::DESTINATION, StringPosition::IS);
+
break;
+
case '-destination_account_is':
- $this->searchAccount($value, 2, 4, true);
+ $this->searchAccount($value, SearchDirection::DESTINATION, StringPosition::IS, true);
+
break;
+
case 'destination_account_nr_contains':
- $this->searchAccountNr($value, 2, 3);
+ $this->searchAccountNr($value, SearchDirection::DESTINATION, StringPosition::CONTAINS);
+
break;
+
case '-destination_account_nr_contains':
- $this->searchAccountNr($value, 2, 3, true);
+ $this->searchAccountNr($value, SearchDirection::DESTINATION, StringPosition::CONTAINS, true);
+
break;
+
case 'destination_account_contains':
- $this->searchAccount($value, 2, 3);
+ $this->searchAccount($value, SearchDirection::DESTINATION, StringPosition::CONTAINS);
+
break;
+
case '-destination_account_contains':
- $this->searchAccount($value, 2, 3, true);
+ $this->searchAccount($value, SearchDirection::DESTINATION, StringPosition::CONTAINS, true);
+
break;
+
case 'destination_account_id':
- $account = $this->accountRepository->find((int)$value);
+ $account = $this->accountRepository->find((int)$value);
if (null !== $account) {
$this->collector->setDestinationAccounts(new Collection([$account]));
}
if (null === $account) {
$this->collector->findNothing();
}
+
break;
+
case '-destination_account_id':
- $account = $this->accountRepository->find((int)$value);
+ $account = $this->accountRepository->find((int)$value);
if (null !== $account) {
$this->collector->excludeDestinationAccounts(new Collection([$account]));
}
if (null === $account) {
$this->collector->findNothing();
}
+
break;
+
case 'account_id':
- $parts = explode(',', $value);
- $collection = new Collection();
+ $parts = explode(',', $value);
+ $collection = new Collection();
foreach ($parts as $accountId) {
$account = $this->accountRepository->find((int)$accountId);
if (null !== $account) {
@@ -480,10 +601,12 @@ class OperatorQuerySearch implements SearchInterface
if (0 === $collection->count()) {
$this->collector->findNothing();
}
+
break;
+
case '-account_id':
- $parts = explode(',', $value);
- $collection = new Collection();
+ $parts = explode(',', $value);
+ $collection = new Collection();
foreach ($parts as $accountId) {
$account = $this->accountRepository->find((int)$accountId);
if (null !== $account) {
@@ -496,704 +619,1011 @@ class OperatorQuerySearch implements SearchInterface
if (0 === $collection->count()) {
$this->collector->findNothing();
}
+
break;
+
//
// cash account
//
case 'source_is_cash':
- $account = $this->getCashAccount();
+ $account = $this->getCashAccount();
$this->collector->setSourceAccounts(new Collection([$account]));
+
break;
+
case '-source_is_cash':
- $account = $this->getCashAccount();
+ $account = $this->getCashAccount();
$this->collector->excludeSourceAccounts(new Collection([$account]));
+
break;
+
case 'destination_is_cash':
- $account = $this->getCashAccount();
+ $account = $this->getCashAccount();
$this->collector->setDestinationAccounts(new Collection([$account]));
+
break;
+
case '-destination_is_cash':
- $account = $this->getCashAccount();
+ $account = $this->getCashAccount();
$this->collector->excludeDestinationAccounts(new Collection([$account]));
+
break;
+
case 'account_is_cash':
- $account = $this->getCashAccount();
+ $account = $this->getCashAccount();
$this->collector->setAccounts(new Collection([$account]));
+
break;
+
case '-account_is_cash':
- $account = $this->getCashAccount();
+ $account = $this->getCashAccount();
$this->collector->excludeAccounts(new Collection([$account]));
+
break;
+
//
// description
//
case 'description_starts':
$this->collector->descriptionStarts([$value]);
+
break;
+
case '-description_starts':
$this->collector->descriptionDoesNotStart([$value]);
+
break;
+
case 'description_ends':
$this->collector->descriptionEnds([$value]);
+
break;
+
case '-description_ends':
$this->collector->descriptionDoesNotEnd([$value]);
+
break;
+
case 'description_contains':
- $this->words[] = $value;
+ $this->words[] = $value;
return false;
+
case '-description_contains':
$this->prohibitedWords[] = $value;
break;
+
case 'description_is':
$this->collector->descriptionIs($value);
+
break;
+
case '-description_is':
$this->collector->descriptionIsNot($value);
+
break;
+
//
// currency
//
case 'currency_is':
- $currency = $this->findCurrency($value);
+ $currency = $this->findCurrency($value);
if (null !== $currency) {
$this->collector->setCurrency($currency);
}
if (null === $currency) {
$this->collector->findNothing();
}
+
break;
+
case '-currency_is':
- $currency = $this->findCurrency($value);
+ $currency = $this->findCurrency($value);
if (null !== $currency) {
$this->collector->excludeCurrency($currency);
}
if (null === $currency) {
$this->collector->findNothing();
}
+
break;
+
case 'foreign_currency_is':
- $currency = $this->findCurrency($value);
+ $currency = $this->findCurrency($value);
if (null !== $currency) {
$this->collector->setForeignCurrency($currency);
}
if (null === $currency) {
$this->collector->findNothing();
}
+
break;
+
case '-foreign_currency_is':
- $currency = $this->findCurrency($value);
+ $currency = $this->findCurrency($value);
if (null !== $currency) {
$this->collector->excludeForeignCurrency($currency);
}
if (null === $currency) {
$this->collector->findNothing();
}
+
break;
+
//
// attachments
//
case 'has_attachments':
case '-has_no_attachments':
- Log::debug('Set collector to filter on attachments.');
+ app('log')->debug('Set collector to filter on attachments.');
$this->collector->hasAttachments();
+
break;
+
case 'has_no_attachments':
case '-has_attachments':
- Log::debug('Set collector to filter on NO attachments.');
+ app('log')->debug('Set collector to filter on NO attachments.');
$this->collector->hasNoAttachments();
+
break;
+
//
// categories
case '-has_any_category':
case 'has_no_category':
$this->collector->withoutCategory();
+
break;
+
case '-has_no_category':
case 'has_any_category':
$this->collector->withCategory();
+
break;
+
case 'category_is':
- $category = $this->categoryRepository->findByName($value);
+ $category = $this->categoryRepository->findByName($value);
if (null !== $category) {
$this->collector->setCategory($category);
+
break;
}
$this->collector->findNothing();
+
break;
+
case '-category_is':
- $category = $this->categoryRepository->findByName($value);
+ $category = $this->categoryRepository->findByName($value);
if (null !== $category) {
$this->collector->excludeCategory($category);
+
break;
}
+
break;
+
case 'category_ends':
- $result = $this->categoryRepository->categoryEndsWith($value, 1337);
+ $result = $this->categoryRepository->categoryEndsWith($value, 1337);
if ($result->count() > 0) {
$this->collector->setCategories($result);
}
if (0 === $result->count()) {
$this->collector->findNothing();
}
+
break;
+
case '-category_ends':
- $result = $this->categoryRepository->categoryEndsWith($value, 1337);
+ $result = $this->categoryRepository->categoryEndsWith($value, 1337);
if ($result->count() > 0) {
$this->collector->excludeCategories($result);
}
if (0 === $result->count()) {
$this->collector->findNothing();
}
+
break;
+
case 'category_starts':
- $result = $this->categoryRepository->categoryStartsWith($value, 1337);
+ $result = $this->categoryRepository->categoryStartsWith($value, 1337);
if ($result->count() > 0) {
$this->collector->setCategories($result);
}
if (0 === $result->count()) {
$this->collector->findNothing();
}
+
break;
+
case '-category_starts':
- $result = $this->categoryRepository->categoryStartsWith($value, 1337);
+ $result = $this->categoryRepository->categoryStartsWith($value, 1337);
if ($result->count() > 0) {
$this->collector->excludeCategories($result);
}
if (0 === $result->count()) {
$this->collector->findNothing();
}
+
break;
+
case 'category_contains':
- $result = $this->categoryRepository->searchCategory($value, 1337);
+ $result = $this->categoryRepository->searchCategory($value, 1337);
if ($result->count() > 0) {
$this->collector->setCategories($result);
}
if (0 === $result->count()) {
$this->collector->findNothing();
}
+
break;
+
case '-category_contains':
- $result = $this->categoryRepository->searchCategory($value, 1337);
+ $result = $this->categoryRepository->searchCategory($value, 1337);
if ($result->count() > 0) {
$this->collector->excludeCategories($result);
}
if (0 === $result->count()) {
$this->collector->findNothing();
}
+
break;
+
//
// budgets
//
case '-has_any_budget':
case 'has_no_budget':
$this->collector->withoutBudget();
+
break;
+
case 'has_any_budget':
case '-has_no_budget':
$this->collector->withBudget();
+
break;
+
case 'budget_contains':
- $result = $this->budgetRepository->searchBudget($value, 1337);
+ $result = $this->budgetRepository->searchBudget($value, 1337);
if ($result->count() > 0) {
$this->collector->setBudgets($result);
}
if (0 === $result->count()) {
$this->collector->findNothing();
}
+
break;
+
case '-budget_contains':
- $result = $this->budgetRepository->searchBudget($value, 1337);
+ $result = $this->budgetRepository->searchBudget($value, 1337);
if ($result->count() > 0) {
$this->collector->excludeBudgets($result);
}
if (0 === $result->count()) {
$this->collector->findNothing();
}
+
break;
+
case 'budget_is':
- $budget = $this->budgetRepository->findByName($value);
+ $budget = $this->budgetRepository->findByName($value);
if (null !== $budget) {
$this->collector->setBudget($budget);
+
break;
}
$this->collector->findNothing();
+
break;
+
case '-budget_is':
- $budget = $this->budgetRepository->findByName($value);
+ $budget = $this->budgetRepository->findByName($value);
if (null !== $budget) {
$this->collector->excludeBudget($budget);
+
break;
}
$this->collector->findNothing();
+
break;
+
case 'budget_ends':
- $result = $this->budgetRepository->budgetEndsWith($value, 1337);
+ $result = $this->budgetRepository->budgetEndsWith($value, 1337);
if ($result->count() > 0) {
$this->collector->setBudgets($result);
}
if (0 === $result->count()) {
$this->collector->findNothing();
}
+
break;
+
case '-budget_ends':
- $result = $this->budgetRepository->budgetEndsWith($value, 1337);
+ $result = $this->budgetRepository->budgetEndsWith($value, 1337);
if ($result->count() > 0) {
$this->collector->excludeBudgets($result);
}
if (0 === $result->count()) {
$this->collector->findNothing();
}
+
break;
+
case 'budget_starts':
- $result = $this->budgetRepository->budgetStartsWith($value, 1337);
+ $result = $this->budgetRepository->budgetStartsWith($value, 1337);
if ($result->count() > 0) {
$this->collector->setBudgets($result);
}
if (0 === $result->count()) {
$this->collector->findNothing();
}
+
break;
+
case '-budget_starts':
- $result = $this->budgetRepository->budgetStartsWith($value, 1337);
+ $result = $this->budgetRepository->budgetStartsWith($value, 1337);
if ($result->count() > 0) {
$this->collector->excludeBudgets($result);
}
if (0 === $result->count()) {
$this->collector->findNothing();
}
+
break;
+
//
// bill
//
case '-has_any_bill':
case 'has_no_bill':
$this->collector->withoutBill();
+
break;
+
case '-has_no_bill':
case 'has_any_bill':
$this->collector->withBill();
+
break;
+
case 'bill_contains':
- $result = $this->billRepository->searchBill($value, 1337);
+ $result = $this->billRepository->searchBill($value, 1337);
if ($result->count() > 0) {
$this->collector->setBills($result);
+
break;
}
$this->collector->findNothing();
+
break;
+
case '-bill_contains':
- $result = $this->billRepository->searchBill($value, 1337);
+ $result = $this->billRepository->searchBill($value, 1337);
if ($result->count() > 0) {
$this->collector->excludeBills($result);
+
break;
}
$this->collector->findNothing();
+
break;
+
case 'bill_is':
- $bill = $this->billRepository->findByName($value);
+ $bill = $this->billRepository->findByName($value);
if (null !== $bill) {
$this->collector->setBill($bill);
+
break;
}
$this->collector->findNothing();
+
break;
+
case '-bill_is':
- $bill = $this->billRepository->findByName($value);
+ $bill = $this->billRepository->findByName($value);
if (null !== $bill) {
$this->collector->excludeBills(new Collection([$bill]));
+
break;
}
$this->collector->findNothing();
+
break;
+
case 'bill_ends':
- $result = $this->billRepository->billEndsWith($value, 1337);
+ $result = $this->billRepository->billEndsWith($value, 1337);
if ($result->count() > 0) {
$this->collector->setBills($result);
}
if (0 === $result->count()) {
$this->collector->findNothing();
}
+
break;
+
case '-bill_ends':
- $result = $this->billRepository->billEndsWith($value, 1337);
+ $result = $this->billRepository->billEndsWith($value, 1337);
if ($result->count() > 0) {
$this->collector->excludeBills($result);
}
if (0 === $result->count()) {
$this->collector->findNothing();
}
+
break;
+
case 'bill_starts':
- $result = $this->billRepository->billStartsWith($value, 1337);
+ $result = $this->billRepository->billStartsWith($value, 1337);
if ($result->count() > 0) {
$this->collector->setBills($result);
}
if (0 === $result->count()) {
$this->collector->findNothing();
}
+
break;
+
case '-bill_starts':
- $result = $this->billRepository->billStartsWith($value, 1337);
+ $result = $this->billRepository->billStartsWith($value, 1337);
if ($result->count() > 0) {
$this->collector->excludeBills($result);
}
if (0 === $result->count()) {
$this->collector->findNothing();
}
+
break;
+
//
// tags
//
case '-has_any_tag':
case 'has_no_tag':
$this->collector->withoutTags();
+
break;
+
case '-has_no_tag':
case 'has_any_tag':
$this->collector->hasAnyTag();
+
break;
+
case '-tag_is_not':
case 'tag_is':
- $result = $this->tagRepository->findByTag($value);
+ $result = $this->tagRepository->findByTag($value);
if (null !== $result) {
- $this->collector->setTags(new Collection([$result]));
+ $this->includeTags[] = $result->id;
+ $this->includeTags = array_unique($this->includeTags);
}
// no tags found means search must result in nothing.
if (null === $result) {
- Log::info(sprintf('No valid tags in "%s"-operator, so search will not return ANY results.', $operator));
+ app('log')->info(sprintf('No valid tags in "%s"-operator, so search will not return ANY results.', $operator));
$this->collector->findNothing();
}
+
break;
+
+ case 'tag_contains':
+ $tags = $this->tagRepository->searchTag($value);
+ if (0 === $tags->count()) {
+ app('log')->info(sprintf('No valid tags in "%s"-operator, so search will not return ANY results.', $operator));
+ $this->collector->findNothing();
+ }
+ if ($tags->count() > 0) {
+ $ids = array_values($tags->pluck('id')->toArray());
+ $this->includeTags = array_unique(array_merge($this->includeTags, $ids));
+ }
+
+ break;
+
+ case 'tag_starts':
+ $tags = $this->tagRepository->tagStartsWith($value);
+ if (0 === $tags->count()) {
+ app('log')->info(sprintf('No valid tags in "%s"-operator, so search will not return ANY results.', $operator));
+ $this->collector->findNothing();
+ }
+ if ($tags->count() > 0) {
+ $ids = array_values($tags->pluck('id')->toArray());
+ $this->includeTags = array_unique(array_merge($this->includeTags, $ids));
+ }
+
+ break;
+
+ case '-tag_starts':
+ $tags = $this->tagRepository->tagStartsWith($value);
+ if (0 === $tags->count()) {
+ app('log')->info(sprintf('No valid tags in "%s"-operator, so search will not return ANY results.', $operator));
+ $this->collector->findNothing();
+ }
+ if ($tags->count() > 0) {
+ $ids = array_values($tags->pluck('id')->toArray());
+ $this->excludeTags = array_unique(array_merge($this->includeTags, $ids));
+ }
+
+ break;
+
+ case 'tag_ends':
+ $tags = $this->tagRepository->tagEndsWith($value);
+ if (0 === $tags->count()) {
+ app('log')->info(sprintf('No valid tags in "%s"-operator, so search will not return ANY results.', $operator));
+ $this->collector->findNothing();
+ }
+ if ($tags->count() > 0) {
+ $ids = array_values($tags->pluck('id')->toArray());
+ $this->includeTags = array_unique(array_merge($this->includeTags, $ids));
+ }
+
+ break;
+
+ case '-tag_ends':
+ $tags = $this->tagRepository->tagEndsWith($value);
+ if (0 === $tags->count()) {
+ app('log')->info(sprintf('No valid tags in "%s"-operator, so search will not return ANY results.', $operator));
+ $this->collector->findNothing();
+ }
+ if ($tags->count() > 0) {
+ $ids = array_values($tags->pluck('id')->toArray());
+ $this->excludeTags = array_unique(array_merge($this->includeTags, $ids));
+ }
+
+ break;
+
+ case '-tag_contains':
+ $tags = $this->tagRepository->searchTag($value)->keyBy('id');
+
+ if (0 === $tags->count()) {
+ app('log')->info(sprintf('No valid tags in "%s"-operator, so search will not return ANY results.', $operator));
+ $this->collector->findNothing();
+ }
+ if ($tags->count() > 0) {
+ $ids = array_values($tags->pluck('id')->toArray());
+ $this->excludeTags = array_unique(array_merge($this->excludeTags, $ids));
+ }
+
+ break;
+
case '-tag_is':
case 'tag_is_not':
- $result = $this->tagRepository->searchTag($value);
- if ($result->count() > 0) {
- $this->collector->setWithoutSpecificTags($result);
+ $result = $this->tagRepository->findByTag($value);
+ if (null !== $result) {
+ $this->excludeTags[] = $result->id;
+ $this->excludeTags = array_unique($this->excludeTags);
}
+
break;
+
//
// notes
//
case 'notes_contains':
$this->collector->notesContain($value);
+
break;
+
case '-notes_contains':
$this->collector->notesDoNotContain($value);
+
break;
+
case 'notes_starts':
$this->collector->notesStartWith($value);
+
break;
+
case '-notes_starts':
$this->collector->notesDontStartWith($value);
+
break;
+
case 'notes_ends':
$this->collector->notesEndWith($value);
+
break;
+
case '-notes_ends':
$this->collector->notesDontEndWith($value);
+
break;
+
case 'notes_is':
$this->collector->notesExactly($value);
+
break;
+
case '-notes_is':
$this->collector->notesExactlyNot($value);
+
break;
+
case '-any_notes':
case 'no_notes':
$this->collector->withoutNotes();
+
break;
+
case 'any_notes':
case '-no_notes':
$this->collector->withAnyNotes();
+
break;
+
case 'reconciled':
$this->collector->isReconciled();
+
break;
+
case '-reconciled':
$this->collector->isNotReconciled();
+
break;
+
//
// amount
//
case 'amount_is':
// strip comma's, make dots.
- Log::debug(sprintf('Original value "%s"', $value));
- $value = str_replace(',', '.', (string)$value);
- $amount = app('steam')->positive($value);
- Log::debug(sprintf('Set "%s" using collector with value "%s"', $operator, $amount));
+ app('log')->debug(sprintf('Original value "%s"', $value));
+ $value = str_replace(',', '.', $value);
+ $amount = app('steam')->positive($value);
+ app('log')->debug(sprintf('Set "%s" using collector with value "%s"', $operator, $amount));
$this->collector->amountIs($amount);
+
break;
+
case '-amount_is':
// strip comma's, make dots.
- Log::debug(sprintf('Original value "%s"', $value));
- $value = str_replace(',', '.', (string)$value);
- $amount = app('steam')->positive($value);
- Log::debug(sprintf('Set "%s" using collector with value "%s"', $operator, $amount));
+ app('log')->debug(sprintf('Original value "%s"', $value));
+ $value = str_replace(',', '.', $value);
+ $amount = app('steam')->positive($value);
+ app('log')->debug(sprintf('Set "%s" using collector with value "%s"', $operator, $amount));
$this->collector->amountIsNot($amount);
+
break;
+
case 'foreign_amount_is':
-
// strip comma's, make dots.
- $value = str_replace(',', '.', (string)$value);
+ $value = str_replace(',', '.', $value);
- $amount = app('steam')->positive($value);
- Log::debug(sprintf('Set "%s" using collector with value "%s"', $operator, $amount));
+ $amount = app('steam')->positive($value);
+ app('log')->debug(sprintf('Set "%s" using collector with value "%s"', $operator, $amount));
$this->collector->foreignAmountIs($amount);
+
break;
+
case '-foreign_amount_is':
-
// strip comma's, make dots.
- $value = str_replace(',', '.', (string)$value);
+ $value = str_replace(',', '.', $value);
- $amount = app('steam')->positive($value);
- Log::debug(sprintf('Set "%s" using collector with value "%s"', $operator, $amount));
+ $amount = app('steam')->positive($value);
+ app('log')->debug(sprintf('Set "%s" using collector with value "%s"', $operator, $amount));
$this->collector->foreignAmountIsNot($amount);
+
break;
+
case '-amount_more':
case 'amount_less':
// strip comma's, make dots.
- $value = str_replace(',', '.', (string)$value);
+ $value = str_replace(',', '.', $value);
- $amount = app('steam')->positive($value);
- Log::debug(sprintf('Set "%s" using collector with value "%s"', $operator, $amount));
+ $amount = app('steam')->positive($value);
+ app('log')->debug(sprintf('Set "%s" using collector with value "%s"', $operator, $amount));
$this->collector->amountLess($amount);
+
break;
+
case '-foreign_amount_more':
case 'foreign_amount_less':
// strip comma's, make dots.
- $value = str_replace(',', '.', (string)$value);
+ $value = str_replace(',', '.', $value);
- $amount = app('steam')->positive($value);
- Log::debug(sprintf('Set "%s" using collector with value "%s"', $operator, $amount));
+ $amount = app('steam')->positive($value);
+ app('log')->debug(sprintf('Set "%s" using collector with value "%s"', $operator, $amount));
$this->collector->foreignAmountLess($amount);
+
break;
+
case '-amount_less':
case 'amount_more':
- Log::debug(sprintf('Now handling operator "%s"', $operator));
+ app('log')->debug(sprintf('Now handling operator "%s"', $operator));
// strip comma's, make dots.
- $value = str_replace(',', '.', (string)$value);
- $amount = app('steam')->positive($value);
- Log::debug(sprintf('Set "%s" using collector with value "%s"', $operator, $amount));
+ $value = str_replace(',', '.', $value);
+ $amount = app('steam')->positive($value);
+ app('log')->debug(sprintf('Set "%s" using collector with value "%s"', $operator, $amount));
$this->collector->amountMore($amount);
+
break;
+
case '-foreign_amount_less':
case 'foreign_amount_more':
- Log::debug(sprintf('Now handling operator "%s"', $operator));
+ app('log')->debug(sprintf('Now handling operator "%s"', $operator));
// strip comma's, make dots.
- $value = str_replace(',', '.', (string)$value);
- $amount = app('steam')->positive($value);
- Log::debug(sprintf('Set "%s" using collector with value "%s"', $operator, $amount));
+ $value = str_replace(',', '.', $value);
+ $amount = app('steam')->positive($value);
+ app('log')->debug(sprintf('Set "%s" using collector with value "%s"', $operator, $amount));
$this->collector->foreignAmountMore($amount);
+
break;
+
//
// transaction type
//
case 'transaction_type':
$this->collector->setTypes([ucfirst($value)]);
- Log::debug(sprintf('Set "%s" using collector with value "%s"', $operator, $value));
+ app('log')->debug(sprintf('Set "%s" using collector with value "%s"', $operator, $value));
+
break;
+
case '-transaction_type':
$this->collector->excludeTypes([ucfirst($value)]);
- Log::debug(sprintf('Set "%s" using collector with value "%s"', $operator, $value));
+ app('log')->debug(sprintf('Set "%s" using collector with value "%s"', $operator, $value));
+
break;
+
//
// dates
//
case '-date_on':
case 'date_on':
- $range = $this->parseDateRange($operator, $value);
+ $range = $this->parseDateRange($operator, $value);
$this->setExactDateParams($range, $prohibited);
+
return false;
+
case 'date_before':
case '-date_after':
- $range = $this->parseDateRange($operator, $value);
+ $range = $this->parseDateRange($operator, $value);
$this->setDateBeforeParams($range);
+
return false;
+
case 'date_after':
case '-date_before':
- $range = $this->parseDateRange($operator, $value);
+ $range = $this->parseDateRange($operator, $value);
$this->setDateAfterParams($range);
+
return false;
case 'interest_date_on':
case '-interest_date_on':
- $range = $this->parseDateRange($operator, $value);
+ $range = $this->parseDateRange($operator, $value);
$this->setExactMetaDateParams('interest_date', $range, $prohibited);
+
return false;
+
case 'interest_date_before':
case '-interest_date_after':
- $range = $this->parseDateRange($operator, $value);
+ $range = $this->parseDateRange($operator, $value);
$this->setMetaDateBeforeParams('interest_date', $range);
+
return false;
+
case 'interest_date_after':
case '-interest_date_before':
- $range = $this->parseDateRange($operator, $value);
+ $range = $this->parseDateRange($operator, $value);
$this->setMetaDateAfterParams('interest_date', $range);
+
return false;
case 'book_date_on':
case '-book_date_on':
- $range = $this->parseDateRange($operator, $value);
+ $range = $this->parseDateRange($operator, $value);
$this->setExactMetaDateParams('book_date', $range, $prohibited);
+
return false;
+
case 'book_date_before':
case '-book_date_after':
- $range = $this->parseDateRange($operator, $value);
+ $range = $this->parseDateRange($operator, $value);
$this->setMetaDateBeforeParams('book_date', $range);
+
return false;
+
case 'book_date_after':
case '-book_date_before':
- $range = $this->parseDateRange($operator, $value);
+ $range = $this->parseDateRange($operator, $value);
$this->setMetaDateAfterParams('book_date', $range);
+
return false;
case 'process_date_on':
case '-process_date_on':
- $range = $this->parseDateRange($operator, $value);
+ $range = $this->parseDateRange($operator, $value);
$this->setExactMetaDateParams('process_date', $range, $prohibited);
+
return false;
+
case 'process_date_before':
case '-process_date_after':
- $range = $this->parseDateRange($operator, $value);
+ $range = $this->parseDateRange($operator, $value);
$this->setMetaDateBeforeParams('process_date', $range);
+
return false;
+
case 'process_date_after':
case '-process_date_before':
- $range = $this->parseDateRange($operator, $value);
+ $range = $this->parseDateRange($operator, $value);
$this->setMetaDateAfterParams('process_date', $range);
+
return false;
case 'due_date_on':
case '-due_date_on':
- $range = $this->parseDateRange($operator, $value);
+ $range = $this->parseDateRange($operator, $value);
$this->setExactMetaDateParams('due_date', $range, $prohibited);
+
return false;
+
case 'due_date_before':
case '-due_date_after':
- $range = $this->parseDateRange($operator, $value);
+ $range = $this->parseDateRange($operator, $value);
$this->setMetaDateBeforeParams('due_date', $range);
+
return false;
+
case 'due_date_after':
case '-due_date_before':
- $range = $this->parseDateRange($operator, $value);
+ $range = $this->parseDateRange($operator, $value);
$this->setMetaDateAfterParams('due_date', $range);
+
return false;
case 'payment_date_on':
case '-payment_date_on':
- $range = $this->parseDateRange($operator, $value);
+ $range = $this->parseDateRange($operator, $value);
$this->setExactMetaDateParams('payment_date', $range, $prohibited);
+
return false;
+
case 'payment_date_before':
case '-payment_date_after':
- $range = $this->parseDateRange($operator, $value);
+ $range = $this->parseDateRange($operator, $value);
$this->setMetaDateBeforeParams('payment_date', $range);
+
return false;
+
case 'payment_date_after':
case '-payment_date_before':
- $range = $this->parseDateRange($operator, $value);
+ $range = $this->parseDateRange($operator, $value);
$this->setMetaDateAfterParams('payment_date', $range);
+
return false;
case 'invoice_date_on':
case '-invoice_date_on':
- $range = $this->parseDateRange($operator, $value);
+ $range = $this->parseDateRange($operator, $value);
$this->setExactMetaDateParams('invoice_date', $range, $prohibited);
+
return false;
+
case 'invoice_date_before':
case '-invoice_date_after':
- $range = $this->parseDateRange($operator, $value);
+ $range = $this->parseDateRange($operator, $value);
$this->setMetaDateBeforeParams('invoice_date', $range);
+
return false;
+
case 'invoice_date_after':
case '-invoice_date_before':
- $range = $this->parseDateRange($operator, $value);
+ $range = $this->parseDateRange($operator, $value);
$this->setMetaDateAfterParams('invoice_date', $range);
+
return false;
case 'created_at_on':
case '-created_at_on':
- Log::debug(sprintf('Set "%s" using collector with value "%s"', $operator, $value));
- $range = $this->parseDateRange($operator, $value);
+ app('log')->debug(sprintf('Set "%s" using collector with value "%s"', $operator, $value));
+ $range = $this->parseDateRange($operator, $value);
$this->setExactObjectDateParams('created_at', $range, $prohibited);
+
return false;
+
case 'created_at_before':
case '-created_at_after':
- Log::debug(sprintf('Set "%s" using collector with value "%s"', $operator, $value));
- $range = $this->parseDateRange($operator, $value);
+ app('log')->debug(sprintf('Set "%s" using collector with value "%s"', $operator, $value));
+ $range = $this->parseDateRange($operator, $value);
$this->setObjectDateBeforeParams('created_at', $range);
+
return false;
+
case 'created_at_after':
case '-created_at_before':
- Log::debug(sprintf('Set "%s" using collector with value "%s"', $operator, $value));
- $range = $this->parseDateRange($operator, $value);
+ app('log')->debug(sprintf('Set "%s" using collector with value "%s"', $operator, $value));
+ $range = $this->parseDateRange($operator, $value);
$this->setObjectDateAfterParams('created_at', $range);
+
return false;
case 'updated_at_on':
case '-updated_at_on':
- Log::debug(sprintf('Set "%s" using collector with value "%s"', $operator, $value));
- $range = $this->parseDateRange($operator, $value);
+ app('log')->debug(sprintf('Set "%s" using collector with value "%s"', $operator, $value));
+ $range = $this->parseDateRange($operator, $value);
$this->setExactObjectDateParams('updated_at', $range, $prohibited);
+
return false;
+
case 'updated_at_before':
case '-updated_at_after':
- Log::debug(sprintf('Set "%s" using collector with value "%s"', $operator, $value));
- $range = $this->parseDateRange($operator, $value);
+ app('log')->debug(sprintf('Set "%s" using collector with value "%s"', $operator, $value));
+ $range = $this->parseDateRange($operator, $value);
$this->setObjectDateBeforeParams('updated_at', $range);
+
return false;
+
case 'updated_at_after':
case '-updated_at_before':
- Log::debug(sprintf('Set "%s" using collector with value "%s"', $operator, $value));
- $range = $this->parseDateRange($operator, $value);
+ app('log')->debug(sprintf('Set "%s" using collector with value "%s"', $operator, $value));
+ $range = $this->parseDateRange($operator, $value);
$this->setObjectDateAfterParams('updated_at', $range);
+
return false;
+
//
// external URL
//
case '-any_external_url':
case 'no_external_url':
$this->collector->withoutExternalUrl();
+
break;
+
case '-no_external_url':
case 'any_external_url':
$this->collector->withExternalUrl();
+
break;
+
case '-any_external_id':
case 'no_external_id':
$this->collector->withoutExternalId();
+
break;
+
case '-no_external_id':
case 'any_external_id':
$this->collector->withExternalId();
+
break;
case 'external_url_is':
$this->collector->setExternalUrl($value);
+
break;
+
case '-external_url_is':
$this->collector->excludeExternalUrl($value);
+
break;
+
case 'external_url_contains':
$this->collector->externalUrlContains($value);
+
break;
+
case '-external_url_contains':
$this->collector->externalUrlDoesNotContain($value);
+
break;
+
case 'external_url_starts':
$this->collector->externalUrlStarts($value);
+
break;
+
case '-external_url_starts':
$this->collector->externalUrlDoesNotStart($value);
+
break;
+
case 'external_url_ends':
$this->collector->externalUrlEnds($value);
+
break;
+
case '-external_url_ends':
$this->collector->externalUrlDoesNotEnd($value);
+
break;
//
@@ -1201,126 +1631,194 @@ class OperatorQuerySearch implements SearchInterface
//
case 'external_id_is':
$this->collector->setExternalId($value);
+
break;
+
case '-external_id_is':
$this->collector->excludeExternalId($value);
+
break;
+
case 'recurrence_id':
$this->collector->setRecurrenceId($value);
+
break;
+
case '-recurrence_id':
$this->collector->excludeRecurrenceId($value);
+
break;
+
case 'external_id_contains':
$this->collector->externalIdContains($value);
+
break;
+
case '-external_id_contains':
$this->collector->externalIdDoesNotContain($value);
+
break;
+
case 'external_id_starts':
$this->collector->externalIdStarts($value);
+
break;
+
case '-external_id_starts':
$this->collector->externalIdDoesNotStart($value);
+
break;
+
case 'external_id_ends':
$this->collector->externalIdEnds($value);
+
break;
+
case '-external_id_ends':
$this->collector->externalIdDoesNotEnd($value);
+
break;
case 'internal_reference_is':
$this->collector->setInternalReference($value);
+
break;
+
case '-internal_reference_is':
$this->collector->excludeInternalReference($value);
+
break;
+
case 'internal_reference_contains':
$this->collector->internalReferenceContains($value);
+
break;
+
case '-internal_reference_contains':
$this->collector->internalReferenceDoesNotContain($value);
+
break;
+
case 'internal_reference_starts':
$this->collector->internalReferenceStarts($value);
+
break;
+
case '-internal_reference_starts':
$this->collector->internalReferenceDoesNotStart($value);
+
break;
+
case 'internal_reference_ends':
$this->collector->internalReferenceEnds($value);
+
break;
+
case '-internal_reference_ends':
$this->collector->internalReferenceDoesNotEnd($value);
+
break;
case 'attachment_name_is':
$this->collector->attachmentNameIs($value);
+
break;
+
case '-attachment_name_is':
$this->collector->attachmentNameIsNot($value);
+
break;
+
case 'attachment_name_contains':
$this->collector->attachmentNameContains($value);
+
break;
+
case '-attachment_name_contains':
$this->collector->attachmentNameDoesNotContain($value);
+
break;
+
case 'attachment_name_starts':
$this->collector->attachmentNameStarts($value);
+
break;
+
case '-attachment_name_starts':
$this->collector->attachmentNameDoesNotStart($value);
+
break;
+
case 'attachment_name_ends':
$this->collector->attachmentNameEnds($value);
+
break;
+
case '-attachment_name_ends':
$this->collector->attachmentNameDoesNotEnd($value);
+
break;
case 'attachment_notes_are':
$this->collector->attachmentNotesAre($value);
+
break;
+
case '-attachment_notes_are':
$this->collector->attachmentNotesAreNot($value);
+
break;
+
case 'attachment_notes_contains':
$this->collector->attachmentNotesContains($value);
+
break;
+
case '-attachment_notes_contains':
$this->collector->attachmentNotesDoNotContain($value);
+
break;
+
case 'attachment_notes_starts':
$this->collector->attachmentNotesStarts($value);
+
break;
+
case '-attachment_notes_starts':
$this->collector->attachmentNotesDoNotStart($value);
+
break;
+
case 'attachment_notes_ends':
$this->collector->attachmentNotesEnds($value);
+
break;
+
case '-attachment_notes_ends':
$this->collector->attachmentNotesDoNotEnd($value);
+
break;
+
case 'exists':
$this->collector->exists();
+
break;
+
case '-exists':
$this->collector->findNothing();
+
break;
+
case 'sepa_ct_is':
$this->collector->setSepaCT($value);
+
break;
}
+
return true;
}
/**
- * @param string $operator
- *
- * @return string
* @throws FireflyException
*/
public static function getRootOperator(string $operator): string
@@ -1332,7 +1830,7 @@ class OperatorQuerySearch implements SearchInterface
$operator = substr($operator, 1);
}
- $config = config(sprintf('search.operators.%s', $operator));
+ $config = config(sprintf('search.operators.%s', $operator));
if (null === $config) {
throw new FireflyException(sprintf('No configuration for search operator "%s"', $operator));
}
@@ -1341,11 +1839,11 @@ class OperatorQuerySearch implements SearchInterface
if (str_starts_with($original, '-')) {
$return = sprintf('-%s', $config['alias_for']);
}
- Log::debug(sprintf('"%s" is an alias for "%s", so return that instead.', $original, $return));
+ app('log')->debug(sprintf('"%s" is an alias for "%s", so return that instead.', $original, $return));
return $return;
}
- Log::debug(sprintf('"%s" is not an alias.', $operator));
+ app('log')->debug(sprintf('"%s" is not an alias.', $operator));
return $original;
}
@@ -1354,14 +1852,12 @@ class OperatorQuerySearch implements SearchInterface
* searchDirection: 1 = source (default), 2 = destination, 3 = both
* stringPosition: 1 = start (default), 2 = end, 3 = contains, 4 = is
*
- * @param string $value
- * @param int $searchDirection
- * @param int $stringPosition
- * @param bool $prohibited
+ * @SuppressWarnings(PHPMD.BooleanArgumentFlag)
+ * @SuppressWarnings(PHPMD.NPathComplexity)
*/
- private function searchAccount(string $value, int $searchDirection, int $stringPosition, bool $prohibited = false): void
+ private function searchAccount(string $value, SearchDirection $searchDirection, StringPosition $stringPosition, bool $prohibited = false): void
{
- Log::debug(sprintf('searchAccount("%s", %d, %d)', $value, $stringPosition, $searchDirection));
+ app('log')->debug(sprintf('searchAccount("%s", %s, %s)', $value, $stringPosition->name, $searchDirection->name));
// search direction (default): for source accounts
$searchTypes = [AccountType::ASSET, AccountType::MORTGAGE, AccountType::LOAN, AccountType::DEBT, AccountType::REVENUE];
@@ -1371,7 +1867,7 @@ class OperatorQuerySearch implements SearchInterface
}
// search direction: for destination accounts
- if (2 === $searchDirection) {
+ if (SearchDirection::DESTINATION === $searchDirection) { // destination
// destination can be
$searchTypes = [AccountType::ASSET, AccountType::MORTGAGE, AccountType::LOAN, AccountType::DEBT, AccountType::EXPENSE];
$collectorMethod = 'setDestinationAccounts';
@@ -1380,7 +1876,7 @@ class OperatorQuerySearch implements SearchInterface
}
}
// either account could be:
- if (3 === $searchDirection) {
+ if (SearchDirection::BOTH === $searchDirection) {
$searchTypes = [AccountType::ASSET, AccountType::MORTGAGE, AccountType::LOAN, AccountType::DEBT, AccountType::EXPENSE, AccountType::REVENUE];
$collectorMethod = 'setAccounts';
if ($prohibited) {
@@ -1388,56 +1884,60 @@ class OperatorQuerySearch implements SearchInterface
}
}
// string position (default): starts with:
- $stringMethod = 'str_starts_with';
+ $stringMethod = 'str_starts_with';
// string position: ends with:
- if (2 === $stringPosition) {
+ if (StringPosition::ENDS === $stringPosition) {
$stringMethod = 'str_ends_with';
}
- if (3 === $stringPosition) {
+ if (StringPosition::CONTAINS === $stringPosition) {
$stringMethod = 'str_contains';
}
- if (4 === $stringPosition) {
+ if (StringPosition::IS === $stringPosition) {
$stringMethod = 'stringIsEqual';
}
// get accounts:
- $accounts = $this->accountRepository->searchAccount($value, $searchTypes, 1337);
- if (0 === $accounts->count()) {
- Log::debug('Found zero accounts, search for non existing account, NO results will be returned.');
+ $accounts = $this->accountRepository->searchAccount($value, $searchTypes, 1337);
+ if (0 === $accounts->count() && false === $prohibited) {
+ app('log')->debug('Found zero accounts, search for non existing account, NO results will be returned.');
$this->collector->findNothing();
return;
}
- Log::debug(sprintf('Found %d accounts, will filter.', $accounts->count()));
- $filtered = $accounts->filter(
- function (Account $account) use ($value, $stringMethod) {
+ if (0 === $accounts->count() && true === $prohibited) {
+ app('log')->debug('Found zero accounts, but the search is negated, so effectively we ignore the search parameter.');
+
+ return;
+ }
+ app('log')->debug(sprintf('Found %d accounts, will filter.', $accounts->count()));
+ $filtered = $accounts->filter(
+ static function (Account $account) use ($value, $stringMethod) {
return $stringMethod(strtolower($account->name), strtolower($value));
}
);
if (0 === $filtered->count()) {
- Log::debug('Left with zero accounts, so cannot find anything, NO results will be returned.');
+ app('log')->debug('Left with zero accounts, so cannot find anything, NO results will be returned.');
$this->collector->findNothing();
return;
}
- Log::debug(sprintf('Left with %d, set as %s().', $filtered->count(), $collectorMethod));
- $this->collector->$collectorMethod($filtered);
+ app('log')->debug(sprintf('Left with %d, set as %s().', $filtered->count(), $collectorMethod));
+ $this->collector->{$collectorMethod}($filtered); // @phpstan-ignore-line
}
/**
+ * TODO make enums
* searchDirection: 1 = source (default), 2 = destination, 3 = both
* stringPosition: 1 = start (default), 2 = end, 3 = contains, 4 = is
*
- * @param string $value
- * @param int $searchDirection
- * @param int $stringPosition
- * @param bool $prohibited
+ * @SuppressWarnings(PHPMD.BooleanArgumentFlag)
+ * @SuppressWarnings(PHPMD.NPathComplexity)
*/
- private function searchAccountNr(string $value, int $searchDirection, int $stringPosition, bool $prohibited = false): void
+ private function searchAccountNr(string $value, SearchDirection $searchDirection, StringPosition $stringPosition, bool $prohibited = false): void
{
- Log::debug(sprintf('searchAccountNr(%s, %d, %d)', $value, $searchDirection, $stringPosition));
+ app('log')->debug(sprintf('searchAccountNr(%s, %d, %d)', $value, $searchDirection->name, $stringPosition->name));
// search direction (default): for source accounts
$searchTypes = [AccountType::ASSET, AccountType::MORTGAGE, AccountType::LOAN, AccountType::DEBT, AccountType::REVENUE];
@@ -1447,7 +1947,7 @@ class OperatorQuerySearch implements SearchInterface
}
// search direction: for destination accounts
- if (2 === $searchDirection) {
+ if (SearchDirection::DESTINATION === $searchDirection) {
// destination can be
$searchTypes = [AccountType::ASSET, AccountType::MORTGAGE, AccountType::LOAN, AccountType::DEBT, AccountType::EXPENSE];
$collectorMethod = 'setDestinationAccounts';
@@ -1457,7 +1957,7 @@ class OperatorQuerySearch implements SearchInterface
}
// either account could be:
- if (3 === $searchDirection) {
+ if (SearchDirection::BOTH === $searchDirection) {
$searchTypes = [AccountType::ASSET, AccountType::MORTGAGE, AccountType::LOAN, AccountType::DEBT, AccountType::EXPENSE, AccountType::REVENUE];
$collectorMethod = 'setAccounts';
if (true === $prohibited) {
@@ -1466,35 +1966,36 @@ class OperatorQuerySearch implements SearchInterface
}
// string position (default): starts with:
- $stringMethod = 'str_starts_with';
+ $stringMethod = 'str_starts_with';
// string position: ends with:
- if (2 === $stringPosition) {
+ if (StringPosition::ENDS === $stringPosition) {
$stringMethod = 'str_ends_with';
}
- if (3 === $stringPosition) {
+ if (StringPosition::CONTAINS === $stringPosition) {
$stringMethod = 'str_contains';
}
- if (4 === $stringPosition) {
+ if (StringPosition::IS === $stringPosition) {
$stringMethod = 'stringIsEqual';
}
// search for accounts:
- $accounts = $this->accountRepository->searchAccountNr($value, $searchTypes, 1337);
+ $accounts = $this->accountRepository->searchAccountNr($value, $searchTypes, 1337);
if (0 === $accounts->count()) {
- Log::debug('Found zero accounts, search for invalid account.');
+ app('log')->debug('Found zero accounts, search for invalid account.');
$this->collector->findNothing();
return;
}
// if found, do filter
- Log::debug(sprintf('Found %d accounts, will filter.', $accounts->count()));
- $filtered = $accounts->filter(
- function (Account $account) use ($value, $stringMethod) {
+ app('log')->debug(sprintf('Found %d accounts, will filter.', $accounts->count()));
+ $filtered = $accounts->filter(
+ static function (Account $account) use ($value, $stringMethod) {
// either IBAN or account number
- $ibanMatch = $stringMethod(strtolower((string)$account->iban), strtolower((string)$value));
+ $ibanMatch = $stringMethod(strtolower((string)$account->iban), strtolower($value));
$accountNrMatch = false;
+
/** @var AccountMeta $meta */
foreach ($account->accountMeta as $meta) {
if ('account_number' === $meta->name && $stringMethod(strtolower($meta->data), strtolower($value))) {
@@ -1507,28 +2008,20 @@ class OperatorQuerySearch implements SearchInterface
);
if (0 === $filtered->count()) {
- Log::debug('Left with zero, search for invalid account');
+ app('log')->debug('Left with zero, search for invalid account');
$this->collector->findNothing();
return;
}
- Log::debug(sprintf('Left with %d, set as %s().', $filtered->count(), $collectorMethod));
- $this->collector->$collectorMethod($filtered);
+ app('log')->debug(sprintf('Left with %d, set as %s().', $filtered->count(), $collectorMethod));
+ $this->collector->{$collectorMethod}($filtered); // @phpstan-ignore-line
}
- /**
- * @return Account
- */
private function getCashAccount(): Account
{
return $this->accountRepository->getCashAccount();
}
- /**
- * @param string $value
- *
- * @return TransactionCurrency|null
- */
private function findCurrency(string $value): ?TransactionCurrency
{
if (str_contains($value, '(') && str_contains($value, ')')) {
@@ -1536,18 +2029,15 @@ class OperatorQuerySearch implements SearchInterface
$parts = explode(' ', $value);
$value = trim($parts[count($parts) - 1], "() \t\n\r\0\x0B");
}
- $result = $this->currencyRepository->findByCodeNull($value);
+ $result = $this->currencyRepository->findByCode($value);
if (null === $result) {
- $result = $this->currencyRepository->findByNameNull($value);
+ $result = $this->currencyRepository->findByName($value);
}
return $result;
}
/**
- * @param string $value
- *
- * @return array
* @throws FireflyException
*/
private function parseDateRange(string $type, string $value): array
@@ -1556,14 +2046,16 @@ class OperatorQuerySearch implements SearchInterface
if ($parser->isDateRange($value)) {
return $parser->parseRange($value);
}
+
try {
$parsedDate = $parser->parseDate($value);
} catch (FireflyException $e) {
- Log::debug(sprintf('Could not parse date "%s", will return empty array.', $value));
+ app('log')->debug(sprintf('Could not parse date "%s", will return empty array.', $value));
$this->invalidOperators[] = [
'type' => $type,
- 'value' => (string)$value,
+ 'value' => $value,
];
+
return [];
}
@@ -1573,8 +2065,9 @@ class OperatorQuerySearch implements SearchInterface
}
/**
- *
* @throws FireflyException
+ *
+ * @SuppressWarnings(PHPMD.BooleanArgumentFlag)
*/
private function setExactDateParams(array $range, bool $prohibited = false): void
{
@@ -1584,55 +2077,89 @@ class OperatorQuerySearch implements SearchInterface
*/
foreach ($range as $key => $value) {
$key = $prohibited ? sprintf('%s_not', $key) : $key;
+
switch ($key) {
default:
throw new FireflyException(sprintf('Cannot handle key "%s" in setExactParameters()', $key));
+
case 'exact':
- Log::debug(sprintf('Set date_is_exact value "%s"', $value->format('Y-m-d')));
- $this->collector->setRange($value, $value);
- $this->operators->push(['type' => 'date_on', 'value' => $value->format('Y-m-d'),]);
+ if ($value instanceof Carbon) {
+ app('log')->debug(sprintf('Set date_is_exact value "%s"', $value->format('Y-m-d')));
+ $this->collector->setRange($value, $value);
+ $this->operators->push(['type' => 'date_on', 'value' => $value->format('Y-m-d')]);
+ }
+
break;
+
case 'exact_not':
- $this->collector->excludeRange($value, $value);
- $this->operators->push(['type' => 'not_date_on', 'value' => $value->format('Y-m-d'),]);
+ if ($value instanceof Carbon) {
+ $this->collector->excludeRange($value, $value);
+ $this->operators->push(['type' => 'not_date_on', 'value' => $value->format('Y-m-d')]);
+ }
+
break;
+
case 'year':
- Log::debug(sprintf('Set date_is_exact YEAR value "%s"', $value));
- $this->collector->yearIs($value);
- $this->operators->push(['type' => 'date_on_year', 'value' => $value,]);
+ if (is_string($value)) {
+ app('log')->debug(sprintf('Set date_is_exact YEAR value "%s"', $value));
+ $this->collector->yearIs($value);
+ $this->operators->push(['type' => 'date_on_year', 'value' => $value]);
+ }
+
break;
+
case 'year_not':
- Log::debug(sprintf('Set date_is_exact_not YEAR value "%s"', $value));
- $this->collector->yearIsNot($value);
- $this->operators->push(['type' => 'not_date_on_year', 'value' => $value,]);
+ if (is_string($value)) {
+ app('log')->debug(sprintf('Set date_is_exact_not YEAR value "%s"', $value));
+ $this->collector->yearIsNot($value);
+ $this->operators->push(['type' => 'not_date_on_year', 'value' => $value]);
+ }
+
break;
+
case 'month':
- Log::debug(sprintf('Set date_is_exact MONTH value "%s"', $value));
- $this->collector->monthIs($value);
- $this->operators->push(['type' => 'date_on_month', 'value' => $value,]);
+ if (is_string($value)) {
+ app('log')->debug(sprintf('Set date_is_exact MONTH value "%s"', $value));
+ $this->collector->monthIs($value);
+ $this->operators->push(['type' => 'date_on_month', 'value' => $value]);
+ }
+
break;
+
case 'month_not':
- Log::debug(sprintf('Set date_is_exact not MONTH value "%s"', $value));
- $this->collector->monthIsNot($value);
- $this->operators->push(['type' => 'not_date_on_month', 'value' => $value,]);
+ if (is_string($value)) {
+ app('log')->debug(sprintf('Set date_is_exact not MONTH value "%s"', $value));
+ $this->collector->monthIsNot($value);
+ $this->operators->push(['type' => 'not_date_on_month', 'value' => $value]);
+ }
+
break;
+
case 'day':
- Log::debug(sprintf('Set date_is_exact DAY value "%s"', $value));
- $this->collector->dayIs($value);
- $this->operators->push(['type' => 'date_on_day', 'value' => $value,]);
+ if (is_string($value)) {
+ app('log')->debug(sprintf('Set date_is_exact DAY value "%s"', $value));
+ $this->collector->dayIs($value);
+ $this->operators->push(['type' => 'date_on_day', 'value' => $value]);
+ }
+
break;
+
case 'day_not':
- Log::debug(sprintf('Set not date_is_exact DAY value "%s"', $value));
- $this->collector->dayIsNot($value);
- $this->operators->push(['type' => 'not_date_on_day', 'value' => $value,]);
+ if (is_string($value)) {
+ app('log')->debug(sprintf('Set not date_is_exact DAY value "%s"', $value));
+ $this->collector->dayIsNot($value);
+ $this->operators->push(['type' => 'not_date_on_day', 'value' => $value]);
+ }
+
break;
}
}
}
/**
- *
* @throws FireflyException
+ *
+ * @SuppressWarnings(PHPMD.BooleanArgumentFlag)
*/
private function setDateBeforeParams(array $range, bool $prohibited = false): void
{
@@ -1642,37 +2169,55 @@ class OperatorQuerySearch implements SearchInterface
*/
foreach ($range as $key => $value) {
$key = $prohibited ? sprintf('%s_not', $key) : $key;
+
switch ($key) {
default:
throw new FireflyException(sprintf('Cannot handle key "%s" in setDateBeforeParams()', $key));
+
case 'exact':
- $this->collector->setBefore($value);
- $this->operators->push(['type' => 'date_before', 'value' => $value->format('Y-m-d'),]);
+ if ($value instanceof Carbon) {
+ $this->collector->setBefore($value);
+ $this->operators->push(['type' => 'date_before', 'value' => $value->format('Y-m-d')]);
+ }
+
break;
+
case 'year':
- Log::debug(sprintf('Set date_is_before YEAR value "%s"', $value));
- $this->collector->yearBefore($value);
- $this->operators->push(['type' => 'date_before_year', 'value' => $value,]);
+ if (is_string($value)) {
+ app('log')->debug(sprintf('Set date_is_before YEAR value "%s"', $value));
+ $this->collector->yearBefore($value);
+ $this->operators->push(['type' => 'date_before_year', 'value' => $value]);
+ }
+
break;
+
case 'month':
- Log::debug(sprintf('Set date_is_before MONTH value "%s"', $value));
- $this->collector->monthBefore($value);
- $this->operators->push(['type' => 'date_before_month', 'value' => $value,]);
+ if (is_string($value)) {
+ app('log')->debug(sprintf('Set date_is_before MONTH value "%s"', $value));
+ $this->collector->monthBefore($value);
+ $this->operators->push(['type' => 'date_before_month', 'value' => $value]);
+ }
+
break;
+
case 'day':
- Log::debug(sprintf('Set date_is_before DAY value "%s"', $value));
- $this->collector->dayBefore($value);
- $this->operators->push(['type' => 'date_before_day', 'value' => $value,]);
+ if (is_string($value)) {
+ app('log')->debug(sprintf('Set date_is_before DAY value "%s"', $value));
+ $this->collector->dayBefore($value);
+ $this->operators->push(['type' => 'date_before_day', 'value' => $value]);
+ }
+
break;
}
}
}
/**
- *
* @throws FireflyException
+ *
+ * @SuppressWarnings(PHPMD.BooleanArgumentFlag)
*/
- private function setDateAfterParams(array $range, bool $prohibited = false)
+ private function setDateAfterParams(array $range, bool $prohibited = false): void
{
/**
* @var string $key
@@ -1680,27 +2225,44 @@ class OperatorQuerySearch implements SearchInterface
*/
foreach ($range as $key => $value) {
$key = $prohibited ? sprintf('%s_not', $key) : $key;
+
switch ($key) {
default:
throw new FireflyException(sprintf('Cannot handle key "%s" in setDateAfterParams()', $key));
+
case 'exact':
- $this->collector->setAfter($value);
- $this->operators->push(['type' => 'date_after', 'value' => $value->format('Y-m-d'),]);
+ if ($value instanceof Carbon) {
+ $this->collector->setAfter($value);
+ $this->operators->push(['type' => 'date_after', 'value' => $value->format('Y-m-d')]);
+ }
+
break;
+
case 'year':
- Log::debug(sprintf('Set date_is_after YEAR value "%s"', $value));
- $this->collector->yearAfter($value);
- $this->operators->push(['type' => 'date_after_year', 'value' => $value,]);
+ if (is_string($value)) {
+ app('log')->debug(sprintf('Set date_is_after YEAR value "%s"', $value));
+ $this->collector->yearAfter($value);
+ $this->operators->push(['type' => 'date_after_year', 'value' => $value]);
+ }
+
break;
+
case 'month':
- Log::debug(sprintf('Set date_is_after MONTH value "%s"', $value));
- $this->collector->monthAfter($value);
- $this->operators->push(['type' => 'date_after_month', 'value' => $value,]);
+ if (is_string($value)) {
+ app('log')->debug(sprintf('Set date_is_after MONTH value "%s"', $value));
+ $this->collector->monthAfter($value);
+ $this->operators->push(['type' => 'date_after_month', 'value' => $value]);
+ }
+
break;
+
case 'day':
- Log::debug(sprintf('Set date_is_after DAY value "%s"', $value));
- $this->collector->dayAfter($value);
- $this->operators->push(['type' => 'date_after_day', 'value' => $value,]);
+ if (is_string($value)) {
+ app('log')->debug(sprintf('Set date_is_after DAY value "%s"', $value));
+ $this->collector->dayAfter($value);
+ $this->operators->push(['type' => 'date_after_day', 'value' => $value]);
+ }
+
break;
}
}
@@ -1708,58 +2270,94 @@ class OperatorQuerySearch implements SearchInterface
/**
* @throws FireflyException
+ *
+ * @SuppressWarnings(PHPMD.BooleanArgumentFlag)
*/
private function setExactMetaDateParams(string $field, array $range, bool $prohibited = false): void
{
- Log::debug('Now in setExactMetaDateParams()');
+ app('log')->debug('Now in setExactMetaDateParams()');
+
/**
* @var string $key
* @var Carbon|string $value
*/
foreach ($range as $key => $value) {
$key = $prohibited ? sprintf('%s_not', $key) : $key;
+
switch ($key) {
default:
throw new FireflyException(sprintf('Cannot handle key "%s" in setExactMetaDateParams()', $key));
+
case 'exact':
- Log::debug(sprintf('Set %s_is_exact value "%s"', $field, $value->format('Y-m-d')));
- $this->collector->setMetaDateRange($value, $value, $field);
- $this->operators->push(['type' => sprintf('%s_on', $field), 'value' => $value->format('Y-m-d'),]);
+ if ($value instanceof Carbon) {
+ app('log')->debug(sprintf('Set %s_is_exact value "%s"', $field, $value->format('Y-m-d')));
+ $this->collector->setMetaDateRange($value, $value, $field);
+ $this->operators->push(['type' => sprintf('%s_on', $field), 'value' => $value->format('Y-m-d')]);
+ }
+
break;
+
case 'exact_not':
- Log::debug(sprintf('Set NOT %s_is_exact value "%s"', $field, $value->format('Y-m-d')));
- $this->collector->excludeMetaDateRange($value, $value, $field);
- $this->operators->push(['type' => sprintf('not_%s_on', $field), 'value' => $value->format('Y-m-d'),]);
+ if ($value instanceof Carbon) {
+ app('log')->debug(sprintf('Set NOT %s_is_exact value "%s"', $field, $value->format('Y-m-d')));
+ $this->collector->excludeMetaDateRange($value, $value, $field);
+ $this->operators->push(['type' => sprintf('not_%s_on', $field), 'value' => $value->format('Y-m-d')]);
+ }
+
break;
+
case 'year':
- Log::debug(sprintf('Set %s_is_exact YEAR value "%s"', $field, $value));
- $this->collector->metaYearIs($value, $field);
- $this->operators->push(['type' => sprintf('%s_on_year', $field), 'value' => $value,]);
+ if (is_string($value)) {
+ app('log')->debug(sprintf('Set %s_is_exact YEAR value "%s"', $field, $value));
+ $this->collector->metaYearIs($value, $field);
+ $this->operators->push(['type' => sprintf('%s_on_year', $field), 'value' => $value]);
+ }
+
break;
+
case 'year_not':
- Log::debug(sprintf('Set NOT %s_is_exact YEAR value "%s"', $field, $value));
- $this->collector->metaYearIsNot($value, $field);
- $this->operators->push(['type' => sprintf('not_%s_on_year', $field), 'value' => $value,]);
+ if (is_string($value)) {
+ app('log')->debug(sprintf('Set NOT %s_is_exact YEAR value "%s"', $field, $value));
+ $this->collector->metaYearIsNot($value, $field);
+ $this->operators->push(['type' => sprintf('not_%s_on_year', $field), 'value' => $value]);
+ }
+
break;
+
case 'month':
- Log::debug(sprintf('Set %s_is_exact MONTH value "%s"', $field, $value));
- $this->collector->metaMonthIs($value, $field);
- $this->operators->push(['type' => sprintf('%s_on_month', $field), 'value' => $value,]);
+ if (is_string($value)) {
+ app('log')->debug(sprintf('Set %s_is_exact MONTH value "%s"', $field, $value));
+ $this->collector->metaMonthIs($value, $field);
+ $this->operators->push(['type' => sprintf('%s_on_month', $field), 'value' => $value]);
+ }
+
break;
+
case 'month_not':
- Log::debug(sprintf('Set NOT %s_is_exact MONTH value "%s"', $field, $value));
- $this->collector->metaMonthIsNot($value, $field);
- $this->operators->push(['type' => sprintf('not_%s_on_month', $field), 'value' => $value,]);
+ if (is_string($value)) {
+ app('log')->debug(sprintf('Set NOT %s_is_exact MONTH value "%s"', $field, $value));
+ $this->collector->metaMonthIsNot($value, $field);
+ $this->operators->push(['type' => sprintf('not_%s_on_month', $field), 'value' => $value]);
+ }
+
break;
+
case 'day':
- Log::debug(sprintf('Set %s_is_exact DAY value "%s"', $field, $value));
- $this->collector->metaDayIs($value, $field);
- $this->operators->push(['type' => sprintf('%s_on_day', $field), 'value' => $value,]);
+ if (is_string($value)) {
+ app('log')->debug(sprintf('Set %s_is_exact DAY value "%s"', $field, $value));
+ $this->collector->metaDayIs($value, $field);
+ $this->operators->push(['type' => sprintf('%s_on_day', $field), 'value' => $value]);
+ }
+
break;
+
case 'day_not':
- Log::debug(sprintf('Set NOT %s_is_exact DAY value "%s"', $field, $value));
- $this->collector->metaDayIsNot($value, $field);
- $this->operators->push(['type' => sprintf('not_%s_on_day', $field), 'value' => $value,]);
+ if (is_string($value)) {
+ app('log')->debug(sprintf('Set NOT %s_is_exact DAY value "%s"', $field, $value));
+ $this->collector->metaDayIsNot($value, $field);
+ $this->operators->push(['type' => sprintf('not_%s_on_day', $field), 'value' => $value]);
+ }
+
break;
}
}
@@ -1767,6 +2365,8 @@ class OperatorQuerySearch implements SearchInterface
/**
* @throws FireflyException
+ *
+ * @SuppressWarnings(PHPMD.BooleanArgumentFlag)
*/
private function setMetaDateBeforeParams(string $field, array $range, bool $prohibited = false): void
{
@@ -1776,27 +2376,44 @@ class OperatorQuerySearch implements SearchInterface
*/
foreach ($range as $key => $value) {
$key = $prohibited ? sprintf('%s_not', $key) : $key;
+
switch ($key) {
default:
throw new FireflyException(sprintf('Cannot handle key "%s" in setMetaDateBeforeParams()', $key));
+
case 'exact':
- $this->collector->setMetaBefore($value, $field);
- $this->operators->push(['type' => sprintf('%s_before', $field), 'value' => $value->format('Y-m-d'),]);
+ if ($value instanceof Carbon) {
+ $this->collector->setMetaBefore($value, $field);
+ $this->operators->push(['type' => sprintf('%s_before', $field), 'value' => $value->format('Y-m-d')]);
+ }
+
break;
+
case 'year':
- Log::debug(sprintf('Set %s_is_before YEAR value "%s"', $field, $value));
- $this->collector->metaYearBefore($value, $field);
- $this->operators->push(['type' => sprintf('%s_before_year', $field), 'value' => $value,]);
+ if (is_string($value)) {
+ app('log')->debug(sprintf('Set %s_is_before YEAR value "%s"', $field, $value));
+ $this->collector->metaYearBefore($value, $field);
+ $this->operators->push(['type' => sprintf('%s_before_year', $field), 'value' => $value]);
+ }
+
break;
+
case 'month':
- Log::debug(sprintf('Set %s_is_before MONTH value "%s"', $field, $value));
- $this->collector->metaMonthBefore($value, $field);
- $this->operators->push(['type' => sprintf('%s_before_month', $field), 'value' => $value,]);
+ if (is_string($value)) {
+ app('log')->debug(sprintf('Set %s_is_before MONTH value "%s"', $field, $value));
+ $this->collector->metaMonthBefore($value, $field);
+ $this->operators->push(['type' => sprintf('%s_before_month', $field), 'value' => $value]);
+ }
+
break;
+
case 'day':
- Log::debug(sprintf('Set %s_is_before DAY value "%s"', $field, $value));
- $this->collector->metaDayBefore($value, $field);
- $this->operators->push(['type' => sprintf('%s_before_day', $field), 'value' => $value,]);
+ if (is_string($value)) {
+ app('log')->debug(sprintf('Set %s_is_before DAY value "%s"', $field, $value));
+ $this->collector->metaDayBefore($value, $field);
+ $this->operators->push(['type' => sprintf('%s_before_day', $field), 'value' => $value]);
+ }
+
break;
}
}
@@ -1804,6 +2421,8 @@ class OperatorQuerySearch implements SearchInterface
/**
* @throws FireflyException
+ *
+ * @SuppressWarnings(PHPMD.BooleanArgumentFlag)
*/
private function setMetaDateAfterParams(string $field, array $range, bool $prohibited = false): void
{
@@ -1813,27 +2432,44 @@ class OperatorQuerySearch implements SearchInterface
*/
foreach ($range as $key => $value) {
$key = $prohibited ? sprintf('%s_not', $key) : $key;
+
switch ($key) {
default:
throw new FireflyException(sprintf('Cannot handle key "%s" in setMetaDateAfterParams()', $key));
+
case 'exact':
- $this->collector->setMetaAfter($value, $field);
- $this->operators->push(['type' => sprintf('%s_after', $field), 'value' => $value->format('Y-m-d'),]);
+ if ($value instanceof Carbon) {
+ $this->collector->setMetaAfter($value, $field);
+ $this->operators->push(['type' => sprintf('%s_after', $field), 'value' => $value->format('Y-m-d')]);
+ }
+
break;
+
case 'year':
- Log::debug(sprintf('Set %s_is_after YEAR value "%s"', $field, $value));
- $this->collector->metaYearAfter($value, $field);
- $this->operators->push(['type' => sprintf('%s_after_year', $field), 'value' => $value,]);
+ if (is_string($value)) {
+ app('log')->debug(sprintf('Set %s_is_after YEAR value "%s"', $field, $value));
+ $this->collector->metaYearAfter($value, $field);
+ $this->operators->push(['type' => sprintf('%s_after_year', $field), 'value' => $value]);
+ }
+
break;
+
case 'month':
- Log::debug(sprintf('Set %s_is_after MONTH value "%s"', $field, $value));
- $this->collector->metaMonthAfter($value, $field);
- $this->operators->push(['type' => sprintf('%s_after_month', $field), 'value' => $value,]);
+ if (is_string($value)) {
+ app('log')->debug(sprintf('Set %s_is_after MONTH value "%s"', $field, $value));
+ $this->collector->metaMonthAfter($value, $field);
+ $this->operators->push(['type' => sprintf('%s_after_month', $field), 'value' => $value]);
+ }
+
break;
+
case 'day':
- Log::debug(sprintf('Set %s_is_after DAY value "%s"', $field, $value));
- $this->collector->metaDayAfter($value, $field);
- $this->operators->push(['type' => sprintf('%s_after_day', $field), 'value' => $value,]);
+ if (is_string($value)) {
+ app('log')->debug(sprintf('Set %s_is_after DAY value "%s"', $field, $value));
+ $this->collector->metaDayAfter($value, $field);
+ $this->operators->push(['type' => sprintf('%s_after_day', $field), 'value' => $value]);
+ }
+
break;
}
}
@@ -1841,6 +2477,8 @@ class OperatorQuerySearch implements SearchInterface
/**
* @throws FireflyException
+ *
+ * @SuppressWarnings(PHPMD.BooleanArgumentFlag)
*/
private function setExactObjectDateParams(string $field, array $range, bool $prohibited = false): void
{
@@ -1850,56 +2488,90 @@ class OperatorQuerySearch implements SearchInterface
*/
foreach ($range as $key => $value) {
$key = $prohibited ? sprintf('%s_not', $key) : $key;
+
switch ($key) {
default:
throw new FireflyException(sprintf('Cannot handle key "%s" in setExactObjectDateParams()', $key));
+
case 'exact':
- Log::debug(sprintf('Set %s_is_exact value "%s"', $field, $value->format('Y-m-d')));
- $this->collector->setObjectRange($value, clone $value, $field);
- $this->operators->push(['type' => sprintf('%s_on', $field), 'value' => $value->format('Y-m-d'),]);
+ if ($value instanceof Carbon) {
+ app('log')->debug(sprintf('Set %s_is_exact value "%s"', $field, $value->format('Y-m-d')));
+ $this->collector->setObjectRange($value, clone $value, $field);
+ $this->operators->push(['type' => sprintf('%s_on', $field), 'value' => $value->format('Y-m-d')]);
+ }
+
break;
+
case 'exact_not':
- Log::debug(sprintf('Set NOT %s_is_exact value "%s"', $field, $value->format('Y-m-d')));
- $this->collector->excludeObjectRange($value, clone $value, $field);
- $this->operators->push(['type' => sprintf('not_%s_on', $field), 'value' => $value->format('Y-m-d'),]);
+ if ($value instanceof Carbon) {
+ app('log')->debug(sprintf('Set NOT %s_is_exact value "%s"', $field, $value->format('Y-m-d')));
+ $this->collector->excludeObjectRange($value, clone $value, $field);
+ $this->operators->push(['type' => sprintf('not_%s_on', $field), 'value' => $value->format('Y-m-d')]);
+ }
+
break;
+
case 'year':
- Log::debug(sprintf('Set %s_is_exact YEAR value "%s"', $field, $value));
- $this->collector->objectYearIs($value, $field);
- $this->operators->push(['type' => sprintf('%s_on_year', $field), 'value' => $value,]);
+ if (is_string($value)) {
+ app('log')->debug(sprintf('Set %s_is_exact YEAR value "%s"', $field, $value));
+ $this->collector->objectYearIs($value, $field);
+ $this->operators->push(['type' => sprintf('%s_on_year', $field), 'value' => $value]);
+ }
+
break;
+
case 'year_not':
- Log::debug(sprintf('Set NOT %s_is_exact YEAR value "%s"', $field, $value));
- $this->collector->objectYearIsNot($value, $field);
- $this->operators->push(['type' => sprintf('not_%s_on_year', $field), 'value' => $value,]);
+ if (is_string($value)) {
+ app('log')->debug(sprintf('Set NOT %s_is_exact YEAR value "%s"', $field, $value));
+ $this->collector->objectYearIsNot($value, $field);
+ $this->operators->push(['type' => sprintf('not_%s_on_year', $field), 'value' => $value]);
+ }
+
break;
+
case 'month':
- Log::debug(sprintf('Set %s_is_exact MONTH value "%s"', $field, $value));
- $this->collector->objectMonthIs($value, $field);
- $this->operators->push(['type' => sprintf('%s_on_month', $field), 'value' => $value,]);
+ if (is_string($value)) {
+ app('log')->debug(sprintf('Set %s_is_exact MONTH value "%s"', $field, $value));
+ $this->collector->objectMonthIs($value, $field);
+ $this->operators->push(['type' => sprintf('%s_on_month', $field), 'value' => $value]);
+ }
+
break;
+
case 'month_not':
- Log::debug(sprintf('Set NOT %s_is_exact MONTH value "%s"', $field, $value));
- $this->collector->objectMonthIsNot($value, $field);
- $this->operators->push(['type' => sprintf('not_%s_on_month', $field), 'value' => $value,]);
+ if (is_string($value)) {
+ app('log')->debug(sprintf('Set NOT %s_is_exact MONTH value "%s"', $field, $value));
+ $this->collector->objectMonthIsNot($value, $field);
+ $this->operators->push(['type' => sprintf('not_%s_on_month', $field), 'value' => $value]);
+ }
+
break;
+
case 'day':
- Log::debug(sprintf('Set %s_is_exact DAY value "%s"', $field, $value));
- $this->collector->objectDayIs($value, $field);
- $this->operators->push(['type' => sprintf('%s_on_day', $field), 'value' => $value,]);
+ if (is_string($value)) {
+ app('log')->debug(sprintf('Set %s_is_exact DAY value "%s"', $field, $value));
+ $this->collector->objectDayIs($value, $field);
+ $this->operators->push(['type' => sprintf('%s_on_day', $field), 'value' => $value]);
+ }
+
break;
+
case 'day_not':
- Log::debug(sprintf('Set NOT %s_is_exact DAY value "%s"', $field, $value));
- $this->collector->objectDayIsNot($value, $field);
- $this->operators->push(['type' => sprintf('not_%s_on_day', $field), 'value' => $value,]);
+ if (is_string($value)) {
+ app('log')->debug(sprintf('Set NOT %s_is_exact DAY value "%s"', $field, $value));
+ $this->collector->objectDayIsNot($value, $field);
+ $this->operators->push(['type' => sprintf('not_%s_on_day', $field), 'value' => $value]);
+ }
+
break;
}
}
}
/**
- *
* @throws FireflyException
+ *
+ * @SuppressWarnings(PHPMD.BooleanArgumentFlag)
*/
private function setObjectDateBeforeParams(string $field, array $range, bool $prohibited = false): void
{
@@ -1909,35 +2581,53 @@ class OperatorQuerySearch implements SearchInterface
*/
foreach ($range as $key => $value) {
$key = $prohibited ? sprintf('%s_not', $key) : $key;
+
switch ($key) {
default:
throw new FireflyException(sprintf('Cannot handle key "%s" in setObjectDateBeforeParams()', $key));
+
case 'exact':
- $this->collector->setObjectBefore($value, $field);
- $this->operators->push(['type' => sprintf('%s_before', $field), 'value' => $value->format('Y-m-d'),]);
+ if ($value instanceof Carbon) {
+ $this->collector->setObjectBefore($value, $field);
+ $this->operators->push(['type' => sprintf('%s_before', $field), 'value' => $value->format('Y-m-d')]);
+ }
+
break;
+
case 'year':
- Log::debug(sprintf('Set date_is_before YEAR value "%s"', $value));
- $this->collector->objectYearBefore($value, $field);
- $this->operators->push(['type' => sprintf('%s_before_year', $field), 'value' => $value,]);
+ if (is_string($value)) {
+ app('log')->debug(sprintf('Set date_is_before YEAR value "%s"', $value));
+ $this->collector->objectYearBefore($value, $field);
+ $this->operators->push(['type' => sprintf('%s_before_year', $field), 'value' => $value]);
+ }
+
break;
+
case 'month':
- Log::debug(sprintf('Set date_is_before MONTH value "%s"', $value));
- $this->collector->objectMonthBefore($value, $field);
- $this->operators->push(['type' => sprintf('%s_before_month', $field), 'value' => $value,]);
+ if (is_string($value)) {
+ app('log')->debug(sprintf('Set date_is_before MONTH value "%s"', $value));
+ $this->collector->objectMonthBefore($value, $field);
+ $this->operators->push(['type' => sprintf('%s_before_month', $field), 'value' => $value]);
+ }
+
break;
+
case 'day':
- Log::debug(sprintf('Set date_is_before DAY value "%s"', $value));
- $this->collector->objectDayBefore($value, $field);
- $this->operators->push(['type' => sprintf('%s_before_day', $field), 'value' => $value,]);
+ if (is_string($value)) {
+ app('log')->debug(sprintf('Set date_is_before DAY value "%s"', $value));
+ $this->collector->objectDayBefore($value, $field);
+ $this->operators->push(['type' => sprintf('%s_before_day', $field), 'value' => $value]);
+ }
+
break;
}
}
}
/**
- *
* @throws FireflyException
+ *
+ * @SuppressWarnings(PHPMD.BooleanArgumentFlag)
*/
private function setObjectDateAfterParams(string $field, array $range, bool $prohibited = false): void
{
@@ -1947,45 +2637,57 @@ class OperatorQuerySearch implements SearchInterface
*/
foreach ($range as $key => $value) {
$key = $prohibited ? sprintf('%s_not', $key) : $key;
+
switch ($key) {
default:
throw new FireflyException(sprintf('Cannot handle key "%s" in setObjectDateAfterParams()', $key));
+
case 'exact':
- $this->collector->setObjectAfter($value, $field);
- $this->operators->push(['type' => sprintf('%s_after', $field), 'value' => $value->format('Y-m-d'),]);
+ if ($value instanceof Carbon) {
+ $this->collector->setObjectAfter($value, $field);
+ $this->operators->push(['type' => sprintf('%s_after', $field), 'value' => $value->format('Y-m-d')]);
+ }
+
break;
+
case 'year':
- Log::debug(sprintf('Set date_is_after YEAR value "%s"', $value));
- $this->collector->objectYearAfter($value, $field);
- $this->operators->push(['type' => sprintf('%s_after_year', $field), 'value' => $value,]);
+ if (is_string($value)) {
+ app('log')->debug(sprintf('Set date_is_after YEAR value "%s"', $value));
+ $this->collector->objectYearAfter($value, $field);
+ $this->operators->push(['type' => sprintf('%s_after_year', $field), 'value' => $value]);
+ }
+
break;
+
case 'month':
- Log::debug(sprintf('Set date_is_after MONTH value "%s"', $value));
- $this->collector->objectMonthAfter($value, $field);
- $this->operators->push(['type' => sprintf('%s_after_month', $field), 'value' => $value,]);
+ if (is_string($value)) {
+ app('log')->debug(sprintf('Set date_is_after MONTH value "%s"', $value));
+ $this->collector->objectMonthAfter($value, $field);
+ $this->operators->push(['type' => sprintf('%s_after_month', $field), 'value' => $value]);
+ }
+
break;
+
case 'day':
- Log::debug(sprintf('Set date_is_after DAY value "%s"', $value));
- $this->collector->objectDayAfter($value, $field);
- $this->operators->push(['type' => sprintf('%s_after_day', $field), 'value' => $value,]);
+ if (is_string($value)) {
+ app('log')->debug(sprintf('Set date_is_after DAY value "%s"', $value));
+ $this->collector->objectDayAfter($value, $field);
+ $this->operators->push(['type' => sprintf('%s_after_day', $field), 'value' => $value]);
+ }
+
break;
}
}
}
- /**
- * @inheritDoc
- */
public function searchTime(): float
{
return microtime(true) - $this->startTime;
}
- /**
- * @inheritDoc
- */
public function searchTransactions(): LengthAwarePaginator
{
+ $this->parseTagInstructions();
if (0 === count($this->getWords()) && 0 === count($this->getOperators())) {
return new LengthAwarePaginator([], 0, 5, 1);
}
@@ -1993,34 +2695,54 @@ class OperatorQuerySearch implements SearchInterface
return $this->collector->getPaginatedGroups();
}
- /**
- * @return array
- */
+ private function parseTagInstructions(): void
+ {
+ app('log')->debug('Now in parseTagInstructions()');
+ // if exclude tags, remove excluded tags.
+ if (count($this->excludeTags) > 0) {
+ app('log')->debug(sprintf('%d exclude tag(s)', count($this->excludeTags)));
+ $collection = new Collection();
+ foreach ($this->excludeTags as $tagId) {
+ $tag = $this->tagRepository->find($tagId);
+ if (null !== $tag) {
+ app('log')->debug(sprintf('Exclude tag "%s"', $tag->tag));
+ $collection->push($tag);
+ }
+ }
+ app('log')->debug(sprintf('Selecting all tags except %d excluded tag(s).', $collection->count()));
+ $this->collector->setWithoutSpecificTags($collection);
+ }
+ // if include tags, include them:
+ if (count($this->includeTags) > 0) {
+ app('log')->debug(sprintf('%d include tag(s)', count($this->includeTags)));
+ $collection = new Collection();
+ foreach ($this->includeTags as $tagId) {
+ $tag = $this->tagRepository->find($tagId);
+ if (null !== $tag) {
+ app('log')->debug(sprintf('Include tag "%s"', $tag->tag));
+ $collection->push($tag);
+ }
+ }
+ $this->collector->setAllTags($collection);
+ }
+ }
+
public function getWords(): array
{
return $this->words;
}
- /**
- * @param Carbon $date
- */
public function setDate(Carbon $date): void
{
$this->date = $date;
}
- /**
- * @inheritDoc
- */
public function setPage(int $page): void
{
$this->page = $page;
$this->collector->setPage($this->page);
}
- /**
- * @inheritDoc
- */
public function setUser(User $user): void
{
$this->accountRepository->setUser($user);
@@ -2035,9 +2757,6 @@ class OperatorQuerySearch implements SearchInterface
$this->setLimit((int)app('preferences')->getForUser($user, 'listPageSize', 50)->data);
}
- /**
- * @param int $limit
- */
public function setLimit(int $limit): void
{
$this->limit = $limit;
diff --git a/app/Support/Search/SearchInterface.php b/app/Support/Search/SearchInterface.php
index 100168f36e..b9197e9daf 100644
--- a/app/Support/Search/SearchInterface.php
+++ b/app/Support/Search/SearchInterface.php
@@ -33,63 +33,27 @@ use Illuminate\Support\Collection;
*/
interface SearchInterface
{
- /**
- * @return array
- */
public function getInvalidOperators(): array;
- /**
- * @return Collection
- */
public function getModifiers(): Collection;
- /**
- * @return Collection
- */
public function getOperators(): Collection;
- /**
- * @return string
- */
public function getWordsAsString(): string;
- /**
- * @return bool
- */
public function hasModifiers(): bool;
- /**
- * @param string $query
- */
- public function parseQuery(string $query);
+ public function parseQuery(string $query): void;
- /**
- * @return float
- */
public function searchTime(): float;
- /**
- * @return LengthAwarePaginator
- */
public function searchTransactions(): LengthAwarePaginator;
- /**
- * @param Carbon $date
- */
public function setDate(Carbon $date): void;
- /**
- * @param int $limit
- */
public function setLimit(int $limit): void;
- /**
- * @param int $page
- */
public function setPage(int $page): void;
- /**
- * @param User $user
- */
- public function setUser(User $user);
+ public function setUser(User $user): void;
}
diff --git a/app/Support/Steam.php b/app/Support/Steam.php
index 335f246abf..b08ccb6389 100644
--- a/app/Support/Steam.php
+++ b/app/Support/Steam.php
@@ -24,7 +24,7 @@ declare(strict_types=1);
namespace FireflyIII\Support;
use Carbon\Carbon;
-use DB;
+use Carbon\Exceptions\InvalidFormatException;
use Exception;
use FireflyIII\Exceptions\FireflyException;
use FireflyIII\Models\Account;
@@ -34,61 +34,45 @@ use FireflyIII\Repositories\Account\AccountRepositoryInterface;
use FireflyIII\Support\Http\Api\ExchangeRateConverter;
use Illuminate\Support\Collection;
use Illuminate\Support\Facades\Log;
-use JsonException;
-use Psr\Container\ContainerExceptionInterface;
-use Psr\Container\NotFoundExceptionInterface;
-use stdClass;
-use Str;
-use ValueError;
/**
* Class Steam.
- *
-
*/
class Steam
{
- /**
- * @param Account $account
- * @param Carbon $date
- *
- * @return string
- */
public function balanceIgnoreVirtual(Account $account, Carbon $date): string
{
/** @var AccountRepositoryInterface $repository */
- $repository = app(AccountRepositoryInterface::class);
+ $repository = app(AccountRepositoryInterface::class);
$repository->setUser($account->user);
- $currencyId = (int)$repository->getMetaValue($account, 'currency_id');
- $transactions = $account->transactions()
- ->leftJoin('transaction_journals', 'transaction_journals.id', '=', 'transactions.transaction_journal_id')
- ->where('transaction_journals.date', '<=', $date->format('Y-m-d 23:59:59'))
- ->where('transactions.transaction_currency_id', $currencyId)
- ->get(['transactions.amount'])->toArray();
- $nativeBalance = $this->sumTransactions($transactions, 'amount');
+ $currencyId = (int)$repository->getMetaValue($account, 'currency_id');
+ $transactions = $account->transactions()
+ ->leftJoin('transaction_journals', 'transaction_journals.id', '=', 'transactions.transaction_journal_id')
+ ->where('transaction_journals.date', '<=', $date->format('Y-m-d 23:59:59'))
+ ->where('transactions.transaction_currency_id', $currencyId)
+ ->get(['transactions.amount'])->toArray()
+ ;
+ $nativeBalance = $this->sumTransactions($transactions, 'amount');
// get all balances in foreign currency:
- $transactions = $account->transactions()
- ->leftJoin('transaction_journals', 'transaction_journals.id', '=', 'transactions.transaction_journal_id')
- ->where('transaction_journals.date', '<=', $date->format('Y-m-d 23:59:59'))
- ->where('transactions.foreign_currency_id', $currencyId)
- ->where('transactions.transaction_currency_id', '!=', $currencyId)
- ->get(['transactions.foreign_amount'])->toArray();
+ $transactions = $account->transactions()
+ ->leftJoin('transaction_journals', 'transaction_journals.id', '=', 'transactions.transaction_journal_id')
+ ->where('transaction_journals.date', '<=', $date->format('Y-m-d 23:59:59'))
+ ->where('transactions.foreign_currency_id', $currencyId)
+ ->where('transactions.transaction_currency_id', '!=', $currencyId)
+ ->get(['transactions.foreign_amount'])->toArray()
+ ;
$foreignBalance = $this->sumTransactions($transactions, 'foreign_amount');
+
return bcadd($nativeBalance, $foreignBalance);
}
- /**
- * @param array $transactions
- * @param string $key
- *
- * @return string
- */
public function sumTransactions(array $transactions, string $key): string
{
$sum = '0';
+
/** @var array $transaction */
foreach ($transactions as $transaction) {
$value = (string)($transaction[$key] ?? '0');
@@ -104,21 +88,14 @@ class Steam
*
* [yyyy-mm-dd] => 123,2
*
- * @param Account $account
- * @param Carbon $start
- * @param Carbon $end
- * @param TransactionCurrency|null $currency
- *
- * @return array
* @throws FireflyException
- * @throws JsonException
*/
public function balanceInRange(Account $account, Carbon $start, Carbon $end, ?TransactionCurrency $currency = null): array
{
- $cache = new CacheProperties();
+ $cache = new CacheProperties();
$cache->addProperty($account->id);
$cache->addProperty('balance-in-range');
- $cache->addProperty($currency ? $currency->id : 0);
+ $cache->addProperty(null !== $currency ? $currency->id : 0);
$cache->addProperty($start);
$cache->addProperty($end);
if ($cache->has()) {
@@ -127,46 +104,48 @@ class Steam
$start->subDay();
$end->addDay();
- $balances = [];
- $formatted = $start->format('Y-m-d');
- $startBalance = $this->balance($account, $start, $currency);
+ $balances = [];
+ $formatted = $start->format('Y-m-d');
+ $startBalance = $this->balance($account, $start, $currency);
$balances[$formatted] = $startBalance;
if (null === $currency) {
$repository = app(AccountRepositoryInterface::class);
$repository->setUser($account->user);
- $currency = $repository->getAccountCurrency($account) ?? app('amount')->getDefaultCurrencyByUser($account->user);
+ $currency = $repository->getAccountCurrency($account) ?? app('amount')->getDefaultCurrencyByUserGroup($account->user->userGroup);
}
- $currencyId = (int)$currency->id;
+ $currencyId = $currency->id;
$start->addDay();
// query!
- $set = $account->transactions()
- ->leftJoin('transaction_journals', 'transactions.transaction_journal_id', '=', 'transaction_journals.id')
- ->where('transaction_journals.date', '>=', $start->format('Y-m-d 00:00:00'))
- ->where('transaction_journals.date', '<=', $end->format('Y-m-d 23:59:59'))
- ->groupBy('transaction_journals.date')
- ->groupBy('transactions.transaction_currency_id')
- ->groupBy('transactions.foreign_currency_id')
- ->orderBy('transaction_journals.date', 'ASC')
- ->whereNull('transaction_journals.deleted_at')
- ->get(
- [
- 'transaction_journals.date',
- 'transactions.transaction_currency_id',
- DB::raw('SUM(transactions.amount) AS modified'),
- 'transactions.foreign_currency_id',
- DB::raw('SUM(transactions.foreign_amount) AS modified_foreign'),
- ]
- );
+ $set = $account->transactions()
+ ->leftJoin('transaction_journals', 'transactions.transaction_journal_id', '=', 'transaction_journals.id')
+ ->where('transaction_journals.date', '>=', $start->format('Y-m-d 00:00:00'))
+ ->where('transaction_journals.date', '<=', $end->format('Y-m-d 23:59:59'))
+ ->groupBy('transaction_journals.date')
+ ->groupBy('transactions.transaction_currency_id')
+ ->groupBy('transactions.foreign_currency_id')
+ ->orderBy('transaction_journals.date', 'ASC')
+ ->whereNull('transaction_journals.deleted_at')
+ ->get(
+ [ // @phpstan-ignore-line
+ 'transaction_journals.date',
+ 'transactions.transaction_currency_id',
+ \DB::raw('SUM(transactions.amount) AS modified'),
+ 'transactions.foreign_currency_id',
+ \DB::raw('SUM(transactions.foreign_amount) AS modified_foreign'),
+ ]
+ )
+ ;
+
+ $currentBalance = $startBalance;
- $currentBalance = $startBalance;
/** @var Transaction $entry */
foreach ($set as $entry) {
// normal amount and foreign amount
- $modified = null === $entry->modified ? '0' : (string)$entry->modified;
- $foreignModified = null === $entry->modified_foreign ? '0' : (string)$entry->modified_foreign;
+ $modified = (string)(null === $entry->modified ? '0' : $entry->modified);
+ $foreignModified = (string)(null === $entry->modified_foreign ? '0' : $entry->modified_foreign);
$amount = '0';
if ($currencyId === (int)$entry->transaction_currency_id || 0 === $currencyId) {
// use normal amount:
@@ -176,7 +155,7 @@ class Steam
// use foreign amount:
$amount = $foreignModified;
}
-
+ // Log::debug(sprintf('Trying to add %s and %s.', var_export($currentBalance, true), var_export($amount, true)));
$currentBalance = bcadd($currentBalance, $amount);
$carbon = new Carbon($entry->date, config('app.timezone'));
$date = $carbon->format('Y-m-d');
@@ -191,46 +170,44 @@ class Steam
/**
* Gets balance at the end of current month by default
*
- * @param Account $account
- * @param Carbon $date
- * @param TransactionCurrency|null $currency
- *
- * @return string
* @throws FireflyException
*/
public function balance(Account $account, Carbon $date, ?TransactionCurrency $currency = null): string
{
// abuse chart properties:
- $cache = new CacheProperties();
+ $cache = new CacheProperties();
$cache->addProperty($account->id);
$cache->addProperty('balance');
$cache->addProperty($date);
- $cache->addProperty($currency ? $currency->id : 0);
+ $cache->addProperty(null !== $currency ? $currency->id : 0);
if ($cache->has()) {
return $cache->get();
}
+
/** @var AccountRepositoryInterface $repository */
- $repository = app(AccountRepositoryInterface::class);
+ $repository = app(AccountRepositoryInterface::class);
if (null === $currency) {
- $currency = $repository->getAccountCurrency($account) ?? app('amount')->getDefaultCurrencyByUser($account->user);
+ $currency = $repository->getAccountCurrency($account) ?? app('amount')->getDefaultCurrencyByUserGroup($account->user->userGroup);
}
// first part: get all balances in own currency:
- $transactions = $account->transactions()
- ->leftJoin('transaction_journals', 'transaction_journals.id', '=', 'transactions.transaction_journal_id')
- ->where('transaction_journals.date', '<=', $date->format('Y-m-d 23:59:59'))
- ->where('transactions.transaction_currency_id', $currency->id)
- ->get(['transactions.amount'])->toArray();
- $nativeBalance = $this->sumTransactions($transactions, 'amount');
+ $transactions = $account->transactions()
+ ->leftJoin('transaction_journals', 'transaction_journals.id', '=', 'transactions.transaction_journal_id')
+ ->where('transaction_journals.date', '<=', $date->format('Y-m-d 23:59:59'))
+ ->where('transactions.transaction_currency_id', $currency->id)
+ ->get(['transactions.amount'])->toArray()
+ ;
+ $nativeBalance = $this->sumTransactions($transactions, 'amount');
// get all balances in foreign currency:
$transactions = $account->transactions()
- ->leftJoin('transaction_journals', 'transaction_journals.id', '=', 'transactions.transaction_journal_id')
- ->where('transaction_journals.date', '<=', $date->format('Y-m-d 23:59:59'))
- ->where('transactions.foreign_currency_id', $currency->id)
- ->where('transactions.transaction_currency_id', '!=', $currency->id)
- ->get(['transactions.foreign_amount'])->toArray();
+ ->leftJoin('transaction_journals', 'transaction_journals.id', '=', 'transactions.transaction_journal_id')
+ ->where('transaction_journals.date', '<=', $date->format('Y-m-d 23:59:59'))
+ ->where('transactions.foreign_currency_id', $currency->id)
+ ->where('transactions.transaction_currency_id', '!=', $currency->id)
+ ->get(['transactions.foreign_amount'])->toArray()
+ ;
$foreignBalance = $this->sumTransactions($transactions, 'foreign_amount');
$balance = bcadd($nativeBalance, $foreignBalance);
- $virtual = null === $account->virtual_balance ? '0' : (string)$account->virtual_balance;
+ $virtual = null === $account->virtual_balance ? '0' : $account->virtual_balance;
$balance = bcadd($balance, $virtual);
$cache->store($balance);
@@ -239,17 +216,13 @@ class Steam
}
/**
- * @param Account $account
- * @param Carbon $start
- * @param Carbon $end
- *
- * @return array
* @throws FireflyException
+ *
+ * @SuppressWarnings(PHPMD.ExcessiveMethodLength)
*/
public function balanceInRangeConverted(Account $account, Carbon $start, Carbon $end, TransactionCurrency $native): array
{
-
- $cache = new CacheProperties();
+ $cache = new CacheProperties();
$cache->addProperty($account->id);
$cache->addProperty('balance-in-range-converted');
$cache->addProperty($native->id);
@@ -258,7 +231,7 @@ class Steam
if ($cache->has()) {
return $cache->get();
}
- app('log')->debug(sprintf('balanceInRangeConverted for account #%d to %s', $account->id, $native->code));
+ Log::debug(sprintf('balanceInRangeConverted for account #%d to %s', $account->id, $native->code));
$start->subDay();
$end->addDay();
$balances = [];
@@ -267,62 +240,75 @@ class Steam
$startBalance = $this->balanceConverted($account, $start, $native); // already converted to native amount
$balances[$formatted] = $startBalance;
- app('log')->debug(sprintf('Start balance on %s is %s', $formatted, $startBalance));
-
- $converter = new ExchangeRateConverter();
+ Log::debug(sprintf('Start balance on %s is %s', $formatted, $startBalance));
+ Log::debug(sprintf('Created new ExchangeRateConverter in %s', __METHOD__));
+ $converter = new ExchangeRateConverter();
// not sure why this is happening:
$start->addDay();
// grab all transactions between start and end:
- $set = $account->transactions()
- ->leftJoin('transaction_journals', 'transactions.transaction_journal_id', '=', 'transaction_journals.id')
- ->where('transaction_journals.date', '>=', $start->format('Y-m-d 00:00:00'))
- ->where('transaction_journals.date', '<=', $end->format('Y-m-d 23:59:59'))
- ->orderBy('transaction_journals.date', 'ASC')
- ->whereNull('transaction_journals.deleted_at')
- ->get(
- [
- 'transaction_journals.date',
- 'transactions.transaction_currency_id',
- 'transactions.amount',
- 'transactions.foreign_currency_id',
- 'transactions.foreign_amount',
- ]
- )->toArray();
+ $set = $account->transactions()
+ ->leftJoin('transaction_journals', 'transactions.transaction_journal_id', '=', 'transaction_journals.id')
+ ->where('transaction_journals.date', '>=', $start->format('Y-m-d 00:00:00'))
+ ->where('transaction_journals.date', '<=', $end->format('Y-m-d 23:59:59'))
+ ->orderBy('transaction_journals.date', 'ASC')
+ ->whereNull('transaction_journals.deleted_at')
+ ->get(
+ [
+ 'transaction_journals.date',
+ 'transactions.transaction_currency_id',
+ 'transactions.amount',
+ 'transactions.foreign_currency_id',
+ 'transactions.foreign_amount',
+ ]
+ )->toArray()
+ ;
// loop the set and convert if necessary:
- $currentBalance = $startBalance;
+ $currentBalance = $startBalance;
+
/** @var Transaction $transaction */
foreach ($set as $transaction) {
- $day = Carbon::createFromFormat('Y-m-d H:i:s', $transaction['date'], config('app.timezone'));
- $format = $day->format('Y-m-d');
+ $day = false;
+
+ try {
+ $day = Carbon::parse($transaction['date'], config('app.timezone'));
+ } catch (InvalidFormatException $e) {
+ Log::error(sprintf('Could not parse date "%s" in %s: %s', $transaction['date'], __METHOD__, $e->getMessage()));
+ }
+ if (false === $day) {
+ $day = today(config('app.timezone'));
+ }
+ $format = $day->format('Y-m-d');
// if the transaction is in the expected currency, change nothing.
- if ((int)$transaction['transaction_currency_id'] === (int)$native->id) {
+ if ((int)$transaction['transaction_currency_id'] === $native->id) {
// change the current balance, set it to today, continue the loop.
$currentBalance = bcadd($currentBalance, $transaction['amount']);
$balances[$format] = $currentBalance;
- app('log')->debug(sprintf('%s: transaction in %s, new balance is %s.', $format, $native->code, $currentBalance));
+ Log::debug(sprintf('%s: transaction in %s, new balance is %s.', $format, $native->code, $currentBalance));
+
continue;
}
// if foreign currency is in the expected currency, do nothing:
- if ((int)$transaction['foreign_currency_id'] === (int)$native->id) {
+ if ((int)$transaction['foreign_currency_id'] === $native->id) {
$currentBalance = bcadd($currentBalance, $transaction['foreign_amount']);
$balances[$format] = $currentBalance;
- app('log')->debug(sprintf('%s: transaction in %s (foreign), new balance is %s.', $format, $native->code, $currentBalance));
+ Log::debug(sprintf('%s: transaction in %s (foreign), new balance is %s.', $format, $native->code, $currentBalance));
+
continue;
}
// otherwise, convert 'amount' to the necessary currency:
- $currencyId = (int)$transaction['transaction_currency_id'];
- $currency = $currencies[$currencyId] ?? TransactionCurrency::find($currencyId);
+ $currencyId = (int)$transaction['transaction_currency_id'];
+ $currency = $currencies[$currencyId] ?? TransactionCurrency::find($currencyId);
+ $currencies[$currencyId] = $currency;
+ $rate = $converter->getCurrencyRate($currency, $native, $day);
+ $convertedAmount = bcmul($transaction['amount'], $rate);
+ $currentBalance = bcadd($currentBalance, $convertedAmount);
+ $balances[$format] = $currentBalance;
- $rate = $converter->getCurrencyRate($currency, $native, $day);
- $convertedAmount = bcmul($transaction['amount'], $rate);
- $currentBalance = bcadd($currentBalance, $convertedAmount);
- $balances[$format] = $currentBalance;
-
- app('log')->debug(sprintf(
+ Log::debug(sprintf(
'%s: transaction in %s(!). Conversion rate is %s. %s %s = %s %s',
$format,
$currency->code,
@@ -332,146 +318,169 @@ class Steam
$native->code,
$convertedAmount
));
-
-
}
$cache->store($balances);
+ $converter->summarize();
return $balances;
}
/**
+ * selection of transactions
+ * 1: all normal transactions. No foreign currency info. In $currency. Need conversion.
+ * 2: all normal transactions. No foreign currency info. In $native. Need NO conversion.
+ * 3: all normal transactions. No foreign currency info. In neither currency. Need conversion.
+ * Then, select everything with foreign currency info:
+ * 4. All transactions with foreign currency info in $native. Normal currency value is ignored. Do not need
+ * conversion.
+ * 5. All transactions with foreign currency info NOT in $native, but currency info in $currency. Need conversion.
+ * 6. All transactions with foreign currency info NOT in $native, and currency info NOT in $currency. Need
+ * conversion.
+ *
* Gets balance at the end of current month by default. Returns the balance converted
* to the indicated currency ($native).
*
- * @param Account $account
- * @param Carbon $date
- * @param TransactionCurrency $native
- *
- * @return string
* @throws FireflyException
+ *
+ * @SuppressWarnings(PHPMD.ExcessiveMethodLength)
*/
public function balanceConverted(Account $account, Carbon $date, TransactionCurrency $native): string
{
- app('log')->debug(sprintf('Now in balanceConverted (%s) for account #%d, converting to %s', $date->format('Y-m-d'), $account->id, $native->code));
- // abuse chart properties:
- $cache = new CacheProperties();
+ Log::debug(sprintf('Now in balanceConverted (%s) for account #%d, converting to %s', $date->format('Y-m-d'), $account->id, $native->code));
+ $cache = new CacheProperties();
$cache->addProperty($account->id);
$cache->addProperty('balance');
$cache->addProperty($date);
$cache->addProperty($native->id);
if ($cache->has()) {
+ Log::debug('Cached!');
+
// return $cache->get();
}
+
/** @var AccountRepositoryInterface $repository */
$repository = app(AccountRepositoryInterface::class);
$currency = $repository->getAccountCurrency($account);
- if (null === $currency) {
- throw new FireflyException('Cannot get converted account balance: no currency found for account.');
- }
- if ((int)$native->id === (int)$currency->id) {
+ $currency = null === $currency ? app('amount')->getDefaultCurrencyByUserGroup($account->user->userGroup) : $currency;
+ if ($native->id === $currency->id) {
+ Log::debug('No conversion necessary!');
+
return $this->balance($account, $date);
}
- /**
- * selection of transactions
- * 1: all normal transactions. No foreign currency info. In $currency. Need conversion.
- * 2: all normal transactions. No foreign currency info. In $native. Need NO conversion.
- * 3: all normal transactions. No foreign currency info. In neither currency. Need conversion.
- * Then, select everything with foreign currency info:
- * 4. All transactions with foreign currency info in $native. Normal currency value is ignored. Do not need conversion.
- * 5. All transactions with foreign currency info NOT in $native, but currency info in $currency. Need conversion.
- * 6. All transactions with foreign currency info NOT in $native, and currency info NOT in $currency. Need conversion.
- *
- */
- $new = [];
- $existing = [];
- // 1
- $new[] = $account->transactions()
- ->leftJoin('transaction_journals', 'transaction_journals.id', '=', 'transactions.transaction_journal_id')
- ->where('transaction_journals.date', '<=', $date->format('Y-m-d 23:59:59'))
- ->where('transactions.transaction_currency_id', $currency->id)
- ->whereNull('transactions.foreign_currency_id')
- ->get(['transaction_journals.date', 'transactions.amount'])->toArray();
- app('log')->debug(sprintf('%d transaction(s) in set #1', count($new[0])));
- // 2
- $existing[] = $account->transactions()
- ->leftJoin('transaction_journals', 'transaction_journals.id', '=', 'transactions.transaction_journal_id')
- ->where('transaction_journals.date', '<=', $date->format('Y-m-d 23:59:59'))
- ->where('transactions.transaction_currency_id', $native->id)
- ->whereNull('transactions.foreign_currency_id')
- ->get(['transactions.amount'])->toArray();
- app('log')->debug(sprintf('%d transaction(s) in set #2', count($existing[0])));
- // 3
- $new[] = $account->transactions()
- ->leftJoin('transaction_journals', 'transaction_journals.id', '=', 'transactions.transaction_journal_id')
- ->where('transaction_journals.date', '<=', $date->format('Y-m-d 23:59:59'))
- ->where('transactions.transaction_currency_id', '!=', $currency->id)
- ->where('transactions.transaction_currency_id', '!=', $native->id)
- ->whereNull('transactions.foreign_currency_id')
- ->get(['transaction_journals.date', 'transactions.amount'])->toArray();
- app('log')->debug(sprintf('%d transactions in set #3', count($new[1])));
- // 4
- $existing[] = $account->transactions()
- ->leftJoin('transaction_journals', 'transaction_journals.id', '=', 'transactions.transaction_journal_id')
- ->where('transaction_journals.date', '<=', $date->format('Y-m-d 23:59:59'))
- ->where('transactions.foreign_currency_id', $native->id)
- ->whereNotNull('transactions.foreign_amount')
- ->get(['transactions.foreign_amount'])->toArray();
- app('log')->debug(sprintf('%d transactions in set #4', count($existing[1])));
- // 5
- $new[] = $account->transactions()
- ->leftJoin('transaction_journals', 'transaction_journals.id', '=', 'transactions.transaction_journal_id')
- ->where('transaction_journals.date', '<=', $date->format('Y-m-d 23:59:59'))
- ->where('transactions.transaction_currency_id', $currency->id)
- ->where('transactions.foreign_currency_id', '!=', $native->id)
- ->whereNotNull('transactions.foreign_amount')
- ->get(['transaction_journals.date', 'transactions.amount'])->toArray();
- app('log')->debug(sprintf('%d transactions in set #5', count($new[2])));
- // 6
- $new[] = $account->transactions()
- ->leftJoin('transaction_journals', 'transaction_journals.id', '=', 'transactions.transaction_journal_id')
- ->where('transaction_journals.date', '<=', $date->format('Y-m-d 23:59:59'))
- ->where('transactions.transaction_currency_id', '!=', $currency->id)
- ->where('transactions.foreign_currency_id', '!=', $native->id)
- ->whereNotNull('transactions.foreign_amount')
- ->get(['transaction_journals.date', 'transactions.amount'])->toArray();
- app('log')->debug(sprintf('%d transactions in set #6', count($new[3])));
+ $new = [];
+ $existing = [];
+ $new[] = $account->transactions() // 1
+ ->leftJoin('transaction_journals', 'transaction_journals.id', '=', 'transactions.transaction_journal_id')
+ ->where('transaction_journals.date', '<=', $date->format('Y-m-d 23:59:59'))
+ ->where('transactions.transaction_currency_id', $currency->id)
+ ->whereNull('transactions.foreign_currency_id')
+ ->get(['transaction_journals.date', 'transactions.amount'])->toArray()
+ ;
+ Log::debug(sprintf('%d transaction(s) in set #1', count($new[0])));
+ $existing[] = $account->transactions() // 2
+ ->leftJoin('transaction_journals', 'transaction_journals.id', '=', 'transactions.transaction_journal_id')
+ ->where('transaction_journals.date', '<=', $date->format('Y-m-d 23:59:59'))
+ ->where('transactions.transaction_currency_id', $native->id)
+ ->whereNull('transactions.foreign_currency_id')
+ ->get(['transactions.amount'])->toArray()
+ ;
+ Log::debug(sprintf('%d transaction(s) in set #2', count($existing[0])));
+ $new[] = $account->transactions() // 3
+ ->leftJoin('transaction_journals', 'transaction_journals.id', '=', 'transactions.transaction_journal_id')
+ ->where('transaction_journals.date', '<=', $date->format('Y-m-d 23:59:59'))
+ ->where('transactions.transaction_currency_id', '!=', $currency->id)
+ ->where('transactions.transaction_currency_id', '!=', $native->id)
+ ->whereNull('transactions.foreign_currency_id')
+ ->get(['transaction_journals.date', 'transactions.amount'])->toArray()
+ ;
+ Log::debug(sprintf('%d transactions in set #3', count($new[1])));
+ $existing[] = $account->transactions() // 4
+ ->leftJoin('transaction_journals', 'transaction_journals.id', '=', 'transactions.transaction_journal_id')
+ ->where('transaction_journals.date', '<=', $date->format('Y-m-d 23:59:59'))
+ ->where('transactions.foreign_currency_id', $native->id)
+ ->whereNotNull('transactions.foreign_amount')
+ ->get(['transactions.foreign_amount'])->toArray()
+ ;
+ Log::debug(sprintf('%d transactions in set #4', count($existing[1])));
+ $new[] = $account->transactions()// 5
+ ->leftJoin('transaction_journals', 'transaction_journals.id', '=', 'transactions.transaction_journal_id')
+ ->where('transaction_journals.date', '<=', $date->format('Y-m-d 23:59:59'))
+ ->where('transactions.transaction_currency_id', $currency->id)
+ ->where('transactions.foreign_currency_id', '!=', $native->id)
+ ->whereNotNull('transactions.foreign_amount')
+ ->get(['transaction_journals.date', 'transactions.amount'])->toArray()
+ ;
+ Log::debug(sprintf('%d transactions in set #5', count($new[2])));
+ $new[] = $account->transactions()// 6
+ ->leftJoin('transaction_journals', 'transaction_journals.id', '=', 'transactions.transaction_journal_id')
+ ->where('transaction_journals.date', '<=', $date->format('Y-m-d 23:59:59'))
+ ->where('transactions.transaction_currency_id', '!=', $currency->id)
+ ->where('transactions.foreign_currency_id', '!=', $native->id)
+ ->whereNotNull('transactions.foreign_amount')
+ ->get(['transaction_journals.date', 'transactions.amount'])->toArray()
+ ;
+ Log::debug(sprintf('%d transactions in set #6', count($new[3])));
// process both sets of transactions. Of course, no need to convert set "existing".
- $balance = $this->sumTransactions($existing[0], 'amount');
- $balance = bcadd($balance, $this->sumTransactions($existing[1], 'foreign_amount'));
- //app('log')->debug(sprintf('Balance from set #2 and #4 is %f', $balance));
+ $balance = $this->sumTransactions($existing[0], 'amount');
+ $balance = bcadd($balance, $this->sumTransactions($existing[1], 'foreign_amount'));
+ Log::debug(sprintf('Balance from set #2 and #4 is %f', $balance));
// need to convert the others. All sets use the "amount" value as their base (that's easy)
// but we need to convert each transaction separately because the date difference may
// incur huge currency changes.
- $converter = new ExchangeRateConverter();
- foreach ($new as $index => $set) {
+ Log::debug(sprintf('Created new ExchangeRateConverter in %s', __METHOD__));
+ $start = clone $date;
+ $end = clone $date;
+ $converter = new ExchangeRateConverter();
+ foreach ($new as $set) {
foreach ($set as $transaction) {
- $date = Carbon::createFromFormat('Y-m-d H:i:s', $transaction['date']);
- $rate = $converter->getCurrencyRate($currency, $native, $date);
+ $currentDate = false;
+
+ try {
+ $currentDate = Carbon::parse($transaction['date'], config('app.timezone'));
+ } catch (InvalidFormatException $e) {
+ Log::error(sprintf('Could not parse date "%s" in %s', $transaction['date'], __METHOD__));
+ }
+ if (false === $currentDate) {
+ $currentDate = today(config('app.timezone'));
+ }
+ if ($currentDate->lte($start)) {
+ $start = clone $currentDate;
+ }
+ }
+ }
+ unset($currentDate);
+ $converter->prepare($currency, $native, $start, $end);
+
+ foreach ($new as $set) {
+ foreach ($set as $transaction) {
+ $currentDate = false;
+
+ try {
+ $currentDate = Carbon::parse($transaction['date'], config('app.timezone'));
+ } catch (InvalidFormatException $e) {
+ Log::error(sprintf('Could not parse date "%s" in %s', $transaction['date'], __METHOD__));
+ }
+ if (false === $currentDate) {
+ $currentDate = today(config('app.timezone'));
+ }
+ $rate = $converter->getCurrencyRate($currency, $native, $currentDate);
$convertedAmount = bcmul($transaction['amount'], $rate);
$balance = bcadd($balance, $convertedAmount);
- // app('log')->debug(sprintf('Date: %s, rate: %s, amount: %s %s, new: %s %s',
- // $date->format('Y-m-d'),
- // $rate,
- // $currency->code,
- // $transaction['amount'],
- // $native->code,
- // $convertedAmount
- // ));
}
- //app('log')->debug(sprintf('Balance from new set #%d is %f', $index, $balance));
}
// add virtual balance (also needs conversion)
- $virtual = null === $account->virtual_balance ? '0' : (string)$account->virtual_balance;
- $virtual = $converter->convert($currency, $native, $account->created_at, $virtual);
- $balance = bcadd($balance, $virtual);
+ $virtual = null === $account->virtual_balance ? '0' : $account->virtual_balance;
+ $virtual = $converter->convert($currency, $native, $account->created_at, $virtual);
+ $balance = bcadd($balance, $virtual);
+ $converter->summarize();
$cache->store($balance);
+ $converter->summarize();
return $balance;
}
@@ -479,17 +488,13 @@ class Steam
/**
* This method always ignores the virtual balance.
*
- * @param Collection $accounts
- * @param Carbon $date
- *
- * @return array
* @throws FireflyException
*/
public function balancesByAccounts(Collection $accounts, Carbon $date): array
{
- $ids = $accounts->pluck('id')->toArray();
+ $ids = $accounts->pluck('id')->toArray();
// cache this property.
- $cache = new CacheProperties();
+ $cache = new CacheProperties();
$cache->addProperty($ids);
$cache->addProperty('balances');
$cache->addProperty($date);
@@ -499,6 +504,7 @@ class Steam
// need to do this per account.
$result = [];
+
/** @var Account $account */
foreach ($accounts as $account) {
$result[$account->id] = $this->balance($account, $date);
@@ -512,17 +518,13 @@ class Steam
/**
* This method always ignores the virtual balance.
*
- * @param Collection $accounts
- * @param Carbon $date
- *
- * @return array
* @throws FireflyException
*/
public function balancesByAccountsConverted(Collection $accounts, Carbon $date): array
{
- $ids = $accounts->pluck('id')->toArray();
+ $ids = $accounts->pluck('id')->toArray();
// cache this property.
- $cache = new CacheProperties();
+ $cache = new CacheProperties();
$cache->addProperty($ids);
$cache->addProperty('balances-converted');
$cache->addProperty($date);
@@ -530,17 +532,17 @@ class Steam
// return $cache->get();
}
-
// need to do this per account.
$result = [];
+
/** @var Account $account */
foreach ($accounts as $account) {
- $default = app('amount')->getDefaultCurrencyByUser($account->user);
- $result[(int)$account->id]
+ $default = app('amount')->getDefaultCurrencyByUserGroup($account->user->userGroup);
+ $result[$account->id]
= [
- 'balance' => $this->balance($account, $date),
- 'native_balance' => $this->balanceConverted($account, $date, $default),
- ];
+ 'balance' => $this->balance($account, $date),
+ 'native_balance' => $this->balanceConverted($account, $date, $default),
+ ];
}
$cache->store($result);
@@ -550,17 +552,12 @@ class Steam
/**
* Same as above, but also groups per currency.
- *
- * @param Collection $accounts
- * @param Carbon $date
- *
- * @return array
*/
public function balancesPerCurrencyByAccounts(Collection $accounts, Carbon $date): array
{
- $ids = $accounts->pluck('id')->toArray();
+ $ids = $accounts->pluck('id')->toArray();
// cache this property.
- $cache = new CacheProperties();
+ $cache = new CacheProperties();
$cache->addProperty($ids);
$cache->addProperty('balances-per-currency');
$cache->addProperty($date);
@@ -570,6 +567,7 @@ class Steam
// need to do this per account.
$result = [];
+
/** @var Account $account */
foreach ($accounts as $account) {
$result[$account->id] = $this->balancePerCurrency($account, $date);
@@ -580,16 +578,10 @@ class Steam
return $result;
}
- /**
- * @param Account $account
- * @param Carbon $date
- *
- * @return array
- */
public function balancePerCurrency(Account $account, Carbon $date): array
{
// abuse chart properties:
- $cache = new CacheProperties();
+ $cache = new CacheProperties();
$cache->addProperty($account->id);
$cache->addProperty('balance-per-currency');
$cache->addProperty($date);
@@ -597,12 +589,14 @@ class Steam
return $cache->get();
}
$query = $account->transactions()
- ->leftJoin('transaction_journals', 'transaction_journals.id', '=', 'transactions.transaction_journal_id')
- ->where('transaction_journals.date', '<=', $date->format('Y-m-d 23:59:59'))
- ->groupBy('transactions.transaction_currency_id');
- $balances = $query->get(['transactions.transaction_currency_id', DB::raw('SUM(transactions.amount) as sum_for_currency')]);
+ ->leftJoin('transaction_journals', 'transaction_journals.id', '=', 'transactions.transaction_journal_id')
+ ->where('transaction_journals.date', '<=', $date->format('Y-m-d 23:59:59'))
+ ->groupBy('transactions.transaction_currency_id')
+ ;
+ $balances = $query->get(['transactions.transaction_currency_id', \DB::raw('SUM(transactions.amount) as sum_for_currency')]); // @phpstan-ignore-line
$return = [];
- /** @var stdClass $entry */
+
+ /** @var \stdClass $entry */
foreach ($balances as $entry) {
$return[(int)$entry->transaction_currency_id] = (string)$entry->sum_for_currency;
}
@@ -613,11 +607,6 @@ class Steam
/**
* https://stackoverflow.com/questions/1642614/how-to-ceil-floor-and-round-bcmath-numbers
- *
- * @param null|string $number
- * @param int $precision
- *
- * @return string
*/
public function bcround(?string $number, int $precision = 0): string
{
@@ -634,21 +623,16 @@ class Steam
// Log::debug(sprintf('Trying bcround("%s",%d)', $number, $precision));
if (str_contains($number, '.')) {
- if ($number[0] !== '-') {
- return bcadd($number, '0.' . str_repeat('0', $precision) . '5', $precision);
+ if ('-' !== $number[0]) {
+ return bcadd($number, '0.'.str_repeat('0', $precision).'5', $precision);
}
- return bcsub($number, '0.' . str_repeat('0', $precision) . '5', $precision);
+ return bcsub($number, '0.'.str_repeat('0', $precision).'5', $precision);
}
return $number;
}
- /**
- * @param string $string
- *
- * @return string
- */
public function filterSpaces(string $string): string
{
$search = [
@@ -707,39 +691,34 @@ class Steam
}
/**
- * @param string $ipAddress
- *
- * @return string
* @throws FireflyException
*/
public function getHostName(string $ipAddress): string
{
try {
$hostName = gethostbyaddr($ipAddress);
- } catch (Exception $e) { // intentional generic exception
+ } catch (\Exception $e) { // intentional generic exception
throw new FireflyException($e->getMessage(), 0, $e);
}
- return $hostName;
+
+ return (string)$hostName;
}
- /**
- * @param array $accounts
- *
- * @return array
- */
public function getLastActivities(array $accounts): array
{
$list = [];
- $set = auth()->user()->transactions()
- ->whereIn('transactions.account_id', $accounts)
- ->groupBy(['transactions.account_id', 'transaction_journals.user_id'])
- ->get(['transactions.account_id', DB::raw('MAX(transaction_journals.date) AS max_date')]);
+ $set = auth()->user()->transactions()
+ ->whereIn('transactions.account_id', $accounts)
+ ->groupBy(['transactions.account_id', 'transaction_journals.user_id'])
+ ->get(['transactions.account_id', \DB::raw('MAX(transaction_journals.date) AS max_date')]) // @phpstan-ignore-line
+ ;
+ /** @var Transaction $entry */
foreach ($set as $entry) {
- $date = new Carbon($entry->max_date, config('app.timezone'));
+ $date = new Carbon($entry->max_date, config('app.timezone'));
$date->setTimezone(config('app.timezone'));
- $list[(int)$entry->account_id] = $date;
+ $list[$entry->account_id] = $date;
}
return $list;
@@ -747,21 +726,20 @@ class Steam
/**
* Get user's locale.
- *
- * @return string
- * @throws FireflyException
- * @throws ContainerExceptionInterface
- * @throws NotFoundExceptionInterface
*/
public function getLocale(): string // get preference
{
$locale = app('preferences')->get('locale', config('firefly.default_locale', 'equal'))->data;
+ if (is_array($locale)) {
+ $locale = 'equal';
+ }
if ('equal' === $locale) {
$locale = $this->getLanguage();
}
+ $locale = (string)$locale;
// Check for Windows to replace the locale correctly.
- if (strtoupper(substr(PHP_OS, 0, 3)) === 'WIN') {
+ if ('WIN' === strtoupper(substr(PHP_OS, 0, 3))) {
$locale = str_replace('_', '-', $locale);
}
@@ -771,10 +749,7 @@ class Steam
/**
* Get user's language.
*
- * @return string
* @throws FireflyException
- * @throws ContainerExceptionInterface
- * @throws NotFoundExceptionInterface
*/
public function getLanguage(): string // get preference
{
@@ -782,14 +757,10 @@ class Steam
if (!is_string($preference)) {
throw new FireflyException(sprintf('Preference "language" must be a string, but is unexpectedly a "%s".', gettype($preference)));
}
+
return str_replace('-', '_', $preference);
}
- /**
- * @param string $locale
- *
- * @return array
- */
public function getLocaleArray(string $locale): array
{
return [
@@ -807,29 +778,22 @@ class Steam
* Uses the session's previousUrl() function as inspired by GitHub user @z1r0-
*
* session()->previousUrl() uses getSafeUrl() so we can safely return it:
- *
- * @return string
*/
public function getSafePreviousUrl(): string
{
- //Log::debug(sprintf('getSafePreviousUrl: "%s"', session()->previousUrl()));
+ // Log::debug(sprintf('getSafePreviousUrl: "%s"', session()->previousUrl()));
return session()->previousUrl() ?? route('index');
}
/**
* Make sure URL is safe.
- *
- * @param string $unknownUrl
- * @param string $safeUrl
- *
- * @return string
*/
public function getSafeUrl(string $unknownUrl, string $safeUrl): string
{
- //Log::debug(sprintf('getSafeUrl(%s, %s)', $unknownUrl, $safeUrl));
- $returnUrl = $safeUrl;
- $unknownHost = parse_url($unknownUrl, PHP_URL_HOST);
- $safeHost = parse_url($safeUrl, PHP_URL_HOST);
+ // Log::debug(sprintf('getSafeUrl(%s, %s)', $unknownUrl, $safeUrl));
+ $returnUrl = $safeUrl;
+ $unknownHost = parse_url($unknownUrl, PHP_URL_HOST);
+ $safeHost = parse_url($safeUrl, PHP_URL_HOST);
if (null !== $unknownHost && $unknownHost === $safeHost) {
$returnUrl = $unknownUrl;
@@ -837,18 +801,13 @@ class Steam
// URL must not lead to weird pages
$forbiddenWords = ['jscript', 'json', 'debug', 'serviceworker', 'offline', 'delete', '/login', '/attachments/view'];
- if (Str::contains($returnUrl, $forbiddenWords)) {
+ if (\Str::contains($returnUrl, $forbiddenWords)) {
$returnUrl = $safeUrl;
}
return $returnUrl;
}
- /**
- * @param string $amount
- *
- * @return string
- */
public function negative(string $amount): string
{
if ('' === $amount) {
@@ -868,37 +827,30 @@ class Steam
*
* Convert a scientific notation to float
* Additionally fixed a problem with PHP <= 5.2.x with big integers
- *
- * @param string $value
- *
- * @return string
*/
public function floatalize(string $value): string
{
- $value = strtoupper($value);
+ $value = strtoupper($value);
if (!str_contains($value, 'E')) {
return $value;
}
- $number = substr($value, 0, strpos($value, 'E'));
+ $number = substr($value, 0, (int)strpos($value, 'E'));
if (str_contains($number, '.')) {
- $post = strlen(substr($number, strpos($number, '.') + 1));
- $mantis = substr($value, strpos($value, 'E') + 1);
+ $post = strlen(substr($number, (int)strpos($number, '.') + 1));
+ $mantis = substr($value, (int)strpos($value, 'E') + 1);
if ($mantis < 0) {
$post += abs((int)$mantis);
}
+
// TODO careless float could break financial math.
return number_format((float)$value, $post, '.', '');
}
+
// TODO careless float could break financial math.
return number_format((float)$value, 0, '.', '');
}
- /**
- * @param string|null $amount
- *
- * @return string|null
- */
public function opposite(string $amount = null): ?string
{
if (null === $amount) {
@@ -908,11 +860,6 @@ class Steam
return bcmul($amount, '-1');
}
- /**
- * @param string $string
- *
- * @return int
- */
public function phpBytes(string $string): int
{
$string = str_replace(['kb', 'mb', 'gb'], ['k', 'm', 'g'], strtolower($string));
@@ -941,23 +888,20 @@ class Steam
return (int)$string;
}
- /**
- * @param string $amount
- *
- * @return string
- */
public function positive(string $amount): string
{
if ('' === $amount) {
return '0';
}
+
try {
- if (bccomp($amount, '0') === -1) {
+ if (-1 === bccomp($amount, '0')) {
$amount = bcmul($amount, '-1');
}
- } catch (ValueError $e) {
+ } catch (\ValueError $e) {
Log::error(sprintf('ValueError in Steam::positive("%s"): %s', $amount, $e->getMessage()));
Log::error($e->getTraceAsString());
+
return '0';
}
diff --git a/app/Support/System/GeneratesInstallationId.php b/app/Support/System/GeneratesInstallationId.php
index beccdaafab..bd017f4f5a 100644
--- a/app/Support/System/GeneratesInstallationId.php
+++ b/app/Support/System/GeneratesInstallationId.php
@@ -25,7 +25,6 @@ declare(strict_types=1);
namespace FireflyIII\Support\System;
use FireflyIII\Exceptions\FireflyException;
-use Illuminate\Support\Facades\Log;
use Ramsey\Uuid\Uuid;
/**
@@ -33,15 +32,12 @@ use Ramsey\Uuid\Uuid;
*/
trait GeneratesInstallationId
{
- /**
- *
- */
protected function generateInstallationId(): void
{
try {
$config = app('fireflyconfig')->get('installation_id');
} catch (FireflyException $e) {
- Log::info('Could not create or generate installation ID. Do not continue.');
+ app('log')->info('Could not create or generate installation ID. Do not continue.');
return;
}
@@ -54,7 +50,7 @@ trait GeneratesInstallationId
if (null === $config) {
$uuid4 = Uuid::uuid4();
$uniqueId = (string)$uuid4;
- Log::info(sprintf('Created Firefly III installation ID %s', $uniqueId));
+ app('log')->info(sprintf('Created Firefly III installation ID %s', $uniqueId));
app('fireflyconfig')->set('installation_id', $uniqueId);
}
}
diff --git a/app/Support/System/OAuthKeys.php b/app/Support/System/OAuthKeys.php
index 8a59ebf739..f46af222c1 100644
--- a/app/Support/System/OAuthKeys.php
+++ b/app/Support/System/OAuthKeys.php
@@ -24,11 +24,8 @@ declare(strict_types=1);
namespace FireflyIII\Support\System;
-use Artisan;
-use Crypt;
use FireflyIII\Exceptions\FireflyException;
use Illuminate\Contracts\Encryption\DecryptException;
-use Illuminate\Support\Facades\Log;
use Laravel\Passport\Console\KeysCommand;
use Psr\Container\ContainerExceptionInterface;
use Psr\Container\NotFoundExceptionInterface;
@@ -38,12 +35,9 @@ use Psr\Container\NotFoundExceptionInterface;
*/
class OAuthKeys
{
- private const PRIVATE_KEY = 'oauth_private_key';
- private const PUBLIC_KEY = 'oauth_public_key';
+ private const string PRIVATE_KEY = 'oauth_private_key';
+ private const string PUBLIC_KEY = 'oauth_public_key';
- /**
- *
- */
public static function verifyKeysRoutine(): void
{
if (!self::keysInDatabase() && !self::hasKeyFiles()) {
@@ -62,9 +56,6 @@ class OAuthKeys
}
}
- /**
- * @return bool
- */
public static function keysInDatabase(): bool
{
$privateKey = '';
@@ -74,9 +65,9 @@ class OAuthKeys
try {
$privateKey = (string)app('fireflyconfig')->get(self::PRIVATE_KEY)?->data;
$publicKey = (string)app('fireflyconfig')->get(self::PUBLIC_KEY)?->data;
- } catch (ContainerExceptionInterface | NotFoundExceptionInterface | FireflyException $e) {
- Log::error(sprintf('Could not validate keysInDatabase(): %s', $e->getMessage()));
- Log::error($e->getTraceAsString());
+ } catch (ContainerExceptionInterface|FireflyException|NotFoundExceptionInterface $e) {
+ app('log')->error(sprintf('Could not validate keysInDatabase(): %s', $e->getMessage()));
+ app('log')->error($e->getTraceAsString());
}
}
if ('' !== $privateKey && '' !== $publicKey) {
@@ -86,9 +77,6 @@ class OAuthKeys
return false;
}
- /**
- * @return bool
- */
public static function hasKeyFiles(): bool
{
$private = storage_path('oauth-private.key');
@@ -97,42 +85,34 @@ class OAuthKeys
return file_exists($private) && file_exists($public);
}
- /**
- *
- */
public static function generateKeys(): void
{
- Artisan::registerCommand(new KeysCommand());
- Artisan::call('passport:keys');
+ \Artisan::registerCommand(new KeysCommand());
+ \Artisan::call('passport:keys');
}
- /**
- *
- */
public static function storeKeysInDB(): void
{
$private = storage_path('oauth-private.key');
$public = storage_path('oauth-public.key');
- app('fireflyconfig')->set(self::PRIVATE_KEY, Crypt::encrypt(file_get_contents($private)));
- app('fireflyconfig')->set(self::PUBLIC_KEY, Crypt::encrypt(file_get_contents($public)));
+ app('fireflyconfig')->set(self::PRIVATE_KEY, \Crypt::encrypt(file_get_contents($private)));
+ app('fireflyconfig')->set(self::PUBLIC_KEY, \Crypt::encrypt(file_get_contents($public)));
}
/**
- * @return bool
- * @throws ContainerExceptionInterface
* @throws FireflyException
- * @throws NotFoundExceptionInterface
*/
public static function restoreKeysFromDB(): bool
{
$privateKey = (string)app('fireflyconfig')->get(self::PRIVATE_KEY)?->data;
$publicKey = (string)app('fireflyconfig')->get(self::PUBLIC_KEY)?->data;
+
try {
- $privateContent = Crypt::decrypt($privateKey);
- $publicContent = Crypt::decrypt($publicKey);
+ $privateContent = \Crypt::decrypt($privateKey);
+ $publicContent = \Crypt::decrypt($publicKey);
} catch (DecryptException $e) {
- Log::error('Could not decrypt pub/private keypair.');
- Log::error($e->getMessage());
+ app('log')->error('Could not decrypt pub/private keypair.');
+ app('log')->error($e->getMessage());
// delete config vars from DB:
app('fireflyconfig')->delete(self::PRIVATE_KEY);
@@ -140,10 +120,11 @@ class OAuthKeys
return false;
}
- $private = storage_path('oauth-private.key');
- $public = storage_path('oauth-public.key');
+ $private = storage_path('oauth-private.key');
+ $public = storage_path('oauth-public.key');
file_put_contents($private, $privateContent);
file_put_contents($public, $publicContent);
+
return true;
}
}
diff --git a/app/Support/Twig/AmountFormat.php b/app/Support/Twig/AmountFormat.php
index 5ae6db2121..6f96f42448 100644
--- a/app/Support/Twig/AmountFormat.php
+++ b/app/Support/Twig/AmountFormat.php
@@ -35,9 +35,6 @@ use Twig\TwigFunction;
*/
class AmountFormat extends AbstractExtension
{
- /**
- * {@inheritdoc}
- */
public function getFilters(): array
{
return [
@@ -46,9 +43,6 @@ class AmountFormat extends AbstractExtension
];
}
- /**
- * @return TwigFilter
- */
protected function formatAmount(): TwigFilter
{
return new TwigFilter(
@@ -62,9 +56,6 @@ class AmountFormat extends AbstractExtension
);
}
- /**
- * @return TwigFilter
- */
protected function formatAmountPlain(): TwigFilter
{
return new TwigFilter(
@@ -78,9 +69,6 @@ class AmountFormat extends AbstractExtension
);
}
- /**
- * {@inheritdoc}
- */
public function getFunctions(): array
{
return [
@@ -93,15 +81,15 @@ class AmountFormat extends AbstractExtension
/**
* Will format the amount by the currency related to the given account.
*
- * @return TwigFunction
- * TODO remove me when layout v1 is deprecated.
+ * TODO Remove me when v2 hits.
*/
protected function formatAmountByAccount(): TwigFunction
{
return new TwigFunction(
'formatAmountByAccount',
static function (AccountModel $account, string $amount, bool $coloured = null): string {
- $coloured = $coloured ?? true;
+ $coloured ??= true;
+
/** @var AccountRepositoryInterface $accountRepos */
$accountRepos = app(AccountRepositoryInterface::class);
$currency = $accountRepos->getAccountCurrency($account) ?? app('amount')->getDefaultCurrency();
@@ -114,16 +102,14 @@ class AmountFormat extends AbstractExtension
/**
* Will format the amount by the currency related to the given account.
- *
- * @return TwigFunction
*/
protected function formatAmountBySymbol(): TwigFunction
{
return new TwigFunction(
'formatAmountBySymbol',
static function (string $amount, string $symbol, int $decimalPlaces = null, bool $coloured = null): string {
- $decimalPlaces = $decimalPlaces ?? 2;
- $coloured = $coloured ?? true;
+ $decimalPlaces ??= 2;
+ $coloured ??= true;
$currency = new TransactionCurrency();
$currency->symbol = $symbol;
$currency->decimal_places = $decimalPlaces;
@@ -136,15 +122,13 @@ class AmountFormat extends AbstractExtension
/**
* Will format the amount by the currency related to the given account.
- *
- * @return TwigFunction
*/
protected function formatAmountByCurrency(): TwigFunction
{
return new TwigFunction(
'formatAmountByCurrency',
static function (TransactionCurrency $currency, string $amount, bool $coloured = null): string {
- $coloured = $coloured ?? true;
+ $coloured ??= true;
return app('amount')->formatAnything($currency, $amount, $coloured);
},
diff --git a/app/Support/Twig/General.php b/app/Support/Twig/General.php
index 4281ff1539..4186ef6f15 100644
--- a/app/Support/Twig/General.php
+++ b/app/Support/Twig/General.php
@@ -39,9 +39,6 @@ use Twig\TwigFunction;
*/
class General extends AbstractExtension
{
- /**
- * @return array
- */
public function getFilters(): array
{
return [
@@ -55,8 +52,6 @@ class General extends AbstractExtension
/**
* Show account balance. Only used on the front page of Firefly III.
- *
- * @return TwigFilter
*/
protected function balance(): TwigFilter
{
@@ -66,6 +61,7 @@ class General extends AbstractExtension
if (null === $account) {
return '0';
}
+
/** @var Carbon $date */
$date = session('end', today(config('app.timezone'))->endOfMonth());
@@ -76,8 +72,6 @@ class General extends AbstractExtension
/**
* Used to convert 1024 to 1kb etc.
- *
- * @return TwigFilter
*/
protected function formatFilesize(): TwigFilter
{
@@ -86,15 +80,15 @@ class General extends AbstractExtension
static function (int $size): string {
// less than one GB, more than one MB
if ($size < (1024 * 1024 * 2014) && $size >= (1024 * 1024)) {
- return round($size / (1024 * 1024), 2) . ' MB';
+ return round($size / (1024 * 1024), 2).' MB';
}
// less than one MB
if ($size < (1024 * 1024)) {
- return round($size / 1024, 2) . ' KB';
+ return round($size / 1024, 2).' KB';
}
- return $size . ' bytes';
+ return $size.' bytes';
}
);
}
@@ -102,7 +96,7 @@ class General extends AbstractExtension
/**
* Show icon with attachment.
*
- * @return TwigFilter
+ * @SuppressWarnings(PHPMD.CyclomaticComplexity)
*/
protected function mimeIcon(): TwigFilter
{
@@ -112,9 +106,11 @@ class General extends AbstractExtension
switch ($string) {
default:
return 'fa-file-o';
+
case 'application/pdf':
return 'fa-file-pdf-o';
- /* image */
+
+ // image
case 'image/png':
case 'image/jpeg':
case 'image/svg+xml':
@@ -122,7 +118,8 @@ class General extends AbstractExtension
case 'image/heic-sequence':
case 'application/vnd.oasis.opendocument.image':
return 'fa-file-image-o';
- /* MS word */
+
+ // MS word
case 'application/msword':
case 'application/vnd.openxmlformats-officedocument.wordprocessingml.document':
case 'application/vnd.openxmlformats-officedocument.wordprocessingml.template':
@@ -137,7 +134,8 @@ class General extends AbstractExtension
case 'application/vnd.oasis.opendocument.text-web':
case 'application/vnd.oasis.opendocument.text-master':
return 'fa-file-word-o';
- /* MS excel */
+
+ // MS excel
case 'application/vnd.ms-excel':
case 'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet':
case 'application/vnd.openxmlformats-officedocument.spreadsheetml.template':
@@ -147,7 +145,8 @@ class General extends AbstractExtension
case 'application/vnd.oasis.opendocument.spreadsheet':
case 'application/vnd.oasis.opendocument.spreadsheet-template':
return 'fa-file-excel-o';
- /* MS powerpoint */
+
+ // MS powerpoint
case 'application/vnd.ms-powerpoint':
case 'application/vnd.openxmlformats-officedocument.presentationml.presentation':
case 'application/vnd.openxmlformats-officedocument.presentationml.template':
@@ -158,12 +157,14 @@ class General extends AbstractExtension
case 'application/vnd.oasis.opendocument.presentation':
case 'application/vnd.oasis.opendocument.presentation-template':
return 'fa-file-powerpoint-o';
- /* calc */
+
+ // calc
case 'application/vnd.sun.xml.draw':
case 'application/vnd.sun.xml.draw.template':
case 'application/vnd.stardivision.draw':
case 'application/vnd.oasis.opendocument.chart':
return 'fa-paint-brush';
+
case 'application/vnd.oasis.opendocument.graphics':
case 'application/vnd.oasis.opendocument.graphics-template':
case 'application/vnd.sun.xml.math':
@@ -177,9 +178,6 @@ class General extends AbstractExtension
);
}
- /**
- * @return TwigFilter
- */
protected function markdown(): TwigFilter
{
return new TwigFilter(
@@ -201,8 +199,6 @@ class General extends AbstractExtension
/**
* Show URL host name
- *
- * @return TwigFilter
*/
protected function phpHostName(): TwigFilter
{
@@ -217,9 +213,6 @@ class General extends AbstractExtension
);
}
- /**
- * {@inheritdoc}
- */
public function getFunctions(): array
{
return [
@@ -238,8 +231,6 @@ class General extends AbstractExtension
/**
* Basic example thing for some views.
- *
- * @return TwigFunction
*/
protected function phpdate(): TwigFunction
{
@@ -254,8 +245,6 @@ class General extends AbstractExtension
/**
* Will return "active" when the current route matches the given argument
* exactly.
- *
- * @return TwigFunction
*/
protected function activeRouteStrict(): TwigFunction
{
@@ -265,7 +254,7 @@ class General extends AbstractExtension
$args = func_get_args();
$route = $args[0]; // name of the route.
- if (Route::getCurrentRoute()->getName() === $route) {
+ if (\Route::getCurrentRoute()->getName() === $route) {
return 'active';
}
@@ -277,8 +266,6 @@ class General extends AbstractExtension
/**
* Will return "active" when a part of the route matches the argument.
* ie. "accounts" will match "accounts.index".
- *
- * @return TwigFunction
*/
protected function activeRoutePartial(): TwigFunction
{
@@ -287,7 +274,7 @@ class General extends AbstractExtension
static function (): string {
$args = func_get_args();
$route = $args[0]; // name of the route.
- $name = Route::getCurrentRoute()->getName() ?? '';
+ $name = \Route::getCurrentRoute()->getName() ?? '';
if (str_contains($name, $route)) {
return 'active';
}
@@ -300,8 +287,6 @@ class General extends AbstractExtension
/**
* This function will return "active" when the current route matches the first argument (even partly)
* but, the variable $objectType has been set and matches the second argument.
- *
- * @return TwigFunction
*/
protected function activeRoutePartialObjectType(): TwigFunction
{
@@ -309,11 +294,11 @@ class General extends AbstractExtension
'activeRoutePartialObjectType',
static function ($context): string {
[, $route, $objectType] = func_get_args();
- $activeObjectType = $context['objectType'] ?? false;
+ $activeObjectType = $context['objectType'] ?? false;
if ($objectType === $activeObjectType
&& false !== stripos(
- Route::getCurrentRoute()->getName(),
+ \Route::getCurrentRoute()->getName(),
$route
)) {
return 'active';
@@ -328,8 +313,6 @@ class General extends AbstractExtension
/**
* Will return "menu-open" when a part of the route matches the argument.
* ie. "accounts" will match "accounts.index".
- *
- * @return TwigFunction
*/
protected function menuOpenRoutePartial(): TwigFunction
{
@@ -338,7 +321,7 @@ class General extends AbstractExtension
static function (): string {
$args = func_get_args();
$route = $args[0]; // name of the route.
- $name = Route::getCurrentRoute()->getName() ?? '';
+ $name = \Route::getCurrentRoute()->getName() ?? '';
if (str_contains($name, $route)) {
return 'menu-open';
}
@@ -350,14 +333,12 @@ class General extends AbstractExtension
/**
* Formats a string as a thing by converting it to a Carbon first.
- *
- * @return TwigFunction
*/
protected function formatDate(): TwigFunction
{
return new TwigFunction(
'formatDate',
- function (string $date, string $format): string {
+ static function (string $date, string $format): string {
$carbon = new Carbon($date);
return $carbon->isoFormat($format);
@@ -366,8 +347,7 @@ class General extends AbstractExtension
}
/**
- * @return TwigFunction
- * TODO remove me when layout v1 is deprecated.
+ * TODO Remove me when v2 hits.
*/
protected function getMetaField(): TwigFunction
{
@@ -388,8 +368,6 @@ class General extends AbstractExtension
/**
* Will return true if the user is of role X.
- *
- * @return TwigFunction
*/
protected function hasRole(): TwigFunction
{
@@ -406,9 +384,6 @@ class General extends AbstractExtension
);
}
- /**
- * @return TwigFunction
- */
protected function getRootSearchOperator(): TwigFunction
{
return new TwigFunction(
@@ -421,9 +396,6 @@ class General extends AbstractExtension
);
}
- /**
- * @return TwigFunction
- */
protected function carbonize(): TwigFunction
{
return new TwigFunction(
diff --git a/app/Support/Twig/Rule.php b/app/Support/Twig/Rule.php
index adc616b129..c79031d807 100644
--- a/app/Support/Twig/Rule.php
+++ b/app/Support/Twig/Rule.php
@@ -23,7 +23,6 @@ declare(strict_types=1);
namespace FireflyIII\Support\Twig;
-use Config;
use Twig\Extension\AbstractExtension;
use Twig\TwigFunction;
@@ -32,9 +31,6 @@ use Twig\TwigFunction;
*/
class Rule extends AbstractExtension
{
- /**
- * @return array
- */
public function getFunctions(): array
{
return [
@@ -44,9 +40,6 @@ class Rule extends AbstractExtension
];
}
- /**
- * @return TwigFunction
- */
public function allJournalTriggers(): TwigFunction
{
return new TwigFunction(
@@ -60,9 +53,6 @@ class Rule extends AbstractExtension
);
}
- /**
- * @return TwigFunction
- */
public function allRuleTriggers(): TwigFunction
{
return new TwigFunction(
@@ -72,7 +62,7 @@ class Rule extends AbstractExtension
$possibleTriggers = [];
foreach ($ruleTriggers as $key) {
if ('user_action' !== $key) {
- $possibleTriggers[$key] = (string)trans('firefly.rule_trigger_' . $key . '_choice');
+ $possibleTriggers[$key] = (string)trans('firefly.rule_trigger_'.$key.'_choice');
}
}
unset($ruleTriggers);
@@ -83,19 +73,16 @@ class Rule extends AbstractExtension
);
}
- /**
- * @return TwigFunction
- */
public function allActionTriggers(): TwigFunction
{
return new TwigFunction(
'allRuleActions',
static function () {
// array of valid values for actions
- $ruleActions = array_keys(Config::get('firefly.rule-actions'));
+ $ruleActions = array_keys(\Config::get('firefly.rule-actions'));
$possibleActions = [];
foreach ($ruleActions as $key) {
- $possibleActions[$key] = (string)trans('firefly.rule_action_' . $key . '_choice');
+ $possibleActions[$key] = (string)trans('firefly.rule_action_'.$key.'_choice');
}
unset($ruleActions);
asort($possibleActions);
diff --git a/app/Support/Twig/TransactionGroupTwig.php b/app/Support/Twig/TransactionGroupTwig.php
index 38e3005eb5..8dda66844c 100644
--- a/app/Support/Twig/TransactionGroupTwig.php
+++ b/app/Support/Twig/TransactionGroupTwig.php
@@ -24,10 +24,10 @@ declare(strict_types=1);
namespace FireflyIII\Support\Twig;
use Carbon\Carbon;
-use DB;
use FireflyIII\Models\AccountType;
use FireflyIII\Models\Transaction;
use FireflyIII\Models\TransactionJournal;
+use FireflyIII\Models\TransactionJournalMeta;
use FireflyIII\Models\TransactionType;
use Twig\Extension\AbstractExtension;
use Twig\TwigFunction;
@@ -37,10 +37,6 @@ use Twig\TwigFunction;
*/
class TransactionGroupTwig extends AbstractExtension
{
- /**
- * @return array
- *
- */
public function getFunctions(): array
{
return [
@@ -54,8 +50,6 @@ class TransactionGroupTwig extends AbstractExtension
/**
* Shows the amount for a single journal array.
- *
- * @return TwigFunction
*/
public function journalArrayAmount(): TwigFunction
{
@@ -78,10 +72,6 @@ class TransactionGroupTwig extends AbstractExtension
/**
* Generate normal amount for transaction from a transaction group.
- *
- * @param array $array
- *
- * @return string
*/
private function normalJournalArrayAmount(array $array): string
{
@@ -91,39 +81,32 @@ class TransactionGroupTwig extends AbstractExtension
$sourceType = $array['source_account_type'] ?? 'invalid';
$amount = $this->signAmount($amount, $type, $sourceType);
- if ($type === TransactionType::TRANSFER) {
+ if (TransactionType::TRANSFER === $type) {
$colored = false;
}
- $result = app('amount')->formatFlat($array['currency_symbol'], (int)$array['currency_decimal_places'], $amount, $colored);
- if ($type === TransactionType::TRANSFER) {
+ $result = app('amount')->formatFlat($array['currency_symbol'], (int)$array['currency_decimal_places'], $amount, $colored);
+ if (TransactionType::TRANSFER === $type) {
$result = sprintf('%s', $result);
}
return $result;
}
- /**
- * @param string $amount
- * @param string $transactionType
- * @param string $sourceType
- *
- * @return string
- */
private function signAmount(string $amount, string $transactionType, string $sourceType): string
{
// withdrawals stay negative
- if ($transactionType !== TransactionType::WITHDRAWAL) {
+ if (TransactionType::WITHDRAWAL !== $transactionType) {
$amount = bcmul($amount, '-1');
}
// opening balance and it comes from initial balance? its expense.
- if ($transactionType === TransactionType::OPENING_BALANCE && AccountType::INITIAL_BALANCE !== $sourceType) {
+ if (TransactionType::OPENING_BALANCE === $transactionType && AccountType::INITIAL_BALANCE !== $sourceType) {
$amount = bcmul($amount, '-1');
}
// reconciliation and it comes from reconciliation?
- if ($transactionType === TransactionType::RECONCILIATION && AccountType::RECONCILIATION !== $sourceType) {
+ if (TransactionType::RECONCILIATION === $transactionType && AccountType::RECONCILIATION !== $sourceType) {
$amount = bcmul($amount, '-1');
}
@@ -132,25 +115,21 @@ class TransactionGroupTwig extends AbstractExtension
/**
* Generate foreign amount for transaction from a transaction group.
- *
- * @param array $array
- *
- * @return string
*/
private function foreignJournalArrayAmount(array $array): string
{
- $type = $array['transaction_type_type'] ?? TransactionType::WITHDRAWAL;
- $amount = $array['foreign_amount'] ?? '0';
- $colored = true;
+ $type = $array['transaction_type_type'] ?? TransactionType::WITHDRAWAL;
+ $amount = $array['foreign_amount'] ?? '0';
+ $colored = true;
$sourceType = $array['source_account_type'] ?? 'invalid';
$amount = $this->signAmount($amount, $type, $sourceType);
- if ($type === TransactionType::TRANSFER) {
+ if (TransactionType::TRANSFER === $type) {
$colored = false;
}
- $result = app('amount')->formatFlat($array['foreign_currency_symbol'], (int)$array['foreign_currency_decimal_places'], $amount, $colored);
- if ($type === TransactionType::TRANSFER) {
+ $result = app('amount')->formatFlat($array['foreign_currency_symbol'], (int)$array['foreign_currency_decimal_places'], $amount, $colored);
+ if (TransactionType::TRANSFER === $type) {
$result = sprintf('%s', $result);
}
@@ -159,8 +138,6 @@ class TransactionGroupTwig extends AbstractExtension
/**
* Shows the amount for a single journal object.
- *
- * @return TwigFunction
*/
public function journalObjectAmount(): TwigFunction
{
@@ -182,10 +159,6 @@ class TransactionGroupTwig extends AbstractExtension
/**
* Generate normal amount for transaction from a transaction group.
- *
- * @param TransactionJournal $journal
- *
- * @return string
*/
private function normalJournalObjectAmount(TransactionJournal $journal): string
{
@@ -196,24 +169,19 @@ class TransactionGroupTwig extends AbstractExtension
$colored = true;
$sourceType = $first->account()->first()->accountType()->first()->type;
- $amount = $this->signAmount($amount, $type, $sourceType);
+ $amount = $this->signAmount($amount, $type, $sourceType);
- if ($type === TransactionType::TRANSFER) {
+ if (TransactionType::TRANSFER === $type) {
$colored = false;
}
- $result = app('amount')->formatFlat($currency->symbol, (int)$currency->decimal_places, $amount, $colored);
- if ($type === TransactionType::TRANSFER) {
+ $result = app('amount')->formatFlat($currency->symbol, $currency->decimal_places, $amount, $colored);
+ if (TransactionType::TRANSFER === $type) {
$result = sprintf('%s', $result);
}
return $result;
}
- /**
- * @param TransactionJournal $journal
- *
- * @return bool
- */
private function journalObjectHasForeign(TransactionJournal $journal): bool
{
/** @var Transaction $first */
@@ -224,14 +192,11 @@ class TransactionGroupTwig extends AbstractExtension
/**
* Generate foreign amount for journal from a transaction group.
- *
- * @param TransactionJournal $journal
- *
- * @return string
*/
private function foreignJournalObjectAmount(TransactionJournal $journal): string
{
- $type = $journal->transactionType->type;
+ $type = $journal->transactionType->type;
+
/** @var Transaction $first */
$first = $journal->transactions()->where('amount', '<', 0)->first();
$currency = $first->foreignCurrency;
@@ -239,51 +204,48 @@ class TransactionGroupTwig extends AbstractExtension
$colored = true;
$sourceType = $first->account()->first()->accountType()->first()->type;
- $amount = $this->signAmount($amount, $type, $sourceType);
+ $amount = $this->signAmount($amount, $type, $sourceType);
- if ($type === TransactionType::TRANSFER) {
+ if (TransactionType::TRANSFER === $type) {
$colored = false;
}
- $result = app('amount')->formatFlat($currency->symbol, (int)$currency->decimal_places, $amount, $colored);
- if ($type === TransactionType::TRANSFER) {
+ $result = app('amount')->formatFlat($currency->symbol, $currency->decimal_places, $amount, $colored);
+ if (TransactionType::TRANSFER === $type) {
$result = sprintf('%s', $result);
}
return $result;
}
- /**
- * @return TwigFunction
- */
public function journalHasMeta(): TwigFunction
{
return new TwigFunction(
'journalHasMeta',
static function (int $journalId, string $metaField) {
- $count = DB::table('journal_meta')
- ->where('name', $metaField)
- ->where('transaction_journal_id', $journalId)
- ->whereNull('deleted_at')
- ->count();
+ $count = \DB::table('journal_meta')
+ ->where('name', $metaField)
+ ->where('transaction_journal_id', $journalId)
+ ->whereNull('deleted_at')
+ ->count()
+ ;
return 1 === $count;
}
);
}
- /**
- * @return TwigFunction
- */
public function journalGetMetaDate(): TwigFunction
{
return new TwigFunction(
'journalGetMetaDate',
static function (int $journalId, string $metaField) {
- $entry = DB::table('journal_meta')
- ->where('name', $metaField)
- ->where('transaction_journal_id', $journalId)
- ->whereNull('deleted_at')
- ->first();
+ /** @var null|TransactionJournalMeta $entry */
+ $entry = \DB::table('journal_meta')
+ ->where('name', $metaField)
+ ->where('transaction_journal_id', $journalId)
+ ->whereNull('deleted_at')
+ ->first()
+ ;
if (null === $entry) {
return today(config('app.timezone'));
}
@@ -293,19 +255,18 @@ class TransactionGroupTwig extends AbstractExtension
);
}
- /**
- * @return TwigFunction
- */
public function journalGetMetaField(): TwigFunction
{
return new TwigFunction(
'journalGetMetaField',
static function (int $journalId, string $metaField) {
- $entry = DB::table('journal_meta')
- ->where('name', $metaField)
- ->where('transaction_journal_id', $journalId)
- ->whereNull('deleted_at')
- ->first();
+ /** @var null|TransactionJournalMeta $entry */
+ $entry = \DB::table('journal_meta')
+ ->where('name', $metaField)
+ ->where('transaction_journal_id', $journalId)
+ ->whereNull('deleted_at')
+ ->first()
+ ;
if (null === $entry) {
return '';
}
diff --git a/app/Support/Twig/Translation.php b/app/Support/Twig/Translation.php
index 11b420f0be..eaeac5ca6c 100644
--- a/app/Support/Twig/Translation.php
+++ b/app/Support/Twig/Translation.php
@@ -32,9 +32,6 @@ use Twig\TwigFunction;
*/
class Translation extends AbstractExtension
{
- /**
- * @return array
- */
public function getFilters(): array
{
return [
@@ -48,9 +45,6 @@ class Translation extends AbstractExtension
];
}
- /**
- * {@inheritdoc}
- */
public function getFunctions(): array
{
return [
@@ -58,9 +52,6 @@ class Translation extends AbstractExtension
];
}
- /**
- * @return TwigFunction
- */
public function journalLinkTranslation(): TwigFunction
{
return new TwigFunction(
diff --git a/app/Support/Validation/ValidatesAmountsTrait.php b/app/Support/Validation/ValidatesAmountsTrait.php
new file mode 100644
index 0000000000..6529daa23b
--- /dev/null
+++ b/app/Support/Validation/ValidatesAmountsTrait.php
@@ -0,0 +1,67 @@
+.
+ */
+
+declare(strict_types=1);
+
+namespace FireflyIII\Support\Validation;
+
+trait ValidatesAmountsTrait
+{
+ // 19-09-2020: my wedding day
+ protected const string BIG_AMOUNT = '10019092020';
+
+ final protected function emptyString(string $value): bool
+ {
+ return '' === $value;
+ }
+
+ final protected function isValidNumber(string $value): bool
+ {
+ return is_numeric($value);
+ }
+
+ final protected function lessOrEqualToZero(string $value): bool
+ {
+ return -1 === bccomp($value, '0') || 0 === bccomp($value, '0');
+ }
+
+ final protected function lessThanLots(string $value): bool
+ {
+ $amount = bcmul('-1', self::BIG_AMOUNT);
+
+ return -1 === bccomp($value, $amount) || 0 === bccomp($value, $amount);
+ }
+
+ final protected function moreThanLots(string $value): bool
+ {
+ return 1 === bccomp($value, self::BIG_AMOUNT) || 0 === bccomp($value, self::BIG_AMOUNT);
+ }
+
+ final protected function scientificNumber(string $value): bool
+ {
+ return str_contains(strtoupper($value), 'E');
+ }
+
+ final protected function zeroOrMore(string $value): bool
+ {
+ return 1 === bccomp($value, '0') || 0 === bccomp($value, '0');
+ }
+}
diff --git a/app/TransactionRules/Actions/ActionInterface.php b/app/TransactionRules/Actions/ActionInterface.php
index c8bd82a992..8a1ffdd5ae 100644
--- a/app/TransactionRules/Actions/ActionInterface.php
+++ b/app/TransactionRules/Actions/ActionInterface.php
@@ -31,10 +31,6 @@ interface ActionInterface
/**
* Execute the action on an array. Returns "true" if the action was a success and the action
* was applied. Returns false if otherwise.
- *
- * @param array $journal
- *
- * @return bool
*/
public function actOnArray(array $journal): bool;
}
diff --git a/app/TransactionRules/Actions/AddTag.php b/app/TransactionRules/Actions/AddTag.php
index 45da90e91e..20d1adfce6 100644
--- a/app/TransactionRules/Actions/AddTag.php
+++ b/app/TransactionRules/Actions/AddTag.php
@@ -24,7 +24,6 @@ declare(strict_types=1);
namespace FireflyIII\TransactionRules\Actions;
-use DB;
use FireflyIII\Events\Model\Rule\RuleActionFailedOnArray;
use FireflyIII\Events\TriggeredAuditLog;
use FireflyIII\Factory\TagFactory;
@@ -32,7 +31,6 @@ use FireflyIII\Models\RuleAction;
use FireflyIII\Models\TransactionJournal;
use FireflyIII\TransactionRules\Expressions\ActionExpressionEvaluator;
use FireflyIII\User;
-use Illuminate\Support\Facades\Log;
/**
* Class AddTag.
@@ -44,8 +42,6 @@ class AddTag implements ActionInterface
/**
* TriggerInterface constructor.
- *
- * @param RuleAction $action
*/
public function __construct(RuleAction $action, ActionExpressionEvaluator $evaluator)
{
@@ -53,17 +49,17 @@ class AddTag implements ActionInterface
$this->evaluator = $evaluator;
}
- /**
- * @inheritDoc
- */
public function actOnArray(array $journal): bool
{
// journal has this tag maybe?
/** @var TagFactory $factory */
$factory = app(TagFactory::class);
- $factory->setUser(User::find($journal['user_id']));
+
+ /** @var User $user */
+ $user = User::find($journal['user_id']);
+ $factory->setUser($user);
$tagName = $this->evaluator->evaluate($journal);
- $tag = $factory->findOrCreate($tagName);
+ $tag = $factory->findOrCreate($tagName);
if (null === $tag) {
// could not find, could not create tag.
@@ -72,21 +68,24 @@ class AddTag implements ActionInterface
return false;
}
- $count = DB::table('tag_transaction_journal')
+ $count = \DB::table('tag_transaction_journal')
->where('tag_id', $tag->id)
->where('transaction_journal_id', $journal['transaction_journal_id'])
->count();
if (0 === $count) {
// add to journal:
- DB::table('tag_transaction_journal')->insert(['tag_id' => $tag->id, 'transaction_journal_id' => $journal['transaction_journal_id']]);
- Log::debug(sprintf('RuleAction AddTag. Added tag #%d ("%s") to journal %d.', $tag->id, $tag->tag, $journal['transaction_journal_id']));
+ \DB::table('tag_transaction_journal')->insert(['tag_id' => $tag->id, 'transaction_journal_id' => $journal['transaction_journal_id']]);
+ app('log')->debug(sprintf('RuleAction AddTag. Added tag #%d ("%s") to journal %d.', $tag->id, $tag->tag, $journal['transaction_journal_id']));
+
+ /** @var TransactionJournal $object */
$object = TransactionJournal::find($journal['transaction_journal_id']);
// event for audit log entry
event(new TriggeredAuditLog($this->action->rule, $object, 'add_tag', null, $tag->tag));
+
return true;
}
- Log::debug(
+ app('log')->debug(
sprintf('RuleAction AddTag fired but tag %d ("%s") was already added to journal %d.', $tag->id, $tag->tag, $journal['transaction_journal_id'])
);
event(new RuleActionFailedOnArray($this->action, $journal, trans('rules.tag_already_added', ['tag' => $tagName])));
diff --git a/app/TransactionRules/Actions/AppendDescription.php b/app/TransactionRules/Actions/AppendDescription.php
index 46eef629af..5f8fa29d66 100644
--- a/app/TransactionRules/Actions/AppendDescription.php
+++ b/app/TransactionRules/Actions/AppendDescription.php
@@ -24,7 +24,6 @@ declare(strict_types=1);
namespace FireflyIII\TransactionRules\Actions;
-use DB;
use FireflyIII\Events\TriggeredAuditLog;
use FireflyIII\Models\RuleAction;
use FireflyIII\Models\TransactionJournal;
@@ -40,8 +39,6 @@ class AppendDescription implements ActionInterface
/**
* TriggerInterface constructor.
- *
- * @param RuleAction $action
*/
public function __construct(RuleAction $action, ActionExpressionEvaluator $evaluator)
{
@@ -49,18 +46,15 @@ class AppendDescription implements ActionInterface
$this->evaluator = $evaluator;
}
- /**
- * @inheritDoc
- */
public function actOnArray(array $journal): bool
{
$actionValue = $this->evaluator->evaluate($journal);
- $description = sprintf('%s%s', $journal['description'], $actionValue);
- DB::table('transaction_journals')->where('id', $journal['transaction_journal_id'])->limit(1)->update(['description' => $description]);
+ $description = sprintf('%s %s', $journal['description'], $actionValue);
+ \DB::table('transaction_journals')->where('id', $journal['transaction_journal_id'])->limit(1)->update(['description' => $description]);
// event for audit log entry
/** @var TransactionJournal $object */
- $object = TransactionJournal::where('user_id', $journal['user_id'])->find($journal['transaction_journal_id']);
+ $object = TransactionJournal::where('user_id', $journal['user_id'])->find($journal['transaction_journal_id']);
event(new TriggeredAuditLog($this->action->rule, $object, 'update_description', $journal['description'], $description));
return true;
diff --git a/app/TransactionRules/Actions/AppendDescriptionToNotes.php b/app/TransactionRules/Actions/AppendDescriptionToNotes.php
index a10e442140..eb5e32815c 100644
--- a/app/TransactionRules/Actions/AppendDescriptionToNotes.php
+++ b/app/TransactionRules/Actions/AppendDescriptionToNotes.php
@@ -29,7 +29,6 @@ use FireflyIII\Events\TriggeredAuditLog;
use FireflyIII\Models\Note;
use FireflyIII\Models\RuleAction;
use FireflyIII\Models\TransactionJournal;
-use Illuminate\Support\Facades\Log;
/**
* Class AppendDescriptionToNotes
@@ -40,29 +39,25 @@ class AppendDescriptionToNotes implements ActionInterface
/**
* TriggerInterface constructor.
- *
- * @param RuleAction $action
*/
public function __construct(RuleAction $action)
{
$this->action = $action;
}
- /**
- * @inheritDoc
- */
public function actOnArray(array $journal): bool
{
- /** @var TransactionJournal $journal */
+ /** @var null|TransactionJournal $object */
$object = TransactionJournal::where('user_id', $journal['user_id'])->find($journal['transaction_journal_id']);
if (null === $object) {
- Log::error(sprintf('No journal #%d belongs to user #%d.', $journal['transaction_journal_id'], $journal['user_id']));
- event(new RuleActionFailedOnArray($this->action, $journal, trans('rules.journal_other_user')));
+ app('log')->error(sprintf('No journal #%d belongs to user #%d.', $journal['transaction_journal_id'], $journal['user_id']));
+ event(new RuleActionFailedOnArray($this->action, $journal, (string)trans('rules.journal_other_user')));
+
return false;
}
- $note = $object->notes()->first();
+ $note = $object->notes()->first();
if (null === $note) {
- $note = new Note();
+ $note = new Note();
$note->noteable()->associate($object);
$note->text = '';
}
@@ -73,12 +68,13 @@ class AppendDescriptionToNotes implements ActionInterface
if ('' === $note->text) {
$note->text = (string)$object->description;
}
- $after = $note->text;
+ $after = $note->text;
// event for audit log entry
event(new TriggeredAuditLog($this->action->rule, $object, 'update_notes', $before, $after));
$note->save();
+
return true;
}
}
diff --git a/app/TransactionRules/Actions/AppendNotes.php b/app/TransactionRules/Actions/AppendNotes.php
index 49d7e6e71f..922be054d2 100644
--- a/app/TransactionRules/Actions/AppendNotes.php
+++ b/app/TransactionRules/Actions/AppendNotes.php
@@ -29,7 +29,6 @@ use FireflyIII\Models\Note;
use FireflyIII\Models\RuleAction;
use FireflyIII\Models\TransactionJournal;
use FireflyIII\TransactionRules\Expressions\ActionExpressionEvaluator;
-use Illuminate\Support\Facades\Log;
/**
* Class AppendNotes.
@@ -41,8 +40,6 @@ class AppendNotes implements ActionInterface
/**
* TriggerInterface constructor.
- *
- * @param RuleAction $action
*/
public function __construct(RuleAction $action, ActionExpressionEvaluator $evaluator)
{
@@ -50,13 +47,10 @@ class AppendNotes implements ActionInterface
$this->evaluator = $evaluator;
}
- /**
- * @inheritDoc
- */
public function actOnArray(array $journal): bool
{
$actionValue = $this->evaluator->evaluate($journal);
- $dbNote = Note::where('noteable_id', (int)$journal['transaction_journal_id'])
+ $dbNote = Note::where('noteable_id', (int)$journal['transaction_journal_id'])
->where('noteable_type', TransactionJournal::class)
->first(['notes.*']);
if (null === $dbNote) {
@@ -65,14 +59,14 @@ class AppendNotes implements ActionInterface
$dbNote->noteable_type = TransactionJournal::class;
$dbNote->text = '';
}
- Log::debug(sprintf('RuleAction AppendNotes appended "%s" to "%s".', $actionValue, $dbNote->text));
+ app('log')->debug(sprintf('RuleAction AppendNotes appended "%s" to "%s".', $actionValue, $dbNote->text));
$before = $dbNote->text;
$text = sprintf('%s%s', $dbNote->text, $actionValue);
$dbNote->text = $text;
$dbNote->save();
/** @var TransactionJournal $object */
- $object = TransactionJournal::where('user_id', $journal['user_id'])->find($journal['transaction_journal_id']);
+ $object = TransactionJournal::where('user_id', $journal['user_id'])->find($journal['transaction_journal_id']);
event(new TriggeredAuditLog($this->action->rule, $object, 'update_notes', $before, $text));
diff --git a/app/TransactionRules/Actions/AppendNotesToDescription.php b/app/TransactionRules/Actions/AppendNotesToDescription.php
index 93469788a8..99caaaeb0d 100644
--- a/app/TransactionRules/Actions/AppendNotesToDescription.php
+++ b/app/TransactionRules/Actions/AppendNotesToDescription.php
@@ -30,7 +30,6 @@ use FireflyIII\Models\Note;
use FireflyIII\Models\RuleAction;
use FireflyIII\Models\TransactionJournal;
use FireflyIII\Support\Request\ConvertsDataTypes;
-use Illuminate\Support\Facades\Log;
/**
* Class AppendNotesToDescription
@@ -43,51 +42,49 @@ class AppendNotesToDescription implements ActionInterface
/**
* TriggerInterface constructor.
- *
- * @param RuleAction $action
*/
public function __construct(RuleAction $action)
{
$this->action = $action;
}
- /**
- * @inheritDoc
- */
public function actOnArray(array $journal): bool
{
- Log::debug('Now in AppendNotesToDescription');
- /** @var TransactionJournal $object */
+ app('log')->debug('Now in AppendNotesToDescription');
+
+ /** @var null|TransactionJournal $object */
$object = TransactionJournal::where('user_id', $journal['user_id'])->find($journal['transaction_journal_id']);
if (null === $object) {
- Log::error(sprintf('No journal #%d belongs to user #%d.', $journal['transaction_journal_id'], $journal['user_id']));
+ app('log')->error(sprintf('No journal #%d belongs to user #%d.', $journal['transaction_journal_id'], $journal['user_id']));
event(new RuleActionFailedOnArray($this->action, $journal, trans('rules.journal_other_user')));
+
return false;
}
- $note = $object->notes()->first();
+ $note = $object->notes()->first();
if (null === $note) {
- Log::debug('Journal has no notes.');
- $note = new Note();
+ app('log')->debug('Journal has no notes.');
+ $note = new Note();
$note->noteable()->associate($object);
$note->text = '';
}
// only append if there is something to append
if ('' !== $note->text) {
$before = $object->description;
- $object->description = trim(sprintf('%s %s', $object->description, (string)$this->clearString($note->text, false)));
+ $object->description = trim(sprintf('%s %s', $object->description, (string)$this->clearString($note->text)));
$object->save();
- Log::debug(sprintf('Journal description is updated to "%s".', $object->description));
+ app('log')->debug(sprintf('Journal description is updated to "%s".', $object->description));
event(new TriggeredAuditLog($this->action->rule, $object, 'update_description', $before, $object->description));
return true;
}
event(new RuleActionFailedOnArray($this->action, $journal, trans('rules.new_notes_empty')));
+
return false;
}
/**
- * @inheritDoc
+ * @SuppressWarnings(PHPMD.UnusedFormalParameter)
*/
public function get(string $key, mixed $default = null): mixed
{
@@ -95,7 +92,7 @@ class AppendNotesToDescription implements ActionInterface
}
/**
- * @inheritDoc
+ * @SuppressWarnings(PHPMD.UnusedFormalParameter)
*/
public function has(mixed $key): mixed
{
diff --git a/app/TransactionRules/Actions/ClearBudget.php b/app/TransactionRules/Actions/ClearBudget.php
index 2c79a535fb..b6ca1af2e0 100644
--- a/app/TransactionRules/Actions/ClearBudget.php
+++ b/app/TransactionRules/Actions/ClearBudget.php
@@ -23,12 +23,10 @@ declare(strict_types=1);
namespace FireflyIII\TransactionRules\Actions;
-use DB;
use FireflyIII\Events\Model\Rule\RuleActionFailedOnArray;
use FireflyIII\Events\TriggeredAuditLog;
use FireflyIII\Models\RuleAction;
use FireflyIII\Models\TransactionJournal;
-use Illuminate\Support\Facades\Log;
/**
* Class ClearBudget.
@@ -39,33 +37,29 @@ class ClearBudget implements ActionInterface
/**
* TriggerInterface constructor.
- *
- * @param RuleAction $action
*/
public function __construct(RuleAction $action)
{
$this->action = $action;
}
- /**
- * @inheritDoc
- */
public function actOnArray(array $journal): bool
{
/** @var TransactionJournal $object */
$object = TransactionJournal::where('user_id', $journal['user_id'])->find($journal['transaction_journal_id']);
$budget = $object->budgets()->first();
if (null === $budget) {
- Log::debug(sprintf('RuleAction ClearBudget, no budget in journal #%d.', $journal['transaction_journal_id']));
+ app('log')->debug(sprintf('RuleAction ClearBudget, no budget in journal #%d.', $journal['transaction_journal_id']));
event(new RuleActionFailedOnArray($this->action, $journal, trans('rules.journal_already_no_budget')));
+
return false;
}
- DB::table('budget_transaction_journal')->where('transaction_journal_id', '=', $journal['transaction_journal_id'])->delete();
+ \DB::table('budget_transaction_journal')->where('transaction_journal_id', '=', $journal['transaction_journal_id'])->delete();
event(new TriggeredAuditLog($this->action->rule, $object, 'clear_budget', $budget->name, null));
- Log::debug(sprintf('RuleAction ClearBudget removed all budgets from journal #%d.', $journal['transaction_journal_id']));
+ app('log')->debug(sprintf('RuleAction ClearBudget removed all budgets from journal #%d.', $journal['transaction_journal_id']));
return true;
}
diff --git a/app/TransactionRules/Actions/ClearCategory.php b/app/TransactionRules/Actions/ClearCategory.php
index 22b9df33f7..fe87dd3c3f 100644
--- a/app/TransactionRules/Actions/ClearCategory.php
+++ b/app/TransactionRules/Actions/ClearCategory.php
@@ -23,12 +23,10 @@ declare(strict_types=1);
namespace FireflyIII\TransactionRules\Actions;
-use DB;
use FireflyIII\Events\Model\Rule\RuleActionFailedOnArray;
use FireflyIII\Events\TriggeredAuditLog;
use FireflyIII\Models\RuleAction;
use FireflyIII\Models\TransactionJournal;
-use Illuminate\Support\Facades\Log;
/**
* Class ClearCategory.
@@ -39,33 +37,29 @@ class ClearCategory implements ActionInterface
/**
* TriggerInterface constructor.
- *
- * @param RuleAction $action
*/
public function __construct(RuleAction $action)
{
$this->action = $action;
}
- /**
- * @inheritDoc
- */
public function actOnArray(array $journal): bool
{
/** @var TransactionJournal $object */
$object = TransactionJournal::where('user_id', $journal['user_id'])->find($journal['transaction_journal_id']);
$category = $object->categories()->first();
if (null === $category) {
- Log::debug(sprintf('RuleAction ClearCategory, no category in journal #%d.', $journal['transaction_journal_id']));
+ app('log')->debug(sprintf('RuleAction ClearCategory, no category in journal #%d.', $journal['transaction_journal_id']));
event(new RuleActionFailedOnArray($this->action, $journal, trans('rules.journal_already_no_category')));
+
return false;
}
- DB::table('category_transaction_journal')->where('transaction_journal_id', '=', $journal['transaction_journal_id'])->delete();
+ \DB::table('category_transaction_journal')->where('transaction_journal_id', '=', $journal['transaction_journal_id'])->delete();
event(new TriggeredAuditLog($this->action->rule, $object, 'clear_category', $category->name, null));
- Log::debug(sprintf('RuleAction ClearCategory removed all categories from journal #%d.', $journal['transaction_journal_id']));
+ app('log')->debug(sprintf('RuleAction ClearCategory removed all categories from journal #%d.', $journal['transaction_journal_id']));
return true;
}
diff --git a/app/TransactionRules/Actions/ClearNotes.php b/app/TransactionRules/Actions/ClearNotes.php
index d67a1b3d90..61d588d542 100644
--- a/app/TransactionRules/Actions/ClearNotes.php
+++ b/app/TransactionRules/Actions/ClearNotes.php
@@ -23,12 +23,11 @@ declare(strict_types=1);
namespace FireflyIII\TransactionRules\Actions;
-use DB;
use FireflyIII\Events\Model\Rule\RuleActionFailedOnArray;
use FireflyIII\Events\TriggeredAuditLog;
+use FireflyIII\Models\Note;
use FireflyIII\Models\RuleAction;
use FireflyIII\Models\TransactionJournal;
-use Illuminate\Support\Facades\Log;
/**
* Class ClearNotes.
@@ -39,33 +38,33 @@ class ClearNotes implements ActionInterface
/**
* TriggerInterface constructor.
- *
- * @param RuleAction $action
*/
public function __construct(RuleAction $action)
{
$this->action = $action;
}
- /**
- * @inheritDoc
- */
public function actOnArray(array $journal): bool
{
+ /** @var TransactionJournal $object */
$object = TransactionJournal::where('user_id', $journal['user_id'])->find($journal['transaction_journal_id']);
+
+ /** @var null|Note $notes */
$notes = $object->notes()->first();
if (null === $notes) {
- Log::debug(sprintf('RuleAction ClearNotes, journal #%d has no notes.', $journal['transaction_journal_id']));
+ app('log')->debug(sprintf('RuleAction ClearNotes, journal #%d has no notes.', $journal['transaction_journal_id']));
event(new RuleActionFailedOnArray($this->action, $journal, trans('rules.journal_already_no_notes')));
+
return false;
}
$before = $notes->text;
- DB::table('notes')
- ->where('noteable_id', $journal['transaction_journal_id'])
- ->where('noteable_type', TransactionJournal::class)
- ->delete();
- Log::debug(sprintf('RuleAction ClearNotes removed all notes from journal #%d.', $journal['transaction_journal_id']));
+ \DB::table('notes')
+ ->where('noteable_id', $journal['transaction_journal_id'])
+ ->where('noteable_type', TransactionJournal::class)
+ ->delete()
+ ;
+ app('log')->debug(sprintf('RuleAction ClearNotes removed all notes from journal #%d.', $journal['transaction_journal_id']));
event(new TriggeredAuditLog($this->action->rule, $object, 'clear_notes', $before, null));
diff --git a/app/TransactionRules/Actions/ConvertToDeposit.php b/app/TransactionRules/Actions/ConvertToDeposit.php
index bd13cfa406..fedea72779 100644
--- a/app/TransactionRules/Actions/ConvertToDeposit.php
+++ b/app/TransactionRules/Actions/ConvertToDeposit.php
@@ -24,7 +24,6 @@ declare(strict_types=1);
namespace FireflyIII\TransactionRules\Actions;
-use DB;
use FireflyIII\Events\Model\Rule\RuleActionFailedOnArray;
use FireflyIII\Events\TriggeredAuditLog;
use FireflyIII\Exceptions\FireflyException;
@@ -37,11 +36,8 @@ use FireflyIII\Models\TransactionJournal;
use FireflyIII\Models\TransactionType;
use FireflyIII\Repositories\Account\AccountRepositoryInterface;
use FireflyIII\TransactionRules\Expressions\ActionExpressionEvaluator;
-use Illuminate\Support\Facades\Log;
-use JsonException;
/**
- *
* Class ConvertToDeposit
*/
class ConvertToDeposit implements ActionInterface
@@ -51,8 +47,6 @@ class ConvertToDeposit implements ActionInterface
/**
* TriggerInterface constructor.
- *
- * @param RuleAction $action
*/
public function __construct(RuleAction $action, ActionExpressionEvaluator $evaluator)
{
@@ -60,45 +54,46 @@ class ConvertToDeposit implements ActionInterface
$this->evaluator = $evaluator;
}
- /**
- * @inheritDoc
- */
public function actOnArray(array $journal): bool
{
$actionValue = $this->evaluator->evaluate($journal);
// make object from array (so the data is fresh).
- /** @var TransactionJournal|null $object */
- $object = TransactionJournal::where('user_id', $journal['user_id'])->find($journal['transaction_journal_id']);
+ /** @var null|TransactionJournal $object */
+ $object = TransactionJournal::where('user_id', $journal['user_id'])->find($journal['transaction_journal_id']);
if (null === $object) {
- Log::error(sprintf('Cannot find journal #%d, cannot convert to deposit.', $journal['transaction_journal_id']));
+ app('log')->error(sprintf('Cannot find journal #%d, cannot convert to deposit.', $journal['transaction_journal_id']));
event(new RuleActionFailedOnArray($this->action, $journal, trans('rules.journal_not_found')));
+
return false;
}
$groupCount = TransactionJournal::where('transaction_group_id', $journal['transaction_group_id'])->count();
if ($groupCount > 1) {
- Log::error(sprintf('Group #%d has more than one transaction in it, cannot convert to deposit.', $journal['transaction_group_id']));
+ app('log')->error(sprintf('Group #%d has more than one transaction in it, cannot convert to deposit.', $journal['transaction_group_id']));
event(new RuleActionFailedOnArray($this->action, $journal, trans('rules.split_group')));
+
return false;
}
- Log::debug(sprintf('Convert journal #%d to deposit.', $journal['transaction_journal_id']));
- $type = $object->transactionType->type;
+ app('log')->debug(sprintf('Convert journal #%d to deposit.', $journal['transaction_journal_id']));
+ $type = $object->transactionType->type;
if (TransactionType::DEPOSIT === $type) {
- Log::error(sprintf('Journal #%d is already a deposit (rule #%d).', $journal['transaction_journal_id'], $this->action->rule_id));
+ app('log')->error(sprintf('Journal #%d is already a deposit (rule #%d).', $journal['transaction_journal_id'], $this->action->rule_id));
event(new RuleActionFailedOnArray($this->action, $journal, trans('rules.is_already_deposit')));
+
return false;
}
if (TransactionType::WITHDRAWAL === $type) {
- Log::debug('Going to transform a withdrawal to a deposit.');
+ app('log')->debug('Going to transform a withdrawal to a deposit.');
try {
$res = $this->convertWithdrawalArray($object, $actionValue);
- } catch (JsonException | FireflyException $e) {
- Log::debug('Could not convert withdrawal to deposit.');
- Log::error($e->getMessage());
+ } catch (FireflyException $e) {
+ app('log')->debug('Could not convert withdrawal to deposit.');
+ app('log')->error($e->getMessage());
event(new RuleActionFailedOnArray($this->action, $journal, trans('rules.complex_error')));
+
return false;
}
@@ -107,14 +102,15 @@ class ConvertToDeposit implements ActionInterface
return $res;
}
if (TransactionType::TRANSFER === $type) {
- Log::debug('Going to transform a transfer to a deposit.');
+ app('log')->debug('Going to transform a transfer to a deposit.');
try {
- $res = $this->convertTransferArray($object);
- } catch (JsonException | FireflyException $e) {
- Log::debug('Could not convert transfer to deposit.');
- Log::error($e->getMessage());
+ $res = $this->convertTransferArray($object, $actionValue);
+ } catch (FireflyException $e) {
+ app('log')->debug('Could not convert transfer to deposit.');
+ app('log')->error($e->getMessage());
event(new RuleActionFailedOnArray($this->action, $journal, trans('rules.complex_error')));
+
return false;
}
event(new TriggeredAuditLog($this->action->rule, $object, 'update_transaction_type', TransactionType::TRANSFER, TransactionType::DEPOSIT));
@@ -122,6 +118,7 @@ class ConvertToDeposit implements ActionInterface
return $res;
}
event(new RuleActionFailedOnArray($this->action, $journal, trans('rules.unsupported_transaction_type_deposit', ['type' => $type])));
+
return false;
}
@@ -129,29 +126,26 @@ class ConvertToDeposit implements ActionInterface
* Input is a withdrawal from A to B
* Is converted to a deposit from C to A.
*
- * @param TransactionJournal $journal
- *
- * @return bool
* @throws FireflyException
- * @throws JsonException
*/
private function convertWithdrawalArray(TransactionJournal $journal, string $actionValue): bool
{
- $user = $journal->user;
+ $user = $journal->user;
+
// find or create revenue account.
/** @var AccountFactory $factory */
- $factory = app(AccountFactory::class);
+ $factory = app(AccountFactory::class);
$factory->setUser($user);
- $repository = app(AccountRepositoryInterface::class);
+ $repository = app(AccountRepositoryInterface::class);
$repository->setUser($user);
- $destAccount = $this->getDestinationAccount($journal);
- $sourceAccount = $this->getSourceAccount($journal);
+ $destAccount = $this->getDestinationAccount($journal);
+ $sourceAccount = $this->getSourceAccount($journal);
// get the action value, or use the original destination name in case the action value is empty:
// this becomes a new or existing (revenue) account, which is the source of the new deposit.
- $opposingName = '' === $actionValue ? $destAccount->name : $actionValue;
+ $opposingName = '' === $actionValue ? $destAccount->name : $actionValue;
// we check all possible source account types if one exists:
$validTypes = config('firefly.expected_source_types.source.Deposit');
$opposingAccount = $repository->findByName($opposingName, $validTypes);
@@ -159,61 +153,57 @@ class ConvertToDeposit implements ActionInterface
$opposingAccount = $factory->findOrCreate($opposingName, AccountType::REVENUE);
}
- Log::debug(sprintf('ConvertToDeposit. Action value is "%s", new opposing name is "%s"', $actionValue, $opposingAccount->name));
+ app('log')->debug(sprintf('ConvertToDeposit. Action value is "%s", new opposing name is "%s"', $actionValue, $opposingAccount->name));
// update the source transaction and put in the new revenue ID.
- DB::table('transactions')
+ \DB::table('transactions')
->where('transaction_journal_id', '=', $journal->id)
->where('amount', '<', 0)
->update(['account_id' => $opposingAccount->id]);
// update the destination transaction and put in the original source account ID.
- DB::table('transactions')
+ \DB::table('transactions')
->where('transaction_journal_id', '=', $journal->id)
->where('amount', '>', 0)
->update(['account_id' => $sourceAccount->id]);
// change transaction type of journal:
- $newType = TransactionType::whereType(TransactionType::DEPOSIT)->first();
+ $newType = TransactionType::whereType(TransactionType::DEPOSIT)->first();
- DB::table('transaction_journals')
+ \DB::table('transaction_journals')
->where('id', '=', $journal->id)
->update(['transaction_type_id' => $newType->id, 'bill_id' => null]);
- Log::debug('Converted withdrawal to deposit.');
+ app('log')->debug('Converted withdrawal to deposit.');
return true;
}
/**
- * @param TransactionJournal $journal
- *
- * @return Account
* @throws FireflyException
*/
private function getDestinationAccount(TransactionJournal $journal): Account
{
- /** @var Transaction|null $destAccount */
+ /** @var null|Transaction $destAccount */
$destAccount = $journal->transactions()->where('amount', '>', 0)->first();
if (null === $destAccount) {
throw new FireflyException(sprintf('Cannot find destination transaction for journal #%d', $journal->id));
}
+
return $destAccount->account;
}
/**
- * @param TransactionJournal $journal
- *
- * @return Account
* @throws FireflyException
*/
private function getSourceAccount(TransactionJournal $journal): Account
{
- /** @var Transaction|null $sourceTransaction */
+ /** @var null|Transaction $sourceTransaction */
$sourceTransaction = $journal->transactions()->where('amount', '<', 0)->first();
if (null === $sourceTransaction) {
throw new FireflyException(sprintf('Cannot find source transaction for journal #%d', $journal->id));
}
+
return $sourceTransaction->account;
}
@@ -222,28 +212,25 @@ class ConvertToDeposit implements ActionInterface
* Output is a deposit from C to B.
* The source account is replaced.
*
- * @param TransactionJournal $journal
- *
- * @return bool
* @throws FireflyException
- * @throws JsonException
*/
- private function convertTransferArray(TransactionJournal $journal): bool
+ private function convertTransferArray(TransactionJournal $journal, string $actionValue): bool
{
- $user = $journal->user;
+ $user = $journal->user;
+
// find or create revenue account.
/** @var AccountFactory $factory */
- $factory = app(AccountFactory::class);
+ $factory = app(AccountFactory::class);
$factory->setUser($user);
- $repository = app(AccountRepositoryInterface::class);
+ $repository = app(AccountRepositoryInterface::class);
$repository->setUser($user);
- $sourceAccount = $this->getSourceAccount($journal);
+ $sourceAccount = $this->getSourceAccount($journal);
// get the action value, or use the original source name in case the action value is empty:
// this becomes a new or existing (revenue) account, which is the source of the new deposit.
- $opposingName = '' === $actionValue ? $sourceAccount->name : $actionValue;
+ $opposingName = '' === $actionValue ? $sourceAccount->name : $actionValue;
// we check all possible source account types if one exists:
$validTypes = config('firefly.expected_source_types.source.Deposit');
$opposingAccount = $repository->findByName($opposingName, $validTypes);
@@ -251,22 +238,22 @@ class ConvertToDeposit implements ActionInterface
$opposingAccount = $factory->findOrCreate($opposingName, AccountType::REVENUE);
}
- Log::debug(sprintf('ConvertToDeposit. Action value is "%s", revenue name is "%s"', $actionValue, $opposingAccount->name));
+ app('log')->debug(sprintf('ConvertToDeposit. Action value is "%s", revenue name is "%s"', $this->action->action_value, $opposingAccount->name));
// update source transaction(s) to be revenue account
- DB::table('transactions')
+ \DB::table('transactions')
->where('transaction_journal_id', '=', $journal->id)
->where('amount', '<', 0)
->update(['account_id' => $opposingAccount->id]);
// change transaction type of journal:
- $newType = TransactionType::whereType(TransactionType::DEPOSIT)->first();
+ $newType = TransactionType::whereType(TransactionType::DEPOSIT)->first();
- DB::table('transaction_journals')
+ \DB::table('transaction_journals')
->where('id', '=', $journal->id)
->update(['transaction_type_id' => $newType->id, 'bill_id' => null]);
- Log::debug('Converted transfer to deposit.');
+ app('log')->debug('Converted transfer to deposit.');
return true;
}
diff --git a/app/TransactionRules/Actions/ConvertToTransfer.php b/app/TransactionRules/Actions/ConvertToTransfer.php
index 7cd5fd887b..559125eced 100644
--- a/app/TransactionRules/Actions/ConvertToTransfer.php
+++ b/app/TransactionRules/Actions/ConvertToTransfer.php
@@ -24,7 +24,6 @@ declare(strict_types=1);
namespace FireflyIII\TransactionRules\Actions;
-use DB;
use FireflyIII\Events\Model\Rule\RuleActionFailedOnArray;
use FireflyIII\Events\Model\Rule\RuleActionFailedOnObject;
use FireflyIII\Events\TriggeredAuditLog;
@@ -36,10 +35,8 @@ use FireflyIII\Models\TransactionJournal;
use FireflyIII\Models\TransactionType;
use FireflyIII\Repositories\Account\AccountRepositoryInterface;
use FireflyIII\TransactionRules\Expressions\ActionExpressionEvaluator;
-use Illuminate\Support\Facades\Log;
/**
- *
* Class ConvertToTransfer
*/
class ConvertToTransfer implements ActionInterface
@@ -49,42 +46,43 @@ class ConvertToTransfer implements ActionInterface
/**
* TriggerInterface constructor.
- *
- * @param RuleAction $action
*/
public function __construct(RuleAction $action, ActionExpressionEvaluator $evaluator)
{
- $this->action = $action;
+ $this->action = $action;
$this->evaluator = $evaluator;
}
/**
- * @inheritDoc
+ * @SuppressWarnings(PHPMD.ExcessiveMethodLength)
+ * @SuppressWarnings(PHPMD.NPathComplexity)
*/
public function actOnArray(array $journal): bool
{
$actionValue = $this->evaluator->evaluate($journal);
// make object from array (so the data is fresh).
- /** @var TransactionJournal|null $object */
- $object = TransactionJournal::where('user_id', $journal['user_id'])->find($journal['transaction_journal_id']);
+ /** @var null|TransactionJournal $object */
+ $object = TransactionJournal::where('user_id', $journal['user_id'])->find($journal['transaction_journal_id']);
if (null === $object) {
- Log::error(sprintf('Cannot find journal #%d, cannot convert to transfer.', $journal['transaction_journal_id']));
+ app('log')->error(sprintf('Cannot find journal #%d, cannot convert to transfer.', $journal['transaction_journal_id']));
event(new RuleActionFailedOnArray($this->action, $journal, trans('rules.journal_not_found')));
+
return false;
}
- $groupCount = TransactionJournal::where('transaction_group_id', $journal['transaction_group_id'])->count();
+ $groupCount = TransactionJournal::where('transaction_group_id', $journal['transaction_group_id'])->count();
if ($groupCount > 1) {
- Log::error(sprintf('Group #%d has more than one transaction in it, cannot convert to transfer.', $journal['transaction_group_id']));
+ app('log')->error(sprintf('Group #%d has more than one transaction in it, cannot convert to transfer.', $journal['transaction_group_id']));
event(new RuleActionFailedOnArray($this->action, $journal, trans('rules.split_group')));
+
return false;
}
- $type = $object->transactionType->type;
- $user = $object->user;
- $journalId = (int)$object->id;
+ $type = $object->transactionType->type;
+ $user = $object->user;
+ $journalId = $object->id;
if (TransactionType::TRANSFER === $type) {
- Log::error(
+ app('log')->error(
sprintf('Journal #%d is already a transfer so cannot be converted (rule #%d).', $object->id, $this->action->rule_id)
);
event(new RuleActionFailedOnArray($this->action, $journal, trans('rules.is_already_transfer')));
@@ -93,12 +91,13 @@ class ConvertToTransfer implements ActionInterface
}
if (TransactionType::DEPOSIT !== $type && TransactionType::WITHDRAWAL !== $type) {
event(new RuleActionFailedOnArray($this->action, $journal, trans('rules.unsupported_transaction_type_transfer', ['type' => $type])));
+
return false;
}
// find the asset account in the action value.
/** @var AccountRepositoryInterface $repository */
- $repository = app(AccountRepositoryInterface::class);
+ $repository = app(AccountRepositoryInterface::class);
$repository->setUser($user);
$expectedType = null;
if (TransactionType::WITHDRAWAL === $type) {
@@ -109,10 +108,10 @@ class ConvertToTransfer implements ActionInterface
$expectedType = $this->getDestinationType($journalId);
// Deposit? Replace source with account with same type as destination.
}
- $opposing = $repository->findByName($actionValue, [$expectedType]);
+ $opposing = $repository->findByName($actionValue, [$expectedType]);
if (null === $opposing) {
- Log::error(
+ app('log')->error(
sprintf(
'Journal #%d cannot be converted because no valid %s account with name "%s" exists (rule #%d).',
$expectedType,
@@ -127,68 +126,65 @@ class ConvertToTransfer implements ActionInterface
}
if (TransactionType::WITHDRAWAL === $type) {
- Log::debug('Going to transform a withdrawal to a transfer.');
+ app('log')->debug('Going to transform a withdrawal to a transfer.');
+
try {
$res = $this->convertWithdrawalArray($object, $opposing);
} catch (FireflyException $e) {
- Log::debug('Could not convert withdrawal to transfer.');
- Log::error($e->getMessage());
+ app('log')->debug('Could not convert withdrawal to transfer.');
+ app('log')->error($e->getMessage());
event(new RuleActionFailedOnArray($this->action, $journal, trans('rules.complex_error')));
+
return false;
}
if (false !== $res) {
event(new TriggeredAuditLog($this->action->rule, $object, 'update_transaction_type', TransactionType::WITHDRAWAL, TransactionType::TRANSFER));
}
+
return $res;
}
- if (TransactionType::DEPOSIT === $type) {
- Log::debug('Going to transform a deposit to a transfer.');
- try {
- $res = $this->convertDepositArray($object, $opposing);
- } catch (FireflyException $e) {
- Log::debug('Could not convert deposit to transfer.');
- Log::error($e->getMessage());
- event(new RuleActionFailedOnArray($this->action, $journal, trans('rules.complex_error')));
- return false;
- }
- if (false !== $res) {
- event(new TriggeredAuditLog($this->action->rule, $object, 'update_transaction_type', TransactionType::DEPOSIT, TransactionType::TRANSFER));
- }
- return $res;
+ // can only be a deposit at this point.
+ app('log')->debug('Going to transform a deposit to a transfer.');
+
+ try {
+ $res = $this->convertDepositArray($object, $opposing);
+ } catch (FireflyException $e) {
+ app('log')->debug('Could not convert deposit to transfer.');
+ app('log')->error($e->getMessage());
+ event(new RuleActionFailedOnArray($this->action, $journal, trans('rules.complex_error')));
+
+ return false;
}
- event(new RuleActionFailedOnArray($this->action, $journal, trans('rules.unsupported_transaction_type_transfer', ['type' => $type])));
- return false;
+ if (false !== $res) {
+ event(new TriggeredAuditLog($this->action->rule, $object, 'update_transaction_type', TransactionType::DEPOSIT, TransactionType::TRANSFER));
+ }
+
+ return $res;
}
- /**
- * @param int $journalId
- *
- * @return string
- */
private function getSourceType(int $journalId): string
{
- /** @var TransactionJournal $journal */
+ /** @var null|TransactionJournal $journal */
$journal = TransactionJournal::find($journalId);
if (null === $journal) {
- Log::error(sprintf('Journal #%d does not exist. Cannot convert to transfer.', $journalId));
+ app('log')->error(sprintf('Journal #%d does not exist. Cannot convert to transfer.', $journalId));
+
return '';
}
+
return (string)$journal->transactions()->where('amount', '<', 0)->first()?->account?->accountType?->type;
}
- /**
- * @param int $journalId
- *
- * @return string
- */
private function getDestinationType(int $journalId): string
{
- /** @var TransactionJournal $journal */
+ /** @var null|TransactionJournal $journal */
$journal = TransactionJournal::find($journalId);
if (null === $journal) {
- Log::error(sprintf('Journal #%d does not exist. Cannot convert to transfer.', $journalId));
+ app('log')->error(sprintf('Journal #%d does not exist. Cannot convert to transfer.', $journalId));
+
return '';
}
+
return (string)$journal->transactions()->where('amount', '>', 0)->first()?->account?->accountType?->type;
}
@@ -197,17 +193,13 @@ class ConvertToTransfer implements ActionInterface
* We replace the Expense with another asset.
* So this replaces the destination
*
- * @param TransactionJournal $journal
- * @param Account $opposing
- *
- * @return bool
* @throws FireflyException
*/
private function convertWithdrawalArray(TransactionJournal $journal, Account $opposing): bool
{
$sourceAccount = $this->getSourceAccount($journal);
- if ((int)$sourceAccount->id === (int)$opposing->id) {
- Log::error(
+ if ($sourceAccount->id === $opposing->id) {
+ app('log')->error(
vsprintf(
'Journal #%d has already has "%s" as a source asset. ConvertToTransfer failed. (rule #%d).',
[$journal->id, $opposing->name, $this->action->rule_id]
@@ -219,36 +211,34 @@ class ConvertToTransfer implements ActionInterface
}
// update destination transaction:
- DB::table('transactions')
+ \DB::table('transactions')
->where('transaction_journal_id', '=', $journal->id)
->where('amount', '>', 0)
->update(['account_id' => $opposing->id]);
// change transaction type of journal:
- $newType = TransactionType::whereType(TransactionType::TRANSFER)->first();
+ $newType = TransactionType::whereType(TransactionType::TRANSFER)->first();
- DB::table('transaction_journals')
+ \DB::table('transaction_journals')
->where('id', '=', $journal->id)
->update(['transaction_type_id' => $newType->id, 'bill_id' => null]);
- Log::debug('Converted withdrawal to transfer.');
+ app('log')->debug('Converted withdrawal to transfer.');
return true;
}
/**
- * @param TransactionJournal $journal
- *
- * @return Account
* @throws FireflyException
*/
private function getSourceAccount(TransactionJournal $journal): Account
{
- /** @var Transaction|null $sourceTransaction */
+ /** @var null|Transaction $sourceTransaction */
$sourceTransaction = $journal->transactions()->where('amount', '<', 0)->first();
if (null === $sourceTransaction) {
throw new FireflyException(sprintf('Cannot find source transaction for journal #%d', $journal->id));
}
+
return $sourceTransaction->account;
}
@@ -256,17 +246,13 @@ class ConvertToTransfer implements ActionInterface
* A deposit is from Revenue to Asset.
* We replace the Revenue with another asset.
*
- * @param TransactionJournal $journal
- * @param Account $opposing
- *
- * @return bool
* @throws FireflyException
*/
private function convertDepositArray(TransactionJournal $journal, Account $opposing): bool
{
$destAccount = $this->getDestinationAccount($journal);
- if ((int)$destAccount->id === (int)$opposing->id) {
- Log::error(
+ if ($destAccount->id === $opposing->id) {
+ app('log')->error(
vsprintf(
'Journal #%d has already has "%s" as a destination asset. ConvertToTransfer failed. (rule #%d).',
[$journal->id, $opposing->name, $this->action->rule_id]
@@ -278,36 +264,34 @@ class ConvertToTransfer implements ActionInterface
}
// update source transaction:
- DB::table('transactions')
+ \DB::table('transactions')
->where('transaction_journal_id', '=', $journal->id)
->where('amount', '<', 0)
->update(['account_id' => $opposing->id]);
// change transaction type of journal:
- $newType = TransactionType::whereType(TransactionType::TRANSFER)->first();
+ $newType = TransactionType::whereType(TransactionType::TRANSFER)->first();
- DB::table('transaction_journals')
+ \DB::table('transaction_journals')
->where('id', '=', $journal->id)
->update(['transaction_type_id' => $newType->id, 'bill_id' => null]);
- Log::debug('Converted deposit to transfer.');
+ app('log')->debug('Converted deposit to transfer.');
return true;
}
/**
- * @param TransactionJournal $journal
- *
- * @return Account
* @throws FireflyException
*/
private function getDestinationAccount(TransactionJournal $journal): Account
{
- /** @var Transaction|null $destAccount */
+ /** @var null|Transaction $destAccount */
$destAccount = $journal->transactions()->where('amount', '>', 0)->first();
if (null === $destAccount) {
throw new FireflyException(sprintf('Cannot find destination transaction for journal #%d', $journal->id));
}
+
return $destAccount->account;
}
}
diff --git a/app/TransactionRules/Actions/ConvertToWithdrawal.php b/app/TransactionRules/Actions/ConvertToWithdrawal.php
index 73b04b0ac8..14725d1320 100644
--- a/app/TransactionRules/Actions/ConvertToWithdrawal.php
+++ b/app/TransactionRules/Actions/ConvertToWithdrawal.php
@@ -24,7 +24,6 @@ declare(strict_types=1);
namespace FireflyIII\TransactionRules\Actions;
-use DB;
use FireflyIII\Events\Model\Rule\RuleActionFailedOnArray;
use FireflyIII\Events\TriggeredAuditLog;
use FireflyIII\Exceptions\FireflyException;
@@ -37,11 +36,8 @@ use FireflyIII\Models\TransactionJournal;
use FireflyIII\Models\TransactionType;
use FireflyIII\Repositories\Account\AccountRepositoryInterface;
use FireflyIII\TransactionRules\Expressions\ActionExpressionEvaluator;
-use Illuminate\Support\Facades\Log;
-use JsonException;
/**
- *
* Class ConvertToWithdrawal
*/
class ConvertToWithdrawal implements ActionInterface
@@ -51,8 +47,6 @@ class ConvertToWithdrawal implements ActionInterface
/**
* TriggerInterface constructor.
- *
- * @param RuleAction $action
*/
public function __construct(RuleAction $action, ActionExpressionEvaluator $evaluator)
{
@@ -60,90 +54,88 @@ class ConvertToWithdrawal implements ActionInterface
$this->evaluator = $evaluator;
}
- /**
- * @inheritDoc
- */
public function actOnArray(array $journal): bool
{
$actionValue = $this->evaluator->evaluate($journal);
// make object from array (so the data is fresh).
- /** @var TransactionJournal|null $object */
- $object = TransactionJournal::where('user_id', $journal['user_id'])->find($journal['transaction_journal_id']);
+ /** @var null|TransactionJournal $object */
+ $object = TransactionJournal::where('user_id', $journal['user_id'])->find($journal['transaction_journal_id']);
if (null === $object) {
- Log::error(sprintf('Cannot find journal #%d, cannot convert to withdrawal.', $journal['transaction_journal_id']));
+ app('log')->error(sprintf('Cannot find journal #%d, cannot convert to withdrawal.', $journal['transaction_journal_id']));
event(new RuleActionFailedOnArray($this->action, $journal, trans('rules.journal_not_found')));
+
return false;
}
$groupCount = TransactionJournal::where('transaction_group_id', $journal['transaction_group_id'])->count();
if ($groupCount > 1) {
- Log::error(sprintf('Group #%d has more than one transaction in it, cannot convert to withdrawal.', $journal['transaction_group_id']));
+ app('log')->error(sprintf('Group #%d has more than one transaction in it, cannot convert to withdrawal.', $journal['transaction_group_id']));
event(new RuleActionFailedOnArray($this->action, $journal, trans('rules.split_group')));
+
return false;
}
- $type = $object->transactionType->type;
+ $type = $object->transactionType->type;
if (TransactionType::WITHDRAWAL === $type) {
- Log::error(sprintf('Journal #%d is already a withdrawal (rule #%d).', $journal['transaction_journal_id'], $this->action->rule_id));
+ app('log')->error(sprintf('Journal #%d is already a withdrawal (rule #%d).', $journal['transaction_journal_id'], $this->action->rule_id));
event(new RuleActionFailedOnArray($this->action, $journal, trans('rules.is_already_withdrawal')));
+
return false;
}
if (TransactionType::DEPOSIT !== $type && TransactionType::TRANSFER !== $type) {
event(new RuleActionFailedOnArray($this->action, $journal, trans('rules.unsupported_transaction_type_withdrawal', ['type' => $type])));
+
return false;
}
if (TransactionType::DEPOSIT === $type) {
- Log::debug('Going to transform a deposit to a withdrawal.');
+ app('log')->debug('Going to transform a deposit to a withdrawal.');
+
try {
$res = $this->convertDepositArray($object, $actionValue);
- } catch (JsonException | FireflyException $e) {
- Log::debug('Could not convert transfer to deposit.');
- Log::error($e->getMessage());
+ } catch (FireflyException $e) {
+ app('log')->debug('Could not convert transfer to deposit.');
+ app('log')->error($e->getMessage());
event(new RuleActionFailedOnArray($this->action, $journal, trans('rules.complex_error')));
+
return false;
}
event(new TriggeredAuditLog($this->action->rule, $object, 'update_transaction_type', TransactionType::DEPOSIT, TransactionType::WITHDRAWAL));
return $res;
}
- if (TransactionType::TRANSFER === $type) {
- Log::debug('Going to transform a transfer to a withdrawal.');
+ // can only be transfer at this point.
+ app('log')->debug('Going to transform a transfer to a withdrawal.');
- try {
- $res = $this->convertTransferArray($object, $actionValue);
- } catch (JsonException | FireflyException $e) {
- Log::debug('Could not convert transfer to deposit.');
- Log::error($e->getMessage());
- event(new RuleActionFailedOnArray($this->action, $journal, trans('rules.complex_error')));
- return false;
- }
- event(new TriggeredAuditLog($this->action->rule, $object, 'update_transaction_type', TransactionType::TRANSFER, TransactionType::WITHDRAWAL));
+ try {
+ $res = $this->convertTransferArray($object, $actionValue);
+ } catch (FireflyException $e) {
+ app('log')->debug('Could not convert transfer to deposit.');
+ app('log')->error($e->getMessage());
+ event(new RuleActionFailedOnArray($this->action, $journal, trans('rules.complex_error')));
- return $res;
+ return false;
}
- event(new RuleActionFailedOnArray($this->action, $journal, trans('rules.unsupported_transaction_type_withdrawal', ['type' => $type])));
- return false;
+ event(new TriggeredAuditLog($this->action->rule, $object, 'update_transaction_type', TransactionType::TRANSFER, TransactionType::WITHDRAWAL));
+
+ return $res;
}
/**
- * @param TransactionJournal $journal
- *
- * @return bool
* @throws FireflyException
- * @throws JsonException
*/
private function convertDepositArray(TransactionJournal $journal, string $actionValue): bool
{
- $user = $journal->user;
+ $user = $journal->user;
+
/** @var AccountFactory $factory */
- $factory = app(AccountFactory::class);
+ $factory = app(AccountFactory::class);
$factory->setUser($user);
- $repository = app(AccountRepositoryInterface::class);
+ $repository = app(AccountRepositoryInterface::class);
$repository->setUser($user);
- $sourceAccount = $this->getSourceAccount($journal);
- $destAccount = $this->getDestinationAccount($journal);
+ $sourceAccount = $this->getSourceAccount($journal);
+ $destAccount = $this->getDestinationAccount($journal);
// get the action value, or use the original source name in case the action value is empty:
// this becomes a new or existing (expense) account, which is the destination of the new withdrawal.
@@ -155,60 +147,56 @@ class ConvertToWithdrawal implements ActionInterface
$opposingAccount = $factory->findOrCreate($opposingName, AccountType::EXPENSE);
}
- Log::debug(sprintf('ConvertToWithdrawal. Action value is "%s", expense name is "%s"', $actionValue, $opposingName));
+ app('log')->debug(sprintf('ConvertToWithdrawal. Action value is "%s", expense name is "%s"', $actionValue, $opposingName));
// update source transaction(s) to be the original destination account
- DB::table('transactions')
+ \DB::table('transactions')
->where('transaction_journal_id', '=', $journal->id)
->where('amount', '<', 0)
->update(['account_id' => $destAccount->id]);
// update destination transaction(s) to be new expense account.
- DB::table('transactions')
+ \DB::table('transactions')
->where('transaction_journal_id', '=', $journal->id)
->where('amount', '>', 0)
->update(['account_id' => $opposingAccount->id]);
// change transaction type of journal:
- $newType = TransactionType::whereType(TransactionType::WITHDRAWAL)->first();
- DB::table('transaction_journals')
+ $newType = TransactionType::whereType(TransactionType::WITHDRAWAL)->first();
+ \DB::table('transaction_journals')
->where('id', '=', $journal->id)
->update(['transaction_type_id' => $newType->id]);
- Log::debug('Converted deposit to withdrawal.');
+ app('log')->debug('Converted deposit to withdrawal.');
return true;
}
/**
- * @param TransactionJournal $journal
- *
- * @return Account
* @throws FireflyException
*/
private function getSourceAccount(TransactionJournal $journal): Account
{
- /** @var Transaction|null $sourceTransaction */
+ /** @var null|Transaction $sourceTransaction */
$sourceTransaction = $journal->transactions()->where('amount', '<', 0)->first();
if (null === $sourceTransaction) {
throw new FireflyException(sprintf('Cannot find source transaction for journal #%d', $journal->id));
}
+
return $sourceTransaction->account;
}
/**
- * @param TransactionJournal $journal
- *
- * @return Account
* @throws FireflyException
*/
private function getDestinationAccount(TransactionJournal $journal): Account
{
- /** @var Transaction|null $destAccount */
+ /** @var null|Transaction $destAccount */
$destAccount = $journal->transactions()->where('amount', '>', 0)->first();
if (null === $destAccount) {
throw new FireflyException(sprintf('Cannot find destination transaction for journal #%d', $journal->id));
}
+
return $destAccount->account;
}
@@ -216,28 +204,25 @@ class ConvertToWithdrawal implements ActionInterface
* Input is a transfer from A to B.
* Output is a withdrawal from A to C.
*
- * @param TransactionJournal $journal
- *
- * @return bool
* @throws FireflyException
- * @throws JsonException
*/
private function convertTransferArray(TransactionJournal $journal, string $actionValue): bool
{
// find or create expense account.
- $user = $journal->user;
+ $user = $journal->user;
+
/** @var AccountFactory $factory */
- $factory = app(AccountFactory::class);
+ $factory = app(AccountFactory::class);
$factory->setUser($user);
- $repository = app(AccountRepositoryInterface::class);
+ $repository = app(AccountRepositoryInterface::class);
$repository->setUser($user);
- $destAccount = $this->getDestinationAccount($journal);
+ $destAccount = $this->getDestinationAccount($journal);
// get the action value, or use the original source name in case the action value is empty:
// this becomes a new or existing (expense) account, which is the destination of the new withdrawal.
- $opposingName = '' === $actionValue ? $destAccount->name : $actionValue;
+ $opposingName = '' === $actionValue ? $destAccount->name : $actionValue;
// we check all possible source account types if one exists:
$validTypes = config('firefly.expected_source_types.destination.Withdrawal');
$opposingAccount = $repository->findByName($opposingName, $validTypes);
@@ -245,21 +230,21 @@ class ConvertToWithdrawal implements ActionInterface
$opposingAccount = $factory->findOrCreate($opposingName, AccountType::EXPENSE);
}
- Log::debug(sprintf('ConvertToWithdrawal. Action value is "%s", destination name is "%s"', $actionValue, $opposingName));
+ app('log')->debug(sprintf('ConvertToWithdrawal. Action value is "%s", destination name is "%s"', $actionValue, $opposingName));
// update destination transaction(s) to be new expense account.
- DB::table('transactions')
+ \DB::table('transactions')
->where('transaction_journal_id', '=', $journal->id)
->where('amount', '>', 0)
->update(['account_id' => $opposingAccount->id]);
// change transaction type of journal:
- $newType = TransactionType::whereType(TransactionType::WITHDRAWAL)->first();
- DB::table('transaction_journals')
+ $newType = TransactionType::whereType(TransactionType::WITHDRAWAL)->first();
+ \DB::table('transaction_journals')
->where('id', '=', $journal->id)
->update(['transaction_type_id' => $newType->id]);
- Log::debug('Converted transfer to withdrawal.');
+ app('log')->debug('Converted transfer to withdrawal.');
return true;
}
diff --git a/app/TransactionRules/Actions/DeleteTransaction.php b/app/TransactionRules/Actions/DeleteTransaction.php
index 0f52553457..5863422fa3 100644
--- a/app/TransactionRules/Actions/DeleteTransaction.php
+++ b/app/TransactionRules/Actions/DeleteTransaction.php
@@ -29,7 +29,6 @@ use FireflyIII\Models\TransactionGroup;
use FireflyIII\Models\TransactionJournal;
use FireflyIII\Services\Internal\Destroy\JournalDestroyService;
use FireflyIII\Services\Internal\Destroy\TransactionGroupDestroyService;
-use Illuminate\Support\Facades\Log;
/**
* Class DeleteTransaction.
@@ -40,30 +39,27 @@ class DeleteTransaction implements ActionInterface
/**
* TriggerInterface constructor.
- *
- * @param RuleAction $action
*/
public function __construct(RuleAction $action)
{
$this->action = $action;
}
- /**
- * @inheritDoc
- */
public function actOnArray(array $journal): bool
{
- $count = TransactionJournal::where('transaction_group_id', $journal['transaction_group_id'])->count();
+ $count = TransactionJournal::where('transaction_group_id', $journal['transaction_group_id'])->count();
// destroy entire group.
if (1 === $count) {
- Log::debug(
+ app('log')->debug(
sprintf(
'RuleAction DeleteTransaction DELETED the entire transaction group of journal #%d ("%s").',
$journal['transaction_journal_id'],
$journal['description']
)
);
+
+ /** @var TransactionGroup $group */
$group = TransactionGroup::find($journal['transaction_group_id']);
$service = app(TransactionGroupDestroyService::class);
$service->destroy($group);
@@ -72,12 +68,13 @@ class DeleteTransaction implements ActionInterface
return true;
}
- Log::debug(
+ app('log')->debug(
sprintf('RuleAction DeleteTransaction DELETED transaction journal #%d ("%s").', $journal['transaction_journal_id'], $journal['description'])
);
// trigger delete factory:
- $object = TransactionJournal::find($journal['transaction_group_id']);
+ /** @var null|TransactionJournal $object */
+ $object = TransactionJournal::find($journal['transaction_journal_id']);
if (null !== $object) {
/** @var JournalDestroyService $service */
$service = app(JournalDestroyService::class);
diff --git a/app/TransactionRules/Actions/LinkToBill.php b/app/TransactionRules/Actions/LinkToBill.php
index 2b817077c6..677a3d2f46 100644
--- a/app/TransactionRules/Actions/LinkToBill.php
+++ b/app/TransactionRules/Actions/LinkToBill.php
@@ -24,7 +24,6 @@ declare(strict_types=1);
namespace FireflyIII\TransactionRules\Actions;
-use DB;
use FireflyIII\Events\Model\Rule\RuleActionFailedOnArray;
use FireflyIII\Events\TriggeredAuditLog;
use FireflyIII\Models\RuleAction;
@@ -33,7 +32,6 @@ use FireflyIII\Models\TransactionType;
use FireflyIII\Repositories\Bill\BillRepositoryInterface;
use FireflyIII\TransactionRules\Expressions\ActionExpressionEvaluator;
use FireflyIII\User;
-use Illuminate\Support\Facades\Log;
/**
* Class LinkToBill.
@@ -45,9 +43,6 @@ class LinkToBill implements ActionInterface
/**
* TriggerInterface constructor.
- *
- *
- * @param RuleAction $action
*/
public function __construct(RuleAction $action, ActionExpressionEvaluator $evaluator)
{
@@ -55,23 +50,22 @@ class LinkToBill implements ActionInterface
$this->evaluator = $evaluator;
}
- /**
- * @inheritDoc
- */
public function actOnArray(array $journal): bool
{
- $user = User::find($journal['user_id']);
+ /** @var User $user */
+ $user = User::find($journal['user_id']);
+
/** @var BillRepositoryInterface $repository */
$repository = app(BillRepositoryInterface::class);
$repository->setUser($user);
- $billName = $this->evaluator->evaluate($journal);
- $bill = $repository->findByName($billName);
+ $billName = $this->evaluator->evaluate($journal);
+ $bill = $repository->findByName($billName);
- if (null !== $bill && $journal['transaction_type_type'] === TransactionType::WITHDRAWAL) {
- $count = DB::table('transaction_journals')->where('id', '=', $journal['transaction_journal_id'])
+ if (null !== $bill && TransactionType::WITHDRAWAL === $journal['transaction_type_type']) {
+ $count = \DB::table('transaction_journals')->where('id', '=', $journal['transaction_journal_id'])
->where('bill_id', $bill->id)->count();
if (0 !== $count) {
- Log::error(
+ app('log')->error(
sprintf(
'RuleAction LinkToBill could not set the bill of journal #%d to bill "%s": already set.',
$journal['transaction_journal_id'],
@@ -79,24 +73,25 @@ class LinkToBill implements ActionInterface
)
);
event(new RuleActionFailedOnArray($this->action, $journal, trans('rules.already_linked_to_subscription', ['name' => $billName])));
+
return false;
}
-
- DB::table('transaction_journals')
+ \DB::table('transaction_journals')
->where('id', '=', $journal['transaction_journal_id'])
->update(['bill_id' => $bill->id]);
- Log::debug(
+ app('log')->debug(
sprintf('RuleAction LinkToBill set the bill of journal #%d to bill #%d ("%s").', $journal['transaction_journal_id'], $bill->id, $bill->name)
);
+ /** @var TransactionJournal $object */
$object = TransactionJournal::where('user_id', $journal['user_id'])->find($journal['transaction_journal_id']);
event(new TriggeredAuditLog($this->action->rule, $object, 'set_bill', null, $bill->name));
return true;
}
- Log::error(
+ app('log')->error(
sprintf(
'RuleAction LinkToBill could not set the bill of journal #%d to bill "%s": no such bill found or not a withdrawal.',
$journal['transaction_journal_id'],
@@ -104,6 +99,7 @@ class LinkToBill implements ActionInterface
)
);
event(new RuleActionFailedOnArray($this->action, $journal, trans('rules.cannot_find_subscription', ['name' => $billName])));
+
return false;
}
}
diff --git a/app/TransactionRules/Actions/MoveDescriptionToNotes.php b/app/TransactionRules/Actions/MoveDescriptionToNotes.php
index 9d17dd8ae2..9b611f7db2 100644
--- a/app/TransactionRules/Actions/MoveDescriptionToNotes.php
+++ b/app/TransactionRules/Actions/MoveDescriptionToNotes.php
@@ -29,7 +29,6 @@ use FireflyIII\Events\TriggeredAuditLog;
use FireflyIII\Models\Note;
use FireflyIII\Models\RuleAction;
use FireflyIII\Models\TransactionJournal;
-use Illuminate\Support\Facades\Log;
/**
* Class MoveDescriptionToNotes
@@ -40,30 +39,27 @@ class MoveDescriptionToNotes implements ActionInterface
/**
* TriggerInterface constructor.
- *
- *
- * @param RuleAction $action
*/
public function __construct(RuleAction $action)
{
$this->action = $action;
}
- /**
- * @inheritDoc
- */
public function actOnArray(array $journal): bool
{
- /** @var TransactionJournal $object */
- $object = TransactionJournal::where('user_id', $journal['user_id'])->find($journal['transaction_journal_id']);
+ /** @var null|TransactionJournal $object */
+ $object = TransactionJournal::where('user_id', $journal['user_id'])->find($journal['transaction_journal_id']);
if (null === $object) {
- Log::error(sprintf('No journal #%d belongs to user #%d.', $journal['transaction_journal_id'], $journal['user_id']));
+ app('log')->error(sprintf('No journal #%d belongs to user #%d.', $journal['transaction_journal_id'], $journal['user_id']));
event(new RuleActionFailedOnArray($this->action, $journal, trans('rules.journal_other_user')));
+
return false;
}
- $note = $object->notes()->first();
+
+ /** @var null|Note $note */
+ $note = $object->notes()->first();
if (null === $note) {
- $note = new Note();
+ $note = new Note();
$note->noteable()->associate($object);
$note->text = '';
}
@@ -77,13 +73,14 @@ class MoveDescriptionToNotes implements ActionInterface
$note->text = (string)$object->description;
$object->description = '(no description)';
}
- $after = $note->text;
+ $after = $note->text;
event(new TriggeredAuditLog($this->action->rule, $object, 'update_description', $beforeDescription, $object->description));
event(new TriggeredAuditLog($this->action->rule, $object, 'update_notes', $before, $after));
$note->save();
$object->save();
+
return true;
}
}
diff --git a/app/TransactionRules/Actions/MoveNotesToDescription.php b/app/TransactionRules/Actions/MoveNotesToDescription.php
index 8ce108aa02..5c18ab78a7 100644
--- a/app/TransactionRules/Actions/MoveNotesToDescription.php
+++ b/app/TransactionRules/Actions/MoveNotesToDescription.php
@@ -29,7 +29,6 @@ use FireflyIII\Events\TriggeredAuditLog;
use FireflyIII\Models\RuleAction;
use FireflyIII\Models\TransactionJournal;
use FireflyIII\Support\Request\ConvertsDataTypes;
-use Illuminate\Support\Facades\Log;
/**
* Class MoveNotesToDescription
@@ -46,30 +45,26 @@ class MoveNotesToDescription implements ActionInterface
/**
* TriggerInterface constructor.
- *
- *
- * @param RuleAction $action
*/
public function __construct(RuleAction $action)
{
$this->action = $action;
}
- /**
- * @inheritDoc
- */
public function actOnArray(array $journal): bool
{
- /** @var TransactionJournal $object */
- $object = TransactionJournal::where('user_id', $journal['user_id'])->find($journal['transaction_journal_id']);
+ /** @var null|TransactionJournal $object */
+ $object = TransactionJournal::where('user_id', $journal['user_id'])->find($journal['transaction_journal_id']);
if (null === $object) {
- Log::error(sprintf('No journal #%d belongs to user #%d.', $journal['transaction_journal_id'], $journal['user_id']));
+ app('log')->error(sprintf('No journal #%d belongs to user #%d.', $journal['transaction_journal_id'], $journal['user_id']));
event(new RuleActionFailedOnArray($this->action, $journal, trans('rules.journal_other_user')));
+
return false;
}
- $note = $object->notes()->first();
+ $note = $object->notes()->first();
if (null === $note) {
event(new RuleActionFailedOnArray($this->action, $journal, trans('rules.no_notes_to_move')));
+
// nothing to move, return null
return false;
}
@@ -77,11 +72,12 @@ class MoveNotesToDescription implements ActionInterface
// nothing to move, return null
$note->delete();
event(new RuleActionFailedOnArray($this->action, $journal, trans('rules.no_notes_to_move')));
+
return false;
}
$before = $object->description;
$beforeNote = $note->text;
- $object->description = (string)$this->clearString($note->text, false);
+ $object->description = (string)$this->clearString($note->text);
$object->save();
$note->delete();
@@ -92,7 +88,7 @@ class MoveNotesToDescription implements ActionInterface
}
/**
- * @inheritDoc
+ * @SuppressWarnings(PHPMD.UnusedFormalParameter)
*/
public function get(string $key, mixed $default = null): mixed
{
@@ -100,7 +96,7 @@ class MoveNotesToDescription implements ActionInterface
}
/**
- * @inheritDoc
+ * @SuppressWarnings(PHPMD.UnusedFormalParameter)
*/
public function has(mixed $key): mixed
{
diff --git a/app/TransactionRules/Actions/PrependDescription.php b/app/TransactionRules/Actions/PrependDescription.php
index ef8a36931c..ba407f4cdb 100644
--- a/app/TransactionRules/Actions/PrependDescription.php
+++ b/app/TransactionRules/Actions/PrependDescription.php
@@ -24,7 +24,6 @@ declare(strict_types=1);
namespace FireflyIII\TransactionRules\Actions;
-use DB;
use FireflyIII\Events\TriggeredAuditLog;
use FireflyIII\Models\RuleAction;
use FireflyIII\Models\TransactionJournal;
@@ -40,8 +39,6 @@ class PrependDescription implements ActionInterface
/**
* TriggerInterface constructor.
- *
- * @param RuleAction $action
*/
public function __construct(RuleAction $action, ActionExpressionEvaluator $evaluator)
{
@@ -49,16 +46,13 @@ class PrependDescription implements ActionInterface
$this->evaluator = $evaluator;
}
- /**
- * @inheritDoc
- */
public function actOnArray(array $journal): bool
{
$actionValue = $this->evaluator->evaluate($journal);
$before = $journal['description'];
$after = sprintf('%s%s', $actionValue, $journal['description']);
- DB::table('transaction_journals')->where('id', $journal['transaction_journal_id'])->limit(1)->update(['description' => $after]);
+ \DB::table('transaction_journals')->where('id', $journal['transaction_journal_id'])->limit(1)->update(['description' => $after]);
// journal
/** @var TransactionJournal $object */
diff --git a/app/TransactionRules/Actions/PrependNotes.php b/app/TransactionRules/Actions/PrependNotes.php
index 9f86739067..d82cbe43b0 100644
--- a/app/TransactionRules/Actions/PrependNotes.php
+++ b/app/TransactionRules/Actions/PrependNotes.php
@@ -29,7 +29,6 @@ use FireflyIII\Models\Note;
use FireflyIII\Models\RuleAction;
use FireflyIII\Models\TransactionJournal;
use FireflyIII\TransactionRules\Expressions\ActionExpressionEvaluator;
-use Illuminate\Support\Facades\Log;
/**
* Class PrependNotes.
@@ -41,23 +40,17 @@ class PrependNotes implements ActionInterface
/**
* TriggerInterface constructor.
- *
- * @param RuleAction $action
*/
public function __construct(RuleAction $action, ActionExpressionEvaluator $evaluator)
{
- $this->action = $action;
+ $this->action = $action;
$this->evaluator = $evaluator;
}
- /**
- * @inheritDoc
- */
public function actOnArray(array $journal): bool
{
- $actionValue = $this->evaluator->evaluate($journal);
-
- $dbNote = Note::where('noteable_id', (int)$journal['transaction_journal_id'])
+ $actionValue = $this->evaluator->evaluate($journal);
+ $dbNote = Note::where('noteable_id', (int)$journal['transaction_journal_id'])
->where('noteable_type', TransactionJournal::class)
->first(['notes.*']);
if (null === $dbNote) {
@@ -66,15 +59,15 @@ class PrependNotes implements ActionInterface
$dbNote->noteable_type = TransactionJournal::class;
$dbNote->text = '';
}
- $before = $dbNote->text;
- Log::debug(sprintf('RuleAction PrependNotes prepended "%s" to "%s".', $actionValue, $dbNote->text));
+ $before = $dbNote->text;
+ app('log')->debug(sprintf('RuleAction PrependNotes prepended "%s" to "%s".', $actionValue, $dbNote->text));
$text = sprintf('%s%s', $actionValue, $dbNote->text);
$dbNote->text = $text;
$dbNote->save();
// journal
/** @var TransactionJournal $object */
- $object = TransactionJournal::where('user_id', $journal['user_id'])->find($journal['transaction_journal_id']);
+ $object = TransactionJournal::where('user_id', $journal['user_id'])->find($journal['transaction_journal_id']);
// audit log
event(new TriggeredAuditLog($this->action->rule, $object, 'update_notes', $before, $text));
diff --git a/app/TransactionRules/Actions/RemoveAllTags.php b/app/TransactionRules/Actions/RemoveAllTags.php
index 87ccbe0b2f..8952d9532d 100644
--- a/app/TransactionRules/Actions/RemoveAllTags.php
+++ b/app/TransactionRules/Actions/RemoveAllTags.php
@@ -23,12 +23,10 @@ declare(strict_types=1);
namespace FireflyIII\TransactionRules\Actions;
-use DB;
use FireflyIII\Events\Model\Rule\RuleActionFailedOnArray;
use FireflyIII\Events\TriggeredAuditLog;
use FireflyIII\Models\RuleAction;
use FireflyIII\Models\TransactionJournal;
-use Illuminate\Support\Facades\Log;
/**
* Class RemoveAllTags.
@@ -39,27 +37,23 @@ class RemoveAllTags implements ActionInterface
/**
* TriggerInterface constructor.
- *
- * @param RuleAction $action
*/
public function __construct(RuleAction $action)
{
$this->action = $action;
}
- /**
- * @inheritDoc
- */
public function actOnArray(array $journal): bool
{
- DB::table('tag_transaction_journal')->where('transaction_journal_id', $journal['transaction_journal_id'])->delete();
- $count = DB::table('tag_transaction_journal')->where('transaction_journal_id', $journal['transaction_journal_id'])->count();
+ \DB::table('tag_transaction_journal')->where('transaction_journal_id', $journal['transaction_journal_id'])->delete();
+ $count = \DB::table('tag_transaction_journal')->where('transaction_journal_id', $journal['transaction_journal_id'])->count();
if (0 === $count) {
- Log::debug(sprintf('RuleAction RemoveAllTags, journal #%d has no tags.', $journal['transaction_journal_id']));
+ app('log')->debug(sprintf('RuleAction RemoveAllTags, journal #%d has no tags.', $journal['transaction_journal_id']));
event(new RuleActionFailedOnArray($this->action, $journal, trans('rules.no_tags_to_remove')));
+
return false;
}
- Log::debug(sprintf('RuleAction RemoveAllTags removed all tags from journal %d.', $journal['transaction_journal_id']));
+ app('log')->debug(sprintf('RuleAction RemoveAllTags removed all tags from journal %d.', $journal['transaction_journal_id']));
/** @var TransactionJournal $object */
$object = TransactionJournal::where('user_id', $journal['user_id'])->find($journal['transaction_journal_id']);
diff --git a/app/TransactionRules/Actions/RemoveTag.php b/app/TransactionRules/Actions/RemoveTag.php
index b67a10aaa4..20693779bf 100644
--- a/app/TransactionRules/Actions/RemoveTag.php
+++ b/app/TransactionRules/Actions/RemoveTag.php
@@ -24,14 +24,12 @@ declare(strict_types=1);
namespace FireflyIII\TransactionRules\Actions;
-use DB;
use FireflyIII\Events\Model\Rule\RuleActionFailedOnArray;
use FireflyIII\Events\TriggeredAuditLog;
use FireflyIII\Models\RuleAction;
use FireflyIII\Models\TransactionJournal;
use FireflyIII\TransactionRules\Expressions\ActionExpressionEvaluator;
use FireflyIII\User;
-use Illuminate\Support\Facades\Log;
/**
* Class RemoveTag.
@@ -43,8 +41,6 @@ class RemoveTag implements ActionInterface
/**
* TriggerInterface constructor.
- *
- * @param RuleAction $action
*/
public function __construct(RuleAction $action, ActionExpressionEvaluator $evaluator)
{
@@ -52,34 +48,35 @@ class RemoveTag implements ActionInterface
$this->evaluator = $evaluator;
}
- /**
- * @inheritDoc
- */
public function actOnArray(array $journal): bool
{
// if tag does not exist, no need to continue:
- $name = $this->evaluator->evaluate($journal);
- $user = User::find($journal['user_id']);
- $tag = $user->tags()->where('tag', $name)->first();
+ $name = $this->evaluator->evaluate($journal);
+
+ /** @var User $user */
+ $user = User::find($journal['user_id']);
+ $tag = $user->tags()->where('tag', $name)->first();
if (null === $tag) {
- Log::debug(
+ app('log')->debug(
sprintf('RuleAction RemoveTag tried to remove tag "%s" from journal #%d but no such tag exists.', $name, $journal['transaction_journal_id'])
);
event(new RuleActionFailedOnArray($this->action, $journal, trans('rules.cannot_find_tag', ['tag' => $name])));
+
return false;
}
- $count = DB::table('tag_transaction_journal')->where('transaction_journal_id', $journal['transaction_journal_id'])->where('tag_id', $tag->id)->count();
+ $count = \DB::table('tag_transaction_journal')->where('transaction_journal_id', $journal['transaction_journal_id'])->where('tag_id', $tag->id)->count();
if (0 === $count) {
- Log::debug(
+ app('log')->debug(
sprintf('RuleAction RemoveTag tried to remove tag "%s" from journal #%d but no such tag is linked.', $name, $journal['transaction_journal_id'])
);
event(new RuleActionFailedOnArray($this->action, $journal, trans('rules.cannot_unlink_tag', ['tag' => $name])));
+
return false;
}
- Log::debug(sprintf('RuleAction RemoveTag removed tag #%d ("%s") from journal #%d.', $tag->id, $tag->tag, $journal['transaction_journal_id']));
- DB::table('tag_transaction_journal')
+ app('log')->debug(sprintf('RuleAction RemoveTag removed tag #%d ("%s") from journal #%d.', $tag->id, $tag->tag, $journal['transaction_journal_id']));
+ \DB::table('tag_transaction_journal')
->where('transaction_journal_id', $journal['transaction_journal_id'])
->where('tag_id', $tag->id)
->delete();
diff --git a/app/TransactionRules/Actions/SetBudget.php b/app/TransactionRules/Actions/SetBudget.php
index 9a88f49257..5dc595de3d 100644
--- a/app/TransactionRules/Actions/SetBudget.php
+++ b/app/TransactionRules/Actions/SetBudget.php
@@ -24,7 +24,6 @@ declare(strict_types=1);
namespace FireflyIII\TransactionRules\Actions;
-use DB;
use FireflyIII\Events\Model\Rule\RuleActionFailedOnArray;
use FireflyIII\Events\TriggeredAuditLog;
use FireflyIII\Models\RuleAction;
@@ -32,7 +31,6 @@ use FireflyIII\Models\TransactionJournal;
use FireflyIII\Models\TransactionType;
use FireflyIII\TransactionRules\Expressions\ActionExpressionEvaluator;
use FireflyIII\User;
-use Illuminate\Support\Facades\Log;
/**
* Class SetBudget.
@@ -44,8 +42,6 @@ class SetBudget implements ActionInterface
/**
* TriggerInterface constructor.
- *
- * @param RuleAction $action
*/
public function __construct(RuleAction $action, ActionExpressionEvaluator $evaluator)
{
@@ -53,17 +49,15 @@ class SetBudget implements ActionInterface
$this->evaluator = $evaluator;
}
- /**
- * @inheritDoc
- */
public function actOnArray(array $journal): bool
{
- $user = User::find($journal['user_id']);
- $search = $this->evaluator->evaluate($journal);
+ /** @var User $user */
+ $user = User::find($journal['user_id']);
+ $search = $this->evaluator->evaluate($journal);
- $budget = $user->budgets()->where('name', $search)->first();
+ $budget = $user->budgets()->where('name', $search)->first();
if (null === $budget) {
- Log::debug(
+ app('log')->debug(
sprintf(
'RuleAction SetBudget could not set budget of journal #%d to "%s" because no such budget exists.',
$journal['transaction_journal_id'],
@@ -71,11 +65,12 @@ class SetBudget implements ActionInterface
)
);
event(new RuleActionFailedOnArray($this->action, $journal, trans('rules.cannot_find_budget', ['name' => $search])));
+
return false;
}
if (TransactionType::WITHDRAWAL !== $journal['transaction_type_type']) {
- Log::debug(
+ app('log')->debug(
sprintf(
'RuleAction SetBudget could not set budget of journal #%d to "%s" because journal is a %s.',
$journal['transaction_journal_id'],
@@ -84,6 +79,7 @@ class SetBudget implements ActionInterface
)
);
event(new RuleActionFailedOnArray($this->action, $journal, trans('rules.cannot_set_budget', ['type' => $journal['transaction_type_type'], 'name' => $search])));
+
return false;
}
@@ -92,21 +88,21 @@ class SetBudget implements ActionInterface
$object = $user->transactionJournals()->find($journal['transaction_journal_id']);
$oldBudget = $object->budgets()->first();
$oldBudgetName = $oldBudget?->name;
- if ((int)$oldBudget?->id === (int)$budget->id) {
+ if ((int)$oldBudget?->id === $budget->id) {
event(new RuleActionFailedOnArray($this->action, $journal, trans('rules.already_linked_to_budget', ['name' => $budget->name])));
+
return false;
}
-
- Log::debug(
+ app('log')->debug(
sprintf('RuleAction SetBudget set the budget of journal #%d to budget #%d ("%s").', $journal['transaction_journal_id'], $budget->id, $budget->name)
);
- DB::table('budget_transaction_journal')->where('transaction_journal_id', '=', $journal['transaction_journal_id'])->delete();
- DB::table('budget_transaction_journal')->insert(['transaction_journal_id' => $journal['transaction_journal_id'], 'budget_id' => $budget->id]);
+ \DB::table('budget_transaction_journal')->where('transaction_journal_id', '=', $journal['transaction_journal_id'])->delete();
+ \DB::table('budget_transaction_journal')->insert(['transaction_journal_id' => $journal['transaction_journal_id'], 'budget_id' => $budget->id]);
/** @var TransactionJournal $object */
- $object = TransactionJournal::where('user_id', $journal['user_id'])->find($journal['transaction_journal_id']);
+ $object = TransactionJournal::where('user_id', $journal['user_id'])->find($journal['transaction_journal_id']);
event(new TriggeredAuditLog($this->action->rule, $object, 'set_budget', $oldBudgetName, $budget->name));
return true;
diff --git a/app/TransactionRules/Actions/SetCategory.php b/app/TransactionRules/Actions/SetCategory.php
index a4ed08d7d6..fe8309647c 100644
--- a/app/TransactionRules/Actions/SetCategory.php
+++ b/app/TransactionRules/Actions/SetCategory.php
@@ -24,7 +24,6 @@ declare(strict_types=1);
namespace FireflyIII\TransactionRules\Actions;
-use DB;
use FireflyIII\Events\Model\Rule\RuleActionFailedOnArray;
use FireflyIII\Events\TriggeredAuditLog;
use FireflyIII\Factory\CategoryFactory;
@@ -32,7 +31,6 @@ use FireflyIII\Models\RuleAction;
use FireflyIII\Models\TransactionJournal;
use FireflyIII\TransactionRules\Expressions\ActionExpressionEvaluator;
use FireflyIII\User;
-use Illuminate\Support\Facades\Log;
/**
* Class SetCategory.
@@ -44,8 +42,6 @@ class SetCategory implements ActionInterface
/**
* TriggerInterface constructor.
- *
- * @param RuleAction $action
*/
public function __construct(RuleAction $action, ActionExpressionEvaluator $evaluator)
{
@@ -53,25 +49,24 @@ class SetCategory implements ActionInterface
$this->evaluator = $evaluator;
}
- /**
- * @inheritDoc
- */
public function actOnArray(array $journal): bool
{
- $user = User::find($journal['user_id']);
- $search = $this->evaluator->evaluate($journal);
+ /** @var null|User $user */
+ $user = User::find($journal['user_id']);
+ $search = $this->evaluator->evaluate($journal);
if (null === $user) {
- Log::error(sprintf('Journal has no valid user ID so action SetCategory("%s") cannot be applied', $search), $journal);
+ app('log')->error(sprintf('Journal has no valid user ID so action SetCategory("%s") cannot be applied', $search), $journal);
event(new RuleActionFailedOnArray($this->action, $journal, trans('rules.no_such_journal')));
+
return false;
}
/** @var CategoryFactory $factory */
- $factory = app(CategoryFactory::class);
+ $factory = app(CategoryFactory::class);
$factory->setUser($user);
- $category = $factory->findOrCreate(null, $search);
+ $category = $factory->findOrCreate(null, $search);
if (null === $category) {
- Log::debug(
+ app('log')->debug(
sprintf(
'RuleAction SetCategory could not set category of journal #%d to "%s" because no such category exists.',
$journal['transaction_journal_id'],
@@ -79,10 +74,11 @@ class SetCategory implements ActionInterface
)
);
event(new RuleActionFailedOnArray($this->action, $journal, trans('rules.cannot_find_category', ['name' => $search])));
+
return false;
}
- Log::debug(
+ app('log')->debug(
sprintf(
'RuleAction SetCategory set the category of journal #%d to category #%d ("%s").',
$journal['transaction_journal_id'],
@@ -96,16 +92,17 @@ class SetCategory implements ActionInterface
$object = $user->transactionJournals()->find($journal['transaction_journal_id']);
$oldCategory = $object->categories()->first();
$oldCategoryName = $oldCategory?->name;
- if ((int)$oldCategory?->id === (int)$category->id) {
- event(new RuleActionFailedOnArray($this->action, $journal, trans('rules.already_linked_to_category', ['name' => $category->name])));
+ if ((int)$oldCategory?->id === $category->id) {
+ // event(new RuleActionFailedOnArray($this->action, $journal, trans('rules.already_linked_to_category', ['name' => $category->name])));
+
return false;
}
- DB::table('category_transaction_journal')->where('transaction_journal_id', '=', $journal['transaction_journal_id'])->delete();
- DB::table('category_transaction_journal')->insert(['transaction_journal_id' => $journal['transaction_journal_id'], 'category_id' => $category->id]);
+ \DB::table('category_transaction_journal')->where('transaction_journal_id', '=', $journal['transaction_journal_id'])->delete();
+ \DB::table('category_transaction_journal')->insert(['transaction_journal_id' => $journal['transaction_journal_id'], 'category_id' => $category->id]);
/** @var TransactionJournal $object */
- $object = TransactionJournal::where('user_id', $journal['user_id'])->find($journal['transaction_journal_id']);
+ $object = TransactionJournal::where('user_id', $journal['user_id'])->find($journal['transaction_journal_id']);
event(new TriggeredAuditLog($this->action->rule, $object, 'set_category', $oldCategoryName, $category->name));
return true;
diff --git a/app/TransactionRules/Actions/SetDescription.php b/app/TransactionRules/Actions/SetDescription.php
index 799a02ed70..8ce0d001b5 100644
--- a/app/TransactionRules/Actions/SetDescription.php
+++ b/app/TransactionRules/Actions/SetDescription.php
@@ -24,12 +24,10 @@ declare(strict_types=1);
namespace FireflyIII\TransactionRules\Actions;
-use DB;
use FireflyIII\Events\TriggeredAuditLog;
use FireflyIII\Models\RuleAction;
use FireflyIII\Models\TransactionJournal;
use FireflyIII\TransactionRules\Expressions\ActionExpressionEvaluator;
-use Illuminate\Support\Facades\Log;
/**
* Class SetDescription.
@@ -41,8 +39,6 @@ class SetDescription implements ActionInterface
/**
* TriggerInterface constructor.
- *
- * @param RuleAction $action
*/
public function __construct(RuleAction $action, ActionExpressionEvaluator $evaluator)
{
@@ -50,9 +46,6 @@ class SetDescription implements ActionInterface
$this->evaluator = $evaluator;
}
- /**
- * @inheritDoc
- */
public function actOnArray(array $journal): bool
{
/** @var TransactionJournal $object */
@@ -60,11 +53,11 @@ class SetDescription implements ActionInterface
$before = $journal['description'];
$after = $this->evaluator->evaluate($journal);
- DB::table('transaction_journals')
+ \DB::table('transaction_journals')
->where('id', '=', $journal['transaction_journal_id'])
- ->update(['description' => $after]);
+ ->update(['description' => $this->action->action_value]);
- Log::debug(
+ app('log')->debug(
sprintf(
'RuleAction SetDescription changed the description of journal #%d from "%s" to "%s".',
$journal['transaction_journal_id'],
diff --git a/app/TransactionRules/Actions/SetDestinationAccount.php b/app/TransactionRules/Actions/SetDestinationAccount.php
index e4c2688831..6521e02e94 100644
--- a/app/TransactionRules/Actions/SetDestinationAccount.php
+++ b/app/TransactionRules/Actions/SetDestinationAccount.php
@@ -24,7 +24,6 @@ declare(strict_types=1);
namespace FireflyIII\TransactionRules\Actions;
-use DB;
use FireflyIII\Events\Model\Rule\RuleActionFailedOnArray;
use FireflyIII\Events\TriggeredAuditLog;
use FireflyIII\Models\Account;
@@ -35,7 +34,6 @@ use FireflyIII\Models\TransactionType;
use FireflyIII\Repositories\Account\AccountRepositoryInterface;
use FireflyIII\TransactionRules\Expressions\ActionExpressionEvaluator;
use FireflyIII\User;
-use Illuminate\Support\Facades\Log;
/**
* Class SetDestinationAccount.
@@ -48,8 +46,6 @@ class SetDestinationAccount implements ActionInterface
/**
* TriggerInterface constructor.
- *
- * @param RuleAction $action
*/
public function __construct(RuleAction $action, ActionExpressionEvaluator $evaluator)
{
@@ -57,30 +53,30 @@ class SetDestinationAccount implements ActionInterface
$this->evaluator = $evaluator;
}
- /**
- * @inheritDoc
- */
public function actOnArray(array $journal): bool
{
$accountName = $this->evaluator->evaluate($journal);
- $user = User::find($journal['user_id']);
- $type = $journal['transaction_type_type'];
- /** @var TransactionJournal|null $object */
+
+ /** @var User $user */
+ $user = User::find($journal['user_id']);
+
+ /** @var null|TransactionJournal $object */
$object = $user->transactionJournals()->find((int)$journal['transaction_journal_id']);
$this->repository = app(AccountRepositoryInterface::class);
if (null === $object) {
- Log::error('Could not find journal.');
+ app('log')->error('Could not find journal.');
event(new RuleActionFailedOnArray($this->action, $journal, trans('rules.no_such_journal')));
+
return false;
}
- $type = $object->transactionType->type;
+ $type = $object->transactionType->type;
$this->repository->setUser($user);
// if this is a transfer or a deposit, the new destination account must be an asset account or a default account, and it MUST exist:
- $newAccount = $this->findAssetAccount($type, $accountName);
+ $newAccount = $this->findAssetAccount($type, $accountName);
if ((TransactionType::DEPOSIT === $type || TransactionType::TRANSFER === $type) && null === $newAccount) {
- Log::error(
+ app('log')->error(
sprintf(
'Cant change destination account of journal #%d because no asset account with name "%s" exists.',
$object->id,
@@ -88,25 +84,28 @@ class SetDestinationAccount implements ActionInterface
)
);
event(new RuleActionFailedOnArray($this->action, $journal, trans('rules.cannot_find_asset', ['name' => $accountName])));
+
return false;
}
// new destination account must be different from the current source account:
- /** @var Transaction|null $source */
- $source = $object->transactions()->where('amount', '<', 0)->first();
+ /** @var null|Transaction $source */
+ $source = $object->transactions()->where('amount', '<', 0)->first();
if (null === $source) {
- Log::error('Could not find source transaction.');
+ app('log')->error('Could not find source transaction.');
event(new RuleActionFailedOnArray($this->action, $journal, trans('rules.cannot_find_source_transaction')));
+
return false;
}
// account must not be deleted (in the meantime):
if (null === $source->account) {
- Log::error('Could not find source transaction account.');
+ app('log')->error('Could not find source transaction account.');
event(new RuleActionFailedOnArray($this->action, $journal, trans('rules.cannot_find_source_transaction_account')));
+
return false;
}
- if (null !== $newAccount && (int)$newAccount->id === (int)$source->account_id) {
- Log::error(
+ if (null !== $newAccount && $newAccount->id === $source->account_id) {
+ app('log')->error(
sprintf(
'New destination account ID #%d and current source account ID #%d are the same. Do nothing.',
$newAccount->id,
@@ -115,6 +114,7 @@ class SetDestinationAccount implements ActionInterface
);
event(new RuleActionFailedOnArray($this->action, $journal, trans('rules.already_has_destination', ['name' => $newAccount->name])));
+
return false;
}
@@ -124,39 +124,31 @@ class SetDestinationAccount implements ActionInterface
$newAccount = $this->findWithdrawalDestinationAccount($accountName);
}
- Log::debug(sprintf('New destination account is #%d ("%s").', $newAccount->id, $newAccount->name));
+ app('log')->debug(sprintf('New destination account is #%d ("%s").', $newAccount->id, $newAccount->name));
event(new TriggeredAuditLog($this->action->rule, $object, 'set_destination', null, $newAccount->name));
// update destination transaction with new destination account:
- DB::table('transactions')
+ \DB::table('transactions')
->where('transaction_journal_id', '=', $object->id)
->where('amount', '>', 0)
->update(['account_id' => $newAccount->id]);
- Log::debug(sprintf('Updated journal #%d (group #%d) and gave it new destination account ID.', $object->id, $object->transaction_group_id));
+ app('log')->debug(sprintf('Updated journal #%d (group #%d) and gave it new destination account ID.', $object->id, $object->transaction_group_id));
return true;
}
- /**
- * @param string $type
- *
- * @return Account|null
- */
private function findAssetAccount(string $type, string $accountName): ?Account
{
// switch on type:
$allowed = config(sprintf('firefly.expected_source_types.destination.%s', $type));
$allowed = is_array($allowed) ? $allowed : [];
- Log::debug(sprintf('Check config for expected_source_types.destination.%s, result is', $type), $allowed);
+ app('log')->debug(sprintf('Check config for expected_source_types.destination.%s, result is', $type), $allowed);
return $this->repository->findByName($accountName, $allowed);
}
- /**
- * @return Account
- */
private function findWithdrawalDestinationAccount(string $accountName): Account
{
$allowed = config('firefly.expected_source_types.destination.Withdrawal');
@@ -172,7 +164,7 @@ class SetDestinationAccount implements ActionInterface
];
$account = $this->repository->store($data);
}
- Log::debug(sprintf('Found or created expense account #%d ("%s")', $account->id, $account->name));
+ app('log')->debug(sprintf('Found or created expense account #%d ("%s")', $account->id, $account->name));
return $account;
}
diff --git a/app/TransactionRules/Actions/SetDestinationToCashAccount.php b/app/TransactionRules/Actions/SetDestinationToCashAccount.php
new file mode 100644
index 0000000000..0e21126e16
--- /dev/null
+++ b/app/TransactionRules/Actions/SetDestinationToCashAccount.php
@@ -0,0 +1,120 @@
+.
+ */
+
+declare(strict_types=1);
+
+namespace FireflyIII\TransactionRules\Actions;
+
+use FireflyIII\Events\Model\Rule\RuleActionFailedOnArray;
+use FireflyIII\Events\TriggeredAuditLog;
+use FireflyIII\Models\RuleAction;
+use FireflyIII\Models\Transaction;
+use FireflyIII\Models\TransactionJournal;
+use FireflyIII\Models\TransactionType;
+use FireflyIII\Repositories\Account\AccountRepositoryInterface;
+use FireflyIII\User;
+
+/**
+ * Class SetDestinationToCashAccount
+ */
+class SetDestinationToCashAccount implements ActionInterface
+{
+ private RuleAction $action;
+
+ /**
+ * TriggerInterface constructor.
+ */
+ public function __construct(RuleAction $action)
+ {
+ $this->action = $action;
+ }
+
+ public function actOnArray(array $journal): bool
+ {
+ /** @var User $user */
+ $user = User::find($journal['user_id']);
+
+ /** @var null|TransactionJournal $object */
+ $object = $user->transactionJournals()->find((int)$journal['transaction_journal_id']);
+ $repository = app(AccountRepositoryInterface::class);
+
+ if (null === $object) {
+ app('log')->error('Could not find journal.');
+ event(new RuleActionFailedOnArray($this->action, $journal, trans('rules.no_such_journal')));
+
+ return false;
+ }
+ $type = $object->transactionType->type;
+ if (TransactionType::WITHDRAWAL !== $type) {
+ app('log')->error('Transaction must be withdrawal.');
+ event(new RuleActionFailedOnArray($this->action, $journal, trans('rules.not_withdrawal')));
+
+ return false;
+ }
+
+ // find cash account
+ $repository->setUser($user);
+ $cashAccount = $repository->getCashAccount();
+
+ // new destination account must be different from the current source account:
+ /** @var null|Transaction $source */
+ $source = $object->transactions()->where('amount', '<', 0)->first();
+ if (null === $source) {
+ app('log')->error('Could not find source transaction.');
+ event(new RuleActionFailedOnArray($this->action, $journal, trans('rules.cannot_find_source_transaction')));
+
+ return false;
+ }
+ // account must not be deleted (in the meantime):
+ if (null === $source->account) {
+ app('log')->error('Could not find source transaction account.');
+ event(new RuleActionFailedOnArray($this->action, $journal, trans('rules.cannot_find_source_transaction_account')));
+
+ return false;
+ }
+ if ($cashAccount->id === $source->account_id) {
+ app('log')->error(
+ sprintf(
+ 'New destination account ID #%d and current source account ID #%d are the same. Do nothing.',
+ $cashAccount->id,
+ $source->account_id
+ )
+ );
+
+ event(new RuleActionFailedOnArray($this->action, $journal, trans('rules.already_has_destination', ['name' => $cashAccount->name])));
+
+ return false;
+ }
+
+ event(new TriggeredAuditLog($this->action->rule, $object, 'set_destination', null, $cashAccount->name));
+
+ // update destination transaction with new destination account:
+ \DB::table('transactions')
+ ->where('transaction_journal_id', '=', $object->id)
+ ->where('amount', '>', 0)
+ ->update(['account_id' => $cashAccount->id])
+ ;
+
+ app('log')->debug(sprintf('Updated journal #%d (group #%d) and gave it new destination account ID.', $object->id, $object->transaction_group_id));
+
+ return true;
+ }
+}
diff --git a/app/TransactionRules/Actions/SetNotes.php b/app/TransactionRules/Actions/SetNotes.php
index 28926ba319..8abdf02f8c 100644
--- a/app/TransactionRules/Actions/SetNotes.php
+++ b/app/TransactionRules/Actions/SetNotes.php
@@ -29,20 +29,17 @@ use FireflyIII\Models\Note;
use FireflyIII\Models\RuleAction;
use FireflyIII\Models\TransactionJournal;
use FireflyIII\TransactionRules\Expressions\ActionExpressionEvaluator;
-use Illuminate\Support\Facades\Log;
/**
* Class SetNotes.
*/
class SetNotes implements ActionInterface
{
- private RuleACtion $action;
+ private RuleAction $action;
private ActionExpressionEvaluator $evaluator;
/**
* TriggerInterface constructor.
- *
- * @param RuleAction $action
*/
public function __construct(RuleAction $action, ActionExpressionEvaluator $evaluator)
{
@@ -50,12 +47,9 @@ class SetNotes implements ActionInterface
$this->evaluator = $evaluator;
}
- /**
- * @inheritDoc
- */
public function actOnArray(array $journal): bool
{
- $dbNote = Note::where('noteable_id', $journal['transaction_journal_id'])
+ $dbNote = Note::where('noteable_id', $journal['transaction_journal_id'])
->where('noteable_type', TransactionJournal::class)->first();
if (null === $dbNote) {
$dbNote = new Note();
@@ -68,7 +62,7 @@ class SetNotes implements ActionInterface
$dbNote->text = $newNotes;
$dbNote->save();
- Log::debug(
+ app('log')->debug(
sprintf(
'RuleAction SetNotes changed the notes of journal #%d from "%s" to "%s".',
$journal['transaction_journal_id'],
@@ -78,7 +72,7 @@ class SetNotes implements ActionInterface
);
/** @var TransactionJournal $object */
- $object = TransactionJournal::where('user_id', $journal['user_id'])->find($journal['transaction_journal_id']);
+ $object = TransactionJournal::where('user_id', $journal['user_id'])->find($journal['transaction_journal_id']);
event(new TriggeredAuditLog($this->action->rule, $object, 'update_notes', $oldNotes, $newNotes));
diff --git a/app/TransactionRules/Actions/SetSourceAccount.php b/app/TransactionRules/Actions/SetSourceAccount.php
index 8a2e1c326b..dc195b9d61 100644
--- a/app/TransactionRules/Actions/SetSourceAccount.php
+++ b/app/TransactionRules/Actions/SetSourceAccount.php
@@ -24,7 +24,6 @@ declare(strict_types=1);
namespace FireflyIII\TransactionRules\Actions;
-use DB;
use FireflyIII\Events\Model\Rule\RuleActionFailedOnArray;
use FireflyIII\Events\TriggeredAuditLog;
use FireflyIII\Models\Account;
@@ -35,7 +34,6 @@ use FireflyIII\Models\TransactionType;
use FireflyIII\Repositories\Account\AccountRepositoryInterface;
use FireflyIII\TransactionRules\Expressions\ActionExpressionEvaluator;
use FireflyIII\User;
-use Illuminate\Support\Facades\Log;
/**
* Class SetSourceAccount.
@@ -48,8 +46,6 @@ class SetSourceAccount implements ActionInterface
/**
* TriggerInterface constructor.
- *
- * @param RuleAction $action
*/
public function __construct(RuleAction $action, ActionExpressionEvaluator $evaluator)
{
@@ -57,51 +53,54 @@ class SetSourceAccount implements ActionInterface
$this->evaluator = $evaluator;
}
- /**
- * @inheritDoc
- */
public function actOnArray(array $journal): bool
{
- $user = User::find($journal['user_id']);
- $type = $journal['transaction_type_type'];
- $name = $this->evaluator->evaluate($journal);
- /** @var TransactionJournal|null $object */
+ $accountName = $this->evaluator->evaluate($journal);
+
+ /** @var User $user */
+ $user = User::find($journal['user_id']);
+
+ /** @var null|TransactionJournal $object */
$object = $user->transactionJournals()->find((int)$journal['transaction_journal_id']);
$this->repository = app(AccountRepositoryInterface::class);
if (null === $object) {
- Log::error('Could not find journal.');
+ app('log')->error('Could not find journal.');
event(new RuleActionFailedOnArray($this->action, $journal, trans('rules.no_such_journal')));
+
return false;
}
- $type = $object->transactionType->type;
+ $type = $object->transactionType->type;
$this->repository->setUser($user);
// if this is a transfer or a withdrawal, the new source account must be an asset account or a default account, and it MUST exist:
- $newAccount = $this->findAssetAccount($type, $name);
+ $newAccount = $this->findAssetAccount($type, $accountName);
if ((TransactionType::WITHDRAWAL === $type || TransactionType::TRANSFER === $type) && null === $newAccount) {
- Log::error(
- sprintf('Cant change source account of journal #%d because no asset account with name "%s" exists.', $object->id, $name)
+ app('log')->error(
+ sprintf('Cant change source account of journal #%d because no asset account with name "%s" exists.', $object->id, $accountName)
);
- event(new RuleActionFailedOnArray($this->action, $journal, trans('rules.cannot_find_asset', ['name' => $name])));
+ event(new RuleActionFailedOnArray($this->action, $journal, trans('rules.cannot_find_asset', ['name' => $accountName])));
+
return false;
}
// new source account must be different from the current destination account:
- /** @var Transaction|null $destination */
- $destination = $object->transactions()->where('amount', '>', 0)->first();
+ /** @var null|Transaction $destination */
+ $destination = $object->transactions()->where('amount', '>', 0)->first();
if (null === $destination) {
- Log::error('Could not find destination transaction.');
+ app('log')->error('Could not find destination transaction.');
event(new RuleActionFailedOnArray($this->action, $journal, trans('rules.cannot_find_destination_transaction')));
+
return false;
}
// account must not be deleted (in the meantime):
if (null === $destination->account) {
- Log::error('Could not find destination transaction account.');
+ app('log')->error('Could not find destination transaction account.');
event(new RuleActionFailedOnArray($this->action, $journal, trans('rules.cannot_find_destination_transaction_account')));
+
return false;
}
- if (null !== $newAccount && (int)$newAccount->id === (int)$destination->account_id) {
- Log::error(
+ if (null !== $newAccount && $newAccount->id === $destination->account_id) {
+ app('log')->error(
sprintf(
'New source account ID #%d and current destination account ID #%d are the same. Do nothing.',
$newAccount->id,
@@ -109,48 +108,41 @@ class SetSourceAccount implements ActionInterface
)
);
event(new RuleActionFailedOnArray($this->action, $journal, trans('rules.already_has_source', ['name' => $newAccount->name])));
+
return false;
}
// if this is a deposit, the new source account must be a revenue account and may be created:
// or it's a liability
if (TransactionType::DEPOSIT === $type) {
- $newAccount = $this->findDepositSourceAccount($name);
+ $newAccount = $this->findDepositSourceAccount($accountName);
}
- Log::debug(sprintf('New source account is #%d ("%s").', $newAccount->id, $newAccount->name));
+ app('log')->debug(sprintf('New source account is #%d ("%s").', $newAccount->id, $newAccount->name));
// update source transaction with new source account:
- DB::table('transactions')
+ \DB::table('transactions')
->where('transaction_journal_id', '=', $object->id)
->where('amount', '<', 0)
->update(['account_id' => $newAccount->id]);
event(new TriggeredAuditLog($this->action->rule, $object, 'set_source', null, $newAccount->name));
- Log::debug(sprintf('Updated journal #%d (group #%d) and gave it new source account ID.', $object->id, $object->transaction_group_id));
+ app('log')->debug(sprintf('Updated journal #%d (group #%d) and gave it new source account ID.', $object->id, $object->transaction_group_id));
return true;
}
- /**
- * @param string $type
- *
- * @return Account|null
- */
private function findAssetAccount(string $type, string $name): ?Account
{
// switch on type:
$allowed = config(sprintf('firefly.expected_source_types.source.%s', $type));
$allowed = is_array($allowed) ? $allowed : [];
- Log::debug(sprintf('Check config for expected_source_types.source.%s, result is', $type), $allowed);
+ app('log')->debug(sprintf('Check config for expected_source_types.source.%s, result is', $type), $allowed);
return $this->repository->findByName($name, $allowed);
}
- /**
- * @return Account
- */
private function findDepositSourceAccount(string $name): Account
{
$allowed = config('firefly.expected_source_types.source.Deposit');
@@ -167,7 +159,7 @@ class SetSourceAccount implements ActionInterface
];
$account = $this->repository->store($data);
}
- Log::debug(sprintf('Found or created revenue account #%d ("%s")', $account->id, $account->name));
+ app('log')->debug(sprintf('Found or created revenue account #%d ("%s")', $account->id, $account->name));
return $account;
}
diff --git a/app/TransactionRules/Actions/SetSourceToCashAccount.php b/app/TransactionRules/Actions/SetSourceToCashAccount.php
new file mode 100644
index 0000000000..f8a4b91565
--- /dev/null
+++ b/app/TransactionRules/Actions/SetSourceToCashAccount.php
@@ -0,0 +1,120 @@
+.
+ */
+
+declare(strict_types=1);
+
+namespace FireflyIII\TransactionRules\Actions;
+
+use FireflyIII\Events\Model\Rule\RuleActionFailedOnArray;
+use FireflyIII\Events\TriggeredAuditLog;
+use FireflyIII\Models\RuleAction;
+use FireflyIII\Models\Transaction;
+use FireflyIII\Models\TransactionJournal;
+use FireflyIII\Models\TransactionType;
+use FireflyIII\Repositories\Account\AccountRepositoryInterface;
+use FireflyIII\User;
+
+/**
+ * Class SetSourceToCashAccount
+ */
+class SetSourceToCashAccount implements ActionInterface
+{
+ private RuleAction $action;
+
+ /**
+ * TriggerInterface constructor.
+ */
+ public function __construct(RuleAction $action)
+ {
+ $this->action = $action;
+ }
+
+ public function actOnArray(array $journal): bool
+ {
+ /** @var User $user */
+ $user = User::find($journal['user_id']);
+
+ /** @var null|TransactionJournal $object */
+ $object = $user->transactionJournals()->find((int)$journal['transaction_journal_id']);
+ $repository = app(AccountRepositoryInterface::class);
+
+ if (null === $object) {
+ app('log')->error('Could not find journal.');
+ event(new RuleActionFailedOnArray($this->action, $journal, trans('rules.no_such_journal')));
+
+ return false;
+ }
+ $type = $object->transactionType->type;
+ if (TransactionType::DEPOSIT !== $type) {
+ app('log')->error('Transaction must be deposit.');
+ event(new RuleActionFailedOnArray($this->action, $journal, trans('rules.not_deposit')));
+
+ return false;
+ }
+
+ // find cash account
+ $repository->setUser($user);
+ $cashAccount = $repository->getCashAccount();
+
+ // new source account must be different from the current destination account:
+ /** @var null|Transaction $destination */
+ $destination = $object->transactions()->where('amount', '>', 0)->first();
+ if (null === $destination) {
+ app('log')->error('Could not find destination transaction.');
+ event(new RuleActionFailedOnArray($this->action, $journal, trans('rules.cannot_find_destination_transaction')));
+
+ return false;
+ }
+ // account must not be deleted (in the meantime):
+ if (null === $destination->account) {
+ app('log')->error('Could not find destination transaction account.');
+ event(new RuleActionFailedOnArray($this->action, $journal, trans('rules.cannot_find_destination_transaction_account')));
+
+ return false;
+ }
+ if ($cashAccount->id === $destination->account_id) {
+ app('log')->error(
+ sprintf(
+ 'New source account ID #%d and current destination account ID #%d are the same. Do nothing.',
+ $cashAccount->id,
+ $destination->account_id
+ )
+ );
+
+ event(new RuleActionFailedOnArray($this->action, $journal, trans('rules.already_has_source', ['name' => $cashAccount->name])));
+
+ return false;
+ }
+
+ event(new TriggeredAuditLog($this->action->rule, $object, 'set_source', null, $cashAccount->name));
+
+ // update destination transaction with new destination account:
+ \DB::table('transactions')
+ ->where('transaction_journal_id', '=', $object->id)
+ ->where('amount', '<', 0)
+ ->update(['account_id' => $cashAccount->id])
+ ;
+
+ app('log')->debug(sprintf('Updated journal #%d (group #%d) and gave it new source account ID.', $object->id, $object->transaction_group_id));
+
+ return true;
+ }
+}
diff --git a/app/TransactionRules/Actions/SwitchAccounts.php b/app/TransactionRules/Actions/SwitchAccounts.php
index 29d71b6bcc..e7df491e32 100644
--- a/app/TransactionRules/Actions/SwitchAccounts.php
+++ b/app/TransactionRules/Actions/SwitchAccounts.php
@@ -23,17 +23,14 @@ declare(strict_types=1);
namespace FireflyIII\TransactionRules\Actions;
-use DB;
use FireflyIII\Events\Model\Rule\RuleActionFailedOnArray;
use FireflyIII\Events\TriggeredAuditLog;
use FireflyIII\Models\RuleAction;
use FireflyIII\Models\Transaction;
use FireflyIII\Models\TransactionJournal;
use FireflyIII\Models\TransactionType;
-use Illuminate\Support\Facades\Log;
/**
- *
* Class SwitchAccounts
*/
class SwitchAccounts implements ActionInterface
@@ -42,51 +39,51 @@ class SwitchAccounts implements ActionInterface
/**
* TriggerInterface constructor.
- *
- * @param RuleAction $action
*/
public function __construct(RuleAction $action)
{
$this->action = $action;
}
- /**
- * @inheritDoc
- */
public function actOnArray(array $journal): bool
{
// make object from array (so the data is fresh).
- /** @var TransactionJournal|null $object */
- $object = TransactionJournal::where('user_id', $journal['user_id'])->find($journal['transaction_journal_id']);
+ /** @var null|TransactionJournal $object */
+ $object = TransactionJournal::where('user_id', $journal['user_id'])->find($journal['transaction_journal_id']);
if (null === $object) {
- Log::error(sprintf('Cannot find journal #%d, cannot switch accounts.', $journal['transaction_journal_id']));
+ app('log')->error(sprintf('Cannot find journal #%d, cannot switch accounts.', $journal['transaction_journal_id']));
event(new RuleActionFailedOnArray($this->action, $journal, trans('rules.no_such_journal')));
+
return false;
}
- $groupCount = TransactionJournal::where('transaction_group_id', $journal['transaction_group_id'])->count();
+ $groupCount = TransactionJournal::where('transaction_group_id', $journal['transaction_group_id'])->count();
if ($groupCount > 1) {
- Log::error(sprintf('Group #%d has more than one transaction in it, cannot switch accounts.', $journal['transaction_group_id']));
+ app('log')->error(sprintf('Group #%d has more than one transaction in it, cannot switch accounts.', $journal['transaction_group_id']));
event(new RuleActionFailedOnArray($this->action, $journal, trans('rules.split_group')));
+
return false;
}
- $type = $object->transactionType->type;
+ $type = $object->transactionType->type;
if (TransactionType::TRANSFER !== $type) {
- Log::error(sprintf('Journal #%d is NOT a transfer (rule #%d), cannot switch accounts.', $journal['transaction_journal_id'], $this->action->rule_id));
+ app('log')->error(sprintf('Journal #%d is NOT a transfer (rule #%d), cannot switch accounts.', $journal['transaction_journal_id'], $this->action->rule_id));
event(new RuleActionFailedOnArray($this->action, $journal, trans('rules.is_not_transfer')));
+
return false;
}
- /** @var Transaction $sourceTransaction */
- $sourceTransaction = $object->transactions()->where('amount', '<', 0)->first();
- /** @var Transaction $destTransaction */
- $destTransaction = $object->transactions()->where('amount', '>', 0)->first();
+ /** @var null|Transaction $sourceTransaction */
+ $sourceTransaction = $object->transactions()->where('amount', '<', 0)->first();
+
+ /** @var null|Transaction $destTransaction */
+ $destTransaction = $object->transactions()->where('amount', '>', 0)->first();
if (null === $sourceTransaction || null === $destTransaction) {
- Log::error(sprintf('Journal #%d has no source or destination transaction (rule #%d), cannot switch accounts.', $journal['transaction_journal_id'], $this->action->rule_id));
+ app('log')->error(sprintf('Journal #%d has no source or destination transaction (rule #%d), cannot switch accounts.', $journal['transaction_journal_id'], $this->action->rule_id));
event(new RuleActionFailedOnArray($this->action, $journal, trans('rules.cannot_find_accounts')));
+
return false;
}
- $sourceAccountId = (int)$sourceTransaction->account_id;
+ $sourceAccountId = $sourceTransaction->account_id;
$destinationAccountId = $destTransaction->account_id;
$sourceTransaction->account_id = $destinationAccountId;
$destTransaction->account_id = $sourceAccountId;
diff --git a/app/TransactionRules/Actions/UpdatePiggybank.php b/app/TransactionRules/Actions/UpdatePiggybank.php
index faab1c7f6c..82061f9b10 100644
--- a/app/TransactionRules/Actions/UpdatePiggybank.php
+++ b/app/TransactionRules/Actions/UpdatePiggybank.php
@@ -30,11 +30,9 @@ use FireflyIII\Models\PiggyBank;
use FireflyIII\Models\RuleAction;
use FireflyIII\Models\Transaction;
use FireflyIII\Models\TransactionJournal;
-use FireflyIII\Models\TransactionType;
use FireflyIII\Repositories\PiggyBank\PiggyBankRepositoryInterface;
use FireflyIII\TransactionRules\Expressions\ActionExpressionEvaluator;
use FireflyIII\User;
-use Illuminate\Support\Facades\Log;
/**
* Class UpdatePiggybank
@@ -46,8 +44,6 @@ class UpdatePiggybank implements ActionInterface
/**
* TriggerInterface constructor.
- *
- * @param RuleAction $action
*/
public function __construct(RuleAction $action, ActionExpressionEvaluator $evaluator)
{
@@ -55,38 +51,38 @@ class UpdatePiggybank implements ActionInterface
$this->evaluator = $evaluator;
}
- /**
- * @inheritDoc
- */
public function actOnArray(array $journal): bool
{
- Log::debug(sprintf('Triggered rule action UpdatePiggybank on journal #%d', $journal['transaction_journal_id']));
+ app('log')->debug(sprintf('Triggered rule action UpdatePiggybank on journal #%d', $journal['transaction_journal_id']));
$piggyBankName = $this->evaluator->evaluate($journal);
// refresh the transaction type.
- $user = User::find($journal['user_id']);
- /** @var TransactionJournal $journalObj */
- $journalObj = $user->transactionJournals()->find($journal['transaction_journal_id']);
- $type = TransactionType::find((int)$journalObj->transaction_type_id);
+ /** @var User $user */
+ $user = User::find($journal['user_id']);
- $piggyBank = $this->findPiggyBank($user, $piggyBankName);
+ /** @var TransactionJournal $journalObj */
+ $journalObj = $user->transactionJournals()->find($journal['transaction_journal_id']);
+
+ $piggyBank = $this->findPiggyBank($user, $piggyBankName);
if (null === $piggyBank) {
- Log::info(
+ app('log')->info(
sprintf('No piggy bank named "%s", cant execute action #%d of rule #%d', $piggyBankName, $this->action->id, $this->action->rule_id)
);
event(new RuleActionFailedOnArray($this->action, $journal, trans('rules.cannot_find_piggy', ['name' => $piggyBankName])));
+
return false;
}
- Log::debug(sprintf('Found piggy bank #%d ("%s")', $piggyBank->id, $piggyBank->name));
+ app('log')->debug(sprintf('Found piggy bank #%d ("%s")', $piggyBank->id, $piggyBank->name));
/** @var Transaction $source */
- $source = $journalObj->transactions()->where('amount', '<', 0)->first();
+ $source = $journalObj->transactions()->where('amount', '<', 0)->first();
+
/** @var Transaction $destination */
$destination = $journalObj->transactions()->where('amount', '>', 0)->first();
- if ((int)$source->account_id === (int)$piggyBank->account_id) {
- Log::debug('Piggy bank account is linked to source, so remove amount from piggy bank.');
+ if ($source->account_id === $piggyBank->account_id) {
+ app('log')->debug('Piggy bank account is linked to source, so remove amount from piggy bank.');
$this->removeAmount($piggyBank, $journalObj, $destination->amount);
event(
@@ -106,8 +102,8 @@ class UpdatePiggybank implements ActionInterface
return true;
}
- if ((int)$destination->account_id === (int)$piggyBank->account_id) {
- Log::debug('Piggy bank account is linked to source, so add amount to piggy bank.');
+ if ($destination->account_id === $piggyBank->account_id) {
+ app('log')->debug('Piggy bank account is linked to source, so add amount to piggy bank.');
$this->addAmount($piggyBank, $journalObj, $destination->amount);
event(
@@ -127,7 +123,7 @@ class UpdatePiggybank implements ActionInterface
return true;
}
- Log::info(
+ app('log')->info(
sprintf(
'Piggy bank is not linked to source ("#%d") or destination ("#%d"), so no action will be taken.',
$source->account_id,
@@ -135,38 +131,27 @@ class UpdatePiggybank implements ActionInterface
)
);
event(new RuleActionFailedOnArray($this->action, $journal, trans('rules.no_link_piggy', ['name' => $piggyBankName])));
+
return false;
}
- /**
- * @param User $user
- *
- * @return PiggyBank|null
- */
private function findPiggyBank(User $user, string $name): ?PiggyBank
{
return $user->piggyBanks()->where('piggy_banks.name', $name)->first();
}
- /**
- * @param PiggyBank $piggyBank
- * @param TransactionJournal $journal
- * @param string $amount
- *
- * @return void
- */
private function removeAmount(PiggyBank $piggyBank, TransactionJournal $journal, string $amount): void
{
$repository = app(PiggyBankRepositoryInterface::class);
$repository->setUser($journal->user);
// how much can we remove from this piggy bank?
- $toRemove = $repository->getCurrentAmount($piggyBank);
- Log::debug(sprintf('Amount is %s, max to remove is %s', $amount, $toRemove));
+ $toRemove = $repository->getCurrentAmount($piggyBank);
+ app('log')->debug(sprintf('Amount is %s, max to remove is %s', $amount, $toRemove));
// if $amount is bigger than $toRemove, shrink it.
- $amount = -1 === bccomp($amount, $toRemove) ? $amount : $toRemove;
- Log::debug(sprintf('Amount is now %s', $amount));
+ $amount = -1 === bccomp($amount, $toRemove) ? $amount : $toRemove;
+ app('log')->debug(sprintf('Amount is now %s', $amount));
// if amount is zero, stop.
if (0 === bccomp('0', $amount)) {
@@ -181,18 +166,11 @@ class UpdatePiggybank implements ActionInterface
return;
}
- Log::debug(sprintf('Will now remove %s from piggy bank.', $amount));
+ app('log')->debug(sprintf('Will now remove %s from piggy bank.', $amount));
$repository->removeAmount($piggyBank, $amount, $journal);
}
- /**
- * @param PiggyBank $piggyBank
- * @param TransactionJournal $journal
- * @param string $amount
- *
- * @return void
- */
private function addAmount(PiggyBank $piggyBank, TransactionJournal $journal, string $amount): void
{
$repository = app(PiggyBankRepositoryInterface::class);
@@ -200,18 +178,17 @@ class UpdatePiggybank implements ActionInterface
// how much can we add to the piggy bank?
if (0 !== bccomp($piggyBank->targetamount, '0')) {
- $toAdd = bcsub($piggyBank->targetamount, $repository->getCurrentAmount($piggyBank));
- Log::debug(sprintf('Max amount to add to piggy bank is %s, amount is %s', $toAdd, $amount));
+ $toAdd = bcsub($piggyBank->targetamount, $repository->getCurrentAmount($piggyBank));
+ app('log')->debug(sprintf('Max amount to add to piggy bank is %s, amount is %s', $toAdd, $amount));
// update amount to fit:
$amount = -1 === bccomp($amount, $toAdd) ? $amount : $toAdd;
- Log::debug(sprintf('Amount is now %s', $amount));
+ app('log')->debug(sprintf('Amount is now %s', $amount));
}
if (0 === bccomp($piggyBank->targetamount, '0')) {
- Log::debug('Target amount is zero, can add anything.');
+ app('log')->debug('Target amount is zero, can add anything.');
}
-
// if amount is zero, stop.
if (0 === bccomp('0', $amount)) {
app('log')->warning('Amount left is zero, stop.');
@@ -225,7 +202,7 @@ class UpdatePiggybank implements ActionInterface
return;
}
- Log::debug(sprintf('Will now add %s to piggy bank.', $amount));
+ app('log')->debug(sprintf('Will now add %s to piggy bank.', $amount));
$repository->addAmount($piggyBank, $amount, $journal);
}
diff --git a/app/TransactionRules/Engine/RuleEngineInterface.php b/app/TransactionRules/Engine/RuleEngineInterface.php
index 687abf7627..3530bc4387 100644
--- a/app/TransactionRules/Engine/RuleEngineInterface.php
+++ b/app/TransactionRules/Engine/RuleEngineInterface.php
@@ -33,8 +33,6 @@ interface RuleEngineInterface
{
/**
* Add operators added to each search by the rule engine.
- *
- * @param array $operator
*/
public function addOperator(array $operator): void;
@@ -50,34 +48,20 @@ interface RuleEngineInterface
/**
* Return the number of changed transactions from the previous "fire" action.
- *
- * @return int
*/
public function getResults(): int;
- /**
- * @param bool $refreshTriggers
- *
- * @return void
- */
public function setRefreshTriggers(bool $refreshTriggers): void;
/**
* Add entire rule groups for the engine to execute.
- *
- * @param Collection $ruleGroups
*/
public function setRuleGroups(Collection $ruleGroups): void;
/**
* Add rules for the engine to execute.
- *
- * @param Collection $rules
*/
public function setRules(Collection $rules): void;
- /**
- * @param User $user
- */
public function setUser(User $user): void;
}
diff --git a/app/TransactionRules/Engine/SearchRuleEngine.php b/app/TransactionRules/Engine/SearchRuleEngine.php
index cb7ffa47b0..45733171a4 100644
--- a/app/TransactionRules/Engine/SearchRuleEngine.php
+++ b/app/TransactionRules/Engine/SearchRuleEngine.php
@@ -35,7 +35,6 @@ use FireflyIII\Support\Search\SearchInterface;
use FireflyIII\TransactionRules\Factory\ActionFactory;
use FireflyIII\User;
use Illuminate\Support\Collection;
-use Illuminate\Support\Facades\Log;
/**
* Class SearchRuleEngine
@@ -51,33 +50,27 @@ class SearchRuleEngine implements RuleEngineInterface
public function __construct()
{
- $this->rules = new Collection();
- $this->groups = new Collection();
- $this->operators = [];
- $this->resultCount = [];
+ $this->rules = new Collection();
+ $this->groups = new Collection();
+ $this->operators = [];
+ $this->resultCount = [];
// always collect the triggers from the database, unless indicated otherwise.
$this->refreshTriggers = true;
}
- /**
- * @inheritDoc
- */
public function addOperator(array $operator): void
{
- Log::debug('Add extra operator: ', $operator);
+ app('log')->debug('Add extra operator: ', $operator);
$this->operators[] = $operator;
}
- /**
- *
- */
public function find(): Collection
{
- Log::debug('SearchRuleEngine::find()');
+ app('log')->debug('SearchRuleEngine::find()');
$collection = new Collection();
foreach ($this->rules as $rule) {
- $found = new Collection();
+ $found = new Collection();
if (true === $rule->strict) {
$found = $this->findStrictRule($rule);
}
@@ -92,16 +85,12 @@ class SearchRuleEngine implements RuleEngineInterface
/**
* Finds the transactions a strict rule will execute on.
- *
- * @param Rule $rule
- *
- * @return Collection
*/
private function findStrictRule(Rule $rule): Collection
{
- Log::debug(sprintf('Now in findStrictRule(#%d)', $rule->id ?? 0));
- $searchArray = [];
- $triggers = [];
+ app('log')->debug(sprintf('Now in findStrictRule(#%d)', $rule->id ?? 0));
+ $searchArray = [];
+ $triggers = [];
if ($this->refreshTriggers) {
$triggers = $rule->ruleTriggers()->orderBy('order', 'ASC')->get();
}
@@ -115,42 +104,44 @@ class SearchRuleEngine implements RuleEngineInterface
continue;
}
- // if needs no context, value is different:
- $needsContext = config(sprintf('search.operators.%s.needs_context', $ruleTrigger->trigger_type)) ?? true;
+ // if the trigger needs no context, value is different:
+ $needsContext = (bool)(config(sprintf('search.operators.%s.needs_context', $ruleTrigger->trigger_type)) ?? true);
if (false === $needsContext) {
- Log::debug(sprintf('SearchRuleEngine:: add a rule trigger: %s:true', $ruleTrigger->trigger_type));
+ app('log')->debug(sprintf('SearchRuleEngine:: add a rule trigger (no context): %s:true', $ruleTrigger->trigger_type));
$searchArray[$ruleTrigger->trigger_type][] = 'true';
}
if (true === $needsContext) {
- Log::debug(sprintf('SearchRuleEngine:: add a rule trigger: %s:"%s"', $ruleTrigger->trigger_type, $ruleTrigger->trigger_value));
+ app('log')->debug(sprintf('SearchRuleEngine:: add a rule trigger (context): %s:"%s"', $ruleTrigger->trigger_type, $ruleTrigger->trigger_value));
$searchArray[$ruleTrigger->trigger_type][] = sprintf('"%s"', $ruleTrigger->trigger_value);
}
}
-
// add local operators:
foreach ($this->operators as $operator) {
- Log::debug(sprintf('SearchRuleEngine:: add local added operator: %s:"%s"', $operator['type'], $operator['value']));
+ app('log')->debug(sprintf('SearchRuleEngine:: add local added operator: %s:"%s"', $operator['type'], $operator['value']));
$searchArray[$operator['type']][] = sprintf('"%s"', $operator['value']);
}
- $date = today(config('app.timezone'));
+ $date = today(config('app.timezone'));
if ($this->hasSpecificJournalTrigger($searchArray)) {
$date = $this->setDateFromJournalTrigger($searchArray);
}
+
// build and run the search engine.
$searchEngine = app(SearchInterface::class);
$searchEngine->setUser($this->user);
$searchEngine->setPage(1);
$searchEngine->setLimit(31337);
$searchEngine->setDate($date);
-
+ app('log')->debug('Search array', $searchArray);
foreach ($searchArray as $type => $searches) {
foreach ($searches as $value) {
- $searchEngine->parseQuery(sprintf('%s:%s', $type, $value));
+ $query = sprintf('%s:%s', $type, $value);
+ app('log')->debug(sprintf('SearchRuleEngine:: add query "%s"', $query));
+ $searchEngine->parseQuery($query);
}
}
- $result = $searchEngine->searchTransactions();
+ $result = $searchEngine->searchTransactions();
return $result->getCollection();
}
@@ -159,113 +150,104 @@ class SearchRuleEngine implements RuleEngineInterface
* Search in the triggers of this particular search and if it contains
* one search operator for "journal_id" it means the date ranges
* in the search may need to be updated.
- *
- * @param array $array
- *
- * @return bool
*/
private function hasSpecificJournalTrigger(array $array): bool
{
- Log::debug('Now in hasSpecificJournalTrigger.');
+ app('log')->debug('Now in hasSpecificJournalTrigger.');
$journalTrigger = false;
$dateTrigger = false;
foreach ($array as $triggerName => $values) {
if ('journal_id' === $triggerName && is_array($values) && 1 === count($values)) {
- Log::debug('Found a journal_id trigger with 1 journal, true.');
+ app('log')->debug('Found a journal_id trigger with 1 journal, true.');
$journalTrigger = true;
}
if (in_array($triggerName, ['date_is', 'date', 'on', 'date_before', 'before', 'date_after', 'after'], true)) {
- Log::debug('Found a date related trigger, set to true.');
+ app('log')->debug('Found a date related trigger, set to true.');
$dateTrigger = true;
}
}
- $result = $journalTrigger && $dateTrigger;
- Log::debug(sprintf('Result of hasSpecificJournalTrigger is %s.', var_export($result, true)));
+ $result = $journalTrigger && $dateTrigger;
+ app('log')->debug(sprintf('Result of hasSpecificJournalTrigger is %s.', var_export($result, true)));
return $result;
}
- /**
- * @param array $array
- *
- * @return Carbon
- */
private function setDateFromJournalTrigger(array $array): Carbon
{
- Log::debug('Now in setDateFromJournalTrigger()');
+ app('log')->debug('Now in setDateFromJournalTrigger()');
$journalId = 0;
foreach ($array as $triggerName => $values) {
if ('journal_id' === $triggerName && is_array($values) && 1 === count($values)) {
- $journalId = (int)trim(($values[0] ?? '"0"'), '"'); // follows format "123".
- Log::debug(sprintf('Found journal ID #%d', $journalId));
+ $journalId = (int)trim($values[0] ?? '"0"', '"'); // follows format "123".
+ app('log')->debug(sprintf('Found journal ID #%d', $journalId));
}
}
if (0 !== $journalId) {
$repository = app(JournalRepositoryInterface::class);
$repository->setUser($this->user);
- $journal = $repository->find($journalId);
+ $journal = $repository->find($journalId);
if (null !== $journal) {
$date = $journal->date;
- Log::debug(sprintf('Found journal #%d with date %s.', $journal->id, $journal->date->format('Y-m-d')));
+ app('log')->debug(sprintf('Found journal #%d with date %s.', $journal->id, $journal->date->format('Y-m-d')));
return $date;
}
}
- Log::debug('Found no journal, return default date.');
+ app('log')->debug('Found no journal, return default date.');
return today(config('app.timezone'));
}
- /**
- * @inheritDoc
- */
public function setUser(User $user): void
{
$this->user = $user;
$this->operators = [];
}
- /**
- * @param Rule $rule
- *
- * @return Collection
- */
private function findNonStrictRule(Rule $rule): Collection
{
+ app('log')->debug(sprintf('findNonStrictRule(#%d)', $rule->id));
// start a search query for individual each trigger:
$total = new Collection();
$count = 0;
$triggers = [];
if ($this->refreshTriggers) {
+ app('log')->debug('Will refresh triggers.');
$triggers = $rule->ruleTriggers()->orderBy('order', 'ASC')->get();
}
if (!$this->refreshTriggers) {
+ app('log')->debug('Will not refresh triggers.');
$triggers = $rule->ruleTriggers;
}
+ app('log')->debug(sprintf('Will run %d trigger(s).', count($triggers)));
/** @var RuleTrigger $ruleTrigger */
foreach ($triggers as $ruleTrigger) {
+ app('log')->debug(sprintf('Now at rule trigger #%d: %s:"%s" (%s).', $ruleTrigger->id, $ruleTrigger->trigger_type, $ruleTrigger->trigger_value, var_export($ruleTrigger->stop_processing, true)));
if (false === $ruleTrigger->active) {
+ app('log')->debug('Trigger is not active, continue.');
+
continue;
}
if ('user_action' === $ruleTrigger->trigger_type) {
- Log::debug('Skip trigger type.');
+ app('log')->debug('Skip trigger type. continue.');
+
continue;
}
$searchArray = [];
$needsContext = config(sprintf('search.operators.%s.needs_context', $ruleTrigger->trigger_type)) ?? true;
if (false === $needsContext) {
- Log::debug(sprintf('SearchRuleEngine:: non strict, will search for: %s:true', $ruleTrigger->trigger_type));
+ app('log')->debug(sprintf('SearchRuleEngine:: non strict, will search for: %s:true', $ruleTrigger->trigger_type));
$searchArray[$ruleTrigger->trigger_type] = 'true';
}
if (true === $needsContext) {
- Log::debug(sprintf('SearchRuleEngine:: non strict, will search for: %s:"%s"', $ruleTrigger->trigger_type, $ruleTrigger->trigger_value));
+ app('log')->debug(sprintf('SearchRuleEngine:: non strict, will search for: %s:"%s"', $ruleTrigger->trigger_type, $ruleTrigger->trigger_value));
$searchArray[$ruleTrigger->trigger_type] = sprintf('"%s"', $ruleTrigger->trigger_value);
}
// then, add local operators as well:
foreach ($this->operators as $operator) {
- Log::debug(sprintf('SearchRuleEngine:: add local added operator: %s:"%s"', $operator['type'], $operator['value']));
+ app('log')->debug(sprintf('SearchRuleEngine:: add local added operator: %s:"%s"', $operator['type'], $operator['value']));
$searchArray[$operator['type']] = sprintf('"%s"', $operator['value']);
}
@@ -279,87 +261,97 @@ class SearchRuleEngine implements RuleEngineInterface
$searchEngine->parseQuery(sprintf('%s:%s', $type, $value));
}
- $result = $searchEngine->searchTransactions();
- $collection = $result->getCollection();
- Log::debug(sprintf('Found in this run, %d transactions', $collection->count()));
- $total = $total->merge($collection);
- Log::debug(sprintf('Total collection is now %d transactions', $total->count()));
- $count++;
+ $result = $searchEngine->searchTransactions();
+ $collection = $result->getCollection();
+ app('log')->debug(sprintf('Found in this run, %d transactions', $collection->count()));
+ $total = $total->merge($collection);
+ app('log')->debug(sprintf('Total collection is now %d transactions', $total->count()));
+ ++$count;
+ // if trigger says stop processing, do so.
+ if ($ruleTrigger->stop_processing && $result->count() > 0) {
+ app('log')->debug('The trigger says to stop processing, so stop processing other triggers.');
+
+ break;
+ }
}
- Log::debug(sprintf('Total collection is now %d transactions', $total->count()));
- Log::debug(sprintf('Done running %d trigger(s)', $count));
+ app('log')->debug(sprintf('Total collection is now %d transactions', $total->count()));
+ app('log')->debug(sprintf('Done running %d trigger(s)', $count));
// make collection unique
- $unique = $total->unique(
- function (array $group) {
+ $unique = $total->unique(
+ static function (array $group) {
$str = '';
foreach ($group['transactions'] as $transaction) {
$str = sprintf('%s%d', $str, $transaction['transaction_journal_id']);
}
- $key = sprintf('%d%s', $group['id'], $str);
- //Log::debug(sprintf('Return key: %s ', $key));
- return $key;
+ return sprintf('%d%s', $group['id'], $str);
+ // app('log')->debug(sprintf('Return key: %s ', $key));
}
);
- Log::debug(sprintf('SearchRuleEngine:: Found %d transactions using search engine.', $unique->count()));
+ app('log')->debug(sprintf('SearchRuleEngine:: Found %d transactions using search engine.', $unique->count()));
return $unique;
}
/**
- * @inheritDoc
* @throws FireflyException
*/
public function fire(): void
{
$this->resultCount = [];
- Log::debug('SearchRuleEngine::fire()!');
+ app('log')->debug('SearchRuleEngine::fire()!');
// if rules and no rule groups, file each rule separately.
if (0 !== $this->rules->count()) {
- Log::debug(sprintf('SearchRuleEngine:: found %d rule(s) to fire.', $this->rules->count()));
+ app('log')->debug(sprintf('SearchRuleEngine:: found %d rule(s) to fire.', $this->rules->count()));
+
+ /** @var Rule $rule */
foreach ($this->rules as $rule) {
- $this->fireRule($rule);
+ $result = $this->fireRule($rule);
+ if (true === $result && $rule->stop_processing) {
+ app('log')->debug(sprintf('Rule #%d has triggered and executed, but calls to stop processing. Since not in the context of a group, do not stop.', $rule->id));
+ }
+ if (false === $result && $rule->stop_processing) {
+ app('log')->debug(sprintf('Rule #%d has triggered and changed nothing, but calls to stop processing. Do not stop.', $rule->id));
+ }
}
- Log::debug('SearchRuleEngine:: done processing all rules!');
+ app('log')->debug('SearchRuleEngine:: done processing all rules!');
return;
}
if (0 !== $this->groups->count()) {
- Log::debug(sprintf('SearchRuleEngine:: found %d rule group(s) to fire.', $this->groups->count()));
+ app('log')->debug(sprintf('SearchRuleEngine:: found %d rule group(s) to fire.', $this->groups->count()));
+
// fire each group:
/** @var RuleGroup $group */
foreach ($this->groups as $group) {
$this->fireGroup($group);
}
}
- Log::debug('SearchRuleEngine:: done processing all rules!');
+ app('log')->debug('SearchRuleEngine:: done processing all rules!');
}
/**
* Returns true if the rule has been triggered.
*
- * @param Rule $rule
- *
- * @return bool
* @throws FireflyException
*/
private function fireRule(Rule $rule): bool
{
- Log::debug(sprintf('Now going to fire rule #%d', $rule->id));
+ app('log')->debug(sprintf('Now going to fire rule #%d', $rule->id));
if (false === $rule->active) {
- Log::debug(sprintf('Rule #%d is not active!', $rule->id));
+ app('log')->debug(sprintf('Rule #%d is not active!', $rule->id));
return false;
}
if (true === $rule->strict) {
- Log::debug(sprintf('Rule #%d is a strict rule.', $rule->id));
+ app('log')->debug(sprintf('Rule #%d is a strict rule.', $rule->id));
return $this->fireStrictRule($rule);
}
- Log::debug(sprintf('Rule #%d is not strict rule.', $rule->id));
+ app('log')->debug(sprintf('Rule #%d is not strict rule.', $rule->id));
return $this->fireNonStrictRule($rule);
}
@@ -367,39 +359,34 @@ class SearchRuleEngine implements RuleEngineInterface
/**
* Return true if the rule is fired (the collection is larger than zero).
*
- * @param Rule $rule
- *
- * @return bool
* @throws FireflyException
*/
private function fireStrictRule(Rule $rule): bool
{
- Log::debug(sprintf('SearchRuleEngine::fireStrictRule(%d)!', $rule->id));
+ app('log')->debug(sprintf('SearchRuleEngine::fireStrictRule(%d)!', $rule->id));
$collection = $this->findStrictRule($rule);
$this->processResults($rule, $collection);
- Log::debug(sprintf('SearchRuleEngine:: done processing strict rule #%d', $rule->id));
+ app('log')->debug(sprintf('SearchRuleEngine:: done processing strict rule #%d', $rule->id));
- $result = $collection->count() > 0;
+ $result = $collection->count() > 0;
if (true === $result) {
- Log::debug(sprintf('SearchRuleEngine:: rule #%d was triggered (on %d transaction(s)).', $rule->id, $collection->count()));
+ app('log')->debug(sprintf('SearchRuleEngine:: rule #%d was triggered (on %d transaction(s)).', $rule->id, $collection->count()));
return true;
}
- Log::debug(sprintf('SearchRuleEngine:: rule #%d was not triggered (on %d transaction(s)).', $rule->id, $collection->count()));
+ app('log')->debug(sprintf('SearchRuleEngine:: rule #%d was not triggered (on %d transaction(s)).', $rule->id, $collection->count()));
return false;
}
/**
- * @param Rule $rule
- * @param Collection $collection
- *
* @throws FireflyException
*/
private function processResults(Rule $rule, Collection $collection): void
{
- Log::debug(sprintf('SearchRuleEngine:: Going to process %d results.', $collection->count()));
+ app('log')->debug(sprintf('SearchRuleEngine:: Going to process %d results.', $collection->count()));
+
/** @var array $group */
foreach ($collection as $group) {
$this->processTransactionGroup($rule, $group);
@@ -407,14 +394,12 @@ class SearchRuleEngine implements RuleEngineInterface
}
/**
- * @param Rule $rule
- * @param array $group
- *
* @throws FireflyException
*/
private function processTransactionGroup(Rule $rule, array $group): void
{
- Log::debug(sprintf('SearchRuleEngine:: Will now execute actions on transaction group #%d', $group['id']));
+ app('log')->debug(sprintf('SearchRuleEngine:: Will now execute actions on transaction group #%d', $group['id']));
+
/** @var array $transaction */
foreach ($group['transactions'] as $transaction) {
$this->processTransactionJournal($rule, $transaction);
@@ -422,15 +407,13 @@ class SearchRuleEngine implements RuleEngineInterface
}
/**
- * @param Rule $rule
- * @param array $transaction
- *
* @throws FireflyException
*/
private function processTransactionJournal(Rule $rule, array $transaction): void
{
- Log::debug(sprintf('SearchRuleEngine:: Will now execute actions on transaction journal #%d', $transaction['transaction_journal_id']));
+ app('log')->debug(sprintf('SearchRuleEngine:: Will now execute actions on transaction journal #%d', $transaction['transaction_journal_id']));
$actions = $rule->ruleActions()->orderBy('order', 'ASC')->get();
+
/** @var RuleAction $ruleAction */
foreach ($actions as $ruleAction) {
if (false === $ruleAction->active) {
@@ -444,21 +427,17 @@ class SearchRuleEngine implements RuleEngineInterface
}
/**
- * @param RuleAction $ruleAction
- * @param array $transaction
- *
- * @return bool
* @throws FireflyException
*/
private function processRuleAction(RuleAction $ruleAction, array $transaction): bool
{
- Log::debug(sprintf('Executing rule action "%s" with value "%s"', $ruleAction->action_type, $ruleAction->action_value));
+ app('log')->debug(sprintf('Executing rule action "%s" with value "%s"', $ruleAction->action_type, $ruleAction->action_value));
$actionClass = ActionFactory::getAction($ruleAction);
$result = $actionClass->actOnArray($transaction);
$journalId = $transaction['transaction_journal_id'] ?? 0;
if (true === $result) {
$this->resultCount[$journalId] = array_key_exists($journalId, $this->resultCount) ? $this->resultCount[$journalId]++ : 1;
- Log::debug(
+ app('log')->debug(
sprintf(
'Action "%s" on journal #%d was executed, so count a result. Updated transaction journal count is now %d.',
$ruleAction->action_type,
@@ -468,15 +447,18 @@ class SearchRuleEngine implements RuleEngineInterface
);
}
if (false === $result) {
- Log::debug(sprintf('Action "%s" reports NO changes were made.', $ruleAction->action_type));
+ app('log')->debug(sprintf('Action "%s" reports NO changes were made.', $ruleAction->action_type));
}
// pick up from the action if it actually acted or not:
- if ($ruleAction->stop_processing) {
- Log::debug(sprintf('Rule action "%s" asks to break, so break!', $ruleAction->action_type));
+ if ($ruleAction->stop_processing && true === $result) {
+ app('log')->debug(sprintf('Rule action "%s" reports changes AND asks to break, so break!', $ruleAction->action_type));
return true;
}
+ if ($ruleAction->stop_processing && false === $result) {
+ app('log')->debug(sprintf('Rule action "%s" reports NO changes AND asks to break, but we wont break!', $ruleAction->action_type));
+ }
return false;
}
@@ -484,41 +466,32 @@ class SearchRuleEngine implements RuleEngineInterface
/**
* Return true if the rule is fired (the collection is larger than zero).
*
- * @param Rule $rule
- *
- * @return bool
* @throws FireflyException
*/
private function fireNonStrictRule(Rule $rule): bool
{
- Log::debug(sprintf('SearchRuleEngine::fireNonStrictRule(%d)!', $rule->id));
+ app('log')->debug(sprintf('SearchRuleEngine::fireNonStrictRule(%d)!', $rule->id));
$collection = $this->findNonStrictRule($rule);
$this->processResults($rule, $collection);
- Log::debug(sprintf('SearchRuleEngine:: done processing non-strict rule #%d', $rule->id));
+ app('log')->debug(sprintf('SearchRuleEngine:: done processing non-strict rule #%d', $rule->id));
return $collection->count() > 0;
}
/**
- * @param RuleGroup $group
- *
- * @return void
* @throws FireflyException
*/
private function fireGroup(RuleGroup $group): void
{
- $all = false;
- Log::debug(sprintf('Going to fire group #%d with %d rule(s)', $group->id, $group->rules->count()));
+ app('log')->debug(sprintf('Going to fire group #%d with %d rule(s)', $group->id, $group->rules->count()));
+
/** @var Rule $rule */
foreach ($group->rules as $rule) {
- Log::debug(sprintf('Going to fire rule #%d from group #%d', $rule->id, $group->id));
+ app('log')->debug(sprintf('Going to fire rule #%d from group #%d', $rule->id, $group->id));
$result = $this->fireRule($rule);
- if (true === $result) {
- $all = true;
- }
if (true === $result && true === $rule->stop_processing) {
- Log::debug(sprintf('The rule was triggered and rule->stop_processing = true, so group #%d will stop processing further rules.', $group->id));
+ app('log')->debug(sprintf('The rule was triggered and rule->stop_processing = true, so group #%d will stop processing further rules.', $group->id));
return;
}
@@ -527,45 +500,34 @@ class SearchRuleEngine implements RuleEngineInterface
/**
* Return the number of changed transactions from the previous "fire" action.
- *
- * @return int
*/
public function getResults(): int
{
return count($this->resultCount);
}
- /**
- * @param bool $refreshTriggers
- */
public function setRefreshTriggers(bool $refreshTriggers): void
{
$this->refreshTriggers = $refreshTriggers;
}
- /**
- * @inheritDoc
- */
public function setRuleGroups(Collection $ruleGroups): void
{
- Log::debug(__METHOD__);
+ app('log')->debug(__METHOD__);
foreach ($ruleGroups as $group) {
if ($group instanceof RuleGroup) {
- Log::debug(sprintf('Adding a rule group to the SearchRuleEngine: #%d ("%s")', $group->id, $group->title));
+ app('log')->debug(sprintf('Adding a rule group to the SearchRuleEngine: #%d ("%s")', $group->id, $group->title));
$this->groups->push($group);
}
}
}
- /**
- * @inheritDoc
- */
public function setRules(Collection $rules): void
{
- Log::debug(__METHOD__);
+ app('log')->debug(__METHOD__);
foreach ($rules as $rule) {
if ($rule instanceof Rule) {
- Log::debug(sprintf('Adding a rule to the SearchRuleEngine: #%d ("%s")', $rule->id, $rule->title));
+ app('log')->debug(sprintf('Adding a rule to the SearchRuleEngine: #%d ("%s")', $rule->id, $rule->title));
$this->rules->push($rule);
}
}
diff --git a/app/TransactionRules/Factory/ActionFactory.php b/app/TransactionRules/Factory/ActionFactory.php
index c53d8c1a67..a34bf7615b 100644
--- a/app/TransactionRules/Factory/ActionFactory.php
+++ b/app/TransactionRules/Factory/ActionFactory.php
@@ -30,12 +30,9 @@ use FireflyIII\Support\Domain;
use FireflyIII\TransactionRules\Actions\ActionInterface;
use FireflyIII\TransactionRules\Expressions\ActionExpressionEvaluator;
use FireflyIII\TransactionRules\Factory\ExpressionLanguageFactory;
-use Illuminate\Support\Facades\Log;
/**
* Class ActionFactory can create actions.
- *
-
*/
class ActionFactory
{
@@ -48,21 +45,17 @@ class ActionFactory
* with value "Groceries" this method will return a corresponding SetCategory object preset
* to "Groceries". Any transaction journal then fed to this object will have its category changed.
*
- * @param RuleAction $action
- *
- * @return ActionInterface
- *
* @throws FireflyException
*/
public static function getAction(RuleAction $action): ActionInterface
{
$class = self::getActionClass($action->action_type);
- Log::debug(sprintf('self::getActionClass("%s") = "%s"', $action->action_type, $class));
+ app('log')->debug(sprintf('self::getActionClass("%s") = "%s"', $action->action_type, $class));
$expressionLanguage = ExpressionLanguageFactory::get();
$expressionEvaluator = new ActionExpressionEvaluator($expressionLanguage, $action->action_value);
- return new $class($action, $expressionEvaluator);
+ return new $class($action, $expressionEvaluator); // @phpstan-ignore-line
}
/**
@@ -70,10 +63,6 @@ class ActionFactory
* that will match the given action type (ie. "change_category") to the matching class name
* (SetCategory) using the configuration (firefly.php).
*
- * @param string $actionType
- *
- * @return string
- *
* @throws FireflyException
*/
public static function getActionClass(string $actionType): string
@@ -84,7 +73,7 @@ class ActionFactory
throw new FireflyException('No such action exists ("' . e($actionType) . '").');
}
- $class = $actionTypes[$actionType];
+ $class = $actionTypes[$actionType];
if (!class_exists($class)) {
throw new FireflyException('Could not instantiate class for rule action type "' . e($actionType) . '" (' . e($class) . ').');
}
@@ -94,8 +83,6 @@ class ActionFactory
/**
* Returns a map with actiontypes, mapped to the class representing that type.
- *
- * @return array
*/
protected static function getActionTypes(): array
{
diff --git a/app/Transformers/AbstractTransformer.php b/app/Transformers/AbstractTransformer.php
index 1e76cf7ac1..ba6331d3ba 100644
--- a/app/Transformers/AbstractTransformer.php
+++ b/app/Transformers/AbstractTransformer.php
@@ -27,24 +27,17 @@ use League\Fractal\TransformerAbstract;
use Symfony\Component\HttpFoundation\ParameterBag;
/**
- *
* Class AbstractTransformer
*/
abstract class AbstractTransformer extends TransformerAbstract
{
protected ParameterBag $parameters;
- /**
- * @return ParameterBag
- */
final public function getParameters(): ParameterBag
{
return $this->parameters;
}
- /**
- * @param ParameterBag $parameters
- */
final public function setParameters(ParameterBag $parameters): void
{
$this->parameters = $parameters;
diff --git a/app/Transformers/AccountTransformer.php b/app/Transformers/AccountTransformer.php
index eaa82dca79..264b4d779d 100644
--- a/app/Transformers/AccountTransformer.php
+++ b/app/Transformers/AccountTransformer.php
@@ -27,7 +27,6 @@ use Carbon\Carbon;
use FireflyIII\Exceptions\FireflyException;
use FireflyIII\Models\Account;
use FireflyIII\Repositories\Account\AccountRepositoryInterface;
-use JsonException;
use Symfony\Component\HttpFoundation\ParameterBag;
/**
@@ -38,10 +37,7 @@ class AccountTransformer extends AbstractTransformer
protected AccountRepositoryInterface $repository;
/**
- *
* AccountTransformer constructor.
- *
-
*/
public function __construct()
{
@@ -52,39 +48,35 @@ class AccountTransformer extends AbstractTransformer
/**
* Transform the account.
*
- * @param Account $account
- *
- * @return array
* @throws FireflyException
- * @throws JsonException
*/
public function transform(Account $account): array
{
$this->repository->setUser($account->user);
// get account type:
- $fullType = $account->accountType->type;
- $accountType = (string)config(sprintf('firefly.shortNamesByFullName.%s', $fullType));
- $liabilityType = (string)config(sprintf('firefly.shortLiabilityNameByFullName.%s', $fullType));
- $liabilityType = '' === $liabilityType ? null : strtolower($liabilityType);
- $liabilityDirection = $this->repository->getMetaValue($account, 'liability_direction');
+ $fullType = $account->accountType->type;
+ $accountType = (string)config(sprintf('firefly.shortNamesByFullName.%s', $fullType));
+ $liabilityType = (string)config(sprintf('firefly.shortLiabilityNameByFullName.%s', $fullType));
+ $liabilityType = '' === $liabilityType ? null : strtolower($liabilityType);
+ $liabilityDirection = $this->repository->getMetaValue($account, 'liability_direction');
// get account role (will only work if the type is asset.
- $accountRole = $this->getAccountRole($account, $accountType);
- $date = $this->getDate();
+ $accountRole = $this->getAccountRole($account, $accountType);
+ $date = $this->getDate();
$date->endOfDay();
[$currencyId, $currencyCode, $currencySymbol, $decimalPlaces] = $this->getCurrency($account);
- [$creditCardType, $monthlyPaymentDate] = $this->getCCInfo($account, $accountRole, $accountType);
- [$openingBalance, $openingBalanceDate] = $this->getOpeningBalance($account, $accountType);
- [$interest, $interestPeriod] = $this->getInterest($account, $accountType);
+ [$creditCardType, $monthlyPaymentDate] = $this->getCCInfo($account, $accountRole, $accountType);
+ [$openingBalance, $openingBalanceDate] = $this->getOpeningBalance($account, $accountType);
+ [$interest, $interestPeriod] = $this->getInterest($account, $accountType);
- $openingBalance = app('steam')->bcround($openingBalance, $decimalPlaces);
- $includeNetWorth = '0' !== $this->repository->getMetaValue($account, 'include_net_worth');
- $longitude = null;
- $latitude = null;
- $zoomLevel = null;
- $location = $this->repository->getLocation($account);
+ $openingBalance = app('steam')->bcround($openingBalance, $decimalPlaces);
+ $includeNetWorth = '0' !== $this->repository->getMetaValue($account, 'include_net_worth');
+ $longitude = null;
+ $latitude = null;
+ $zoomLevel = null;
+ $location = $this->repository->getLocation($account);
if (null !== $location) {
$longitude = $location->longitude;
$latitude = $location->latitude;
@@ -92,7 +84,7 @@ class AccountTransformer extends AbstractTransformer
}
// no order for some accounts:
- $order = (int)$account->order;
+ $order = $account->order;
if (!in_array(strtolower($accountType), ['liability', 'liabilities', 'asset'], true)) {
$order = null;
}
@@ -133,19 +125,12 @@ class AccountTransformer extends AbstractTransformer
'links' => [
[
'rel' => 'self',
- 'uri' => '/accounts/' . $account->id,
+ 'uri' => '/accounts/'.$account->id,
],
],
];
}
- /**
- * @param Account $account
- *
- * @param string $accountType
- *
- * @return string|null
- */
private function getAccountRole(Account $account, string $accountType): ?string
{
$accountRole = $this->repository->getMetaValue($account, 'account_role');
@@ -158,8 +143,6 @@ class AccountTransformer extends AbstractTransformer
/**
* TODO duplicated in the V2 transformer.
- *
- * @return Carbon
*/
private function getDate(): Carbon
{
@@ -172,19 +155,15 @@ class AccountTransformer extends AbstractTransformer
}
/**
- * @param Account $account
- *
- * @return array
* @throws FireflyException
- * @throws JsonException
*/
private function getCurrency(Account $account): array
{
- $currency = $this->repository->getAccountCurrency($account);
+ $currency = $this->repository->getAccountCurrency($account);
// only grab default when result is null:
if (null === $currency) {
- $currency = app('amount')->getDefaultCurrencyByUser($account->user);
+ $currency = app('amount')->getDefaultCurrencyByUserGroup($account->user->userGroup);
}
$currencyId = (string)$currency->id;
$currencyCode = $currency->code;
@@ -194,13 +173,6 @@ class AccountTransformer extends AbstractTransformer
return [$currencyId, $currencyCode, $currencySymbol, $decimalPlaces];
}
- /**
- * @param Account $account
- * @param string|null $accountRole
- * @param string $accountType
- *
- * @return array
- */
private function getCCInfo(Account $account, ?string $accountRole, string $accountType): array
{
$monthlyPaymentDate = null;
@@ -212,7 +184,11 @@ class AccountTransformer extends AbstractTransformer
if (null !== $monthlyPaymentDate) {
// try classic date:
if (10 === strlen($monthlyPaymentDate)) {
- $monthlyPaymentDate = Carbon::createFromFormat('!Y-m-d', $monthlyPaymentDate, config('app.timezone'))->toAtomString();
+ $object = Carbon::createFromFormat('!Y-m-d', $monthlyPaymentDate, config('app.timezone'));
+ if (false === $object) {
+ $object = today(config('app.timezone'));
+ }
+ $monthlyPaymentDate = $object->toAtomString();
}
if (10 !== strlen($monthlyPaymentDate)) {
$monthlyPaymentDate = Carbon::parse($monthlyPaymentDate, config('app.timezone'))->toAtomString();
@@ -223,12 +199,7 @@ class AccountTransformer extends AbstractTransformer
}
/**
- * @param Account $account
- * @param string $accountType
- *
- * @return array
- *
- * TODO refactor call to get~OpeningBalanceAmount / Date because it is a lot of queries.
+ * TODO refactor call to get~OpeningBalanceAmount / Date because it is a lot of queries
*/
private function getOpeningBalance(Account $account, string $accountType): array
{
@@ -240,18 +211,16 @@ class AccountTransformer extends AbstractTransformer
$openingBalanceDate = $this->repository->getOpeningBalanceDate($account);
}
if (null !== $openingBalanceDate) {
- $openingBalanceDate = Carbon::createFromFormat('Y-m-d H:i:s', $openingBalanceDate, config('app.timezone'))->toAtomString();
+ $object = Carbon::createFromFormat('Y-m-d H:i:s', $openingBalanceDate, config('app.timezone'));
+ if (false === $object) {
+ $object = today(config('app.timezone'));
+ }
+ $openingBalanceDate = $object->toAtomString();
}
return [$openingBalance, $openingBalanceDate];
}
- /**
- * @param Account $account
- * @param string $accountType
- *
- * @return array
- */
private function getInterest(Account $account, string $accountType): array
{
$interest = null;
diff --git a/app/Transformers/AttachmentTransformer.php b/app/Transformers/AttachmentTransformer.php
index 2429d02438..e8b162bcd1 100644
--- a/app/Transformers/AttachmentTransformer.php
+++ b/app/Transformers/AttachmentTransformer.php
@@ -35,8 +35,6 @@ class AttachmentTransformer extends AbstractTransformer
/**
* BillTransformer constructor.
- *
-
*/
public function __construct()
{
@@ -45,10 +43,6 @@ class AttachmentTransformer extends AbstractTransformer
/**
* Transform attachment.
- *
- * @param Attachment $attachment
- *
- * @return array
*/
public function transform(Attachment $attachment): array
{
@@ -71,7 +65,7 @@ class AttachmentTransformer extends AbstractTransformer
'links' => [
[
'rel' => 'self',
- 'uri' => '/attachment/' . $attachment->id,
+ 'uri' => '/attachment/'.$attachment->id,
],
],
];
diff --git a/app/Transformers/AvailableBudgetTransformer.php b/app/Transformers/AvailableBudgetTransformer.php
index 5f24686e0f..7c880200cd 100644
--- a/app/Transformers/AvailableBudgetTransformer.php
+++ b/app/Transformers/AvailableBudgetTransformer.php
@@ -39,8 +39,6 @@ class AvailableBudgetTransformer extends AbstractTransformer
/**
* CurrencyTransformer constructor.
- *
-
*/
public function __construct()
{
@@ -51,10 +49,6 @@ class AvailableBudgetTransformer extends AbstractTransformer
/**
* Transform the note.
- *
- * @param AvailableBudget $availableBudget
- *
- * @return array
*/
public function transform(AvailableBudget $availableBudget): array
{
@@ -68,7 +62,7 @@ class AvailableBudgetTransformer extends AbstractTransformer
'currency_id' => (string)$currency->id,
'currency_code' => $currency->code,
'currency_symbol' => $currency->symbol,
- 'currency_decimal_places' => (int)$currency->decimal_places,
+ 'currency_decimal_places' => $currency->decimal_places,
'amount' => app('steam')->bcround($availableBudget->amount, $currency->decimal_places),
'start' => $availableBudget->start_date->toAtomString(),
'end' => $availableBudget->end_date->endOfDay()->toAtomString(),
@@ -77,7 +71,7 @@ class AvailableBudgetTransformer extends AbstractTransformer
'links' => [
[
'rel' => 'self',
- 'uri' => '/available_budgets/' . $availableBudget->id,
+ 'uri' => '/available_budgets/'.$availableBudget->id,
],
],
];
@@ -91,9 +85,6 @@ class AvailableBudgetTransformer extends AbstractTransformer
return $data;
}
- /**
- * @return array
- */
private function getSpentInBudgets(): array
{
$allActive = $this->repository->getActiveBudgets();
@@ -102,9 +93,6 @@ class AvailableBudgetTransformer extends AbstractTransformer
return array_values($sums);
}
- /**
- * @return array
- */
private function spentOutsideBudgets(): array
{
$sums = $this->noBudgetRepository->sumExpenses($this->parameters->get('start'), $this->parameters->get('end'));
diff --git a/app/Transformers/BillTransformer.php b/app/Transformers/BillTransformer.php
index 22a7e8c16d..36988b5e2a 100644
--- a/app/Transformers/BillTransformer.php
+++ b/app/Transformers/BillTransformer.php
@@ -29,6 +29,7 @@ use FireflyIII\Models\Bill;
use FireflyIII\Models\ObjectGroup;
use FireflyIII\Models\TransactionJournal;
use FireflyIII\Repositories\Bill\BillRepositoryInterface;
+use FireflyIII\Support\Models\BillDateCalculator;
use Illuminate\Support\Collection;
/**
@@ -36,81 +37,111 @@ use Illuminate\Support\Collection;
*/
class BillTransformer extends AbstractTransformer
{
+ private BillDateCalculator $calculator;
private BillRepositoryInterface $repository;
/**
* BillTransformer constructor.
- *
-
*/
public function __construct()
{
$this->repository = app(BillRepositoryInterface::class);
+ $this->calculator = app(BillDateCalculator::class);
}
/**
* Transform the bill.
*
- * @param Bill $bill
- *
- * @return array
+ * @SuppressWarnings(PHPMD.ExcessiveMethodLength)
+ * @SuppressWarnings(PHPMD.NPathComplexity)
*/
public function transform(Bill $bill): array
{
- $paidData = $this->paidData($bill);
- $payDates = $this->payDates($bill);
- $currency = $bill->transactionCurrency;
- $notes = $this->repository->getNoteText($bill);
- $notes = '' === $notes ? null : $notes;
+ $paidData = $this->paidData($bill);
+ $lastPaidDate = $this->getLastPaidDate($paidData);
+ $start = $this->parameters->get('start') ?? today()->subYears(10);
+ $end = $this->parameters->get('end') ?? today()->addYears(10);
+ $payDates = $this->calculator->getPayDates($start, $end, $bill->date, $bill->repeat_freq, $bill->skip, $lastPaidDate);
+ $currency = $bill->transactionCurrency;
+ $notes = $this->repository->getNoteText($bill);
+ $notes = '' === $notes ? null : $notes;
+ $objectGroupId = null;
+ $objectGroupOrder = null;
+ $objectGroupTitle = null;
$this->repository->setUser($bill->user);
- $objectGroupId = null;
- $objectGroupOrder = null;
- $objectGroupTitle = null;
- /** @var ObjectGroup $objectGroup */
- $objectGroup = $bill->objectGroups->first();
+ /** @var null|ObjectGroup $objectGroup */
+ $objectGroup = $bill->objectGroups->first();
if (null !== $objectGroup) {
- $objectGroupId = (int)$objectGroup->id;
- $objectGroupOrder = (int)$objectGroup->order;
+ $objectGroupId = $objectGroup->id;
+ $objectGroupOrder = $objectGroup->order;
$objectGroupTitle = $objectGroup->title;
}
$paidDataFormatted = [];
$payDatesFormatted = [];
- foreach ($paidData['paid_dates'] as $object) {
- $object['date'] = Carbon::createFromFormat('!Y-m-d', $object['date'], config('app.timezone'))->toAtomString();
+ foreach ($paidData as $object) {
+ $date = Carbon::createFromFormat('!Y-m-d', $object['date'], config('app.timezone'));
+ if (false === $date) {
+ $date = today(config('app.timezone'));
+ }
+ $object['date'] = $date->toAtomString();
$paidDataFormatted[] = $object;
}
foreach ($payDates as $string) {
- $payDatesFormatted[] = Carbon::createFromFormat('!Y-m-d', $string, config('app.timezone'))->toAtomString();
+ $date = Carbon::createFromFormat('!Y-m-d', $string, config('app.timezone'));
+ if (false === $date) {
+ $date = today(config('app.timezone'));
+ }
+ $payDatesFormatted[] = $date->toAtomString();
}
- $nextExpectedMatch = null;
- if (null !== $paidData['next_expected_match']) {
- $nextExpectedMatch = Carbon::createFromFormat('!Y-m-d', $paidData['next_expected_match'], config('app.timezone'))->toAtomString();
- }
- $nextExpectedMatchDiff = trans('firefly.not_expected_period');
- // converting back and forth is bad code but OK.
- $temp = new Carbon($nextExpectedMatch);
- if ($temp->isToday()) {
- $nextExpectedMatchDiff = trans('firefly.today');
+ // next expected match
+ $nem = null;
+ $nemDate = null;
+ $nemDiff = trans('firefly.not_expected_period');
+ $firstPayDate = $payDates[0] ?? null;
+
+ if (null !== $firstPayDate) {
+ $nemDate = Carbon::createFromFormat('!Y-m-d', $firstPayDate, config('app.timezone'));
+ if (false === $nemDate) {
+ $nemDate = today(config('app.timezone'));
+ }
+ $nem = $nemDate->toAtomString();
+
+ // nullify again when it's outside the current view range.
+ if ($nemDate->lt($this->parameters->get('start')) || $nemDate->gt($this->parameters->get('end'))) {
+ $nem = null;
+ $nemDate = null;
+ $firstPayDate = null;
+ }
}
- $current = $payDatesFormatted[0] ?? null;
- if (null !== $current && !$temp->isToday()) {
- $temp2 = Carbon::createFromFormat('Y-m-d\TH:i:sP', $current);
- $nextExpectedMatchDiff = $temp2->diffForHumans(today(config('app.timezone')), CarbonInterface::DIFF_RELATIVE_TO_NOW);
+ // converting back and forth is bad code but OK.
+ if (null !== $nemDate) {
+ if ($nemDate->isToday()) {
+ $nemDiff = trans('firefly.today');
+ }
+
+ $current = $payDatesFormatted[0] ?? null;
+ if (null !== $current && !$nemDate->isToday()) {
+ $temp2 = Carbon::createFromFormat('Y-m-d\TH:i:sP', $current);
+ if (false === $temp2) {
+ $temp2 = today(config('app.timezone'));
+ }
+ $nemDiff = trans('firefly.bill_expected_date', ['date' => $temp2->diffForHumans(today(config('app.timezone')), CarbonInterface::DIFF_RELATIVE_TO_NOW)]);
+ }
+ unset($temp2);
}
- unset($temp, $temp2);
return [
- 'id' => (int)$bill->id,
+ 'id' => $bill->id,
'created_at' => $bill->created_at->toAtomString(),
'updated_at' => $bill->updated_at->toAtomString(),
'currency_id' => (string)$bill->transaction_currency_id,
'currency_code' => $currency->code,
'currency_symbol' => $currency->symbol,
- 'currency_decimal_places' => (int)$currency->decimal_places,
+ 'currency_decimal_places' => $currency->decimal_places,
'name' => $bill->name,
'amount_min' => app('steam')->bcround($bill->amount_min, $currency->decimal_places),
'amount_max' => app('steam')->bcround($bill->amount_max, $currency->decimal_places),
@@ -118,23 +149,23 @@ class BillTransformer extends AbstractTransformer
'end_date' => $bill->end_date?->toAtomString(),
'extension_date' => $bill->extension_date?->toAtomString(),
'repeat_freq' => $bill->repeat_freq,
- 'skip' => (int)$bill->skip,
+ 'skip' => $bill->skip,
'active' => $bill->active,
- 'order' => (int)$bill->order,
+ 'order' => $bill->order,
'notes' => $notes,
- 'object_group_id' => $objectGroupId ? (string)$objectGroupId : null,
+ 'object_group_id' => null !== $objectGroupId ? (string)$objectGroupId : null,
'object_group_order' => $objectGroupOrder,
'object_group_title' => $objectGroupTitle,
// these fields need work:
- 'next_expected_match' => $nextExpectedMatch,
- 'next_expected_match_diff' => $nextExpectedMatchDiff,
+ 'next_expected_match' => $nem,
+ 'next_expected_match_diff' => $nemDiff,
'pay_dates' => $payDatesFormatted,
'paid_dates' => $paidDataFormatted,
'links' => [
[
'rel' => 'self',
- 'uri' => '/bills/' . $bill->id,
+ 'uri' => '/bills/'.$bill->id,
],
],
];
@@ -142,10 +173,6 @@ class BillTransformer extends AbstractTransformer
/**
* Get the data the bill was paid and predict the next expected match.
- *
- * @param Bill $bill
- *
- * @return array
*/
protected function paidData(Bill $bill): array
{
@@ -153,87 +180,45 @@ class BillTransformer extends AbstractTransformer
if (null === $this->parameters->get('start') || null === $this->parameters->get('end')) {
app('log')->debug('parameters are NULL, return empty array');
- return [
- 'paid_dates' => [],
- 'next_expected_match' => null,
- ];
+ return [];
}
+
// 2023-07-1 sub one day from the start date to fix a possible bug (see #7704)
// 2023-07-18 this particular date is used to search for the last paid date.
// 2023-07-18 the cloned $searchDate is used to grab the correct transactions.
/** @var Carbon $start */
- $start = clone $this->parameters->get('start');
- $searchStart = clone $start;
+ $start = clone $this->parameters->get('start');
+ $searchStart = clone $start;
$start->subDay();
app('log')->debug(sprintf('Parameters are start: %s end: %s', $start->format('Y-m-d'), $this->parameters->get('end')->format('Y-m-d')));
app('log')->debug(sprintf('Search parameters are: start: %s', $searchStart->format('Y-m-d')));
- /*
- * Get from database when bill was paid.
- */
- $set = $this->repository->getPaidDatesInRange($bill, $searchStart, $this->parameters->get('end'));
+ // Get from database when bill was paid.
+ $set = $this->repository->getPaidDatesInRange($bill, $searchStart, $this->parameters->get('end'));
app('log')->debug(sprintf('Count %d entries in getPaidDatesInRange()', $set->count()));
- /*
- * Grab from array the most recent payment. If none exist, fall back to the start date and pretend *that* was the last paid date.
- */
+ // Grab from array the most recent payment. If none exist, fall back to the start date and pretend *that* was the last paid date.
app('log')->debug(sprintf('Grab last paid date from function, return %s if it comes up with nothing.', $start->format('Y-m-d')));
$lastPaidDate = $this->lastPaidDate($set, $start);
app('log')->debug(sprintf('Result of lastPaidDate is %s', $lastPaidDate->format('Y-m-d')));
- /*
- * The next expected match (nextMatch) is, initially, the bill's date.
- */
- $nextMatch = clone $bill->date;
- /*
- * Diff in months (or other period) between bill start and last paid date or $start.
- */
- $steps = app('navigation')->diffInPeriods($bill->repeat_freq, $start, $nextMatch);
- $nextMatch = app('navigation')->addPeriod($nextMatch, $bill->repeat_freq, $steps);
-
- if ($nextMatch->lt($lastPaidDate)) {
- /*
- * Add another period because it's before the last paid date
- */
- app('log')->debug('Because the last paid date was before our next expected match, add another period.');
- $nextMatch = app('navigation')->addPeriod($nextMatch, $bill->repeat_freq, $bill->skip);
- }
-
- if ($nextMatch->isSameDay($lastPaidDate)) {
- /*
- * Add another period because it's the same day as the last paid date.
- */
- app('log')->debug('Because the last paid date was on the same day as our next expected match, add another day.');
- $nextMatch = app('navigation')->addPeriod($nextMatch, $bill->repeat_freq, $bill->skip);
- }
- /*
- * At this point the "next match" is exactly after the last time the bill was paid.
- */
- $result = [];
+ // At this point the "next match" is exactly after the last time the bill was paid.
+ $result = [];
foreach ($set as $entry) {
$result[] = [
- 'transaction_group_id' => (int)$entry->transaction_group_id,
- 'transaction_journal_id' => (int)$entry->id,
+ 'transaction_group_id' => (string)$entry->transaction_group_id,
+ 'transaction_journal_id' => (string)$entry->id,
'date' => $entry->date->format('Y-m-d'),
+ 'date_object' => $entry->date,
];
}
- app('log')->debug(sprintf('Next match: %s', $nextMatch->toIso8601String()));
-
- return [
- 'paid_dates' => $result,
- 'next_expected_match' => $nextMatch->format('Y-m-d'),
- ];
+ return $result;
}
/**
* Returns the latest date in the set, or start when set is empty.
- *
- * @param Collection $dates
- * @param Carbon $default
- *
- * @return Carbon
*/
protected function lastPaidDate(Collection $dates, Carbon $default): Carbon
{
@@ -241,6 +226,7 @@ class BillTransformer extends AbstractTransformer
return $default;
}
$latest = $dates->first()->date;
+
/** @var TransactionJournal $journal */
foreach ($dates as $journal) {
if ($journal->date->gte($latest)) {
@@ -251,72 +237,27 @@ class BillTransformer extends AbstractTransformer
return $latest;
}
- /**
- * @param Bill $bill
- *
- * @return array
- */
- protected function payDates(Bill $bill): array
+ private function getLastPaidDate(array $paidData): ?Carbon
{
- app('log')->debug(sprintf('Now in payDates() for bill #%d', $bill->id));
- if (null === $this->parameters->get('start') || null === $this->parameters->get('end')) {
- app('log')->debug('No start or end date, give empty array.');
-
- return [];
- }
- app('log')->debug(sprintf('Start: %s, end: %s', $this->parameters->get('start')->toIso8601String(), $this->parameters->get('end')->toIso8601String()));
- $set = new Collection();
- $currentStart = clone $this->parameters->get('start');
- // 2023-06-23 subDay to fix 7655
- $currentStart->subDay();
- $loop = 0;
- while ($currentStart <= $this->parameters->get('end')) {
- app('log')->debug(sprintf('Current start is %s', $currentStart->toIso8601String()));
- $nextExpectedMatch = $this->nextDateMatch($bill, $currentStart);
-
- // If nextExpectedMatch is after end, we continue:
- if ($nextExpectedMatch > $this->parameters->get('end')) {
- app('log')->debug('Next expected match is after END, so stop looking');
- break;
+ app('log')->debug('getLastPaidDate()');
+ $return = null;
+ foreach ($paidData as $entry) {
+ if (null !== $return) {
+ /** @var Carbon $current */
+ $current = $entry['date_object'];
+ if ($current->gt($return)) {
+ $return = clone $current;
+ }
+ app('log')->debug(sprintf('Last paid date is: %s', $return->format('Y-m-d')));
}
- app('log')->debug(sprintf('Next expected match is %s', $nextExpectedMatch->toIso8601String()));
- // add to set
- $set->push(clone $nextExpectedMatch);
- $nextExpectedMatch->addDay();
- $currentStart = clone $nextExpectedMatch;
- $loop++;
- if ($loop > 4) {
- break;
+ if (null === $return) {
+ /** @var Carbon $return */
+ $return = $entry['date_object'];
+ app('log')->debug(sprintf('Last paid date is: %s', $return->format('Y-m-d')));
}
}
- $simple = $set->map(
- static function (Carbon $date) {
- return $date->format('Y-m-d');
- }
- );
- app('log')->debug(sprintf('Found %d pay dates', $set->count()), $simple->toArray());
+ app('log')->debug(sprintf('Last paid date is: "%s"', $return?->format('Y-m-d')));
- return $simple->toArray();
- }
-
- /**
- * Given a bill and a date, this method will tell you at which moment this bill expects its next
- * transaction. Whether it is there already, is not relevant.
- *
- * @param Bill $bill
- * @param Carbon $date
- *
- * @return Carbon
- */
- protected function nextDateMatch(Bill $bill, Carbon $date): Carbon
- {
- app('log')->debug(sprintf('Now in nextDateMatch(%d, %s)', $bill->id, $date->format('Y-m-d')));
- $start = clone $bill->date;
- app('log')->debug(sprintf('Bill start date is %s', $start->format('Y-m-d')));
-
- $steps = app('navigation')->diffInPeriods($bill->repeat_freq, $start, $date);
- $result = app('navigation')->addPeriod($start, $bill->repeat_freq, $steps);
- app('log')->debug(sprintf('Number of steps is %d, result is %s', $steps, $start->format('Y-m-d')));
- return $result;
+ return $return;
}
}
diff --git a/app/Transformers/BudgetLimitTransformer.php b/app/Transformers/BudgetLimitTransformer.php
index f4d9ea6532..d2a3e19dee 100644
--- a/app/Transformers/BudgetLimitTransformer.php
+++ b/app/Transformers/BudgetLimitTransformer.php
@@ -33,7 +33,6 @@ use League\Fractal\Resource\Item;
*/
class BudgetLimitTransformer extends AbstractTransformer
{
- /** @var string[] */
protected array $availableIncludes
= [
'budget',
@@ -42,8 +41,6 @@ class BudgetLimitTransformer extends AbstractTransformer
/**
* Include Budget
*
- * @param BudgetLimit $limit
- *
* @return Item
*/
public function includeBudget(BudgetLimit $limit)
@@ -53,14 +50,10 @@ class BudgetLimitTransformer extends AbstractTransformer
/**
* Transform the note.
- *
- * @param BudgetLimit $budgetLimit
- *
- * @return array
*/
public function transform(BudgetLimit $budgetLimit): array
{
- $repository = app(OperationsRepository::class);
+ $repository = app(OperationsRepository::class);
$repository->setUser($budgetLimit->budget->user);
$expenses = $repository->sumExpenses(
$budgetLimit->start_date,
@@ -78,13 +71,13 @@ class BudgetLimitTransformer extends AbstractTransformer
$currencySymbol = null;
if (null !== $currency) {
$amount = $budgetLimit->amount;
- $currencyId = (int)$currency->id;
+ $currencyId = $currency->id;
$currencyName = $currency->name;
$currencyCode = $currency->code;
$currencySymbol = $currency->symbol;
$currencyDecimalPlaces = $currency->decimal_places;
}
- $amount = app('steam')->bcround($amount, $currencyDecimalPlaces);
+ $amount = app('steam')->bcround($amount, $currencyDecimalPlaces);
return [
'id' => (string)$budgetLimit->id,
@@ -104,7 +97,7 @@ class BudgetLimitTransformer extends AbstractTransformer
'links' => [
[
'rel' => 'self',
- 'uri' => '/budgets/limits/' . $budgetLimit->id,
+ 'uri' => '/budgets/limits/'.$budgetLimit->id,
],
],
];
diff --git a/app/Transformers/BudgetTransformer.php b/app/Transformers/BudgetTransformer.php
index 75411190d7..a786e7c327 100644
--- a/app/Transformers/BudgetTransformer.php
+++ b/app/Transformers/BudgetTransformer.php
@@ -40,8 +40,6 @@ class BudgetTransformer extends AbstractTransformer
/**
* BudgetTransformer constructor.
- *
-
*/
public function __construct()
{
@@ -52,18 +50,14 @@ class BudgetTransformer extends AbstractTransformer
/**
* Transform a budget.
- *
- * @param Budget $budget
- *
- * @return array
*/
public function transform(Budget $budget): array
{
$this->opsRepository->setUser($budget->user);
- $start = $this->parameters->get('start');
- $end = $this->parameters->get('end');
- $autoBudget = $this->repository->getAutoBudget($budget);
- $spent = [];
+ $start = $this->parameters->get('start');
+ $end = $this->parameters->get('end');
+ $autoBudget = $this->repository->getAutoBudget($budget);
+ $spent = [];
if (null !== $start && null !== $end) {
$spent = $this->beautify($this->opsRepository->sumExpenses($start, $end, null, new Collection([$budget])));
}
@@ -75,7 +69,7 @@ class BudgetTransformer extends AbstractTransformer
$abPeriod = null;
$notes = $this->repository->getNoteText($budget);
- $types = [
+ $types = [
AutoBudget::AUTO_BUDGET_RESET => 'reset',
AutoBudget::AUTO_BUDGET_ROLLOVER => 'rollover',
AutoBudget::AUTO_BUDGET_ADJUSTED => 'adjusted',
@@ -106,17 +100,12 @@ class BudgetTransformer extends AbstractTransformer
'links' => [
[
'rel' => 'self',
- 'uri' => '/budgets/' . $budget->id,
+ 'uri' => '/budgets/'.$budget->id,
],
],
];
}
- /**
- * @param array $array
- *
- * @return array
- */
private function beautify(array $array): array
{
$return = [];
diff --git a/app/Transformers/CategoryTransformer.php b/app/Transformers/CategoryTransformer.php
index f04df6ced5..21b4756f5d 100644
--- a/app/Transformers/CategoryTransformer.php
+++ b/app/Transformers/CategoryTransformer.php
@@ -38,8 +38,6 @@ class CategoryTransformer extends AbstractTransformer
/**
* CategoryTransformer constructor.
- *
-
*/
public function __construct()
{
@@ -49,10 +47,6 @@ class CategoryTransformer extends AbstractTransformer
/**
* Convert category.
- *
- * @param Category $category
- *
- * @return array
*/
public function transform(Category $category): array
{
@@ -67,10 +61,10 @@ class CategoryTransformer extends AbstractTransformer
$earned = $this->beautify($this->opsRepository->sumIncome($start, $end, null, new Collection([$category])));
$spent = $this->beautify($this->opsRepository->sumExpenses($start, $end, null, new Collection([$category])));
}
- $notes = $this->repository->getNoteText($category);
+ $notes = $this->repository->getNoteText($category);
return [
- 'id' => (int)$category->id,
+ 'id' => $category->id,
'created_at' => $category->created_at->toAtomString(),
'updated_at' => $category->updated_at->toAtomString(),
'name' => $category->name,
@@ -80,17 +74,12 @@ class CategoryTransformer extends AbstractTransformer
'links' => [
[
'rel' => 'self',
- 'uri' => '/categories/' . $category->id,
+ 'uri' => '/categories/'.$category->id,
],
],
];
}
- /**
- * @param array $array
- *
- * @return array
- */
private function beautify(array $array): array
{
$return = [];
diff --git a/app/Transformers/CurrencyTransformer.php b/app/Transformers/CurrencyTransformer.php
index 2c363f19eb..6043291e56 100644
--- a/app/Transformers/CurrencyTransformer.php
+++ b/app/Transformers/CurrencyTransformer.php
@@ -32,33 +32,23 @@ class CurrencyTransformer extends AbstractTransformer
{
/**
* Transform the currency.
- *
- * @param TransactionCurrency $currency
- *
- * @return array
*/
public function transform(TransactionCurrency $currency): array
{
- $isDefault = false;
- $defaultCurrency = $this->parameters->get('defaultCurrency');
- if (null !== $defaultCurrency) {
- $isDefault = (int)$defaultCurrency->id === (int)$currency->id;
- }
-
return [
- 'id' => (int)$currency->id,
+ 'id' => $currency->id,
'created_at' => $currency->created_at->toAtomString(),
'updated_at' => $currency->updated_at->toAtomString(),
- 'default' => $isDefault,
- 'enabled' => $currency->enabled,
+ 'default' => $currency->userGroupDefault,
+ 'enabled' => $currency->userGroupEnabled,
'name' => $currency->name,
'code' => $currency->code,
'symbol' => $currency->symbol,
- 'decimal_places' => (int)$currency->decimal_places,
+ 'decimal_places' => $currency->decimal_places,
'links' => [
[
'rel' => 'self',
- 'uri' => '/currencies/' . $currency->id,
+ 'uri' => '/currencies/'.$currency->id,
],
],
];
diff --git a/app/Transformers/LinkTypeTransformer.php b/app/Transformers/LinkTypeTransformer.php
index 13f3b36eb5..3efe57546a 100644
--- a/app/Transformers/LinkTypeTransformer.php
+++ b/app/Transformers/LinkTypeTransformer.php
@@ -26,22 +26,17 @@ namespace FireflyIII\Transformers;
use FireflyIII\Models\LinkType;
/**
- *
* Class LinkTypeTransformer
*/
class LinkTypeTransformer extends AbstractTransformer
{
/**
* Transform the currency.
- *
- * @param LinkType $linkType
- *
- * @return array
*/
public function transform(LinkType $linkType): array
{
return [
- 'id' => (int)$linkType->id,
+ 'id' => $linkType->id,
'created_at' => $linkType->created_at->toAtomString(),
'updated_at' => $linkType->updated_at->toAtomString(),
'name' => $linkType->name,
@@ -51,7 +46,7 @@ class LinkTypeTransformer extends AbstractTransformer
'links' => [
[
'rel' => 'self',
- 'uri' => '/link_types/' . $linkType->id,
+ 'uri' => '/link_types/'.$linkType->id,
],
],
];
diff --git a/app/Transformers/ObjectGroupTransformer.php b/app/Transformers/ObjectGroupTransformer.php
index 4bc4f70a8b..c49275f849 100644
--- a/app/Transformers/ObjectGroupTransformer.php
+++ b/app/Transformers/ObjectGroupTransformer.php
@@ -34,10 +34,7 @@ class ObjectGroupTransformer extends AbstractTransformer
protected ObjectGroupRepositoryInterface $repository;
/**
- *
* AccountTransformer constructor.
- *
-
*/
public function __construct()
{
@@ -46,10 +43,6 @@ class ObjectGroupTransformer extends AbstractTransformer
/**
* Transform the account.
- *
- * @param ObjectGroup $objectGroup
- *
- * @return array
*/
public function transform(ObjectGroup $objectGroup): array
{
@@ -60,11 +53,11 @@ class ObjectGroupTransformer extends AbstractTransformer
'created_at' => $objectGroup->created_at?->toAtomString(),
'updated_at' => $objectGroup->updated_at?->toAtomString(),
'title' => $objectGroup->title,
- 'order' => (int)$objectGroup->order,
+ 'order' => $objectGroup->order,
'links' => [
[
'rel' => 'self',
- 'uri' => '/object_groups/' . $objectGroup->id,
+ 'uri' => '/object_groups/'.$objectGroup->id,
],
],
];
diff --git a/app/Transformers/PiggyBankEventTransformer.php b/app/Transformers/PiggyBankEventTransformer.php
index 0ab17a4f07..aac61a2d09 100644
--- a/app/Transformers/PiggyBankEventTransformer.php
+++ b/app/Transformers/PiggyBankEventTransformer.php
@@ -26,52 +26,41 @@ namespace FireflyIII\Transformers;
use FireflyIII\Exceptions\FireflyException;
use FireflyIII\Models\PiggyBankEvent;
use FireflyIII\Repositories\Account\AccountRepositoryInterface;
-use FireflyIII\Repositories\Currency\CurrencyRepositoryInterface;
use FireflyIII\Repositories\PiggyBank\PiggyBankRepositoryInterface;
-use JsonException;
/**
* Class PiggyBankEventTransformer
*/
class PiggyBankEventTransformer extends AbstractTransformer
{
- private CurrencyRepositoryInterface $currencyRepos;
private PiggyBankRepositoryInterface $piggyRepos;
private AccountRepositoryInterface $repository;
/**
* PiggyBankEventTransformer constructor.
- *
-
*/
public function __construct()
{
- $this->repository = app(AccountRepositoryInterface::class);
- $this->currencyRepos = app(CurrencyRepositoryInterface::class);
- $this->piggyRepos = app(PiggyBankRepositoryInterface::class);
+ $this->repository = app(AccountRepositoryInterface::class);
+ $this->piggyRepos = app(PiggyBankRepositoryInterface::class);
}
/**
* Convert piggy bank event.
*
- * @param PiggyBankEvent $event
- *
- * @return array
* @throws FireflyException
- * @throws JsonException
*/
public function transform(PiggyBankEvent $event): array
{
// get account linked to piggy bank
- $account = $event->piggyBank->account;
+ $account = $event->piggyBank->account;
// set up repositories.
$this->repository->setUser($account->user);
- $this->currencyRepos->setUser($account->user);
$this->piggyRepos->setUser($account->user);
// get associated currency or fall back to the default:
- $currency = $this->repository->getAccountCurrency($account) ?? app('amount')->getDefaultCurrencyByUser($account->user);
+ $currency = $this->repository->getAccountCurrency($account) ?? app('amount')->getDefaultCurrencyByUserGroup($account->user->userGroup);
// get associated journal and transaction, if any:
$journalId = $event->transaction_journal_id;
@@ -89,13 +78,13 @@ class PiggyBankEventTransformer extends AbstractTransformer
'currency_id' => (string)$currency->id,
'currency_code' => $currency->code,
'currency_symbol' => $currency->symbol,
- 'currency_decimal_places' => (int)$currency->decimal_places,
- 'transaction_journal_id' => $journalId ? (string)$journalId : null,
- 'transaction_group_id' => $groupId ? (string)$groupId : null,
+ 'currency_decimal_places' => $currency->decimal_places,
+ 'transaction_journal_id' => null !== $journalId ? (string)$journalId : null,
+ 'transaction_group_id' => null !== $groupId ? (string)$groupId : null,
'links' => [
[
'rel' => 'self',
- 'uri' => '/piggy_bank_events/' . $event->id,
+ 'uri' => '/piggy_bank_events/'.$event->id,
],
],
];
diff --git a/app/Transformers/PiggyBankTransformer.php b/app/Transformers/PiggyBankTransformer.php
index 0af30de935..fea26e16c5 100644
--- a/app/Transformers/PiggyBankTransformer.php
+++ b/app/Transformers/PiggyBankTransformer.php
@@ -27,9 +27,7 @@ use FireflyIII\Exceptions\FireflyException;
use FireflyIII\Models\ObjectGroup;
use FireflyIII\Models\PiggyBank;
use FireflyIII\Repositories\Account\AccountRepositoryInterface;
-use FireflyIII\Repositories\Currency\CurrencyRepositoryInterface;
use FireflyIII\Repositories\PiggyBank\PiggyBankRepositoryInterface;
-use JsonException;
/**
* Class PiggyBankTransformer
@@ -37,65 +35,57 @@ use JsonException;
class PiggyBankTransformer extends AbstractTransformer
{
private AccountRepositoryInterface $accountRepos;
- private CurrencyRepositoryInterface $currencyRepos;
private PiggyBankRepositoryInterface $piggyRepos;
/**
* PiggyBankTransformer constructor.
- *
-
*/
public function __construct()
{
- $this->accountRepos = app(AccountRepositoryInterface::class);
- $this->currencyRepos = app(CurrencyRepositoryInterface::class);
- $this->piggyRepos = app(PiggyBankRepositoryInterface::class);
+ $this->accountRepos = app(AccountRepositoryInterface::class);
+ $this->piggyRepos = app(PiggyBankRepositoryInterface::class);
}
/**
* Transform the piggy bank.
*
- * @param PiggyBank $piggyBank
- *
- * @return array
* @throws FireflyException
- * @throws JsonException
*/
public function transform(PiggyBank $piggyBank): array
{
- $account = $piggyBank->account;
+ $account = $piggyBank->account;
// set up repositories
$this->accountRepos->setUser($account->user);
- $this->currencyRepos->setUser($account->user);
$this->piggyRepos->setUser($account->user);
// get currency from account, or use default.
- $currency = $this->accountRepos->getAccountCurrency($account) ?? app('amount')->getDefaultCurrencyByUser($account->user);
+ $currency = $this->accountRepos->getAccountCurrency($account) ?? app('amount')->getDefaultCurrencyByUserGroup($account->user->userGroup);
// note
- $notes = $this->piggyRepos->getNoteText($piggyBank);
- $notes = '' === $notes ? null : $notes;
+ $notes = $this->piggyRepos->getNoteText($piggyBank);
+ $notes = '' === $notes ? null : $notes;
$objectGroupId = null;
$objectGroupOrder = null;
$objectGroupTitle = null;
- /** @var ObjectGroup $objectGroup */
- $objectGroup = $piggyBank->objectGroups->first();
+
+ /** @var null|ObjectGroup $objectGroup */
+ $objectGroup = $piggyBank->objectGroups->first();
if (null !== $objectGroup) {
- $objectGroupId = (int)$objectGroup->id;
- $objectGroupOrder = (int)$objectGroup->order;
+ $objectGroupId = $objectGroup->id;
+ $objectGroupOrder = $objectGroup->order;
$objectGroupTitle = $objectGroup->title;
}
// get currently saved amount:
- $currentAmount = app('steam')->bcround($this->piggyRepos->getCurrentAmount($piggyBank), $currency->decimal_places);
+ $currentAmount = app('steam')->bcround($this->piggyRepos->getCurrentAmount($piggyBank), $currency->decimal_places);
// Amounts, depending on 0.0 state of target amount
- $percentage = null;
- $targetAmount = $piggyBank->targetamount;
- $leftToSave = null;
- $savePerMonth = null;
+ $percentage = null;
+ $targetAmount = $piggyBank->targetamount;
+ $leftToSave = null;
+ $savePerMonth = null;
if (0 !== bccomp($targetAmount, '0')) { // target amount is not 0.00
$leftToSave = bcsub($piggyBank->targetamount, $currentAmount);
$percentage = (int)bcmul(bcdiv($currentAmount, $targetAmount), '100');
@@ -103,8 +93,8 @@ class PiggyBankTransformer extends AbstractTransformer
$leftToSave = app('steam')->bcround($leftToSave, $currency->decimal_places);
$savePerMonth = app('steam')->bcround($this->piggyRepos->getSuggestedMonthlyAmount($piggyBank), $currency->decimal_places);
}
- $startDate = $piggyBank->startdate?->format('Y-m-d');
- $targetDate = $piggyBank->targetdate?->format('Y-m-d');
+ $startDate = $piggyBank->startdate?->format('Y-m-d');
+ $targetDate = $piggyBank->targetdate?->format('Y-m-d');
return [
'id' => (string)$piggyBank->id,
@@ -116,7 +106,7 @@ class PiggyBankTransformer extends AbstractTransformer
'currency_id' => (string)$currency->id,
'currency_code' => $currency->code,
'currency_symbol' => $currency->symbol,
- 'currency_decimal_places' => (int)$currency->decimal_places,
+ 'currency_decimal_places' => $currency->decimal_places,
'target_amount' => $targetAmount,
'percentage' => $percentage,
'current_amount' => $currentAmount,
@@ -124,16 +114,16 @@ class PiggyBankTransformer extends AbstractTransformer
'save_per_month' => $savePerMonth,
'start_date' => $startDate,
'target_date' => $targetDate,
- 'order' => (int)$piggyBank->order,
+ 'order' => $piggyBank->order,
'active' => true,
'notes' => $notes,
- 'object_group_id' => $objectGroupId ? (string)$objectGroupId : null,
+ 'object_group_id' => null !== $objectGroupId ? (string)$objectGroupId : null,
'object_group_order' => $objectGroupOrder,
'object_group_title' => $objectGroupTitle,
'links' => [
[
'rel' => 'self',
- 'uri' => '/piggy_banks/' . $piggyBank->id,
+ 'uri' => '/piggy_banks/'.$piggyBank->id,
],
],
];
diff --git a/app/Transformers/PreferenceTransformer.php b/app/Transformers/PreferenceTransformer.php
index e108e3effb..a944a0bea9 100644
--- a/app/Transformers/PreferenceTransformer.php
+++ b/app/Transformers/PreferenceTransformer.php
@@ -32,15 +32,11 @@ class PreferenceTransformer extends AbstractTransformer
{
/**
* Transform the preference
- *
- * @param Preference $preference
- *
- * @return array
*/
public function transform(Preference $preference): array
{
return [
- 'id' => (int)$preference->id,
+ 'id' => $preference->id,
'created_at' => $preference->created_at->toAtomString(),
'updated_at' => $preference->updated_at->toAtomString(),
'name' => $preference->name,
diff --git a/app/Transformers/RecurrenceTransformer.php b/app/Transformers/RecurrenceTransformer.php
index ddc95d7ef4..efff57080c 100644
--- a/app/Transformers/RecurrenceTransformer.php
+++ b/app/Transformers/RecurrenceTransformer.php
@@ -26,6 +26,7 @@ namespace FireflyIII\Transformers;
use Carbon\Carbon;
use FireflyIII\Exceptions\FireflyException;
use FireflyIII\Factory\CategoryFactory;
+use FireflyIII\Models\Account;
use FireflyIII\Models\Recurrence;
use FireflyIII\Models\RecurrenceRepetition;
use FireflyIII\Models\RecurrenceTransaction;
@@ -34,10 +35,8 @@ use FireflyIII\Repositories\Bill\BillRepositoryInterface;
use FireflyIII\Repositories\Budget\BudgetRepositoryInterface;
use FireflyIII\Repositories\PiggyBank\PiggyBankRepositoryInterface;
use FireflyIII\Repositories\Recurring\RecurringRepositoryInterface;
-use Illuminate\Support\Facades\Log;
/**
- *
* Class RecurringTransactionTransformer
*/
class RecurrenceTransformer extends AbstractTransformer
@@ -50,8 +49,6 @@ class RecurrenceTransformer extends AbstractTransformer
/**
* RecurrenceTransformer constructor.
- *
-
*/
public function __construct()
{
@@ -65,9 +62,6 @@ class RecurrenceTransformer extends AbstractTransformer
/**
* Transform the recurring transaction.
*
- * @param Recurrence $recurrence
- *
- * @return array
* @throws FireflyException
*/
public function transform(Recurrence $recurrence): array
@@ -104,16 +98,13 @@ class RecurrenceTransformer extends AbstractTransformer
'links' => [
[
'rel' => 'self',
- 'uri' => '/recurring/' . $recurrence->id,
+ 'uri' => '/recurring/'.$recurrence->id,
],
],
];
}
/**
- * @param Recurrence $recurrence
- *
- * @return array
* @throws FireflyException
*/
private function getRepetitions(Recurrence $recurrence): array
@@ -130,39 +121,41 @@ class RecurrenceTransformer extends AbstractTransformer
'updated_at' => $repetition->updated_at->toAtomString(),
'type' => $repetition->repetition_type,
'moment' => $repetition->repetition_moment,
- 'skip' => (int)$repetition->repetition_skip,
- 'weekend' => (int)$repetition->weekend,
+ 'skip' => $repetition->repetition_skip,
+ 'weekend' => $repetition->weekend,
'description' => $this->repository->repetitionDescription($repetition),
'occurrences' => [],
];
// get the (future) occurrences for this specific type of repetition:
- $occurrences = $this->repository->getXOccurrencesSince($repetition, $fromDate, new Carbon(), 5);
+ $occurrences = $this->repository->getXOccurrencesSince($repetition, $fromDate, new Carbon(), 5);
+
/** @var Carbon $carbon */
foreach ($occurrences as $carbon) {
$repetitionArray['occurrences'][] = $carbon->toAtomString();
}
- $return[] = $repetitionArray;
+ $return[] = $repetitionArray;
}
return $return;
}
/**
- * @param Recurrence $recurrence
- *
- * @return array
* @throws FireflyException
*/
private function getTransactions(Recurrence $recurrence): array
{
app('log')->debug(sprintf('Now in %s', __METHOD__));
$return = [];
+
// get all transactions:
/** @var RecurrenceTransaction $transaction */
foreach ($recurrence->recurrenceTransactions()->get() as $transaction) {
+ /** @var null|Account $sourceAccount */
$sourceAccount = $transaction->sourceAccount;
+
+ /** @var null|Account $destinationAccount */
$destinationAccount = $transaction->destinationAccount;
$foreignCurrencyCode = null;
$foreignCurrencySymbol = null;
@@ -172,41 +165,41 @@ class RecurrenceTransformer extends AbstractTransformer
$foreignCurrencyId = (int)$transaction->foreign_currency_id;
$foreignCurrencyCode = $transaction->foreignCurrency->code;
$foreignCurrencySymbol = $transaction->foreignCurrency->symbol;
- $foreignCurrencyDp = (int)$transaction->foreignCurrency->decimal_places;
+ $foreignCurrencyDp = $transaction->foreignCurrency->decimal_places;
}
// source info:
- $sourceName = '';
- $sourceId = null;
- $sourceType = null;
- $sourceIban = null;
+ $sourceName = '';
+ $sourceId = null;
+ $sourceType = null;
+ $sourceIban = null;
if (null !== $sourceAccount) {
$sourceName = $sourceAccount->name;
- $sourceId = (int)$sourceAccount->id;
+ $sourceId = $sourceAccount->id;
$sourceType = $sourceAccount->accountType->type;
$sourceIban = $sourceAccount->iban;
}
- $destinationName = '';
- $destinationId = null;
- $destinationType = null;
- $destinationIban = null;
+ $destinationName = '';
+ $destinationId = null;
+ $destinationType = null;
+ $destinationIban = null;
if (null !== $destinationAccount) {
$destinationName = $destinationAccount->name;
- $destinationId = (int)$destinationAccount->id;
+ $destinationId = $destinationAccount->id;
$destinationType = $destinationAccount->accountType->type;
$destinationIban = $destinationAccount->iban;
}
- $amount = app('steam')->bcround($transaction->amount, $transaction->transactionCurrency->decimal_places);
- $foreignAmount = null;
+ $amount = app('steam')->bcround($transaction->amount, $transaction->transactionCurrency->decimal_places);
+ $foreignAmount = null;
if (null !== $transaction->foreign_currency_id && null !== $transaction->foreign_amount) {
$foreignAmount = app('steam')->bcround($transaction->foreign_amount, $foreignCurrencyDp);
}
- $transactionArray = [
+ $transactionArray = [
'id' => (string)$transaction->id,
'currency_id' => (string)$transaction->transaction_currency_id,
'currency_code' => $transaction->transactionCurrency->code,
'currency_symbol' => $transaction->transactionCurrency->symbol,
- 'currency_decimal_places' => (int)$transaction->transactionCurrency->decimal_places,
+ 'currency_decimal_places' => $transaction->transactionCurrency->decimal_places,
'foreign_currency_id' => null === $foreignCurrencyId ? null : (string)$foreignCurrencyId,
'foreign_currency_code' => $foreignCurrencyCode,
'foreign_currency_symbol' => $foreignCurrencySymbol,
@@ -223,7 +216,7 @@ class RecurrenceTransformer extends AbstractTransformer
'foreign_amount' => $foreignAmount,
'description' => $transaction->description,
];
- $transactionArray = $this->getTransactionMeta($transaction, $transactionArray);
+ $transactionArray = $this->getTransactionMeta($transaction, $transactionArray);
if (null !== $transaction->foreign_currency_id) {
$transactionArray['foreign_currency_code'] = $transaction->foreignCurrency->code;
$transactionArray['foreign_currency_symbol'] = $transaction->foreignCurrency->symbol;
@@ -231,17 +224,13 @@ class RecurrenceTransformer extends AbstractTransformer
}
// store transaction in recurrence array.
- $return[] = $transactionArray;
+ $return[] = $transactionArray;
}
return $return;
}
/**
- * @param RecurrenceTransaction $transaction
- * @param array $array
- *
- * @return array
* @throws FireflyException
*/
private function getTransactionMeta(RecurrenceTransaction $transaction, array $array): array
@@ -262,43 +251,55 @@ class RecurrenceTransformer extends AbstractTransformer
switch ($transactionMeta->name) {
default:
throw new FireflyException(sprintf('Recurrence transformer cant handle field "%s"', $transactionMeta->name));
+
case 'bill_id':
- $bill = $this->billRepos->find((int)$transactionMeta->value);
+ $bill = $this->billRepos->find((int)$transactionMeta->value);
if (null !== $bill) {
$array['bill_id'] = (string)$bill->id;
$array['bill_name'] = $bill->name;
}
+
break;
+
case 'tags':
$array['tags'] = json_decode($transactionMeta->value);
+
break;
+
case 'piggy_bank_id':
- $piggy = $this->piggyRepos->find((int)$transactionMeta->value);
+ $piggy = $this->piggyRepos->find((int)$transactionMeta->value);
if (null !== $piggy) {
$array['piggy_bank_id'] = (string)$piggy->id;
$array['piggy_bank_name'] = $piggy->name;
}
+
break;
+
case 'category_id':
- $category = $this->factory->findOrCreate((int)$transactionMeta->value, null);
+ $category = $this->factory->findOrCreate((int)$transactionMeta->value, null);
if (null !== $category) {
$array['category_id'] = (string)$category->id;
$array['category_name'] = $category->name;
}
+
break;
+
case 'category_name':
- $category = $this->factory->findOrCreate(null, $transactionMeta->value);
+ $category = $this->factory->findOrCreate(null, $transactionMeta->value);
if (null !== $category) {
$array['category_id'] = (string)$category->id;
$array['category_name'] = $category->name;
}
+
break;
+
case 'budget_id':
- $budget = $this->budgetRepos->find((int)$transactionMeta->value);
+ $budget = $this->budgetRepos->find((int)$transactionMeta->value);
if (null !== $budget) {
$array['budget_id'] = (string)$budget->id;
$array['budget_name'] = $budget->name;
}
+
break;
}
}
diff --git a/app/Transformers/RuleGroupTransformer.php b/app/Transformers/RuleGroupTransformer.php
index bb83a5dc05..ee685516c2 100644
--- a/app/Transformers/RuleGroupTransformer.php
+++ b/app/Transformers/RuleGroupTransformer.php
@@ -32,15 +32,11 @@ class RuleGroupTransformer extends AbstractTransformer
{
/**
* Transform the rule group
- *
- * @param RuleGroup $ruleGroup
- *
- * @return array
*/
public function transform(RuleGroup $ruleGroup): array
{
return [
- 'id' => (int)$ruleGroup->id,
+ 'id' => $ruleGroup->id,
'created_at' => $ruleGroup->created_at->toAtomString(),
'updated_at' => $ruleGroup->updated_at->toAtomString(),
'title' => $ruleGroup->title,
@@ -50,7 +46,7 @@ class RuleGroupTransformer extends AbstractTransformer
'links' => [
[
'rel' => 'self',
- 'uri' => '/rule_groups/' . $ruleGroup->id,
+ 'uri' => '/rule_groups/'.$ruleGroup->id,
],
],
];
diff --git a/app/Transformers/RuleTransformer.php b/app/Transformers/RuleTransformer.php
index 2a0d3f80a5..bb4431d536 100644
--- a/app/Transformers/RuleTransformer.php
+++ b/app/Transformers/RuleTransformer.php
@@ -39,8 +39,6 @@ class RuleTransformer extends AbstractTransformer
/**
* CurrencyTransformer constructor.
- *
-
*/
public function __construct()
{
@@ -50,9 +48,6 @@ class RuleTransformer extends AbstractTransformer
/**
* Transform the rule.
*
- * @param Rule $rule
- *
- * @return array
* @throws FireflyException
*/
public function transform(Rule $rule): array
@@ -67,7 +62,7 @@ class RuleTransformer extends AbstractTransformer
'rule_group_title' => (string)$rule->ruleGroup->title,
'title' => $rule->title,
'description' => $rule->description,
- 'order' => (int)$rule->order,
+ 'order' => $rule->order,
'active' => $rule->active,
'strict' => $rule->strict,
'stop_processing' => $rule->stop_processing,
@@ -77,22 +72,20 @@ class RuleTransformer extends AbstractTransformer
'links' => [
[
'rel' => 'self',
- 'uri' => '/rules/' . $rule->id,
+ 'uri' => '/rules/'.$rule->id,
],
],
];
}
/**
- * @param Rule $rule
- *
- * @return string
* @throws FireflyException
*/
private function getRuleTrigger(Rule $rule): string
{
$moment = null;
$triggers = $this->ruleRepository->getRuleTriggers($rule);
+
/** @var RuleTrigger $ruleTrigger */
foreach ($triggers as $ruleTrigger) {
if ('user_action' === $ruleTrigger->trigger_type) {
@@ -106,26 +99,28 @@ class RuleTransformer extends AbstractTransformer
return $moment;
}
- /**
- * @param Rule $rule
- *
- * @return array
- */
private function triggers(Rule $rule): array
{
$result = [];
$triggers = $this->ruleRepository->getRuleTriggers($rule);
+
/** @var RuleTrigger $ruleTrigger */
foreach ($triggers as $ruleTrigger) {
if ('user_action' === $ruleTrigger->trigger_type) {
continue;
}
- $result[] = [
+ $triggerValue = (string)$ruleTrigger->trigger_value;
+ $needsContext = config(sprintf('search.operators.%s.needs_context', $ruleTrigger->trigger_type), true);
+ if (false === $needsContext) {
+ $triggerValue = 'true';
+ }
+
+ $result[] = [
'id' => (string)$ruleTrigger->id,
'created_at' => $ruleTrigger->created_at->toAtomString(),
'updated_at' => $ruleTrigger->updated_at->toAtomString(),
'type' => $ruleTrigger->trigger_type,
- 'value' => $ruleTrigger->trigger_value,
+ 'value' => $triggerValue,
'order' => $ruleTrigger->order,
'active' => $ruleTrigger->active,
'stop_processing' => $ruleTrigger->stop_processing,
@@ -135,15 +130,11 @@ class RuleTransformer extends AbstractTransformer
return $result;
}
- /**
- * @param Rule $rule
- *
- * @return array
- */
private function actions(Rule $rule): array
{
$result = [];
$actions = $this->ruleRepository->getRuleActions($rule);
+
/** @var RuleAction $ruleAction */
foreach ($actions as $ruleAction) {
$result[] = [
diff --git a/app/Transformers/TagTransformer.php b/app/Transformers/TagTransformer.php
index 067a508cd2..6cc5e8b0a0 100644
--- a/app/Transformers/TagTransformer.php
+++ b/app/Transformers/TagTransformer.php
@@ -35,15 +35,12 @@ class TagTransformer extends AbstractTransformer
* Transform a tag.
*
* TODO add spent, earned, transferred, etc.
- *
- * @param Tag $tag
- *
- * @return array
*/
public function transform(Tag $tag): array
{
- $date = $tag->date?->format('Y-m-d');
- /** @var Location $location */
+ $date = $tag->date?->format('Y-m-d');
+
+ /** @var null|Location $location */
$location = $tag->locations()->first();
$latitude = null;
$longitude = null;
@@ -55,7 +52,7 @@ class TagTransformer extends AbstractTransformer
}
return [
- 'id' => (int)$tag->id,
+ 'id' => $tag->id,
'created_at' => $tag->created_at->toAtomString(),
'updated_at' => $tag->updated_at->toAtomString(),
'tag' => $tag->tag,
@@ -67,7 +64,7 @@ class TagTransformer extends AbstractTransformer
'links' => [
[
'rel' => 'self',
- 'uri' => '/tags/' . $tag->id,
+ 'uri' => '/tags/'.$tag->id,
],
],
];
diff --git a/app/Transformers/TransactionGroupTransformer.php b/app/Transformers/TransactionGroupTransformer.php
index cb12faa4de..a0247b7314 100644
--- a/app/Transformers/TransactionGroupTransformer.php
+++ b/app/Transformers/TransactionGroupTransformer.php
@@ -36,7 +36,6 @@ use FireflyIII\Models\TransactionType;
use FireflyIII\Repositories\TransactionGroup\TransactionGroupRepositoryInterface;
use FireflyIII\Support\NullArrayObject;
use Illuminate\Support\Collection;
-use Illuminate\Support\Facades\Log;
/**
* Class TransactionGroupTransformer
@@ -49,8 +48,6 @@ class TransactionGroupTransformer extends AbstractTransformer
/**
* Constructor.
- *
-
*/
public function __construct()
{
@@ -77,11 +74,6 @@ class TransactionGroupTransformer extends AbstractTransformer
$this->metaDateFields = ['interest_date', 'book_date', 'process_date', 'due_date', 'payment_date', 'invoice_date'];
}
- /**
- * @param array $group
- *
- * @return array
- */
public function transform(array $group): array
{
$data = new NullArrayObject($group);
@@ -97,17 +89,12 @@ class TransactionGroupTransformer extends AbstractTransformer
'links' => [
[
'rel' => 'self',
- 'uri' => '/transactions/' . $first['transaction_group_id'],
+ 'uri' => '/transactions/'.$first['transaction_group_id'],
],
],
];
}
- /**
- * @param NullArrayObject $data
- *
- * @return array
- */
private function transformTransactions(NullArrayObject $data): array
{
$result = [];
@@ -120,18 +107,16 @@ class TransactionGroupTransformer extends AbstractTransformer
}
/**
- * @param array $transaction
- *
- * @return array
+ * @SuppressWarnings(PHPMD.ExcessiveMethodLength)
*/
private function transformTransaction(array $transaction): array
{
- $row = new NullArrayObject($transaction);
+ $row = new NullArrayObject($transaction);
// amount:
$amount = app('steam')->positive((string)($row['amount'] ?? '0'));
$foreignAmount = null;
- if (null !== $row['foreign_amount'] && '' !== $row['foreign_amount'] && bccomp('0', $row['foreign_amount']) !== 0) {
+ if (null !== $row['foreign_amount'] && '' !== $row['foreign_amount'] && 0 !== bccomp('0', $row['foreign_amount'])) {
$foreignAmount = app('steam')->positive($row['foreign_amount']);
}
@@ -139,11 +124,10 @@ class TransactionGroupTransformer extends AbstractTransformer
$metaDateData = $this->groupRepos->getMetaDateFields((int)$row['transaction_journal_id'], $this->metaDateFields);
$type = $this->stringFromArray($transaction, 'transaction_type_type', TransactionType::WITHDRAWAL);
-
- $longitude = null;
- $latitude = null;
- $zoomLevel = null;
- $location = $this->getLocationById((int)$row['transaction_journal_id']);
+ $longitude = null;
+ $latitude = null;
+ $zoomLevel = null;
+ $location = $this->getLocationById((int)$row['transaction_journal_id']);
if (null !== $location) {
$longitude = $location->longitude;
$latitude = $location->latitude;
@@ -151,93 +135,86 @@ class TransactionGroupTransformer extends AbstractTransformer
}
return [
- 'user' => (string)$row['user_id'],
- 'transaction_journal_id' => (string)$row['transaction_journal_id'],
- 'type' => strtolower($type),
- 'date' => $row['date']->toAtomString(),
- 'order' => $row['order'],
+ 'user' => (string)$row['user_id'],
+ 'transaction_journal_id' => (string)$row['transaction_journal_id'],
+ 'type' => strtolower($type),
+ 'date' => $row['date']->toAtomString(),
+ 'order' => $row['order'],
- 'currency_id' => (string)$row['currency_id'],
- 'currency_code' => $row['currency_code'],
- 'currency_name' => $row['currency_name'],
- 'currency_symbol' => $row['currency_symbol'],
- 'currency_decimal_places' => (int)$row['currency_decimal_places'],
+ 'currency_id' => (string)$row['currency_id'],
+ 'currency_code' => $row['currency_code'],
+ 'currency_name' => $row['currency_name'],
+ 'currency_symbol' => $row['currency_symbol'],
+ 'currency_decimal_places' => (int)$row['currency_decimal_places'],
'foreign_currency_id' => $this->stringFromArray($transaction, 'foreign_currency_id', null),
'foreign_currency_code' => $row['foreign_currency_code'],
'foreign_currency_symbol' => $row['foreign_currency_symbol'],
'foreign_currency_decimal_places' => $row['foreign_currency_decimal_places'],
- 'amount' => $amount,
- 'foreign_amount' => $foreignAmount,
+ 'amount' => $amount,
+ 'foreign_amount' => $foreignAmount,
- 'description' => $row['description'],
+ 'description' => $row['description'],
- 'source_id' => (string)$row['source_account_id'],
- 'source_name' => $row['source_account_name'],
- 'source_iban' => $row['source_account_iban'],
- 'source_type' => $row['source_account_type'],
+ 'source_id' => (string)$row['source_account_id'],
+ 'source_name' => $row['source_account_name'],
+ 'source_iban' => $row['source_account_iban'],
+ 'source_type' => $row['source_account_type'],
- 'destination_id' => (string)$row['destination_account_id'],
- 'destination_name' => $row['destination_account_name'],
- 'destination_iban' => $row['destination_account_iban'],
- 'destination_type' => $row['destination_account_type'],
+ 'destination_id' => (string)$row['destination_account_id'],
+ 'destination_name' => $row['destination_account_name'],
+ 'destination_iban' => $row['destination_account_iban'],
+ 'destination_type' => $row['destination_account_type'],
- 'budget_id' => $this->stringFromArray($transaction, 'budget_id', null),
- 'budget_name' => $row['budget_name'],
+ 'budget_id' => $this->stringFromArray($transaction, 'budget_id', null),
+ 'budget_name' => $row['budget_name'],
- 'category_id' => $this->stringFromArray($transaction, 'category_id', null),
- 'category_name' => $row['category_name'],
+ 'category_id' => $this->stringFromArray($transaction, 'category_id', null),
+ 'category_name' => $row['category_name'],
- 'bill_id' => $this->stringFromArray($transaction, 'bill_id', null),
- 'bill_name' => $row['bill_name'],
+ 'bill_id' => $this->stringFromArray($transaction, 'bill_id', null),
+ 'bill_name' => $row['bill_name'],
- 'reconciled' => $row['reconciled'],
- 'notes' => $this->groupRepos->getNoteText((int)$row['transaction_journal_id']),
- 'tags' => $this->groupRepos->getTags((int)$row['transaction_journal_id']),
+ 'reconciled' => $row['reconciled'],
+ 'notes' => $this->groupRepos->getNoteText((int)$row['transaction_journal_id']),
+ 'tags' => $this->groupRepos->getTags((int)$row['transaction_journal_id']),
- 'internal_reference' => $metaFieldData['internal_reference'],
- 'external_id' => $metaFieldData['external_id'],
- 'original_source' => $metaFieldData['original_source'],
- 'recurrence_id' => $this->stringFromArray($metaFieldData->getArrayCopy(), 'recurrence_id', null),
- 'recurrence_total' => $this->integerFromArray($metaFieldData->getArrayCopy(), 'recurrence_total'),
- 'recurrence_count' => $this->integerFromArray($metaFieldData->getArrayCopy(), 'recurrence_count'),
- 'bunq_payment_id' => $metaFieldData['bunq_payment_id'],
- 'external_url' => $metaFieldData['external_url'],
- 'import_hash_v2' => $metaFieldData['import_hash_v2'],
+ 'internal_reference' => $metaFieldData['internal_reference'],
+ 'external_id' => $metaFieldData['external_id'],
+ 'original_source' => $metaFieldData['original_source'],
+ 'recurrence_id' => $this->stringFromArray($metaFieldData->getArrayCopy(), 'recurrence_id', null),
+ 'recurrence_total' => $this->integerFromArray($metaFieldData->getArrayCopy(), 'recurrence_total'),
+ 'recurrence_count' => $this->integerFromArray($metaFieldData->getArrayCopy(), 'recurrence_count'),
+ 'bunq_payment_id' => $metaFieldData['bunq_payment_id'],
+ 'external_url' => $metaFieldData['external_url'],
+ 'import_hash_v2' => $metaFieldData['import_hash_v2'],
- 'sepa_cc' => $metaFieldData['sepa_cc'],
- 'sepa_ct_op' => $metaFieldData['sepa_ct_op'],
- 'sepa_ct_id' => $metaFieldData['sepa_ct_id'],
- 'sepa_db' => $metaFieldData['sepa_db'],
- 'sepa_country' => $metaFieldData['sepa_country'],
- 'sepa_ep' => $metaFieldData['sepa_ep'],
- 'sepa_ci' => $metaFieldData['sepa_ci'],
- 'sepa_batch_id' => $metaFieldData['sepa_batch_id'],
+ 'sepa_cc' => $metaFieldData['sepa_cc'],
+ 'sepa_ct_op' => $metaFieldData['sepa_ct_op'],
+ 'sepa_ct_id' => $metaFieldData['sepa_ct_id'],
+ 'sepa_db' => $metaFieldData['sepa_db'],
+ 'sepa_country' => $metaFieldData['sepa_country'],
+ 'sepa_ep' => $metaFieldData['sepa_ep'],
+ 'sepa_ci' => $metaFieldData['sepa_ci'],
+ 'sepa_batch_id' => $metaFieldData['sepa_batch_id'],
- 'interest_date' => $this->dateFromArray($metaDateData, 'interest_date'),
- 'book_date' => $this->dateFromArray($metaDateData, 'book_date'),
- 'process_date' => $this->dateFromArray($metaDateData, 'process_date'),
- 'due_date' => $this->dateFromArray($metaDateData, 'due_date'),
- 'payment_date' => $this->dateFromArray($metaDateData, 'payment_date'),
- 'invoice_date' => $this->dateFromArray($metaDateData, 'invoice_date'),
+ 'interest_date' => $this->dateFromArray($metaDateData, 'interest_date'),
+ 'book_date' => $this->dateFromArray($metaDateData, 'book_date'),
+ 'process_date' => $this->dateFromArray($metaDateData, 'process_date'),
+ 'due_date' => $this->dateFromArray($metaDateData, 'due_date'),
+ 'payment_date' => $this->dateFromArray($metaDateData, 'payment_date'),
+ 'invoice_date' => $this->dateFromArray($metaDateData, 'invoice_date'),
// location data
- 'longitude' => $longitude,
- 'latitude' => $latitude,
- 'zoom_level' => $zoomLevel,
+ 'longitude' => $longitude,
+ 'latitude' => $latitude,
+ 'zoom_level' => $zoomLevel,
- 'has_attachments' => $this->hasAttachments((int)$row['transaction_journal_id']),
+ 'has_attachments' => $this->hasAttachments((int)$row['transaction_journal_id']),
];
}
- /**
- * @param array $array
- * @param string $key
- * @param string|null $default
- *
- * @return string|null
- */
private function stringFromArray(array $array, string $key, ?string $default): ?string
{
if (array_key_exists($key, $array) && null === $array[$key]) {
@@ -250,42 +227,27 @@ class TransactionGroupTransformer extends AbstractTransformer
if ('0' === $array[$key]) {
return $default;
}
+
return (string)$array[$key];
}
if (null !== $default) {
- return (string)$default;
+ return $default;
}
return null;
}
- /**
- * @param int $journalId
- *
- * @return Location|null
- */
private function getLocationById(int $journalId): ?Location
{
return $this->groupRepos->getLocation($journalId);
}
- /**
- * @param TransactionJournal $journal
- *
- * @return Location|null
- */
private function getLocation(TransactionJournal $journal): ?Location
{
return $journal->locations()->first();
}
- /**
- * @param array $array
- * @param string $key
- *
- * @return int|null
- */
private function integerFromArray(array $array, string $key): ?int
{
if (array_key_exists($key, $array)) {
@@ -295,12 +257,6 @@ class TransactionGroupTransformer extends AbstractTransformer
return null;
}
- /**
- * @param NullArrayObject $object
- * @param string $key
- *
- * @return string|null
- */
private function dateFromArray(NullArrayObject $object, string $key): ?string
{
if (null === $object[$key]) {
@@ -310,42 +266,35 @@ class TransactionGroupTransformer extends AbstractTransformer
return $object[$key]->toAtomString();
}
- /**
- * @param int $journalId
- *
- * @return bool
- */
private function hasAttachments(int $journalId): bool
{
return $this->groupRepos->countAttachments($journalId) > 0;
}
/**
- * @param TransactionGroup $group
- *
- * @return array
* @throws FireflyException
*/
public function transformObject(TransactionGroup $group): array
{
try {
$result = [
- 'id' => (int)$group->id,
+ 'id' => $group->id,
'created_at' => $group->created_at->toAtomString(),
'updated_at' => $group->updated_at->toAtomString(),
- 'user' => (int)$group->user_id,
+ 'user' => $group->user_id,
'group_title' => $group->title,
'transactions' => $this->transformJournals($group->transactionJournals),
'links' => [
[
'rel' => 'self',
- 'uri' => '/transactions/' . $group->id,
+ 'uri' => '/transactions/'.$group->id,
],
],
];
} catch (FireflyException $e) {
app('log')->error($e->getMessage());
app('log')->error($e->getTraceAsString());
+
throw new FireflyException(sprintf('Transaction group #%d is broken. Please check out your log files.', $group->id), 0, $e);
}
@@ -355,14 +304,12 @@ class TransactionGroupTransformer extends AbstractTransformer
}
/**
- * @param Collection $transactionJournals
- *
- * @return array
* @throws FireflyException
*/
private function transformJournals(Collection $transactionJournals): array
{
$result = [];
+
/** @var TransactionJournal $journal */
foreach ($transactionJournals as $journal) {
$result[] = $this->transformJournal($journal);
@@ -372,10 +319,9 @@ class TransactionGroupTransformer extends AbstractTransformer
}
/**
- * @param TransactionJournal $journal
- *
- * @return array
* @throws FireflyException
+ *
+ * @SuppressWarnings(PHPMD.ExcessiveMethodLength)
*/
private function transformJournal(TransactionJournal $journal): array
{
@@ -383,8 +329,8 @@ class TransactionGroupTransformer extends AbstractTransformer
$destination = $this->getDestinationTransaction($journal);
$type = $journal->transactionType->type;
$currency = $source->transactionCurrency;
- $amount = app('steam')->bcround($this->getAmount($type, (string)$source->amount), $currency->decimal_places ?? 0);
- $foreignAmount = $this->getForeignAmount($type, null === $source->foreign_amount ? null : (string)$source->foreign_amount);
+ $amount = app('steam')->bcround($this->getAmount($source->amount), $currency->decimal_places ?? 0);
+ $foreignAmount = $this->getForeignAmount(null === $source->foreign_amount ? null : $source->foreign_amount);
$metaFieldData = $this->groupRepos->getMetaFields($journal->id, $this->metaFields);
$metaDates = $this->getDates($this->groupRepos->getMetaDateFields($journal->id, $this->metaDateFields));
$foreignCurrency = $this->getForeignCurrency($source->foreignCurrency);
@@ -396,10 +342,10 @@ class TransactionGroupTransformer extends AbstractTransformer
$foreignAmount = app('steam')->bcround($foreignAmount, $foreignCurrency['decimal_places'] ?? 0);
}
- $longitude = null;
- $latitude = null;
- $zoomLevel = null;
- $location = $this->getLocation($journal);
+ $longitude = null;
+ $latitude = null;
+ $zoomLevel = null;
+ $location = $this->getLocation($journal);
if (null !== $location) {
$longitude = $location->longitude;
$latitude = $location->latitude;
@@ -407,84 +353,81 @@ class TransactionGroupTransformer extends AbstractTransformer
}
return [
- 'user' => (int)$journal->user_id,
- 'transaction_journal_id' => (int)$journal->id,
- 'type' => strtolower($type),
- 'date' => $journal->date->toAtomString(),
- 'order' => $journal->order,
+ 'user' => $journal->user_id,
+ 'transaction_journal_id' => $journal->id,
+ 'type' => strtolower($type),
+ 'date' => $journal->date->toAtomString(),
+ 'order' => $journal->order,
- 'currency_id' => (int)$currency->id,
- 'currency_code' => $currency->code,
- 'currency_symbol' => $currency->symbol,
- 'currency_decimal_places' => (int)$currency->decimal_places,
+ 'currency_id' => $currency->id,
+ 'currency_code' => $currency->code,
+ 'currency_symbol' => $currency->symbol,
+ 'currency_decimal_places' => $currency->decimal_places,
'foreign_currency_id' => $foreignCurrency['id'],
'foreign_currency_code' => $foreignCurrency['code'],
'foreign_currency_symbol' => $foreignCurrency['symbol'],
'foreign_currency_decimal_places' => $foreignCurrency['decimal_places'],
- 'amount' => app('steam')->bcround($amount, $currency->decimal_places),
- 'foreign_amount' => $foreignAmount,
+ 'amount' => app('steam')->bcround($amount, $currency->decimal_places),
+ 'foreign_amount' => $foreignAmount,
- 'description' => $journal->description,
+ 'description' => $journal->description,
- 'source_id' => (int)$source->account_id,
- 'source_name' => $source->account->name,
- 'source_iban' => $source->account->iban,
- 'source_type' => $source->account->accountType->type,
+ 'source_id' => $source->account_id,
+ 'source_name' => $source->account->name,
+ 'source_iban' => $source->account->iban,
+ 'source_type' => $source->account->accountType->type,
- 'destination_id' => (int)$destination->account_id,
- 'destination_name' => $destination->account->name,
- 'destination_iban' => $destination->account->iban,
- 'destination_type' => $destination->account->accountType->type,
+ 'destination_id' => $destination->account_id,
+ 'destination_name' => $destination->account->name,
+ 'destination_iban' => $destination->account->iban,
+ 'destination_type' => $destination->account->accountType->type,
- 'budget_id' => $budget['id'],
- 'budget_name' => $budget['name'],
+ 'budget_id' => $budget['id'],
+ 'budget_name' => $budget['name'],
- 'category_id' => $category['id'],
- 'category_name' => $category['name'],
+ 'category_id' => $category['id'],
+ 'category_name' => $category['name'],
- 'bill_id' => $bill['id'],
- 'bill_name' => $bill['name'],
+ 'bill_id' => $bill['id'],
+ 'bill_name' => $bill['name'],
- 'reconciled' => $source->reconciled,
- 'notes' => $this->groupRepos->getNoteText($journal->id),
- 'tags' => $this->groupRepos->getTags($journal->id),
+ 'reconciled' => $source->reconciled,
+ 'notes' => $this->groupRepos->getNoteText($journal->id),
+ 'tags' => $this->groupRepos->getTags($journal->id),
- 'internal_reference' => $metaFieldData['internal_reference'],
- 'external_id' => $metaFieldData['external_id'],
- 'original_source' => $metaFieldData['original_source'],
- 'recurrence_id' => $metaFieldData['recurrence_id'],
- 'bunq_payment_id' => $metaFieldData['bunq_payment_id'],
- 'import_hash_v2' => $metaFieldData['import_hash_v2'],
+ 'internal_reference' => $metaFieldData['internal_reference'],
+ 'external_id' => $metaFieldData['external_id'],
+ 'original_source' => $metaFieldData['original_source'],
+ 'recurrence_id' => $metaFieldData['recurrence_id'],
+ 'bunq_payment_id' => $metaFieldData['bunq_payment_id'],
+ 'import_hash_v2' => $metaFieldData['import_hash_v2'],
- 'sepa_cc' => $metaFieldData['sepa_cc'],
- 'sepa_ct_op' => $metaFieldData['sepa_ct_op'],
- 'sepa_ct_id' => $metaFieldData['sepa_ct_id'],
- 'sepa_db' => $metaFieldData['sepa_db'],
- 'sepa_country' => $metaFieldData['sepa_country'],
- 'sepa_ep' => $metaFieldData['sepa_ep'],
- 'sepa_ci' => $metaFieldData['sepa_ci'],
- 'sepa_batch_id' => $metaFieldData['sepa_batch_id'],
+ 'sepa_cc' => $metaFieldData['sepa_cc'],
+ 'sepa_ct_op' => $metaFieldData['sepa_ct_op'],
+ 'sepa_ct_id' => $metaFieldData['sepa_ct_id'],
+ 'sepa_db' => $metaFieldData['sepa_db'],
+ 'sepa_country' => $metaFieldData['sepa_country'],
+ 'sepa_ep' => $metaFieldData['sepa_ep'],
+ 'sepa_ci' => $metaFieldData['sepa_ci'],
+ 'sepa_batch_id' => $metaFieldData['sepa_batch_id'],
- 'interest_date' => $metaDates['interest_date'],
- 'book_date' => $metaDates['book_date'],
- 'process_date' => $metaDates['process_date'],
- 'due_date' => $metaDates['due_date'],
- 'payment_date' => $metaDates['payment_date'],
- 'invoice_date' => $metaDates['invoice_date'],
+ 'interest_date' => $metaDates['interest_date'],
+ 'book_date' => $metaDates['book_date'],
+ 'process_date' => $metaDates['process_date'],
+ 'due_date' => $metaDates['due_date'],
+ 'payment_date' => $metaDates['payment_date'],
+ 'invoice_date' => $metaDates['invoice_date'],
// location data
- 'longitude' => $longitude,
- 'latitude' => $latitude,
- 'zoom_level' => $zoomLevel,
+ 'longitude' => $longitude,
+ 'latitude' => $latitude,
+ 'zoom_level' => $zoomLevel,
];
}
/**
- * @param TransactionJournal $journal
- *
- * @return Transaction
* @throws FireflyException
*/
private function getSourceTransaction(TransactionJournal $journal): Transaction
@@ -502,9 +445,6 @@ class TransactionGroupTransformer extends AbstractTransformer
}
/**
- * @param TransactionJournal $journal
- *
- * @return Transaction
* @throws FireflyException
*/
private function getDestinationTransaction(TransactionJournal $journal): Transaction
@@ -521,38 +461,21 @@ class TransactionGroupTransformer extends AbstractTransformer
return $result;
}
- /**
- * @param string $type
- * @param string $amount
- *
- * @return string
- */
- private function getAmount(string $type, string $amount): string
+ private function getAmount(string $amount): string
{
return app('steam')->positive($amount);
}
- /**
- * @param string $type
- * @param string|null $foreignAmount
- *
- * @return string|null
- */
- private function getForeignAmount(string $type, ?string $foreignAmount): ?string
+ private function getForeignAmount(?string $foreignAmount): ?string
{
$result = null;
- if (null !== $foreignAmount && '' !== $foreignAmount && bccomp('0', $foreignAmount) !== 0) {
+ if (null !== $foreignAmount && '' !== $foreignAmount && 0 !== bccomp('0', $foreignAmount)) {
$result = app('steam')->positive($foreignAmount);
}
return $result;
}
- /**
- * @param NullArrayObject $dates
- *
- * @return array
- */
private function getDates(NullArrayObject $dates): array
{
$fields = [
@@ -574,14 +497,9 @@ class TransactionGroupTransformer extends AbstractTransformer
return $return;
}
- /**
- * @param TransactionCurrency|null $currency
- *
- * @return array
- */
private function getForeignCurrency(?TransactionCurrency $currency): array
{
- $array = [
+ $array = [
'id' => null,
'code' => null,
'symbol' => null,
@@ -590,62 +508,47 @@ class TransactionGroupTransformer extends AbstractTransformer
if (null === $currency) {
return $array;
}
- $array['id'] = (int)$currency->id;
+ $array['id'] = $currency->id;
$array['code'] = $currency->code;
$array['symbol'] = $currency->symbol;
- $array['decimal_places'] = (int)$currency->decimal_places;
+ $array['decimal_places'] = $currency->decimal_places;
return $array;
}
- /**
- * @param Budget|null $budget
- *
- * @return array
- */
private function getBudget(?Budget $budget): array
{
- $array = [
+ $array = [
'id' => null,
'name' => null,
];
if (null === $budget) {
return $array;
}
- $array['id'] = (int)$budget->id;
+ $array['id'] = $budget->id;
$array['name'] = $budget->name;
return $array;
}
- /**
- * @param Category|null $category
- *
- * @return array
- */
private function getCategory(?Category $category): array
{
- $array = [
+ $array = [
'id' => null,
'name' => null,
];
if (null === $category) {
return $array;
}
- $array['id'] = (int)$category->id;
+ $array['id'] = $category->id;
$array['name'] = $category->name;
return $array;
}
- /**
- * @param Bill|null $bill
- *
- * @return array
- */
private function getBill(?Bill $bill): array
{
- $array = [
+ $array = [
'id' => null,
'name' => null,
];
diff --git a/app/Transformers/TransactionLinkTransformer.php b/app/Transformers/TransactionLinkTransformer.php
index 82d717b5f7..ca34064533 100644
--- a/app/Transformers/TransactionLinkTransformer.php
+++ b/app/Transformers/TransactionLinkTransformer.php
@@ -27,7 +27,6 @@ use FireflyIII\Models\TransactionJournalLink;
use FireflyIII\Repositories\Journal\JournalRepositoryInterface;
/**
- *
* Class TransactionLinkTransformer
*/
class TransactionLinkTransformer extends AbstractTransformer
@@ -37,19 +36,12 @@ class TransactionLinkTransformer extends AbstractTransformer
/**
* Constructor.
- *
-
*/
public function __construct()
{
$this->repository = app(JournalRepositoryInterface::class);
}
- /**
- * @param TransactionJournalLink $link
- *
- * @return array
- */
public function transform(TransactionJournalLink $link): array
{
$notes = $this->repository->getLinkNoteText($link);
@@ -65,7 +57,7 @@ class TransactionLinkTransformer extends AbstractTransformer
'links' => [
[
'rel' => 'self',
- 'uri' => '/transaction_links/' . $link->id,
+ 'uri' => '/transaction_links/'.$link->id,
],
],
];
diff --git a/app/Transformers/UserTransformer.php b/app/Transformers/UserTransformer.php
index 790ec698eb..de5ed25c65 100644
--- a/app/Transformers/UserTransformer.php
+++ b/app/Transformers/UserTransformer.php
@@ -32,20 +32,16 @@ use FireflyIII\User;
*/
class UserTransformer extends AbstractTransformer
{
- /** @var UserRepositoryInterface */
private UserRepositoryInterface $repository;
/**
* Transform user.
*
- * @param User $user
- *
- * @return array
* @throws FireflyException
*/
public function transform(User $user): array
{
- $this->repository = $this->repository ?? app(UserRepositoryInterface::class);
+ $this->repository ??= app(UserRepositoryInterface::class);
return [
'id' => (int)$user->id,
@@ -58,7 +54,7 @@ class UserTransformer extends AbstractTransformer
'links' => [
[
'rel' => 'self',
- 'uri' => '/users/' . $user->id,
+ 'uri' => '/users/'.$user->id,
],
],
];
diff --git a/app/Transformers/V2/AbstractTransformer.php b/app/Transformers/V2/AbstractTransformer.php
index ef03237dd8..9803753688 100644
--- a/app/Transformers/V2/AbstractTransformer.php
+++ b/app/Transformers/V2/AbstractTransformer.php
@@ -37,25 +37,14 @@ abstract class AbstractTransformer extends TransformerAbstract
/**
* This method is called exactly ONCE from FireflyIII\Api\V2\Controllers\Controller::jsonApiList
- *
- * @param Collection $objects
- *
- * @return void
*/
abstract public function collectMetaData(Collection $objects): void;
-
- /**
- * @return ParameterBag
- */
final public function getParameters(): ParameterBag
{
return $this->parameters;
}
- /**
- * @param ParameterBag $parameters
- */
final public function setParameters(ParameterBag $parameters): void
{
$this->parameters = $parameters;
diff --git a/app/Transformers/V2/AccountTransformer.php b/app/Transformers/V2/AccountTransformer.php
index 74b198976b..c36d19f1f2 100644
--- a/app/Transformers/V2/AccountTransformer.php
+++ b/app/Transformers/V2/AccountTransformer.php
@@ -30,7 +30,7 @@ use FireflyIII\Models\Account;
use FireflyIII\Models\AccountMeta;
use FireflyIII\Models\AccountType;
use FireflyIII\Models\TransactionCurrency;
-use FireflyIII\Repositories\Currency\CurrencyRepositoryInterface;
+use FireflyIII\Repositories\UserGroups\Currency\CurrencyRepositoryInterface;
use Illuminate\Support\Collection;
/**
@@ -46,7 +46,6 @@ class AccountTransformer extends AbstractTransformer
private TransactionCurrency $default;
/**
- * @inheritDoc
* @throws FireflyException
*/
public function collectMetaData(Collection $objects): void
@@ -56,39 +55,41 @@ class AccountTransformer extends AbstractTransformer
$this->accountTypes = [];
$this->balances = app('steam')->balancesByAccounts($objects, $this->getDate());
$this->convertedBalances = app('steam')->balancesByAccountsConverted($objects, $this->getDate());
+
+ /** @var CurrencyRepositoryInterface $repository */
$repository = app(CurrencyRepositoryInterface::class);
$this->default = app('amount')->getDefaultCurrency();
// get currencies:
- $accountIds = $objects->pluck('id')->toArray();
- $meta = AccountMeta::whereIn('account_id', $accountIds)
- ->where('name', 'currency_id')
- ->get(['account_meta.id', 'account_meta.account_id', 'account_meta.name', 'account_meta.data']);
- $currencyIds = $meta->pluck('data')->toArray();
+ $accountIds = $objects->pluck('id')->toArray();
+ $meta = AccountMeta::whereIn('account_id', $accountIds)
+ ->where('name', 'currency_id')
+ ->get(['account_meta.id', 'account_meta.account_id', 'account_meta.name', 'account_meta.data'])
+ ;
+ $currencyIds = $meta->pluck('data')->toArray();
- $currencies = $repository->getByIds($currencyIds);
+ $currencies = $repository->getByIds($currencyIds);
foreach ($currencies as $currency) {
- $id = (int)$currency->id;
+ $id = $currency->id;
$this->currencies[$id] = $currency;
}
foreach ($meta as $entry) {
- $id = (int)$entry->account_id;
+ $id = $entry->account_id;
$this->accountMeta[$id][$entry->name] = $entry->data;
}
// get account types:
// select accounts.id, account_types.type from account_types left join accounts on accounts.account_type_id = account_types.id;
- $accountTypes = AccountType::leftJoin('accounts', 'accounts.account_type_id', '=', 'account_types.id')
- ->whereIn('accounts.id', $accountIds)
- ->get(['accounts.id', 'account_types.type']);
+ $accountTypes = AccountType::leftJoin('accounts', 'accounts.account_type_id', '=', 'account_types.id')
+ ->whereIn('accounts.id', $accountIds)
+ ->get(['accounts.id', 'account_types.type'])
+ ;
+
/** @var AccountType $row */
foreach ($accountTypes as $row) {
- $this->accountTypes[(int)$row->id] = (string)config(sprintf('firefly.shortNamesByFullName.%s', $row->type));
+ $this->accountTypes[$row->id] = (string)config(sprintf('firefly.shortNamesByFullName.%s', $row->type));
}
}
- /**
- * @return Carbon
- */
private function getDate(): Carbon
{
$date = today(config('app.timezone'));
@@ -101,22 +102,18 @@ class AccountTransformer extends AbstractTransformer
/**
* Transform the account.
- *
- * @param Account $account
- *
- * @return array
*/
public function transform(Account $account): array
{
- $id = (int)$account->id;
+ $id = $account->id;
// various meta
- $accountRole = $this->accountMeta[$id]['account_role'] ?? null;
- $accountType = $this->accountTypes[$id];
- $order = (int)$account->order;
+ $accountRole = $this->accountMeta[$id]['account_role'] ?? null;
+ $accountType = $this->accountTypes[$id];
+ $order = $account->order;
// no currency? use default
- $currency = $this->default;
+ $currency = $this->default;
if (0 !== (int)$this->accountMeta[$id]['currency_id']) {
$currency = $this->currencies[(int)$this->accountMeta[$id]['currency_id']];
}
@@ -130,29 +127,29 @@ class AccountTransformer extends AbstractTransformer
}
return [
- 'id' => (string)$account->id,
- 'created_at' => $account->created_at->toAtomString(),
- 'updated_at' => $account->updated_at->toAtomString(),
- 'active' => $account->active,
- 'order' => $order,
- 'name' => $account->name,
- 'iban' => '' === $account->iban ? null : $account->iban,
- 'type' => strtolower($accountType),
- 'account_role' => $accountRole,
- 'currency_id' => (string)$currency->id,
- 'currency_code' => $currency->code,
- 'currency_symbol' => $currency->symbol,
- 'currency_decimal_places' => (int)$currency->decimal_places,
+ 'id' => (string)$account->id,
+ 'created_at' => $account->created_at->toAtomString(),
+ 'updated_at' => $account->updated_at->toAtomString(),
+ 'active' => $account->active,
+ 'order' => $order,
+ 'name' => $account->name,
+ 'iban' => '' === $account->iban ? null : $account->iban,
+ 'type' => strtolower($accountType),
+ 'account_role' => $accountRole,
+ 'currency_id' => (string)$currency->id,
+ 'currency_code' => $currency->code,
+ 'currency_symbol' => $currency->symbol,
+ 'currency_decimal_places' => $currency->decimal_places,
'native_currency_id' => (string)$this->default->id,
'native_currency_code' => $this->default->code,
'native_currency_symbol' => $this->default->symbol,
- 'native_currency_decimal_places' => (int)$this->default->decimal_places,
+ 'native_currency_decimal_places' => $this->default->decimal_places,
// balance:
'current_balance' => $balance,
'native_current_balance' => $nativeBalance,
- 'current_balance_date' => $this->getDate(),
+ 'current_balance_date' => $this->getDate()->endOfDay()->toAtomString(),
// more meta
@@ -176,7 +173,7 @@ class AccountTransformer extends AbstractTransformer
'links' => [
[
'rel' => 'self',
- 'uri' => '/accounts/' . $account->id,
+ 'uri' => '/accounts/'.$account->id,
],
],
];
diff --git a/app/Transformers/V2/BillTransformer.php b/app/Transformers/V2/BillTransformer.php
index 4dae4997c5..d6f7a36968 100644
--- a/app/Transformers/V2/BillTransformer.php
+++ b/app/Transformers/V2/BillTransformer.php
@@ -25,146 +25,139 @@ namespace FireflyIII\Transformers\V2;
use Carbon\Carbon;
use Carbon\CarbonInterface;
+use FireflyIII\Exceptions\FireflyException;
use FireflyIII\Models\Bill;
use FireflyIII\Models\Note;
use FireflyIII\Models\ObjectGroup;
use FireflyIII\Models\Transaction;
use FireflyIII\Models\TransactionCurrency;
use FireflyIII\Models\TransactionJournal;
-use FireflyIII\Repositories\Bill\BillRepositoryInterface;
use FireflyIII\Support\Http\Api\ExchangeRateConverter;
use Illuminate\Support\Collection;
use Illuminate\Support\Facades\DB;
-use Log;
+use Illuminate\Support\Facades\Log;
/**
* Class BillTransformer
*/
class BillTransformer extends AbstractTransformer
{
- private ExchangeRateConverter $converter;
- private array $currencies;
- private TransactionCurrency $default;
- private array $groups;
- private array $notes;
- private array $paidDates;
- private BillRepositoryInterface $repository;
+ private ExchangeRateConverter $converter;
+ private array $currencies;
+ private TransactionCurrency $default;
+ private array $groups;
+ private array $notes;
+ private array $paidDates;
/**
- * BillTransformer constructor.
+ * @throws FireflyException
*
-
- */
- public function __construct()
- {
- $this->repository = app(BillRepositoryInterface::class);
- }
-
- /**
- * @inheritDoc
+ * @SuppressWarnings(PHPMD.ExcessiveMethodLength)
*/
public function collectMetaData(Collection $objects): void
{
- $currencies = [];
- $bills = [];
- $this->notes = [];
- $this->groups = [];
- $this->paidDates = [];
+ $currencies = [];
+ $bills = [];
+ $this->notes = [];
+ $this->groups = [];
+ $this->paidDates = [];
-
- // start with currencies:
/** @var Bill $object */
foreach ($objects as $object) {
- $id = (int)$object->transaction_currency_id;
- $bills[] = (int)$object->id;
- $currencies[$id] = $currencies[$id] ?? TransactionCurrency::find($id);
+ $id = $object->transaction_currency_id;
+ $bills[] = $object->id;
+ $currencies[$id] ??= TransactionCurrency::find($id);
}
$this->currencies = $currencies;
+ $notes = Note::whereNoteableType(Bill::class)->whereIn('noteable_id', array_keys($bills))->get();
- // continue with notes
- $notes = Note::whereNoteableType(Bill::class)->whereIn('noteable_id', array_keys($bills))->get();
/** @var Note $note */
foreach ($notes as $note) {
- $id = (int)$note->noteable_id;
+ $id = $note->noteable_id;
$this->notes[$id] = $note;
}
// grab object groups:
- $set = DB::table('object_groupables')
- ->leftJoin('object_groups', 'object_groups.id', '=', 'object_groupables.object_group_id')
- ->where('object_groupables.object_groupable_type', Bill::class)
- ->get(['object_groupables.*', 'object_groups.title', 'object_groups.order']);
+ $set = DB::table('object_groupables')
+ ->leftJoin('object_groups', 'object_groups.id', '=', 'object_groupables.object_group_id')
+ ->where('object_groupables.object_groupable_type', Bill::class)
+ ->get(['object_groupables.*', 'object_groups.title', 'object_groups.order'])
+ ;
+
/** @var ObjectGroup $entry */
foreach ($set as $entry) {
$billId = (int)$entry->object_groupable_id;
$id = (int)$entry->object_group_id;
- $order = (int)$entry->order;
+ $order = $entry->order;
$this->groups[$billId] = [
'object_group_id' => $id,
'object_group_title' => $entry->title,
'object_group_order' => $order,
];
-
}
- $this->default = app('amount')->getDefaultCurrency();
- $this->converter = new ExchangeRateConverter();
+ Log::debug(sprintf('Created new ExchangeRateConverter in %s', __METHOD__));
+ $this->default = app('amount')->getDefaultCurrency();
+ $this->converter = new ExchangeRateConverter();
// grab all paid dates:
if (null !== $this->parameters->get('start') && null !== $this->parameters->get('end')) {
- $journals = TransactionJournal::whereIn('bill_id', $bills)
- ->where('date', '>=', $this->parameters->get('start'))
- ->where('date', '<=', $this->parameters->get('end'))
- ->get(['transaction_journals.id', 'transaction_journals.transaction_group_id', 'transaction_journals.date', 'transaction_journals.bill_id']);
- $journalIds = $journals->pluck('id')->toArray();
+ $journals = TransactionJournal::whereIn('bill_id', $bills)
+ ->where('date', '>=', $this->parameters->get('start'))
+ ->where('date', '<=', $this->parameters->get('end'))
+ ->get(['transaction_journals.id', 'transaction_journals.transaction_group_id', 'transaction_journals.date', 'transaction_journals.bill_id'])
+ ;
+ $journalIds = $journals->pluck('id')->toArray();
// grab transactions for amount:
- $set = Transaction::whereIn('transaction_journal_id', $journalIds)
- ->where('transactions.amount', '<', 0)
- ->get(['transactions.id', 'transactions.transaction_journal_id', 'transactions.amount', 'transactions.foreign_amount', 'transactions.transaction_currency_id', 'transactions.foreign_currency_id']);
- // convert to array for easy finding:
+ $set = Transaction::whereIn('transaction_journal_id', $journalIds)
+ ->where('transactions.amount', '<', 0)
+ ->get(['transactions.id', 'transactions.transaction_journal_id', 'transactions.amount', 'transactions.foreign_amount', 'transactions.transaction_currency_id', 'transactions.foreign_currency_id'])
+ ;
$transactions = [];
+
/** @var Transaction $transaction */
foreach ($set as $transaction) {
- $journalId = (int)$transaction->transaction_journal_id;
+ $journalId = $transaction->transaction_journal_id;
$transactions[$journalId] = $transaction->toArray();
}
+
/** @var TransactionJournal $journal */
foreach ($journals as $journal) {
app('log')->debug(sprintf('Processing journal #%d', $journal->id));
- $transaction = $transactions[(int)$journal->id] ?? [];
- $billId = (int)$journal->bill_id;
- $currencyId = (int)$transaction['transaction_currency_id'] ?? 0;
- $currencies[$currencyId] = $currencies[$currencyId] ?? TransactionCurrency::find($currencyId);
+ $transaction = $transactions[$journal->id] ?? [];
+ $billId = (int)$journal->bill_id;
+ $currencyId = (int)($transaction['transaction_currency_id'] ?? 0);
+ $currencies[$currencyId] ??= TransactionCurrency::find($currencyId);
// foreign currency
- $foreignCurrencyId = null;
- $foreignCurrencyCode = null;
- $foreignCurrencyName = null;
- $foreignCurrencySymbol = null;
- $foreignCurrencyDp = null;
+ $foreignCurrencyId = null;
+ $foreignCurrencyCode = null;
+ $foreignCurrencyName = null;
+ $foreignCurrencySymbol = null;
+ $foreignCurrencyDp = null;
app('log')->debug('Foreign currency is NULL');
if (null !== $transaction['foreign_currency_id']) {
app('log')->debug(sprintf('Foreign currency is #%d', $transaction['foreign_currency_id']));
- $foreignCurrencyId = (int)$transaction['foreign_currency_id'];
- $currencies[$foreignCurrencyId] = $currencies[$foreignCurrencyId] ?? TransactionCurrency::find($foreignCurrencyId);
- $foreignCurrencyCode = $currencies[$foreignCurrencyId]->code;
- $foreignCurrencyName = $currencies[$foreignCurrencyId]->name;
- $foreignCurrencySymbol = $currencies[$foreignCurrencyId]->symbol;
- $foreignCurrencyDp = (int)$currencies[$foreignCurrencyId]->decimal_places;
+ $foreignCurrencyId = (int)$transaction['foreign_currency_id'];
+ $currencies[$foreignCurrencyId] ??= TransactionCurrency::find($foreignCurrencyId);
+ $foreignCurrencyCode = $currencies[$foreignCurrencyId]->code;
+ $foreignCurrencyName = $currencies[$foreignCurrencyId]->name;
+ $foreignCurrencySymbol = $currencies[$foreignCurrencyId]->symbol;
+ $foreignCurrencyDp = $currencies[$foreignCurrencyId]->decimal_places;
}
$this->paidDates[$billId][] = [
'transaction_group_id' => (string)$journal->id,
'transaction_journal_id' => (string)$journal->transaction_group_id,
'date' => $journal->date->toAtomString(),
- 'currency_id' => (int)$currencies[$currencyId]->id,
+ 'currency_id' => $currencies[$currencyId]->id,
'currency_code' => $currencies[$currencyId]->code,
'currency_name' => $currencies[$currencyId]->name,
'currency_symbol' => $currencies[$currencyId]->symbol,
- 'currency_decimal_places' => (int)$currencies[$currencyId]->decimal_places,
- 'native_currency_id' => (int)$currencies[$currencyId]->id,
+ 'currency_decimal_places' => $currencies[$currencyId]->decimal_places,
+ 'native_currency_id' => $currencies[$currencyId]->id,
'native_currency_code' => $currencies[$currencyId]->code,
'native_currency_symbol' => $currencies[$currencyId]->symbol,
- 'native_currency_decimal_places' => (int)$currencies[$currencyId]->decimal_places,
+ 'native_currency_decimal_places' => $currencies[$currencyId]->decimal_places,
'foreign_currency_id' => $foreignCurrencyId,
'foreign_currency_code' => $foreignCurrencyCode,
'foreign_currency_name' => $foreignCurrencyName,
@@ -186,29 +179,27 @@ class BillTransformer extends AbstractTransformer
/**
* Transform the bill.
- *
- * @param Bill $bill
- *
- * @return array
*/
public function transform(Bill $bill): array
{
- $paidData = $this->paidDates[(int)$bill->id] ?? [];
- $nextExpectedMatch = $this->nextExpectedMatch($bill, $this->paidDates[(int)$bill->id] ?? []);
- $payDates = $this->payDates($bill);
- $currency = $this->currencies[(int)$bill->transaction_currency_id];
- $group = $this->groups[(int)$bill->id] ?? null;
+ $paidData = $this->paidDates[$bill->id] ?? [];
+ $nextExpectedMatch = $this->nextExpectedMatch($bill, $this->paidDates[$bill->id] ?? []);
+ $payDates = $this->payDates($bill);
+ $currency = $this->currencies[$bill->transaction_currency_id];
+ $group = $this->groups[$bill->id] ?? null;
// date for currency conversion
- /** @var Carbon|null $startParam */
- $startParam = $this->parameters->get('start');
- /** @var Carbon|null $start */
- $date = null === $startParam ? today() : clone $startParam;
+ /** @var null|Carbon $startParam */
+ $startParam = $this->parameters->get('start');
+ /** @var null|Carbon $date */
+ $date = null === $startParam ? today() : clone $startParam;
$nextExpectedMatchDiff = $this->getNextExpectedMatchDiff($nextExpectedMatch, $payDates);
+ $this->converter->summarize();
+
return [
- 'id' => (int)$bill->id,
+ 'id' => $bill->id,
'created_at' => $bill->created_at->toAtomString(),
'updated_at' => $bill->updated_at->toAtomString(),
'name' => $bill->name,
@@ -220,20 +211,20 @@ class BillTransformer extends AbstractTransformer
'currency_code' => $currency->code,
'currency_name' => $currency->name,
'currency_symbol' => $currency->symbol,
- 'currency_decimal_places' => (int)$currency->decimal_places,
+ 'currency_decimal_places' => $currency->decimal_places,
'native_currency_id' => $this->default->id,
'native_currency_code' => $this->default->code,
'native_currency_name' => $this->default->name,
'native_currency_symbol' => $this->default->symbol,
- 'native_currency_decimal_places' => (int)$this->default->decimal_places,
+ 'native_currency_decimal_places' => $this->default->decimal_places,
'date' => $bill->date->toAtomString(),
'end_date' => $bill->end_date?->toAtomString(),
'extension_date' => $bill->extension_date?->toAtomString(),
'repeat_freq' => $bill->repeat_freq,
- 'skip' => (int)$bill->skip,
+ 'skip' => $bill->skip,
'active' => $bill->active,
- 'order' => (int)$bill->order,
- 'notes' => $this->notes[(int)$bill->id] ?? null,
+ 'order' => $bill->order,
+ 'notes' => $this->notes[$bill->id] ?? null,
'object_group_id' => $group ? $group['object_group_id'] : null,
'object_group_order' => $group ? $group['object_group_order'] : null,
'object_group_title' => $group ? $group['object_group_title'] : null,
@@ -252,11 +243,6 @@ class BillTransformer extends AbstractTransformer
/**
* Get the data the bill was paid and predict the next expected match.
- *
- * @param Bill $bill
- * @param array $dates
- *
- * @return Carbon
*/
protected function nextExpectedMatch(Bill $bill, array $dates): Carbon
{
@@ -264,10 +250,11 @@ class BillTransformer extends AbstractTransformer
// 2023-07-18 this particular date is used to search for the last paid date.
// 2023-07-18 the cloned $searchDate is used to grab the correct transactions.
- /** @var Carbon|null $startParam */
- $startParam = $this->parameters->get('start');
- /** @var Carbon|null $start */
- $start = null === $startParam ? today() : clone $startParam;
+ /** @var null|Carbon $startParam */
+ $startParam = $this->parameters->get('start');
+
+ /** @var null|Carbon $start */
+ $start = null === $startParam ? today() : clone $startParam;
$start->subDay();
$lastPaidDate = $this->lastPaidDate($dates, $start);
@@ -280,21 +267,15 @@ class BillTransformer extends AbstractTransformer
$nextMatch = app('navigation')->addPeriod($nextMatch, $bill->repeat_freq, $bill->skip);
}
if ($nextMatch->isSameDay($lastPaidDate)) {
- /*
- * Add another period because it's the same day as the last paid date.
- */
+ // Add another period because it's the same day as the last paid date.
$nextMatch = app('navigation')->addPeriod($nextMatch, $bill->repeat_freq, $bill->skip);
}
+
return $nextMatch;
}
/**
* Returns the latest date in the set, or start when set is empty.
- *
- * @param Collection $dates
- * @param Carbon $default
- *
- * @return Carbon
*/
protected function lastPaidDate(array $dates, Carbon $default): Carbon
{
@@ -302,6 +283,7 @@ class BillTransformer extends AbstractTransformer
return $default;
}
$latest = $dates[0]['date'];
+
/** @var array $row */
foreach ($dates as $row) {
$carbon = new Carbon($row['date']);
@@ -313,16 +295,11 @@ class BillTransformer extends AbstractTransformer
return new Carbon($latest);
}
- /**
- * @param Bill $bill
- *
- * @return array
- */
protected function payDates(Bill $bill): array
{
- //app('log')->debug(sprintf('Now in payDates() for bill #%d', $bill->id));
+ // app('log')->debug(sprintf('Now in payDates() for bill #%d', $bill->id));
if (null === $this->parameters->get('start') || null === $this->parameters->get('end')) {
- //app('log')->debug('No start or end date, give empty array.');
+ // app('log')->debug('No start or end date, give empty array.');
return [];
}
@@ -330,7 +307,7 @@ class BillTransformer extends AbstractTransformer
$currentStart = clone $this->parameters->get('start');
// 2023-06-23 subDay to fix 7655
$currentStart->subDay();
- $loop = 0;
+ $loop = 0;
while ($currentStart <= $this->parameters->get('end')) {
$nextExpectedMatch = $this->nextDateMatch($bill, $currentStart);
// If nextExpectedMatch is after end, we continue:
@@ -340,13 +317,13 @@ class BillTransformer extends AbstractTransformer
// add to set
$set->push(clone $nextExpectedMatch);
$nextExpectedMatch->addDay();
- $currentStart = clone $nextExpectedMatch;
- $loop++;
+ $currentStart = clone $nextExpectedMatch;
+ ++$loop;
if ($loop > 4) {
break;
}
}
- $simple = $set->map(
+ $simple = $set->map(
static function (Carbon $date) {
return $date->toAtomString();
}
@@ -359,31 +336,22 @@ class BillTransformer extends AbstractTransformer
* Given a bill and a date, this method will tell you at which moment this bill expects its next
* transaction. Whether or not it is there already, is not relevant.
*
- * @param Bill $bill
- * @param Carbon $date
- *
- * @return Carbon
+ * TODO this method is bad compared to the v1 one.
*/
protected function nextDateMatch(Bill $bill, Carbon $date): Carbon
{
- //app('log')->debug(sprintf('Now in nextDateMatch(%d, %s)', $bill->id, $date->format('Y-m-d')));
+ // app('log')->debug(sprintf('Now in nextDateMatch(%d, %s)', $bill->id, $date->format('Y-m-d')));
$start = clone $bill->date;
- //app('log')->debug(sprintf('Bill start date is %s', $start->format('Y-m-d')));
+ // app('log')->debug(sprintf('Bill start date is %s', $start->format('Y-m-d')));
while ($start < $date) {
$start = app('navigation')->addPeriod($start, $bill->repeat_freq, $bill->skip);
}
- //app('log')->debug(sprintf('End of loop, bill start date is now %s', $start->format('Y-m-d')));
+ // app('log')->debug(sprintf('End of loop, bill start date is now %s', $start->format('Y-m-d')));
return $start;
}
- /**
- * @param Carbon $next
- * @param array $dates
- *
- * @return string
- */
private function getNextExpectedMatchDiff(Carbon $next, array $dates): string
{
if ($next->isToday()) {
@@ -393,9 +361,8 @@ class BillTransformer extends AbstractTransformer
if (null === $current) {
return trans('firefly.not_expected_period');
}
- $carbon = new Carbon($current);
+ $carbon = new Carbon($current);
+
return $carbon->diffForHumans(today(config('app.timezone')), CarbonInterface::DIFF_RELATIVE_TO_NOW);
}
-
-
}
diff --git a/app/Transformers/V2/BudgetLimitTransformer.php b/app/Transformers/V2/BudgetLimitTransformer.php
index 0b46b0fcae..ff0d15bd59 100644
--- a/app/Transformers/V2/BudgetLimitTransformer.php
+++ b/app/Transformers/V2/BudgetLimitTransformer.php
@@ -32,15 +32,11 @@ use League\Fractal\Resource\Item;
*/
class BudgetLimitTransformer extends AbstractTransformer
{
- /** @var string[] */
protected array $availableIncludes
= [
'budget',
];
- /**
- * @inheritDoc
- */
public function collectMetaData(Collection $objects): void
{
// TODO: Implement collectMetaData() method.
@@ -49,8 +45,6 @@ class BudgetLimitTransformer extends AbstractTransformer
/**
* Include Budget
*
- * @param BudgetLimit $limit
- *
* @return Item
*/
public function includeBudget(BudgetLimit $limit)
@@ -60,10 +54,6 @@ class BudgetLimitTransformer extends AbstractTransformer
/**
* Transform the note.
- *
- * @param BudgetLimit $budgetLimit
- *
- * @return array
*/
public function transform(BudgetLimit $budgetLimit): array
{
@@ -81,13 +71,13 @@ class BudgetLimitTransformer extends AbstractTransformer
$currencySymbol = null;
if (null !== $currency) {
$amount = $budgetLimit->amount;
- $currencyId = (int)$currency->id;
+ $currencyId = $currency->id;
$currencyName = $currency->name;
$currencyCode = $currency->code;
$currencySymbol = $currency->symbol;
$currencyDecimalPlaces = $currency->decimal_places;
}
- $amount = number_format((float)$amount, $currencyDecimalPlaces, '.', '');
+ $amount = number_format((float)$amount, $currencyDecimalPlaces, '.', '');
return [
'id' => (string)$budgetLimit->id,
@@ -103,7 +93,7 @@ class BudgetLimitTransformer extends AbstractTransformer
'currency_symbol' => $currencySymbol,
'amount' => $amount,
'period' => $budgetLimit->period,
- //'spent' => $expenses[$currencyId]['sum'] ?? '0',
+ // 'spent' => $expenses[$currencyId]['sum'] ?? '0',
'links' => [
[
'rel' => 'self',
diff --git a/app/Transformers/V2/BudgetTransformer.php b/app/Transformers/V2/BudgetTransformer.php
index 8d25a2628d..eb86c28a7b 100644
--- a/app/Transformers/V2/BudgetTransformer.php
+++ b/app/Transformers/V2/BudgetTransformer.php
@@ -32,24 +32,19 @@ use Symfony\Component\HttpFoundation\ParameterBag;
*/
class BudgetTransformer extends AbstractTransformer
{
- //private OperationsRepositoryInterface $opsRepository;
- //private BudgetRepositoryInterface $repository;
+ // private OperationsRepositoryInterface $opsRepository;
+ // private BudgetRepositoryInterface $repository;
/**
* BudgetTransformer constructor.
- *
-
*/
public function __construct()
{
- //$this->opsRepository = app(OperationsRepositoryInterface::class);
- //$this->repository = app(BudgetRepositoryInterface::class);
+ // $this->opsRepository = app(OperationsRepositoryInterface::class);
+ // $this->repository = app(BudgetRepositoryInterface::class);
$this->parameters = new ParameterBag();
}
- /**
- * @inheritDoc
- */
public function collectMetaData(Collection $objects): void
{
// TODO: Implement collectMetaData() method.
@@ -57,17 +52,13 @@ class BudgetTransformer extends AbstractTransformer
/**
* Transform a budget.
- *
- * @param Budget $budget
- *
- * @return array
*/
public function transform(Budget $budget): array
{
- //$this->opsRepository->setUser($budget->user);
- $start = $this->parameters->get('start');
- $end = $this->parameters->get('end');
- //$autoBudget = $this->repository->getAutoBudget($budget);
+ // $this->opsRepository->setUser($budget->user);
+ // $start = $this->parameters->get('start');
+ // $end = $this->parameters->get('end');
+ // $autoBudget = $this->repository->getAutoBudget($budget);
// $spent = [];
// if (null !== $start && null !== $end) {
// $spent = $this->beautify($this->opsRepository->sumExpenses($start, $end, null, new Collection([$budget])));
@@ -115,20 +106,4 @@ class BudgetTransformer extends AbstractTransformer
],
];
}
-
- /**
- * @param array $array
- *
- * @return array
- */
- private function beautify(array $array): array
- {
- $return = [];
- foreach ($array as $data) {
- $data['sum'] = number_format((float)$data['sum'], (int)$data['currency_decimal_places'], '.', '');
- $return[] = $data;
- }
-
- return $return;
- }
}
diff --git a/app/Transformers/V2/CurrencyTransformer.php b/app/Transformers/V2/CurrencyTransformer.php
new file mode 100644
index 0000000000..9466b253cf
--- /dev/null
+++ b/app/Transformers/V2/CurrencyTransformer.php
@@ -0,0 +1,59 @@
+.
+ */
+
+declare(strict_types=1);
+
+namespace FireflyIII\Transformers\V2;
+
+use FireflyIII\Models\TransactionCurrency;
+use Illuminate\Support\Collection;
+
+/**
+ * Class CurrencyTransformer
+ */
+class CurrencyTransformer extends AbstractTransformer
+{
+ public function collectMetaData(Collection $objects): void {}
+
+ /**
+ * Transform the currency.
+ */
+ public function transform(TransactionCurrency $currency): array
+ {
+ return [
+ 'id' => $currency->id,
+ 'created_at' => $currency->created_at->toAtomString(),
+ 'updated_at' => $currency->updated_at->toAtomString(),
+ 'default' => $currency->userGroupDefault,
+ 'enabled' => $currency->userGroupEnabled,
+ 'name' => $currency->name,
+ 'code' => $currency->code,
+ 'symbol' => $currency->symbol,
+ 'decimal_places' => $currency->decimal_places,
+ 'links' => [
+ [
+ 'rel' => 'self',
+ 'uri' => '/currencies/'.$currency->id,
+ ],
+ ],
+ ];
+ }
+}
diff --git a/app/Transformers/V2/PiggyBankTransformer.php b/app/Transformers/V2/PiggyBankTransformer.php
index 82e9b05de6..bf16a99608 100644
--- a/app/Transformers/V2/PiggyBankTransformer.php
+++ b/app/Transformers/V2/PiggyBankTransformer.php
@@ -36,7 +36,7 @@ use FireflyIII\Models\TransactionJournal;
use FireflyIII\Support\Http\Api\ExchangeRateConverter;
use Illuminate\Support\Collection;
use Illuminate\Support\Facades\DB;
-use JsonException;
+use Illuminate\Support\Facades\Log;
/**
* Class PiggyBankTransformer
@@ -56,8 +56,6 @@ class PiggyBankTransformer extends AbstractTransformer
/**
* PiggyBankTransformer constructor.
- *
-
*/
public function __construct()
{
@@ -71,78 +69,78 @@ class PiggyBankTransformer extends AbstractTransformer
// $this->piggyRepos = app(PiggyBankRepositoryInterface::class);
}
- /**
- * @inheritDoc
- */
public function collectMetaData(Collection $objects): void
{
// TODO move to repository (does not exist yet)
$piggyBanks = $objects->pluck('id')->toArray();
$accountInfo = Account::whereIn('id', $objects->pluck('account_id')->toArray())->get();
$currencyPreferences = AccountMeta::where('name', '"currency_id"')->whereIn('account_id', $objects->pluck('account_id')->toArray())->get();
+ $currencies = [];
+
/** @var Account $account */
foreach ($accountInfo as $account) {
- $id = (int)$account->id;
+ $id = $account->id;
$this->accounts[$id] = [
'name' => $account->name,
];
}
+
/** @var AccountMeta $preference */
foreach ($currencyPreferences as $preference) {
$currencyId = (int)$preference->data;
- $accountId = (int)$preference->account_id;
- $currencies[$currencyId] = $currencies[$currencyId] ?? TransactionJournal::find($currencyId);
+ $accountId = $preference->account_id;
+ $currencies[$currencyId] ??= TransactionJournal::find($currencyId);
$this->currencies[$accountId] = $currencies[$currencyId];
}
// grab object groups:
- $set = DB::table('object_groupables')
- ->leftJoin('object_groups', 'object_groups.id', '=', 'object_groupables.object_group_id')
- ->where('object_groupables.object_groupable_type', PiggyBank::class)
- ->get(['object_groupables.*', 'object_groups.title', 'object_groups.order']);
+ $set = DB::table('object_groupables')
+ ->leftJoin('object_groups', 'object_groups.id', '=', 'object_groupables.object_group_id')
+ ->where('object_groupables.object_groupable_type', PiggyBank::class)
+ ->get(['object_groupables.*', 'object_groups.title', 'object_groups.order'])
+ ;
+
/** @var ObjectGroup $entry */
foreach ($set as $entry) {
$piggyBankId = (int)$entry->object_groupable_id;
$id = (int)$entry->object_group_id;
- $order = (int)$entry->order;
+ $order = $entry->order;
$this->groups[$piggyBankId] = [
- 'object_group_id' => $id,
+ 'object_group_id' => (string)$id,
'object_group_title' => $entry->title,
'object_group_order' => $order,
];
-
}
// grab repetitions (for current amount):
- $repetitions = PiggyBankRepetition::whereIn('piggy_bank_id', $piggyBanks)->get();
+ $repetitions = PiggyBankRepetition::whereIn('piggy_bank_id', $piggyBanks)->get();
+
/** @var PiggyBankRepetition $repetition */
foreach ($repetitions as $repetition) {
- $this->repetitions[(int)$repetition->piggy_bank_id] = [
+ $this->repetitions[$repetition->piggy_bank_id] = [
'amount' => $repetition->currentamount,
];
}
// grab notes
// continue with notes
- $notes = Note::whereNoteableType(PiggyBank::class)->whereIn('noteable_id', array_keys($piggyBanks))->get();
+ $notes = Note::whereNoteableType(PiggyBank::class)->whereIn('noteable_id', array_keys($piggyBanks))->get();
+
/** @var Note $note */
foreach ($notes as $note) {
- $id = (int)$note->noteable_id;
+ $id = $note->noteable_id;
$this->notes[$id] = $note;
}
- $this->default = app('amount')->getDefaultCurrencyByUser(auth()->user());
- $this->converter = new ExchangeRateConverter();
+ Log::debug(sprintf('Created new ExchangeRateConverter in %s', __METHOD__));
+ $this->default = app('amount')->getDefaultCurrencyByUserGroup(auth()->user()->userGroup);
+ $this->converter = new ExchangeRateConverter();
}
/**
* Transform the piggy bank.
*
- * @param PiggyBank $piggyBank
- *
- * @return array
* @throws FireflyException
- * @throws JsonException
*/
public function transform(PiggyBank $piggyBank): array
{
@@ -179,15 +177,15 @@ class PiggyBankTransformer extends AbstractTransformer
$nativeSavePerMonth = null;
$startDate = $piggyBank->startdate?->format('Y-m-d');
$targetDate = $piggyBank->targetdate?->format('Y-m-d');
- $accountId = (int)$piggyBank->account_id;
+ $accountId = $piggyBank->account_id;
$accountName = $this->accounts[$accountId]['name'] ?? null;
$currency = $this->currencies[$accountId] ?? $this->default;
- $currentAmount = app('steam')->bcround($this->repetitions[(int)$piggyBank->id]['amount'] ?? '0', $currency->decimal_places);
+ $currentAmount = app('steam')->bcround($this->repetitions[$piggyBank->id]['amount'] ?? '0', $currency->decimal_places);
$nativeCurrentAmount = $this->converter->convert($this->default, $currency, today(), $currentAmount);
$targetAmount = $piggyBank->targetamount;
$nativeTargetAmount = $this->converter->convert($this->default, $currency, today(), $targetAmount);
- $note = $this->notes[(int)$piggyBank->id] ?? null;
- $group = $this->groups[(int)$piggyBank->id] ?? null;
+ $note = $this->notes[$piggyBank->id] ?? null;
+ $group = $this->groups[$piggyBank->id] ?? null;
if (0 !== bccomp($targetAmount, '0')) { // target amount is not 0.00
$leftToSave = bcsub($targetAmount, $currentAmount);
@@ -196,6 +194,7 @@ class PiggyBankTransformer extends AbstractTransformer
$savePerMonth = $this->getSuggestedMonthlyAmount($currentAmount, $targetAmount, $piggyBank->startdate, $piggyBank->targetdate);
$nativeSavePerMonth = $this->converter->convert($this->default, $currency, today(), $savePerMonth);
}
+ $this->converter->summarize();
return [
'id' => (string)$piggyBank->id,
@@ -207,11 +206,11 @@ class PiggyBankTransformer extends AbstractTransformer
'currency_id' => (string)$currency->id,
'currency_code' => $currency->code,
'currency_symbol' => $currency->symbol,
- 'currency_decimal_places' => (int)$currency->decimal_places,
+ 'currency_decimal_places' => $currency->decimal_places,
'native_currency_id' => (string)$this->default->id,
'native_currency_code' => $this->default->code,
'native_currency_symbol' => $this->default->symbol,
- 'native_currency_decimal_places' => (int)$this->default->decimal_places,
+ 'native_currency_decimal_places' => $this->default->decimal_places,
'current_amount' => $currentAmount,
'native_current_amount' => $nativeCurrentAmount,
'target_amount' => $targetAmount,
@@ -223,7 +222,7 @@ class PiggyBankTransformer extends AbstractTransformer
'native_save_per_month' => $nativeSavePerMonth,
'start_date' => $startDate,
'target_date' => $targetDate,
- 'order' => (int)$piggyBank->order,
+ 'order' => $piggyBank->order,
'active' => $piggyBank->active,
'notes' => $note,
'object_group_id' => $group ? $group['object_group_id'] : null,
@@ -232,15 +231,12 @@ class PiggyBankTransformer extends AbstractTransformer
'links' => [
[
'rel' => 'self',
- 'uri' => '/piggy_banks/' . $piggyBank->id,
+ 'uri' => '/piggy_banks/'.$piggyBank->id,
],
],
];
}
- /**
- * @return string|null
- */
private function getSuggestedMonthlyAmount(string $currentAmount, string $targetAmount, ?Carbon $startDate, ?Carbon $targetDate): string
{
$savePerMonth = '0';
diff --git a/app/Transformers/V2/PreferenceTransformer.php b/app/Transformers/V2/PreferenceTransformer.php
index 44131339f3..5736daf853 100644
--- a/app/Transformers/V2/PreferenceTransformer.php
+++ b/app/Transformers/V2/PreferenceTransformer.php
@@ -31,9 +31,6 @@ use Illuminate\Support\Collection;
*/
class PreferenceTransformer extends AbstractTransformer
{
- /**
- * @inheritDoc
- */
public function collectMetaData(Collection $objects): void
{
// TODO: Implement collectMetaData() method.
@@ -41,15 +38,11 @@ class PreferenceTransformer extends AbstractTransformer
/**
* Transform the preference
- *
- * @param Preference $preference
- *
- * @return array
*/
public function transform(Preference $preference): array
{
return [
- 'id' => (int)$preference->id,
+ 'id' => $preference->id,
'created_at' => $preference->created_at->toAtomString(),
'updated_at' => $preference->updated_at->toAtomString(),
'name' => $preference->name,
diff --git a/app/Transformers/V2/TransactionGroupTransformer.php b/app/Transformers/V2/TransactionGroupTransformer.php
index e67db9c145..7838b24fca 100644
--- a/app/Transformers/V2/TransactionGroupTransformer.php
+++ b/app/Transformers/V2/TransactionGroupTransformer.php
@@ -26,138 +26,296 @@ namespace FireflyIII\Transformers\V2;
use Carbon\Carbon;
use FireflyIII\Exceptions\FireflyException;
+use FireflyIII\Models\Budget;
+use FireflyIII\Models\Category;
+use FireflyIII\Models\Location;
use FireflyIII\Models\Note;
+use FireflyIII\Models\Transaction;
use FireflyIII\Models\TransactionCurrency;
+use FireflyIII\Models\TransactionGroup;
use FireflyIII\Models\TransactionJournal;
use FireflyIII\Models\TransactionJournalMeta;
use FireflyIII\Models\TransactionType;
-use FireflyIII\Support\Http\Api\ConvertsExchangeRates;
use FireflyIII\Support\Http\Api\ExchangeRateConverter;
use FireflyIII\Support\NullArrayObject;
use Illuminate\Support\Collection;
use Illuminate\Support\Facades\DB;
-use stdClass;
/**
* Class TransactionGroupTransformer
*/
class TransactionGroupTransformer extends AbstractTransformer
{
- use ConvertsExchangeRates;
+ private array $accountTypes = []; // account types collection.
+ private ExchangeRateConverter $converter; // collection of all journals and some important meta-data.
+ private array $currencies = [];
+ private TransactionCurrency $default; // collection of all currencies for this transformer.
+ private array $journals = [];
+ private array $objects = [];
- private ExchangeRateConverter $converter;
- private array $currencies = [];
- private TransactionCurrency $default;
- private array $meta;
- private array $notes;
- private array $tags;
+ // private array $currencies = [];
+ // private array $transactionTypes = [];
+ // private array $meta = [];
+ // private array $notes = [];
+ // private array $locations = [];
+ // private array $tags = [];
+ // private array $amounts = [];
+ // private array $foreignAmounts = [];
+ // private array $journalCurrencies = [];
+ // private array $foreignCurrencies = [];
- /**
- * @inheritDoc
- */
public function collectMetaData(Collection $objects): void
{
- // start with currencies:
- $currencies = [];
- $journals = [];
- /** @var array $object */
+ $collectForObjects = false;
+
+ /** @var array|TransactionGroup $object */
foreach ($objects as $object) {
- foreach ($object['sums'] as $sum) {
- $id = (int)$sum['currency_id'];
- $currencies[$id] = $currencies[$id] ?? TransactionCurrency::find($sum['currency_id']);
+ if (is_array($object)) {
+ $this->collectForArray($object);
}
- /** @var array $transaction */
- foreach ($object['transactions'] as $transaction) {
- $id = (int)$transaction['transaction_journal_id'];
- $journals[$id] = [];
+ if ($object instanceof TransactionGroup) {
+ $this->collectForObject($object);
+ $collectForObjects = true;
}
}
- $this->currencies = $currencies;
- $this->default = app('amount')->getDefaultCurrency();
- // grab meta for all journals:
- $meta = TransactionJournalMeta::whereIn('transaction_journal_id', array_keys($journals))->get();
- /** @var TransactionJournalMeta $entry */
- foreach ($meta as $entry) {
- $id = (int)$entry->transaction_journal_id;
- $this->meta[$id][$entry->name] = $entry->data;
+ $this->default = app('amount')->getDefaultCurrency();
+ $this->converter = new ExchangeRateConverter();
+
+ $this->collectAllMetaData();
+ $this->collectAllNotes();
+ $this->collectAllLocations();
+ $this->collectAllTags();
+ if ($collectForObjects) {
+ $this->collectAllCurrencies();
+ // $this->collectAllAmounts();
+ // $this->collectTransactionTypes();
+ // $this->collectAccounts();
+ // source accounts
+ // destination accounts
}
-
- // grab all notes for all journals:
- $notes = Note::whereNoteableType(TransactionJournal::class)->whereIn('noteable_id', array_keys($journals))->get();
- /** @var Note $note */
- foreach ($notes as $note) {
- $id = (int)$note->noteable_id;
- $this->notes[$id] = $note;
- }
-
- // grab all tags for all journals:
- $tags = DB::table('tag_transaction_journal')
- ->leftJoin('tags', 'tags.id', 'tag_transaction_journal.tag_id')
- ->whereIn('tag_transaction_journal.transaction_journal_id', array_keys($journals))
- ->get(['tag_transaction_journal.transaction_journal_id', 'tags.tag']);
- /** @var stdClass $tag */
- foreach ($tags as $tag) {
- $id = (int)$tag->transaction_journal_id;
- $this->tags[$id][] = $tag->tag;
- }
-
- // create converter
- $this->converter = new ExchangeRateConverter();
}
- /**
- * @param array $group
- *
- * @return array
- */
- public function transform(array $group): array
+ private function collectForArray(array $object): void
{
- $first = reset($group['transactions']);
+ foreach ($object['sums'] as $sum) {
+ $this->currencies[(int)$sum['currency_id']] ??= TransactionCurrency::find($sum['currency_id']);
+ }
+
+ /** @var array $transaction */
+ foreach ($object['transactions'] as $transaction) {
+ $this->journals[(int)$transaction['transaction_journal_id']] = [];
+ }
+ }
+
+ private function collectForObject(TransactionGroup $object): void
+ {
+ foreach ($object->transactionJournals as $journal) {
+ $this->journals[$journal->id] = [];
+ $this->objects[] = $journal;
+ }
+ }
+
+ private function collectAllMetaData(): void
+ {
+ $meta = TransactionJournalMeta::whereIn('transaction_journal_id', array_keys($this->journals))->get();
+
+ /** @var TransactionJournalMeta $entry */
+ foreach ($meta as $entry) {
+ $id = $entry->transaction_journal_id;
+ $this->journals[$id]['meta'] ??= [];
+ $this->journals[$id]['meta'][$entry->name] = $entry->data;
+ }
+ }
+
+ private function collectAllNotes(): void
+ {
+ // grab all notes for all journals:
+ $notes = Note::whereNoteableType(TransactionJournal::class)->whereIn('noteable_id', array_keys($this->journals))->get();
+
+ /** @var Note $note */
+ foreach ($notes as $note) {
+ $id = $note->noteable_id;
+ $this->journals[$id]['notes'] = $note->text;
+ }
+ }
+
+ private function collectAllLocations(): void
+ {
+ // grab all locations for all journals:
+ $locations = Location::whereLocatableType(TransactionJournal::class)->whereIn('locatable_id', array_keys($this->journals))->get();
+
+ /** @var Location $location */
+ foreach ($locations as $location) {
+ $id = $location->locatable_id;
+ $this->journals[$id]['location'] = [
+ 'latitude' => $location->latitude,
+ 'longitude' => $location->longitude,
+ 'zoom_level' => $location->zoom_level,
+ ];
+ }
+ }
+
+ private function collectAllTags(): void
+ {
+ // grab all tags for all journals:
+ $tags = DB::table('tag_transaction_journal')
+ ->leftJoin('tags', 'tags.id', 'tag_transaction_journal.tag_id')
+ ->whereIn('tag_transaction_journal.transaction_journal_id', array_keys($this->journals))
+ ->get(['tag_transaction_journal.transaction_journal_id', 'tags.tag'])
+ ;
+
+ /** @var \stdClass $tag */
+ foreach ($tags as $tag) {
+ $id = (int)$tag->transaction_journal_id;
+ $this->journals[$id]['tags'][] = $tag->tag;
+ }
+ }
+
+ private function collectAllCurrencies(): void
+ {
+ /** @var TransactionJournal $journal */
+ foreach ($this->objects as $journal) {
+ $id = $journal->id;
+ $this->journals[$id]['reconciled'] = false;
+ $this->journals[$id]['foreign_amount'] = null;
+ $this->journals[$id]['foreign_currency_id'] = null;
+ $this->journals[$id]['amount'] = null;
+ $this->journals[$id]['currency_id'] = null;
+ $this->journals[$id]['type'] = $journal->transactionType->type;
+ $this->journals[$id]['budget_id'] = null;
+ $this->journals[$id]['budget_name'] = null;
+ $this->journals[$id]['category_id'] = null;
+ $this->journals[$id]['category_name'] = null;
+ $this->journals[$id]['bill_id'] = null;
+ $this->journals[$id]['bill_name'] = null;
+
+ // collect budget:
+ /** @var null|Budget $budget */
+ $budget = $journal->budgets()->first();
+ if (null !== $budget) {
+ $this->journals[$id]['budget_id'] = (string)$budget->id;
+ $this->journals[$id]['budget_name'] = $budget->name;
+ }
+
+ // collect category:
+ /** @var null|Category $category */
+ $category = $journal->categories()->first();
+ if (null !== $category) {
+ $this->journals[$id]['category_id'] = (string)$category->id;
+ $this->journals[$id]['category_name'] = $category->name;
+ }
+
+ // collect bill:
+ if (null !== $journal->bill_id) {
+ $bill = $journal->bill;
+ $this->journals[$id]['bill_id'] = (string)$bill->id;
+ $this->journals[$id]['bill_name'] = $bill->name;
+ }
+
+ /** @var Transaction $transaction */
+ foreach ($journal->transactions as $transaction) {
+ if (-1 === bccomp($transaction->amount, '0')) {
+ // only collect source account info
+ $account = $transaction->account;
+ $this->accountTypes[$account->account_type_id] ??= $account->accountType->type;
+ $this->journals[$id]['source_account_name'] = $account->name;
+ $this->journals[$id]['source_account_iban'] = $account->iban;
+ $this->journals[$id]['source_account_type'] = $this->accountTypes[$account->account_type_id];
+ $this->journals[$id]['source_account_id'] = $transaction->account_id;
+ $this->journals[$id]['reconciled'] = $transaction->reconciled;
+
+ continue;
+ }
+
+ // add account
+ $account = $transaction->account;
+ $this->accountTypes[$account->account_type_id] ??= $account->accountType->type;
+ $this->journals[$id]['destination_account_name'] = $account->name;
+ $this->journals[$id]['destination_account_iban'] = $account->iban;
+ $this->journals[$id]['destination_account_type'] = $this->accountTypes[$account->account_type_id];
+ $this->journals[$id]['destination_account_id'] = $transaction->account_id;
+
+ // find and set currency
+ $currencyId = $transaction->transaction_currency_id;
+ $this->currencies[$currencyId] ??= $transaction->transactionCurrency;
+ $this->journals[$id]['currency_id'] = $currencyId;
+ $this->journals[$id]['amount'] = $transaction->amount;
+ // find and set foreign currency
+ if (null !== $transaction->foreign_currency_id) {
+ $foreignCurrencyId = $transaction->foreign_currency_id;
+ $this->currencies[$foreignCurrencyId] ??= $transaction->foreignCurrency;
+ $this->journals[$id]['foreign_currency_id'] = $foreignCurrencyId;
+ $this->journals[$id]['foreign_amount'] = $transaction->foreign_amount;
+ }
+
+ // find and set destination account info.
+ }
+ }
+ }
+
+ public function transform(array|TransactionGroup $group): array
+ {
+ if (is_array($group)) {
+ $first = reset($group['transactions']);
+
+ return [
+ 'id' => (string)$group['id'],
+ 'created_at' => $group['created_at']->toAtomString(),
+ 'updated_at' => $group['updated_at']->toAtomString(),
+ 'user' => (string)$first['user_id'],
+ 'user_group' => (string)$first['user_group_id'],
+ 'group_title' => $group['title'] ?? null,
+ 'transactions' => $this->transformTransactions($group['transactions'] ?? []),
+ 'links' => [
+ [
+ 'rel' => 'self',
+ 'uri' => sprintf('/transactions/%d', $group['id']),
+ ],
+ ],
+ ];
+ }
+
return [
- 'id' => (string)$group['id'],
- 'created_at' => $first['created_at']->toAtomString(),
- 'updated_at' => $first['updated_at']->toAtomString(),
- 'user' => (string)$first['user_id'],
- 'user_group' => (string)$first['user_group_id'],
- 'group_title' => $group['title'] ?? null,
- 'transactions' => $this->transformTransactions($group['transactions'] ?? []),
+ 'id' => (string)$group->id,
+ 'created_at' => $group->created_at->toAtomString(),
+ 'updated_at' => $group->created_at->toAtomString(),
+ 'user' => (string)$group->user_id,
+ 'user_group' => (string)$group->user_group_id,
+ 'group_title' => $group->title ?? null,
+ 'transactions' => $this->transformJournals($group),
'links' => [
[
'rel' => 'self',
- 'uri' => sprintf('/transactions/%d', $group['id']),
+ 'uri' => sprintf('/transactions/%d', $group->id),
],
],
];
}
- /**
- * @param array $transactions
- *
- * @return array
- */
private function transformTransactions(array $transactions): array
{
$return = [];
+
/** @var array $transaction */
foreach ($transactions as $transaction) {
$return[] = $this->transformTransaction($transaction);
}
+
return $return;
}
/**
- * @param array $transaction
- *
- * @return array
* @throws FireflyException
+ *
+ * @SuppressWarnings(PHPMD.ExcessiveMethodLength)
*/
private function transformTransaction(array $transaction): array
{
- $transaction = new NullArrayObject($transaction);
- $type = $this->stringFromArray($transaction, 'transaction_type_type', TransactionType::WITHDRAWAL);
- $journalId = (int)$transaction['transaction_journal_id'];
- $meta = new NullArrayObject($this->meta[$journalId] ?? []);
+ $transaction = new NullArrayObject($transaction);
+ $type = $this->stringFromArray($transaction, 'transaction_type_type', TransactionType::WITHDRAWAL);
+ $journalId = (int)$transaction['transaction_journal_id'];
+ $meta = new NullArrayObject($this->meta[$journalId] ?? []);
/**
* Convert and use amount:
@@ -172,6 +330,16 @@ class TransactionGroupTransformer extends AbstractTransformer
$foreignAmount = app('steam')->positive($transaction['foreign_amount']);
$nativeForeignAmount = $this->converter->convert($this->default, $this->currencies[$foreignCurrencyId], $transaction['date'], $foreignAmount);
}
+ $this->converter->summarize();
+
+ $longitude = null;
+ $latitude = null;
+ $zoomLevel = null;
+ if (array_key_exists('location', $this->journals[$journalId])) {
+ $latitude = (string)$this->journals[$journalId]['location']['latitude'];
+ $longitude = (string)$this->journals[$journalId]['location']['longitude'];
+ $zoomLevel = $this->journals[$journalId]['location']['zoom_level'];
+ }
return [
'user' => (string)$transaction['user_id'],
@@ -195,7 +363,7 @@ class TransactionGroupTransformer extends AbstractTransformer
'native_currency_code' => $this->default->code,
'native_currency_name' => $this->default->name,
'native_currency_symbol' => $this->default->symbol,
- 'native_currency_decimal_places' => (int)$this->default->decimal_places,
+ 'native_currency_decimal_places' => $this->default->decimal_places,
// foreign currency amount:
'foreign_currency_id' => $this->stringFromArray($transaction, 'foreign_currency_id', null),
@@ -229,7 +397,6 @@ class TransactionGroupTransformer extends AbstractTransformer
'recurrence_id' => $meta['recurrence_id'],
'recurrence_total' => $meta['recurrence_total'],
'recurrence_count' => $meta['recurrence_count'],
- 'bunq_payment_id' => $meta['bunq_payment_id'],
'external_url' => $meta['external_url'],
'import_hash_v2' => $meta['import_hash_v2'],
'sepa_cc' => $meta['sepa_cc'],
@@ -248,9 +415,9 @@ class TransactionGroupTransformer extends AbstractTransformer
'invoice_date' => $this->date($meta['invoice_date']),
// location data
- // 'longitude' => $longitude,
- // 'latitude' => $latitude,
- // 'zoom_level' => $zoomLevel,
+ 'longitude' => $longitude,
+ 'latitude' => $latitude,
+ 'zoom_level' => $zoomLevel,
//
// 'has_attachments' => $this->hasAttachments((int) $row['transaction_journal_id']),
];
@@ -261,16 +428,10 @@ class TransactionGroupTransformer extends AbstractTransformer
*
* Used to extract a value from the given array, and fall back on a sensible default or NULL
* if it can't be helped.
- *
- * @param NullArrayObject $array
- * @param string $key
- * @param string|null $default
- *
- * @return string|null
*/
private function stringFromArray(NullArrayObject $array, string $key, ?string $default): ?string
{
- //app('log')->debug(sprintf('%s: %s', $key, var_export($array[$key], true)));
+ // app('log')->debug(sprintf('%s: %s', $key, var_export($array[$key], true)));
if (null === $array[$key] && null === $default) {
return null;
}
@@ -291,11 +452,6 @@ class TransactionGroupTransformer extends AbstractTransformer
return null;
}
- /**
- * @param string|null $string
- *
- * @return Carbon|null
- */
private function date(?string $string): ?Carbon
{
if (null === $string) {
@@ -303,16 +459,162 @@ class TransactionGroupTransformer extends AbstractTransformer
}
// app('log')->debug(sprintf('Now in date("%s")', $string));
if (10 === strlen($string)) {
- return Carbon::createFromFormat('Y-m-d', $string, config('app.timezone'));
+ $res = Carbon::createFromFormat('Y-m-d', $string, config('app.timezone'));
+ if (false === $res) {
+ return null;
+ }
+
+ return $res;
}
if (25 === strlen($string)) {
return Carbon::parse($string, config('app.timezone'));
}
if (19 === strlen($string) && str_contains($string, 'T')) {
- return Carbon::createFromFormat('Y-m-d\TH:i:s', substr($string, 0, 19), config('app.timezone'));
+ $res = Carbon::createFromFormat('Y-m-d\TH:i:s', substr($string, 0, 19), config('app.timezone'));
+ if (false === $res) {
+ return null;
+ }
+
+ return $res;
}
// 2022-01-01 01:01:01
- return Carbon::createFromFormat('Y-m-d H:i:s', substr($string, 0, 19), config('app.timezone'));
+ $res = Carbon::createFromFormat('Y-m-d H:i:s', substr($string, 0, 19), config('app.timezone'));
+ if (false === $res) {
+ return null;
+ }
+
+ return $res;
+ }
+
+ private function transformJournals(TransactionGroup $group): array
+ {
+ $return = [];
+
+ /** @var TransactionJournal $journal */
+ foreach ($group->transactionJournals as $journal) {
+ $return[] = $this->transformJournal($journal);
+ }
+
+ return $return;
+ }
+
+ /**
+ * @throws FireflyException
+ *
+ * @SuppressWarnings(PHPMD.ExcessiveMethodLength)
+ */
+ private function transformJournal(TransactionJournal $journal): array
+ {
+ $id = $journal->id;
+
+ /** @var null|TransactionCurrency $foreignCurrency */
+ $foreignCurrency = null;
+
+ /** @var TransactionCurrency $currency */
+ $currency = $this->currencies[$this->journals[$id]['currency_id']];
+ $nativeForeignAmount = null;
+ $amount = $this->journals[$journal->id]['amount'];
+ $foreignAmount = $this->journals[$journal->id]['foreign_amount'];
+ $meta = new NullArrayObject($this->meta[$id] ?? []);
+
+ // has foreign amount?
+ if (null !== $foreignAmount) {
+ $foreignCurrency = $this->currencies[$this->journals[$id]['foreign_currency_id']];
+ $nativeForeignAmount = $this->converter->convert($this->default, $foreignCurrency, $journal->date, $foreignAmount);
+ }
+
+ $nativeAmount = $this->converter->convert($this->default, $currency, $journal->date, $amount);
+
+ $longitude = null;
+ $latitude = null;
+ $zoomLevel = null;
+ if (array_key_exists('location', $this->journals[$id])) {
+ $latitude = (string)$this->journals[$id]['location']['latitude'];
+ $longitude = (string)$this->journals[$id]['location']['longitude'];
+ $zoomLevel = $this->journals[$id]['location']['zoom_level'];
+ }
+
+ return [
+ 'user' => (string)$journal->user_id,
+ 'user_group' => (string)$journal->user_group_id,
+ 'transaction_journal_id' => (string)$journal->id,
+ 'type' => $this->journals[$journal->id]['type'],
+ 'date' => $journal->date->toAtomString(),
+ 'order' => $journal->order,
+ 'amount' => $amount,
+ 'native_amount' => $nativeAmount,
+ 'foreign_amount' => $foreignAmount,
+ 'native_foreign_amount' => $nativeForeignAmount,
+ 'currency_id' => (string)$currency->id,
+ 'currency_code' => $currency->code,
+ 'currency_name' => $currency->name,
+ 'currency_symbol' => $currency->symbol,
+ 'currency_decimal_places' => $currency->decimal_places,
+
+ // converted to native currency
+ 'native_currency_id' => (string)$this->default->id,
+ 'native_currency_code' => $this->default->code,
+ 'native_currency_name' => $this->default->name,
+ 'native_currency_symbol' => $this->default->symbol,
+ 'native_currency_decimal_places' => $this->default->decimal_places,
+
+ // foreign currency amount:
+ 'foreign_currency_id' => $foreignCurrency?->id,
+ 'foreign_currency_code' => $foreignCurrency?->code,
+ 'foreign_currency_name' => $foreignCurrency?->name,
+ 'foreign_currency_symbol' => $foreignCurrency?->symbol,
+ 'foreign_currency_decimal_places' => $foreignCurrency?->decimal_places,
+
+ 'description' => $journal->description,
+ 'source_id' => (string)$this->journals[$id]['source_account_id'],
+ 'source_name' => $this->journals[$id]['source_account_name'],
+ 'source_iban' => $this->journals[$id]['source_account_iban'],
+ 'source_type' => $this->journals[$id]['source_account_type'],
+
+ 'destination_id' => (string)$this->journals[$id]['destination_account_id'],
+ 'destination_name' => $this->journals[$id]['destination_account_name'],
+ 'destination_iban' => $this->journals[$id]['destination_account_iban'],
+ 'destination_type' => $this->journals[$id]['destination_account_type'],
+
+ 'budget_id' => $this->journals[$id]['budget_id'],
+ 'budget_name' => $this->journals[$id]['budget_name'],
+ 'category_id' => $this->journals[$id]['category_id'],
+ 'category_name' => $this->journals[$id]['category_name'],
+ 'bill_id' => $this->journals[$id]['bill_id'],
+ 'bill_name' => $this->journals[$id]['bill_name'],
+ 'reconciled' => $this->journals[$id]['reconciled'],
+ 'notes' => $this->journals[$id]['notes'] ?? null,
+ 'tags' => $this->journals[$id]['tags'] ?? [],
+ 'internal_reference' => $meta['internal_reference'],
+ 'external_id' => $meta['external_id'],
+ 'original_source' => $meta['original_source'],
+ 'recurrence_id' => $meta['recurrence_id'],
+ 'recurrence_total' => $meta['recurrence_total'],
+ 'recurrence_count' => $meta['recurrence_count'],
+ 'external_url' => $meta['external_url'],
+ 'import_hash_v2' => $meta['import_hash_v2'],
+ 'sepa_cc' => $meta['sepa_cc'],
+ 'sepa_ct_op' => $meta['sepa_ct_op'],
+ 'sepa_ct_id' => $meta['sepa_ct_id'],
+ 'sepa_db' => $meta['sepa_db'],
+ 'sepa_country' => $meta['sepa_country'],
+ 'sepa_ep' => $meta['sepa_ep'],
+ 'sepa_ci' => $meta['sepa_ci'],
+ 'sepa_batch_id' => $meta['sepa_batch_id'],
+ 'interest_date' => $this->date($meta['interest_date']),
+ 'book_date' => $this->date($meta['book_date']),
+ 'process_date' => $this->date($meta['process_date']),
+ 'due_date' => $this->date($meta['due_date']),
+ 'payment_date' => $this->date($meta['payment_date']),
+ 'invoice_date' => $this->date($meta['invoice_date']),
+
+ // location data
+ 'longitude' => $longitude,
+ 'latitude' => $latitude,
+ 'zoom_level' => $zoomLevel,
+ //
+ // 'has_attachments' => $this->hasAttachments((int) $row['transaction_journal_id']),
+ ];
}
}
diff --git a/app/Transformers/V2/UserGroupTransformer.php b/app/Transformers/V2/UserGroupTransformer.php
index 3f7c44b0d2..2c523a0281 100644
--- a/app/Transformers/V2/UserGroupTransformer.php
+++ b/app/Transformers/V2/UserGroupTransformer.php
@@ -1,6 +1,5 @@
memberships = [];
}
- /**
- * @inheritDoc
- */
public function collectMetaData(Collection $objects): void
{
if (auth()->check()) {
// collect memberships so they can be listed in the group.
/** @var User $user */
$user = auth()->user();
+
/** @var UserGroup $userGroup */
foreach ($objects as $userGroup) {
- $userGroupId = (int)$userGroup->id;
- $access = $user->hasRoleInGroup($userGroup, UserRoleEnum::VIEW_MEMBERSHIPS, true, true);
+ $userGroupId = $userGroup->id;
+ $access = $user->hasRoleInGroupOrOwner($userGroup, UserRoleEnum::VIEW_MEMBERSHIPS) || $user->hasRole('owner');
if ($access) {
$groupMemberships = $userGroup->groupMemberships()->get();
+
/** @var GroupMembership $groupMembership */
foreach ($groupMemberships as $groupMembership) {
$this->memberships[$userGroupId][] = [
@@ -76,22 +71,16 @@ class UserGroupTransformer extends AbstractTransformer
/**
* Transform the user group.
- *
- * @param UserGroup $userGroup
- *
- * @return array
*/
public function transform(UserGroup $userGroup): array
{
- $return = [
- 'id' => (int)$userGroup->id,
+ return [
+ 'id' => $userGroup->id,
'created_at' => $userGroup->created_at->toAtomString(),
'updated_at' => $userGroup->updated_at->toAtomString(),
'title' => $userGroup->title,
- 'members' => $this->memberships[(int)$userGroup->id] ?? [],
+ 'members' => $this->memberships[$userGroup->id] ?? [],
];
// if the user has a specific role in this group, then collect the memberships.
-
- return $return;
}
}
diff --git a/app/Transformers/WebhookAttemptTransformer.php b/app/Transformers/WebhookAttemptTransformer.php
index 8576c3800f..6feafb88e1 100644
--- a/app/Transformers/WebhookAttemptTransformer.php
+++ b/app/Transformers/WebhookAttemptTransformer.php
@@ -32,10 +32,6 @@ class WebhookAttemptTransformer extends AbstractTransformer
{
/**
* Transform the preference
- *
- * @param WebhookAttempt $attempt
- *
- * @return array
*/
public function transform(WebhookAttempt $attempt): array
{
diff --git a/app/Transformers/WebhookMessageTransformer.php b/app/Transformers/WebhookMessageTransformer.php
index 02a290a069..7cdee7adc7 100644
--- a/app/Transformers/WebhookMessageTransformer.php
+++ b/app/Transformers/WebhookMessageTransformer.php
@@ -24,8 +24,6 @@ declare(strict_types=1);
namespace FireflyIII\Transformers;
use FireflyIII\Models\WebhookMessage;
-use Illuminate\Support\Facades\Log;
-use Jsonexception;
/**
* Class WebhookMessageTransformer
@@ -34,17 +32,14 @@ class WebhookMessageTransformer extends AbstractTransformer
{
/**
* Transform the preference
- *
- * @param WebhookMessage $message
- *
- * @return array
*/
public function transform(WebhookMessage $message): array
{
$json = '{}';
+
try {
$json = json_encode($message->message, JSON_THROW_ON_ERROR);
- } catch (JsonException $e) {
+ } catch (\JsonException $e) {
app('log')->error(sprintf('Could not encode webhook message #%d: %s', $message->id, $e->getMessage()));
}
diff --git a/app/Transformers/WebhookTransformer.php b/app/Transformers/WebhookTransformer.php
index c39e015f58..d913b38f3d 100644
--- a/app/Transformers/WebhookTransformer.php
+++ b/app/Transformers/WebhookTransformer.php
@@ -34,26 +34,18 @@ use FireflyIII\Models\Webhook;
*/
class WebhookTransformer extends AbstractTransformer
{
- private array $enums;
-
/**
* WebhookTransformer constructor.
*/
- public function __construct()
- {
- }
+ public function __construct() {}
/**
* Transform webhook.
- *
- * @param Webhook $webhook
- *
- * @return array
*/
public function transform(Webhook $webhook): array
{
return [
- 'id' => (int)$webhook->id,
+ 'id' => $webhook->id,
'created_at' => $webhook->created_at->toAtomString(),
'updated_at' => $webhook->updated_at->toAtomString(),
'active' => $webhook->active,
@@ -72,12 +64,6 @@ class WebhookTransformer extends AbstractTransformer
];
}
- /**
- * @param string $type
- * @param int $value
- *
- * @return string
- */
private function getEnum(string $type, int $value): string
{
if ('trigger' === $type) {
@@ -86,6 +72,7 @@ class WebhookTransformer extends AbstractTransformer
if ('response' === $type) {
return WebhookResponse::from($value)->name;
}
+
return WebhookDelivery::from($value)->name;
}
}
diff --git a/app/User.php b/app/User.php
index d4cfe96cf3..1218e7deaf 100644
--- a/app/User.php
+++ b/app/User.php
@@ -24,8 +24,8 @@ declare(strict_types=1);
namespace FireflyIII;
+use Carbon\Carbon;
use Eloquent;
-use Exception;
use FireflyIII\Enums\UserRoleEnum;
use FireflyIII\Events\RequestedNewPassword;
use FireflyIII\Exceptions\FireflyException;
@@ -46,6 +46,7 @@ use FireflyIII\Models\Rule;
use FireflyIII\Models\RuleGroup;
use FireflyIII\Models\Tag;
use FireflyIII\Models\Transaction;
+use FireflyIII\Models\TransactionCurrency;
use FireflyIII\Models\TransactionGroup;
use FireflyIII\Models\TransactionJournal;
use FireflyIII\Models\UserGroup;
@@ -65,53 +66,52 @@ use Illuminate\Notifications\DatabaseNotification;
use Illuminate\Notifications\DatabaseNotificationCollection;
use Illuminate\Notifications\Notifiable;
use Illuminate\Notifications\Notification;
-use Illuminate\Support\Carbon;
use Illuminate\Support\Collection;
use Illuminate\Support\Str;
use Laravel\Passport\Client;
use Laravel\Passport\HasApiTokens;
use Laravel\Passport\Token;
-use Psr\Container\ContainerExceptionInterface;
-use Psr\Container\NotFoundExceptionInterface;
-use Request;
use Symfony\Component\HttpKernel\Exception\NotFoundHttpException;
/**
* Class User.
*
- * @property int $id
- * @property string $email
- * @property bool $isAdmin
- * @property bool $has2FA
- * @property array $prefs
- * @property string $password
- * @property string $mfa_secret
- * @property Collection $roles
- * @property string $blocked_code
- * @property bool $blocked
- * @property Carbon|null $created_at
- * @property Carbon|null $updated_at
- * @property string|null $remember_token
- * @property string|null $reset
- * @property-read \Illuminate\Database\Eloquent\Collection|Account[] $accounts
- * @property-read \Illuminate\Database\Eloquent\Collection|Attachment[] $attachments
- * @property-read \Illuminate\Database\Eloquent\Collection|AvailableBudget[] $availableBudgets
- * @property-read \Illuminate\Database\Eloquent\Collection|Bill[] $bills
- * @property-read \Illuminate\Database\Eloquent\Collection|Budget[] $budgets
- * @property-read \Illuminate\Database\Eloquent\Collection|Category[] $categories
- * @property-read \Illuminate\Database\Eloquent\Collection|Client[] $clients
- * @property-read \Illuminate\Database\Eloquent\Collection|CurrencyExchangeRate[] $currencyExchangeRates
- * @property-read DatabaseNotificationCollection|DatabaseNotification[] $notifications
- * @property-read \Illuminate\Database\Eloquent\Collection|PiggyBank[] $piggyBanks
- * @property-read \Illuminate\Database\Eloquent\Collection|Preference[] $preferences
- * @property-read \Illuminate\Database\Eloquent\Collection|Recurrence[] $recurrences
- * @property-read \Illuminate\Database\Eloquent\Collection|RuleGroup[] $ruleGroups
- * @property-read \Illuminate\Database\Eloquent\Collection|Rule[] $rules
- * @property-read \Illuminate\Database\Eloquent\Collection|Tag[] $tags
- * @property-read \Illuminate\Database\Eloquent\Collection|Token[] $tokens
- * @property-read \Illuminate\Database\Eloquent\Collection|TransactionGroup[] $transactionGroups
- * @property-read \Illuminate\Database\Eloquent\Collection|TransactionJournal[] $transactionJournals
- * @property-read \Illuminate\Database\Eloquent\Collection|Transaction[] $transactions
+ * @SuppressWarnings(PHPMD.CouplingBetweenObjects)
+ *
+ * @property int|string $id
+ * @property string $email
+ * @property bool $isAdmin
+ * @property bool $has2FA
+ * @property array $prefs
+ * @property string $password
+ * @property string $mfa_secret
+ * @property Collection $roles
+ * @property string $blocked_code
+ * @property bool $blocked
+ * @property null|Carbon $created_at
+ * @property null|Carbon $updated_at
+ * @property null|string $remember_token
+ * @property null|string $reset
+ * @property Account[]|\Illuminate\Database\Eloquent\Collection $accounts
+ * @property Attachment[]|\Illuminate\Database\Eloquent\Collection $attachments
+ * @property AvailableBudget[]|\Illuminate\Database\Eloquent\Collection $availableBudgets
+ * @property Bill[]|\Illuminate\Database\Eloquent\Collection $bills
+ * @property Budget[]|\Illuminate\Database\Eloquent\Collection $budgets
+ * @property Category[]|\Illuminate\Database\Eloquent\Collection $categories
+ * @property Client[]|\Illuminate\Database\Eloquent\Collection $clients
+ * @property CurrencyExchangeRate[]|\Illuminate\Database\Eloquent\Collection $currencyExchangeRates
+ * @property DatabaseNotification[]|DatabaseNotificationCollection $notifications
+ * @property \Illuminate\Database\Eloquent\Collection|PiggyBank[] $piggyBanks
+ * @property \Illuminate\Database\Eloquent\Collection|Preference[] $preferences
+ * @property \Illuminate\Database\Eloquent\Collection|Recurrence[] $recurrences
+ * @property \Illuminate\Database\Eloquent\Collection|RuleGroup[] $ruleGroups
+ * @property \Illuminate\Database\Eloquent\Collection|Rule[] $rules
+ * @property \Illuminate\Database\Eloquent\Collection|Tag[] $tags
+ * @property \Illuminate\Database\Eloquent\Collection|Token[] $tokens
+ * @property \Illuminate\Database\Eloquent\Collection|TransactionGroup[] $transactionGroups
+ * @property \Illuminate\Database\Eloquent\Collection|TransactionJournal[] $transactionJournals
+ * @property \Illuminate\Database\Eloquent\Collection|Transaction[] $transactions
+ *
* @method static Builder|User newModelQuery()
* @method static Builder|User newQuery()
* @method static Builder|User query()
@@ -124,92 +124,81 @@ use Symfony\Component\HttpKernel\Exception\NotFoundHttpException;
* @method static Builder|User whereRememberToken($value)
* @method static Builder|User whereReset($value)
* @method static Builder|User whereUpdatedAt($value)
- * @property string|null $objectguid
- * @property-read int|null $accounts_count
- * @property-read int|null $attachments_count
- * @property-read int|null $available_budgets_count
- * @property-read int|null $bills_count
- * @property-read int|null $budgets_count
- * @property-read int|null $categories_count
- * @property-read int|null $clients_count
- * @property-read int|null $currency_exchange_rates_count
- * @property-read int|null $notifications_count
- * @property-read int|null $piggy_banks_count
- * @property-read int|null $preferences_count
- * @property-read int|null $recurrences_count
- * @property-read int|null $roles_count
- * @property-read int|null $rule_groups_count
- * @property-read int|null $rules_count
- * @property-read int|null $tags_count
- * @property-read int|null $tokens_count
- * @property-read int|null $transaction_groups_count
- * @property-read int|null $transaction_journals_count
- * @property-read int|null $transactions_count
+ *
+ * @property null|string $objectguid
+ * @property null|int $accounts_count
+ * @property null|int $attachments_count
+ * @property null|int $available_budgets_count
+ * @property null|int $bills_count
+ * @property null|int $budgets_count
+ * @property null|int $categories_count
+ * @property null|int $clients_count
+ * @property null|int $currency_exchange_rates_count
+ * @property null|int $notifications_count
+ * @property null|int $piggy_banks_count
+ * @property null|int $preferences_count
+ * @property null|int $recurrences_count
+ * @property null|int $roles_count
+ * @property null|int $rule_groups_count
+ * @property null|int $rules_count
+ * @property null|int $tags_count
+ * @property null|int $tokens_count
+ * @property null|int $transaction_groups_count
+ * @property null|int $transaction_journals_count
+ * @property null|int $transactions_count
+ *
* @method static Builder|User whereMfaSecret($value)
* @method static Builder|User whereObjectguid($value)
- * @property string|null $provider
+ *
+ * @property null|string $provider
+ *
* @method static Builder|User whereProvider($value)
- * @property-read \Illuminate\Database\Eloquent\Collection|ObjectGroup[] $objectGroups
- * @property-read int|null $object_groups_count
- * @property-read \Illuminate\Database\Eloquent\Collection|Webhook[] $webhooks
- * @property-read int|null $webhooks_count
- * @property string|null $two_factor_secret
- * @property string|null $two_factor_recovery_codes
- * @property string|null $guid
- * @property string|null $domain
+ *
+ * @property \Illuminate\Database\Eloquent\Collection|ObjectGroup[] $objectGroups
+ * @property null|int $object_groups_count
+ * @property \Illuminate\Database\Eloquent\Collection|Webhook[] $webhooks
+ * @property null|int $webhooks_count
+ * @property null|string $two_factor_secret
+ * @property null|string $two_factor_recovery_codes
+ * @property null|string $guid
+ * @property null|string $domain
+ *
* @method static Builder|User whereDomain($value)
* @method static Builder|User whereGuid($value)
* @method static Builder|User whereTwoFactorRecoveryCodes($value)
* @method static Builder|User whereTwoFactorSecret($value)
- * @property int|null $user_group_id
- * @property-read \Illuminate\Database\Eloquent\Collection|GroupMembership[] $groupMemberships
- * @property-read int|null $group_memberships_count
- * @property-read UserGroup|null $userGroup
+ *
+ * @property null|int $user_group_id
+ * @property GroupMembership[]|\Illuminate\Database\Eloquent\Collection $groupMemberships
+ * @property null|int $group_memberships_count
+ * @property null|UserGroup $userGroup
+ *
* @method static Builder|User whereUserGroupId($value)
+ *
+ * @property \Illuminate\Database\Eloquent\Collection $currencies
+ * @property null|int $currencies_count
+ *
* @mixin Eloquent
*/
class User extends Authenticatable
{
- use Notifiable;
use HasApiTokens;
+ use Notifiable;
- /**
- * The attributes that should be cast to native types.
- *
- * @var array
- */
protected $casts
- = [
- 'created_at' => 'datetime',
- 'updated_at' => 'datetime',
- 'blocked' => 'boolean',
- ];
- /**
- * The attributes that are mass assignable.
- *
- * @var array
- */
+ = [
+ 'created_at' => 'datetime',
+ 'updated_at' => 'datetime',
+ 'blocked' => 'boolean',
+ ];
protected $fillable = ['email', 'password', 'blocked', 'blocked_code'];
- /**
- * The attributes excluded from the model's JSON form.
- *
- * @var array
- */
- protected $hidden = ['password', 'remember_token'];
- /**
- * The database table used by the model.
- *
- * @var string
- */
- protected $table = 'users';
+ protected $hidden = ['password', 'remember_token'];
+ protected $table = 'users';
/**
- * @param string $value
- *
- * @return User
* @throws NotFoundHttpException
*/
- public static function routeBinder(string $value): User
+ public static function routeBinder(string $value): self
{
if (auth()->check()) {
$userId = (int)$value;
@@ -218,13 +207,12 @@ class User extends Authenticatable
return $user;
}
}
+
throw new NotFoundHttpException();
}
/**
* Link to accounts.
- *
- * @return HasMany
*/
public function accounts(): HasMany
{
@@ -233,8 +221,6 @@ class User extends Authenticatable
/**
* Link to attachments
- *
- * @return HasMany
*/
public function attachments(): HasMany
{
@@ -243,8 +229,6 @@ class User extends Authenticatable
/**
* Link to available budgets
- *
- * @return HasMany
*/
public function availableBudgets(): HasMany
{
@@ -253,8 +237,6 @@ class User extends Authenticatable
/**
* Link to bills.
- *
- * @return HasMany
*/
public function bills(): HasMany
{
@@ -263,8 +245,6 @@ class User extends Authenticatable
/**
* Link to budgets.
- *
- * @return HasMany
*/
public function budgets(): HasMany
{
@@ -273,18 +253,22 @@ class User extends Authenticatable
/**
* Link to categories
- *
- * @return HasMany
*/
public function categories(): HasMany
{
return $this->hasMany(Category::class);
}
+ /**
+ * Link to currencies
+ */
+ public function currencies(): BelongsToMany
+ {
+ return $this->belongsToMany(TransactionCurrency::class)->withTimestamps()->withPivot('user_default');
+ }
+
/**
* Link to currency exchange rates
- *
- * @return HasMany
*/
public function currencyExchangeRates(): HasMany
{
@@ -294,8 +278,7 @@ class User extends Authenticatable
/**
* Generates access token.
*
- * @return string
- * @throws Exception
+ * @throws \Exception
*/
public function generateAccessToken(): string
{
@@ -307,7 +290,6 @@ class User extends Authenticatable
/**
* A safe method that returns the user's current administration ID (group ID).
*
- * @return int
* @throws FireflyException
*/
public function getAdministrationId(): int
@@ -316,6 +298,7 @@ class User extends Authenticatable
if (0 === $groupId) {
throw new FireflyException('User has no administration ID.');
}
+
return $groupId;
}
@@ -323,8 +306,8 @@ class User extends Authenticatable
* Get the models LDAP domain.
*
* @return string
- * @deprecated
*
+ * @deprecated
*/
public function getLdapDomain()
{
@@ -335,8 +318,8 @@ class User extends Authenticatable
* Get the database column name of the domain.
*
* @return string
- * @deprecated
*
+ * @deprecated
*/
public function getLdapDomainColumn()
{
@@ -347,8 +330,8 @@ class User extends Authenticatable
* Get the models LDAP GUID.
*
* @return string
- * @deprecated
*
+ * @deprecated
*/
public function getLdapGuid()
{
@@ -359,61 +342,59 @@ class User extends Authenticatable
* Get the models LDAP GUID database column name.
*
* @return string
- * @deprecated
*
+ * @deprecated
*/
public function getLdapGuidColumn()
{
return 'objectguid';
}
-
/**
- * Does the user have role X in group Y?
+ * Does the user have role X in group Y, or is the user the group owner of has full rights to the group?
*
* If $allowOverride is set to true, then the roles FULL or OWNER will also be checked,
* which means that in most cases the user DOES have access, regardless of the original role submitted in $role.
- *
- * @param UserGroup $userGroup
- * @param UserRoleEnum $role
- * @param bool $allowOverride
- *
- * @return bool
*/
- public function hasRoleInGroup(UserGroup $userGroup, UserRoleEnum $role, bool $allowGroupOverride = false, bool $allowSystemOverride = false): bool
+ public function hasRoleInGroupOrOwner(UserGroup $userGroup, UserRoleEnum $role): bool
{
- if ($allowSystemOverride && $this->hasRole('owner')) {
- app('log')->debug(sprintf('hasRoleInGroup: user "#%d %s" is system owner and allowSystemOverride = true, return true', $this->id, $this->email));
- return true;
- }
- $roles = [$role->value];
- if ($allowGroupOverride) {
- $roles[] = UserRoleEnum::OWNER->value;
- $roles[] = UserRoleEnum::FULL->value;
- }
- app('log')->debug(sprintf('in hasRoleInGroup(%s)', join(', ', $roles)));
+ $roles = [$role->value, UserRoleEnum::OWNER->value, UserRoleEnum::FULL->value];
+
+ return $this->hasAnyRoleInGroup($userGroup, $roles);
+ }
+
+ /**
+ * Does the user have role X, Y or Z in group A?
+ */
+ private function hasAnyRoleInGroup(UserGroup $userGroup, array $roles): bool
+ {
+ app('log')->debug(sprintf('in hasAnyRoleInGroup(%s)', implode(', ', $roles)));
+
/** @var Collection $dbRoles */
- $dbRoles = UserRole::whereIn('title', $roles)->get();
+ $dbRoles = UserRole::whereIn('title', $roles)->get();
if (0 === $dbRoles->count()) {
- app('log')->error(sprintf('Could not find role(s): %s. Probably migration mishap.', join(', ', $roles)));
+ app('log')->error(sprintf('Could not find role(s): %s. Probably migration mishap.', implode(', ', $roles)));
+
return false;
}
- $dbRolesIds = $dbRoles->pluck('id')->toArray();
- $dbRolesTitles = $dbRoles->pluck('title')->toArray();
+ $dbRolesIds = $dbRoles->pluck('id')->toArray();
+ $dbRolesTitles = $dbRoles->pluck('title')->toArray();
/** @var Collection $groupMemberships */
$groupMemberships = $this->groupMemberships()
- ->whereIn('user_role_id', $dbRolesIds)
- ->where('user_group_id', $userGroup->id)->get();
+ ->whereIn('user_role_id', $dbRolesIds)
+ ->where('user_group_id', $userGroup->id)->get()
+ ;
if (0 === $groupMemberships->count()) {
app('log')->error(sprintf(
'User #%d "%s" does not have roles %s in user group #%d "%s"',
$this->id,
$this->email,
- join(', ', $roles),
+ implode(', ', $roles),
$userGroup->id,
$userGroup->title
));
+
return false;
}
foreach ($groupMemberships as $membership) {
@@ -427,6 +408,7 @@ class User extends Authenticatable
));
if (in_array($membership->userRole->title, $dbRolesTitles, true)) {
app('log')->debug(sprintf('Return true, found role "%s"', $membership->userRole->title));
+
return true;
}
}
@@ -434,52 +416,29 @@ class User extends Authenticatable
'User #%d "%s" does not have roles %s in user group #%d "%s"',
$this->id,
$this->email,
- join(', ', $roles),
+ implode(', ', $roles),
$userGroup->id,
$userGroup->title
));
+
return false;
- // // not necessary, should always return true:
- // $result = $groupMembership->userRole->title === $role->value;
- // app('log')->error(sprintf('Does user #%d "%s" have role "%s" in user group #%d "%s"? %s',
- // $this->id, $this->email,
- // $role->value, $userGroup->id, $userGroup->title, var_export($result, true)));
- // return $result;
}
- /**
- * @param string $role
- *
- * @return bool
- */
- public function hasRole(string $role): bool
- {
- return $this->roles()->where('name', $role)->count() === 1;
- }
-
- /**
- * Link to roles.
- *
- * @return BelongsToMany
- */
- public function roles(): BelongsToMany
- {
- return $this->belongsToMany(Role::class);
- }
-
- /**
- *
- * @return HasMany
- */
public function groupMemberships(): HasMany
{
return $this->hasMany(GroupMembership::class)->with(['userGroup', 'userRole']);
}
+ /**
+ * Does the user have role X in group Y?
+ */
+ public function hasSpecificRoleInGroup(UserGroup $userGroup, UserRoleEnum $role): bool
+ {
+ return $this->hasAnyRoleInGroup($userGroup, [$role]);
+ }
+
/**
* Link to object groups.
- *
- * @return HasMany
*/
public function objectGroups(): HasMany
{
@@ -488,8 +447,6 @@ class User extends Authenticatable
/**
* Link to piggy banks.
- *
- * @return HasManyThrough
*/
public function piggyBanks(): HasManyThrough
{
@@ -498,8 +455,6 @@ class User extends Authenticatable
/**
* Link to preferences.
- *
- * @return HasMany
*/
public function preferences(): HasMany
{
@@ -508,8 +463,6 @@ class User extends Authenticatable
/**
* Link to recurring transactions.
- *
- * @return HasMany
*/
public function recurrences(): HasMany
{
@@ -520,18 +473,19 @@ class User extends Authenticatable
* Get the notification routing information for the given driver.
*
* @param string $driver
- * @param Notification|null $notification
+ * @param null|Notification $notification
*
* @return mixed
*/
public function routeNotificationFor($driver, $notification = null)
{
- if (method_exists($this, $method = 'routeNotificationFor' . Str::studly($driver))) {
- return $this->{$method}($notification);
+ $method = 'routeNotificationFor'.Str::studly($driver);
+ if (method_exists($this, $method)) {
+ return $this->{$method}($notification); // @phpstan-ignore-line
}
- $email = $this->email;
+ $email = $this->email;
// see if user has alternative email address:
- $pref = app('preferences')->getForUser($this, 'remote_guard_alt_email');
+ $pref = app('preferences')->getForUser($this, 'remote_guard_alt_email');
if (null !== $pref) {
$email = $pref->data;
}
@@ -547,56 +501,71 @@ class User extends Authenticatable
};
}
+ /**
+ * This method refers to the "global" role a user can have, outside of any group they may be part of.
+ */
+ public function hasRole(string $role): bool
+ {
+ return 1 === $this->roles()->where('name', $role)->count();
+ }
+
+ /**
+ * Link to roles.
+ */
+ public function roles(): BelongsToMany
+ {
+ return $this->belongsToMany(Role::class);
+ }
+
/**
* Route notifications for the Slack channel.
- *
- * @param Notification $notification
- *
- * @return string
- * @throws ContainerExceptionInterface
- * @throws NotFoundExceptionInterface
*/
public function routeNotificationForSlack(Notification $notification): string
{
// this check does not validate if the user is owner, Should be done by notification itself.
+ $res = app('fireflyconfig')->get('slack_webhook_url', '')->data;
+ if (is_array($res)) {
+ $res = '';
+ }
+ $res = (string)$res;
if ($notification instanceof TestNotification) {
- return app('fireflyconfig')->get('slack_webhook_url', '')->data;
+ return $res;
}
if ($notification instanceof UserInvitation) {
- return app('fireflyconfig')->get('slack_webhook_url', '')->data;
+ return $res;
}
if ($notification instanceof UserRegistration) {
- return app('fireflyconfig')->get('slack_webhook_url', '')->data;
+ return $res;
}
if ($notification instanceof VersionCheckResult) {
- return app('fireflyconfig')->get('slack_webhook_url', '')->data;
+ return $res;
+ }
+ $pref = app('preferences')->getForUser($this, 'slack_webhook_url', '')->data;
+ if (is_array($pref)) {
+ return '';
}
- return app('preferences')->getForUser($this, 'slack_webhook_url', '')->data;
+ return (string)$pref;
}
/**
* Link to rule groups.
- *
- * @return HasMany
*/
public function ruleGroups(): HasMany
{
return $this->hasMany(RuleGroup::class);
}
+ // start LDAP related code
+
/**
* Link to rules.
- *
- * @return HasMany
*/
public function rules(): HasMany
{
return $this->hasMany(Rule::class);
}
- // start LDAP related code
-
/**
* Send the password reset notification.
*
@@ -604,7 +573,7 @@ class User extends Authenticatable
*/
public function sendPasswordResetNotification($token): void
{
- $ipAddress = Request::ip();
+ $ipAddress = \Request::ip();
event(new RequestedNewPassword($this, $token, $ipAddress));
}
@@ -614,11 +583,9 @@ class User extends Authenticatable
*
* @param string $domain
*
- * @return void
* @deprecated
- *
*/
- public function setLdapDomain($domain)
+ public function setLdapDomain($domain): void
{
$this->{$this->getLdapDomainColumn()} = $domain;
}
@@ -628,18 +595,15 @@ class User extends Authenticatable
*
* @param string $guid
*
- * @return void
* @deprecated
*/
- public function setLdapGuid($guid)
+ public function setLdapGuid($guid): void
{
$this->{$this->getLdapGuidColumn()} = $guid;
}
/**
* Link to tags.
- *
- * @return HasMany
*/
public function tags(): HasMany
{
@@ -648,8 +612,6 @@ class User extends Authenticatable
/**
* Link to transaction groups.
- *
- * @return HasMany
*/
public function transactionGroups(): HasMany
{
@@ -658,8 +620,6 @@ class User extends Authenticatable
/**
* Link to transaction journals.
- *
- * @return HasMany
*/
public function transactionJournals(): HasMany
{
@@ -668,27 +628,19 @@ class User extends Authenticatable
/**
* Link to transactions.
- *
- * @return HasManyThrough
*/
public function transactions(): HasManyThrough
{
return $this->hasManyThrough(Transaction::class, TransactionJournal::class);
}
- /**
- * @return BelongsTo
- */
public function userGroup(): BelongsTo
{
- return $this->belongsTo(UserGroup::class, );
+ return $this->belongsTo(UserGroup::class);
}
/**
- *
* Link to webhooks
- *
- * @return HasMany
*/
public function webhooks(): HasMany
{
diff --git a/app/Validation/Account/AccountValidatorProperties.php b/app/Validation/Account/AccountValidatorProperties.php
index b77f592bdf..106c3660f5 100644
--- a/app/Validation/Account/AccountValidatorProperties.php
+++ b/app/Validation/Account/AccountValidatorProperties.php
@@ -29,6 +29,4 @@ namespace FireflyIII\Validation\Account;
*
* Trait AccountValidatorProperties
*/
-trait AccountValidatorProperties
-{
-}
+trait AccountValidatorProperties {}
diff --git a/app/Validation/Account/DepositValidation.php b/app/Validation/Account/DepositValidation.php
index 4e306e18f5..ea75e241ae 100644
--- a/app/Validation/Account/DepositValidation.php
+++ b/app/Validation/Account/DepositValidation.php
@@ -25,18 +25,12 @@ namespace FireflyIII\Validation\Account;
use FireflyIII\Models\Account;
use FireflyIII\Models\AccountType;
-use Illuminate\Support\Facades\Log;
/**
* Trait DepositValidation
*/
trait DepositValidation
{
- /**
- * @param array $array
- *
- * @return bool
- */
protected function validateDepositDestination(array $array): bool
{
$result = null;
@@ -44,20 +38,20 @@ trait DepositValidation
$accountName = array_key_exists('name', $array) ? $array['name'] : null;
$accountIban = array_key_exists('iban', $array) ? $array['iban'] : null;
- Log::debug('Now in validateDepositDestination', $array);
+ app('log')->debug('Now in validateDepositDestination', $array);
// source can be any of the following types.
- $validTypes = $this->combinations[$this->transactionType][$this->source->accountType->type] ?? [];
+ $validTypes = $this->combinations[$this->transactionType][$this->source->accountType->type] ?? [];
if (null === $accountId && null === $accountName && null === $accountIban && false === $this->canCreateTypes($validTypes)) {
// if both values are NULL we return false,
// because the destination of a deposit can't be created.
$this->destError = (string)trans('validation.deposit_dest_need_data');
- Log::error('Both values are NULL, cant create deposit destination.');
- $result = false;
+ app('log')->error('Both values are NULL, cant create deposit destination.');
+ $result = false;
}
// if the account can be created anyway we don't need to search.
if (null === $result && true === $this->canCreateTypes($validTypes)) {
- Log::debug('Can create some of these types, so return true.');
+ app('log')->debug('Can create some of these types, so return true.');
$result = true;
}
@@ -65,40 +59,30 @@ trait DepositValidation
// otherwise try to find the account:
$search = $this->findExistingAccount($validTypes, $array);
if (null === $search) {
- Log::debug('findExistingAccount() returned NULL, so the result is false.');
+ app('log')->debug('findExistingAccount() returned NULL, so the result is false.');
$this->destError = (string)trans('validation.deposit_dest_bad_data', ['id' => $accountId, 'name' => $accountName]);
$result = false;
}
if (null !== $search) {
- Log::debug(sprintf('findExistingAccount() returned #%d ("%s"), so the result is true.', $search->id, $search->name));
+ app('log')->debug(sprintf('findExistingAccount() returned #%d ("%s"), so the result is true.', $search->id, $search->name));
$this->setDestination($search);
$result = true;
}
}
- Log::debug(sprintf('validateDepositDestination will return %s', var_export($result, true)));
+ app('log')->debug(sprintf('validateDepositDestination will return %s', var_export($result, true)));
return $result;
}
- /**
- * @param array $accountTypes
- *
- * @return bool
- */
abstract protected function canCreateTypes(array $accountTypes): bool;
- /**
- * @param array $validTypes
- * @param array $data
- *
- * @return Account|null
- */
abstract protected function findExistingAccount(array $validTypes, array $data): ?Account;
/**
- * @param array $array
+ * Pretty complex unfortunately.
*
- * @return bool
+ * @SuppressWarnings(PHPMD.NPathComplexity)
+ * @SuppressWarnings(PHPMD.CyclomaticComplexity)
*/
protected function validateDepositSource(array $array): bool
{
@@ -106,19 +90,19 @@ trait DepositValidation
$accountName = array_key_exists('name', $array) ? $array['name'] : null;
$accountIban = array_key_exists('iban', $array) ? $array['iban'] : null;
$accountNumber = array_key_exists('number', $array) ? $array['number'] : null;
- Log::debug('Now in validateDepositSource', $array);
+ app('log')->debug('Now in validateDepositSource', $array);
// null = we found nothing at all or didn't even search
// false = invalid results
- $result = null;
+ $result = null;
// source can be any of the following types.
- $validTypes = array_keys($this->combinations[$this->transactionType]);
- if (null === $accountId &&
- null === $accountName &&
- null === $accountIban &&
- null === $accountNumber &&
- false === $this->canCreateTypes($validTypes)) {
+ $validTypes = array_keys($this->combinations[$this->transactionType]);
+ if (null === $accountId
+ && null === $accountName
+ && null === $accountIban
+ && null === $accountNumber
+ && false === $this->canCreateTypes($validTypes)) {
// if both values are NULL return false,
// because the source of a deposit can't be created.
// (this never happens).
@@ -128,10 +112,11 @@ trait DepositValidation
// if there is an iban, it can only be in use by a valid source type, or we will fail.
if (null !== $accountIban && '' !== $accountIban) {
- app('log')->debug('Check if there is not already an account with this IBAN');
+ app('log')->debug('Check if there is not already another account with this IBAN');
$existing = $this->findExistingAccount($validTypes, ['iban' => $accountIban], true);
if (null !== $existing) {
$this->sourceError = (string)trans('validation.deposit_src_iban_exists');
+
return false;
}
}
@@ -141,11 +126,11 @@ trait DepositValidation
if (null !== $accountId) {
$search = $this->getRepository()->find($accountId);
if (null !== $search && !in_array($search->accountType->type, $validTypes, true)) {
- Log::debug(sprintf('User submitted an ID (#%d), which is a "%s", so this is not a valid source.', $accountId, $search->accountType->type));
- Log::debug(sprintf('Firefly III accepts ID #%d as valid account data.', $accountId));
+ app('log')->debug(sprintf('User submitted an ID (#%d), which is a "%s", so this is not a valid source.', $accountId, $search->accountType->type));
+ app('log')->debug(sprintf('Firefly III accepts ID #%d as valid account data.', $accountId));
}
if (null !== $search && in_array($search->accountType->type, $validTypes, true)) {
- Log::debug('ID result is not null and seems valid, save as source account.');
+ app('log')->debug('ID result is not null and seems valid, save as source account.');
$this->setSource($search);
$result = true;
}
@@ -155,11 +140,11 @@ trait DepositValidation
if (null !== $accountIban) {
$search = $this->getRepository()->findByIbanNull($accountIban, $validTypes);
if (null !== $search && !in_array($search->accountType->type, $validTypes, true)) {
- Log::debug(sprintf('User submitted IBAN ("%s"), which is a "%s", so this is not a valid source.', $accountIban, $search->accountType->type));
+ app('log')->debug(sprintf('User submitted IBAN ("%s"), which is a "%s", so this is not a valid source.', $accountIban, $search->accountType->type));
$result = false;
}
if (null !== $search && in_array($search->accountType->type, $validTypes, true)) {
- Log::debug('IBAN result is not null and seems valid, save as source account.');
+ app('log')->debug('IBAN result is not null and seems valid, save as source account.');
$this->setSource($search);
$result = true;
}
@@ -169,13 +154,13 @@ trait DepositValidation
if (null !== $accountNumber && '' !== $accountNumber) {
$search = $this->getRepository()->findByAccountNumber($accountNumber, $validTypes);
if (null !== $search && !in_array($search->accountType->type, $validTypes, true)) {
- Log::debug(
+ app('log')->debug(
sprintf('User submitted number ("%s"), which is a "%s", so this is not a valid source.', $accountNumber, $search->accountType->type)
);
$result = false;
}
if (null !== $search && in_array($search->accountType->type, $validTypes, true)) {
- Log::debug('Number result is not null and seems valid, save as source account.');
+ app('log')->debug('Number result is not null and seems valid, save as source account.');
$this->setSource($search);
$result = true;
}
@@ -183,7 +168,7 @@ trait DepositValidation
// if the account can be created anyway we don't need to search.
if (null === $result && true === $this->canCreateTypes($validTypes)) {
- $result = true;
+ $result = true;
// set the source to be a (dummy) revenue account.
$account = new Account();
diff --git a/app/Validation/Account/LiabilityValidation.php b/app/Validation/Account/LiabilityValidation.php
index b9a94d3dce..f3fc714c9d 100644
--- a/app/Validation/Account/LiabilityValidation.php
+++ b/app/Validation/Account/LiabilityValidation.php
@@ -26,21 +26,15 @@ namespace FireflyIII\Validation\Account;
use FireflyIII\Models\Account;
use FireflyIII\Models\AccountType;
-use Illuminate\Support\Facades\Log;
/**
* Trait LiabilityValidation
*/
trait LiabilityValidation
{
- /**
- * @param array $array
- *
- * @return bool
- */
protected function validateLCDestination(array $array): bool
{
- Log::debug('Now in validateLCDestination', $array);
+ app('log')->debug('Now in validateLCDestination', $array);
$result = null;
$accountId = array_key_exists('id', $array) ? $array['id'] : null;
$accountName = array_key_exists('name', $array) ? $array['name'] : null;
@@ -49,62 +43,65 @@ trait LiabilityValidation
// if the ID is not null the source account should be a dummy account of the type liability credit.
// the ID of the destination must belong to a liability.
if (null !== $accountId) {
- if (AccountType::LIABILITY_CREDIT !== $this?->source?->accountType?->type) {
- Log::error('Source account is not a liability.');
+ if (AccountType::LIABILITY_CREDIT !== $this->source?->accountType?->type) {
+ app('log')->error('Source account is not a liability.');
+
return false;
}
$result = $this->findExistingAccount($validTypes, $array);
if (null === $result) {
- Log::error('Destination account is not a liability.');
+ app('log')->error('Destination account is not a liability.');
+
return false;
}
+
return true;
}
if (null !== $accountName && '' !== $accountName) {
- Log::debug('Destination ID is null, now we can assume the destination is a (new) liability credit account.');
+ app('log')->debug('Destination ID is null, now we can assume the destination is a (new) liability credit account.');
+
return true;
}
- Log::error('Destination ID is null, but destination name is also NULL.');
+ app('log')->error('Destination ID is null, but destination name is also NULL.');
+
return false;
}
/**
* Source of a liability credit must be a liability or liability credit account.
- *
- * @param array $array
- *
- * @return bool
*/
protected function validateLCSource(array $array): bool
{
- Log::debug('Now in validateLCSource', $array);
+ app('log')->debug('Now in validateLCSource', $array);
// if the array has an ID and ID is not null, try to find it and check type.
// this account must be a liability
- $accountId = array_key_exists('id', $array) ? $array['id'] : null;
+ $accountId = array_key_exists('id', $array) ? $array['id'] : null;
if (null !== $accountId) {
- Log::debug('Source ID is not null, assume were looking for a liability.');
+ app('log')->debug('Source ID is not null, assume were looking for a liability.');
// find liability credit:
$result = $this->findExistingAccount(config('firefly.valid_liabilities'), $array);
if (null === $result) {
- Log::error('Did not find a liability account, return false.');
+ app('log')->error('Did not find a liability account, return false.');
+
return false;
}
- Log::debug(sprintf('Return true, found #%d ("%s")', $result->id, $result->name));
+ app('log')->debug(sprintf('Return true, found #%d ("%s")', $result->id, $result->name));
$this->setSource($result);
+
return true;
}
// if array has name and is not null, return true.
$accountName = array_key_exists('name', $array) ? $array['name'] : null;
- $result = true;
+ $result = true;
if ('' === $accountName || null === $accountName) {
- Log::error('Array must have a name, is not the case, return false.');
+ app('log')->error('Array must have a name, is not the case, return false.');
$result = false;
}
if (true === $result) {
- Log::error('Array has a name, return true.');
+ app('log')->error('Array has a name, return true.');
// set the source to be a (dummy) revenue account.
$account = new Account();
$accountType = AccountType::whereType(AccountType::LIABILITY_CREDIT)->first();
diff --git a/app/Validation/Account/OBValidation.php b/app/Validation/Account/OBValidation.php
index c77d65d4da..de2dc2c11d 100644
--- a/app/Validation/Account/OBValidation.php
+++ b/app/Validation/Account/OBValidation.php
@@ -26,37 +26,31 @@ namespace FireflyIII\Validation\Account;
use FireflyIII\Models\Account;
use FireflyIII\Models\AccountType;
-use Illuminate\Support\Facades\Log;
/**
* Trait OBValidation
*/
trait OBValidation
{
- /**
- * @param array $array
- *
- * @return bool
- */
protected function validateOBDestination(array $array): bool
{
$result = null;
$accountId = array_key_exists('id', $array) ? $array['id'] : null;
$accountName = array_key_exists('name', $array) ? $array['name'] : null;
- Log::debug('Now in validateOBDestination', $array);
+ app('log')->debug('Now in validateOBDestination', $array);
// source can be any of the following types.
- $validTypes = $this->combinations[$this->transactionType][$this->source->accountType->type] ?? [];
+ $validTypes = $this->combinations[$this->transactionType][$this->source?->accountType->type] ?? [];
if (null === $accountId && null === $accountName && false === $this->canCreateTypes($validTypes)) {
// if both values are NULL we return false,
// because the destination of a deposit can't be created.
$this->destError = (string)trans('validation.ob_dest_need_data');
- Log::error('Both values are NULL, cant create OB destination.');
- $result = false;
+ app('log')->error('Both values are NULL, cant create OB destination.');
+ $result = false;
}
// if the account can be created anyway we don't need to search.
if (null === $result && true === $this->canCreateTypes($validTypes)) {
- Log::debug('Can create some of these types, so return true.');
+ app('log')->debug('Can create some of these types, so return true.');
$result = true;
}
@@ -64,44 +58,35 @@ trait OBValidation
// otherwise try to find the account:
$search = $this->findExistingAccount($validTypes, $array);
if (null === $search) {
- Log::debug('findExistingAccount() returned NULL, so the result is false.', $validTypes);
+ app('log')->debug('findExistingAccount() returned NULL, so the result is false.', $validTypes);
$this->destError = (string)trans('validation.ob_dest_bad_data', ['id' => $accountId, 'name' => $accountName]);
$result = false;
}
if (null !== $search) {
- Log::debug(sprintf('findExistingAccount() returned #%d ("%s"), so the result is true.', $search->id, $search->name));
+ app('log')->debug(sprintf('findExistingAccount() returned #%d ("%s"), so the result is true.', $search->id, $search->name));
$this->setDestination($search);
$result = true;
}
}
- Log::debug(sprintf('validateOBDestination(%d, "%s") will return %s', $accountId, $accountName, var_export($result, true)));
+ app('log')->debug(sprintf('validateOBDestination(%d, "%s") will return %s', $accountId, $accountName, var_export($result, true)));
return $result;
}
- /**
- * @param array $accountTypes
- *
- * @return bool
- */
abstract protected function canCreateTypes(array $accountTypes): bool;
/**
* Source of an opening balance can either be an asset account
* or an "initial balance account". The latter can be created.
- *
- * @param array $array
- *
- * @return bool
*/
protected function validateOBSource(array $array): bool
{
$accountId = array_key_exists('id', $array) ? $array['id'] : null;
$accountName = array_key_exists('name', $array) ? $array['name'] : null;
- Log::debug('Now in validateOBSource', $array);
- $result = null;
+ app('log')->debug('Now in validateOBSource', $array);
+ $result = null;
// source can be any of the following types.
- $validTypes = array_keys($this->combinations[$this->transactionType]);
+ $validTypes = array_keys($this->combinations[$this->transactionType]);
if (null === $accountId && null === $accountName && false === $this->canCreateTypes($validTypes)) {
// if both values are NULL return false,
@@ -114,19 +99,19 @@ trait OBValidation
// if the user submits an ID only but that ID is not of the correct type,
// return false.
if (null !== $accountId && null === $accountName) {
- Log::debug('Source ID is not null, but name is null.');
+ app('log')->debug('Source ID is not null, but name is null.');
$search = $this->getRepository()->find($accountId);
// the source resulted in an account, but it's not of a valid type.
if (null !== $search && !in_array($search->accountType->type, $validTypes, true)) {
- $message = sprintf('User submitted only an ID (#%d), which is a "%s", so this is not a valid source.', $accountId, $search->accountType->type);
- Log::debug($message);
+ $message = sprintf('User submitted only an ID (#%d), which is a "%s", so this is not a valid source.', $accountId, $search->accountType->type);
+ app('log')->debug($message);
$this->sourceError = $message;
$result = false;
}
// the source resulted in an account, AND it's of a valid type.
if (null !== $search && in_array($search->accountType->type, $validTypes, true)) {
- Log::debug(sprintf('Found account of correct type: #%d, "%s"', $search->id, $search->name));
+ app('log')->debug(sprintf('Found account of correct type: #%d, "%s"', $search->id, $search->name));
$this->setSource($search);
$result = true;
}
@@ -134,11 +119,13 @@ trait OBValidation
// if the account can be created anyway we don't need to search.
if (null === $result && true === $this->canCreateTypes($validTypes)) {
- Log::debug('Result is still null.');
- $result = true;
+ app('log')->debug('Result is still null.');
+ $result = true;
// set the source to be a (dummy) initial balance account.
$account = new Account();
+
+ /** @var AccountType $accountType */
$accountType = AccountType::whereType(AccountType::INITIAL_BALANCE)->first();
$account->accountType = $accountType;
$this->setSource($account);
diff --git a/app/Validation/Account/ReconciliationValidation.php b/app/Validation/Account/ReconciliationValidation.php
index f3e3e1071a..be3695eef3 100644
--- a/app/Validation/Account/ReconciliationValidation.php
+++ b/app/Validation/Account/ReconciliationValidation.php
@@ -25,7 +25,6 @@ declare(strict_types=1);
namespace FireflyIII\Validation\Account;
use FireflyIII\Models\Account;
-use Illuminate\Support\Facades\Log;
/**
* Trait ReconciliationValidation
@@ -35,11 +34,6 @@ trait ReconciliationValidation
public ?Account $destination;
public ?Account $source;
- /**
- * @param array $array
- *
- * @return bool
- */
protected function validateReconciliationDestination(array $array): bool
{
$accountId = array_key_exists('id', $array) ? $array['id'] : null;
@@ -53,11 +47,11 @@ trait ReconciliationValidation
}
// after that, search for it expecting an asset account or a liability.
- Log::debug('Now in validateReconciliationDestination', $array);
+ app('log')->debug('Now in validateReconciliationDestination', $array);
// source can be any of the following types.
- $validTypes = array_keys($this->combinations[$this->transactionType]);
- $search = $this->findExistingAccount($validTypes, $array);
+ $validTypes = array_keys($this->combinations[$this->transactionType]);
+ $search = $this->findExistingAccount($validTypes, $array);
if (null === $search) {
$this->sourceError = (string)trans('validation.reconciliation_source_bad_data', ['id' => $accountId, 'name' => $accountName]);
app('log')->warning('Not a valid source. Cant find it.', $validTypes);
@@ -65,17 +59,13 @@ trait ReconciliationValidation
return false;
}
$this->setSource($search);
- Log::debug('Valid source account!');
+ app('log')->debug('Valid source account!');
return true;
}
/**
* Basically the same check
- *
- * @param array $array
- *
- * @return bool
*/
protected function validateReconciliationSource(array $array): bool
{
@@ -85,17 +75,18 @@ trait ReconciliationValidation
// is expected to be "positive", i.e. the money flows from the
// source to the asset account that is the destination.
if (null === $accountId && null === $accountName) {
- Log::debug('The source is valid because ID and name are NULL.');
+ app('log')->debug('The source is valid because ID and name are NULL.');
$this->setSource(new Account());
+
return true;
}
// after that, search for it expecting an asset account or a liability.
- Log::debug('Now in validateReconciliationSource', $array);
+ app('log')->debug('Now in validateReconciliationSource', $array);
// source can be any of the following types.
- $validTypes = array_keys($this->combinations[$this->transactionType]);
- $search = $this->findExistingAccount($validTypes, $array);
+ $validTypes = array_keys($this->combinations[$this->transactionType]);
+ $search = $this->findExistingAccount($validTypes, $array);
if (null === $search) {
$this->sourceError = (string)trans('validation.reconciliation_source_bad_data', ['id' => $accountId, 'name' => $accountName]);
app('log')->warning('Not a valid source. Cant find it.', $validTypes);
@@ -103,7 +94,7 @@ trait ReconciliationValidation
return false;
}
$this->setSource($search);
- Log::debug('Valid source account!');
+ app('log')->debug('Valid source account!');
return true;
}
diff --git a/app/Validation/Account/TransferValidation.php b/app/Validation/Account/TransferValidation.php
index b7227d6db0..dbf5808fcb 100644
--- a/app/Validation/Account/TransferValidation.php
+++ b/app/Validation/Account/TransferValidation.php
@@ -24,37 +24,31 @@ declare(strict_types=1);
namespace FireflyIII\Validation\Account;
use FireflyIII\Models\Account;
-use Illuminate\Support\Facades\Log;
/**
* Trait TransferValidation
*/
trait TransferValidation
{
- /**
- * @param array $array
- *
- * @return bool
- */
protected function validateTransferDestination(array $array): bool
{
$accountId = array_key_exists('id', $array) ? $array['id'] : null;
$accountName = array_key_exists('name', $array) ? $array['name'] : null;
$accountIban = array_key_exists('iban', $array) ? $array['iban'] : null;
- Log::debug('Now in validateTransferDestination', $array);
+ app('log')->debug('Now in validateTransferDestination', $array);
// source can be any of the following types.
- $validTypes = $this->combinations[$this->transactionType][$this->source->accountType->type] ?? [];
+ $validTypes = $this->combinations[$this->transactionType][$this->source->accountType->type] ?? [];
if (null === $accountId && null === $accountName && null === $accountIban && false === $this->canCreateTypes($validTypes)) {
// if both values are NULL we return false,
// because the destination of a transfer can't be created.
$this->destError = (string)trans('validation.transfer_dest_need_data');
- Log::error('Both values are NULL, cant create transfer destination.');
+ app('log')->error('Both values are NULL, cant create transfer destination.');
return false;
}
// or try to find the account:
- $search = $this->findExistingAccount($validTypes, $array);
+ $search = $this->findExistingAccount($validTypes, $array);
if (null === $search) {
$this->destError = (string)trans('validation.transfer_dest_bad_data', ['id' => $accountId, 'name' => $accountName]);
@@ -73,35 +67,19 @@ trait TransferValidation
return true;
}
- /**
- * @param array $accountTypes
- *
- * @return bool
- */
abstract protected function canCreateTypes(array $accountTypes): bool;
- /**
- * @param array $validTypes
- * @param array $data
- *
- * @return Account|null
- */
abstract protected function findExistingAccount(array $validTypes, array $data): ?Account;
- /**
- * @param array $array
- *
- * @return bool
- */
protected function validateTransferSource(array $array): bool
{
$accountId = array_key_exists('id', $array) ? $array['id'] : null;
$accountName = array_key_exists('name', $array) ? $array['name'] : null;
$accountIban = array_key_exists('iban', $array) ? $array['iban'] : null;
$accountNumber = array_key_exists('number', $array) ? $array['number'] : null;
- Log::debug('Now in validateTransferSource', $array);
+ app('log')->debug('Now in validateTransferSource', $array);
// source can be any of the following types.
- $validTypes = array_keys($this->combinations[$this->transactionType]);
+ $validTypes = array_keys($this->combinations[$this->transactionType]);
if (null === $accountId && null === $accountName
&& null === $accountIban && null === $accountNumber
&& false === $this->canCreateTypes($validTypes)) {
@@ -114,7 +92,7 @@ trait TransferValidation
}
// otherwise try to find the account:
- $search = $this->findExistingAccount($validTypes, $array);
+ $search = $this->findExistingAccount($validTypes, $array);
if (null === $search) {
$this->sourceError = (string)trans('validation.transfer_source_bad_data', ['id' => $accountId, 'name' => $accountName]);
app('log')->warning('Not a valid source, cant find it.', $validTypes);
@@ -122,7 +100,7 @@ trait TransferValidation
return false;
}
$this->setSource($search);
- Log::debug('Valid source!');
+ app('log')->debug('Valid source!');
return true;
}
diff --git a/app/Validation/Account/WithdrawalValidation.php b/app/Validation/Account/WithdrawalValidation.php
index e7ad03e8e5..9f4102b12d 100644
--- a/app/Validation/Account/WithdrawalValidation.php
+++ b/app/Validation/Account/WithdrawalValidation.php
@@ -25,26 +25,20 @@ namespace FireflyIII\Validation\Account;
use FireflyIII\Models\Account;
use FireflyIII\Models\AccountType;
-use Illuminate\Support\Facades\Log;
/**
* Trait WithdrawalValidation
*/
trait WithdrawalValidation
{
- /**
- * @param array $array
- *
- * @return bool
- */
protected function validateGenericSource(array $array): bool
{
$accountId = array_key_exists('id', $array) ? $array['id'] : null;
$accountName = array_key_exists('name', $array) ? $array['name'] : null;
$accountIban = array_key_exists('iban', $array) ? $array['iban'] : null;
- Log::debug('Now in validateGenericSource', $array);
+ app('log')->debug('Now in validateGenericSource', $array);
// source can be any of the following types.
- $validTypes = [AccountType::ASSET, AccountType::REVENUE, AccountType::LOAN, AccountType::DEBT, AccountType::MORTGAGE];
+ $validTypes = [AccountType::ASSET, AccountType::REVENUE, AccountType::LOAN, AccountType::DEBT, AccountType::MORTGAGE];
if (null === $accountId && null === $accountName && null === $accountIban && false === $this->canCreateTypes($validTypes)) {
// if both values are NULL we return TRUE
// because we assume the user doesn't want to submit / change anything.
@@ -55,7 +49,7 @@ trait WithdrawalValidation
}
// otherwise try to find the account:
- $search = $this->findExistingAccount($validTypes, $array);
+ $search = $this->findExistingAccount($validTypes, $array);
if (null === $search) {
$this->sourceError = (string)trans('validation.withdrawal_source_bad_data', ['id' => $accountId, 'name' => $accountName]);
app('log')->warning('Not a valid source. Cant find it.', $validTypes);
@@ -63,40 +57,24 @@ trait WithdrawalValidation
return false;
}
$this->setSource($search);
- Log::debug('Valid source account!');
+ app('log')->debug('Valid source account!');
return true;
}
- /**
- * @param array $accountTypes
- *
- * @return bool
- */
abstract protected function canCreateTypes(array $accountTypes): bool;
- /**
- * @param array $validTypes
- * @param array $data
- *
- * @return Account|null
- */
abstract protected function findExistingAccount(array $validTypes, array $data): ?Account;
- /**
- * @param array $array
- *
- * @return bool
- */
protected function validateWithdrawalDestination(array $array): bool
{
$accountId = array_key_exists('id', $array) ? $array['id'] : null;
$accountName = array_key_exists('name', $array) ? $array['name'] : null;
$accountIban = array_key_exists('iban', $array) ? $array['iban'] : null;
$accountNumber = array_key_exists('number', $array) ? $array['number'] : null;
- Log::debug('Now in validateWithdrawalDestination()', $array);
+ app('log')->debug('Now in validateWithdrawalDestination()', $array);
// source can be any of the following types.
- $validTypes = $this->combinations[$this->transactionType][$this->source->accountType->type] ?? [];
+ $validTypes = $this->combinations[$this->transactionType][$this->source->accountType->type] ?? [];
app('log')->debug('Source type can be: ', $validTypes);
if (null === $accountId && null === $accountName && null === $accountIban && null === $accountNumber && false === $this->canCreateTypes($validTypes)) {
// if both values are NULL return false,
@@ -110,9 +88,10 @@ trait WithdrawalValidation
if (null !== $accountId && 0 !== $accountId) {
$found = $this->getRepository()->find($accountId);
if (null !== $found) {
- $type = $found->accountType->type;
+ $type = $found->accountType->type;
if (in_array($type, $validTypes, true)) {
$this->setDestination($found);
+
return true;
}
// todo explain error in log message.
@@ -129,6 +108,7 @@ trait WithdrawalValidation
$existing = $this->findExistingAccount($validTypes, ['iban' => $accountIban], true);
if (null !== $existing) {
$this->destError = (string)trans('validation.withdrawal_dest_iban_exists');
+
return false;
}
}
@@ -137,11 +117,6 @@ trait WithdrawalValidation
return true === $this->canCreateTypes($validTypes);
}
- /**
- * @param array $array
- *
- * @return bool
- */
protected function validateWithdrawalSource(array $array): bool
{
$accountId = array_key_exists('id', $array) ? $array['id'] : null;
@@ -149,9 +124,9 @@ trait WithdrawalValidation
$accountIban = array_key_exists('iban', $array) ? $array['iban'] : null;
$accountNumber = array_key_exists('number', $array) ? $array['number'] : null;
- Log::debug('Now in validateWithdrawalSource', $array);
+ app('log')->debug('Now in validateWithdrawalSource', $array);
// source can be any of the following types.
- $validTypes = array_keys($this->combinations[$this->transactionType]);
+ $validTypes = array_keys($this->combinations[$this->transactionType]);
if (null === $accountId && null === $accountName && null === $accountNumber && null === $accountIban && false === $this->canCreateTypes($validTypes)) {
// if both values are NULL we return false,
// because the source of a withdrawal can't be created.
@@ -162,7 +137,7 @@ trait WithdrawalValidation
}
// otherwise try to find the account:
- $search = $this->findExistingAccount($validTypes, $array);
+ $search = $this->findExistingAccount($validTypes, $array);
if (null === $search) {
$this->sourceError = (string)trans('validation.withdrawal_source_bad_data', ['id' => $accountId, 'name' => $accountName]);
app('log')->warning('Not a valid source. Cant find it.', $validTypes);
@@ -170,7 +145,7 @@ trait WithdrawalValidation
return false;
}
$this->setSource($search);
- Log::debug('Valid source account!');
+ app('log')->debug('Valid source account!');
return true;
}
diff --git a/app/Validation/AccountValidator.php b/app/Validation/AccountValidator.php
index 080665e403..62a4ee6258 100644
--- a/app/Validation/AccountValidator.php
+++ b/app/Validation/AccountValidator.php
@@ -36,19 +36,18 @@ use FireflyIII\Validation\Account\OBValidation;
use FireflyIII\Validation\Account\ReconciliationValidation;
use FireflyIII\Validation\Account\TransferValidation;
use FireflyIII\Validation\Account\WithdrawalValidation;
-use Illuminate\Support\Facades\Log;
/**
* Class AccountValidator
*/
class AccountValidator
{
- use WithdrawalValidation;
use DepositValidation;
- use TransferValidation;
- use ReconciliationValidation;
- use OBValidation;
use LiabilityValidation;
+ use OBValidation;
+ use ReconciliationValidation;
+ use TransferValidation;
+ use WithdrawalValidation;
public bool $createMode;
public string $destError;
@@ -59,8 +58,6 @@ class AccountValidator
private array $combinations;
private string $transactionType;
private bool $useUserGroupRepository = false;
- private User $user;
- private UserGroup $userGroup;
private UserGroupAccountRepositoryInterface $userGroupAccountRepository;
/**
@@ -78,182 +75,167 @@ class AccountValidator
$this->userGroupAccountRepository = app(UserGroupAccountRepositoryInterface::class);
}
- /**
- * @return Account|null
- */
public function getSource(): ?Account
{
return $this->source;
}
- /**
- * @param Account|null $account
- */
public function setSource(?Account $account): void
{
if (null === $account) {
- Log::debug('AccountValidator source is set to NULL');
+ app('log')->debug('AccountValidator source is set to NULL');
}
if (null !== $account) {
- Log::debug(sprintf('AccountValidator source is set to #%d: "%s" (%s)', $account->id, $account->name, $account->accountType->type));
+ app('log')->debug(sprintf('AccountValidator source is set to #%d: "%s" (%s)', $account->id, $account->name, $account->accountType->type));
}
$this->source = $account;
}
- /**
- * @param Account|null $account
- */
public function setDestination(?Account $account): void
{
if (null === $account) {
- Log::debug('AccountValidator destination is set to NULL');
+ app('log')->debug('AccountValidator destination is set to NULL');
}
if (null !== $account) {
- Log::debug(sprintf('AccountValidator destination is set to #%d: "%s" (%s)', $account->id, $account->name, $account->accountType->type));
+ app('log')->debug(sprintf('AccountValidator destination is set to #%d: "%s" (%s)', $account->id, $account->name, $account->accountType->type));
}
$this->destination = $account;
}
- /**
- * @param string $transactionType
- */
public function setTransactionType(string $transactionType): void
{
- Log::debug(sprintf('Transaction type for validator is now "%s".', ucfirst($transactionType)));
+ app('log')->debug(sprintf('Transaction type for validator is now "%s".', ucfirst($transactionType)));
$this->transactionType = ucfirst($transactionType);
}
- /**
- * @param User $user
- */
public function setUser(User $user): void
{
- $this->user = $user;
$this->accountRepository->setUser($user);
$this->useUserGroupRepository = false;
}
- /**
- * @param UserGroup $userGroup
- *
- * @return void
- */
public function setUserGroup(UserGroup $userGroup): void
{
- $this->userGroup = $userGroup;
$this->userGroupAccountRepository->setUserGroup($userGroup);
$this->useUserGroupRepository = true;
}
- /**
- * @param array $array
- *
- * @return bool
- */
public function validateDestination(array $array): bool
{
- Log::debug('Now in AccountValidator::validateDestination()', $array);
+ app('log')->debug('Now in AccountValidator::validateDestination()', $array);
if (null === $this->source) {
- Log::error('Source is NULL, always FALSE.');
+ app('log')->error('Source is NULL, always FALSE.');
$this->destError = 'No source account validation has taken place yet. Please do this first or overrule the object.';
return false;
}
+
switch ($this->transactionType) {
default:
$this->destError = sprintf('AccountValidator::validateDestination cannot handle "%s", so it will always return false.', $this->transactionType);
- Log::error(sprintf('AccountValidator::validateDestination cannot handle "%s", so it will always return false.', $this->transactionType));
+ app('log')->error(sprintf('AccountValidator::validateDestination cannot handle "%s", so it will always return false.', $this->transactionType));
+
+ $result = false;
- $result = false;
break;
case TransactionType::WITHDRAWAL:
- $result = $this->validateWithdrawalDestination($array);
+ $result = $this->validateWithdrawalDestination($array);
+
break;
+
case TransactionType::DEPOSIT:
- $result = $this->validateDepositDestination($array);
+ $result = $this->validateDepositDestination($array);
+
break;
+
case TransactionType::TRANSFER:
- $result = $this->validateTransferDestination($array);
+ $result = $this->validateTransferDestination($array);
+
break;
+
case TransactionType::OPENING_BALANCE:
- $result = $this->validateOBDestination($array);
+ $result = $this->validateOBDestination($array);
+
break;
+
case TransactionType::LIABILITY_CREDIT:
- $result = $this->validateLCDestination($array);
+ $result = $this->validateLCDestination($array);
+
break;
+
case TransactionType::RECONCILIATION:
- $result = $this->validateReconciliationDestination($array);
+ $result = $this->validateReconciliationDestination($array);
+
break;
}
return $result;
}
- /**
- * @param array $array
- *
- * @return bool
- */
public function validateSource(array $array): bool
{
- Log::debug('Now in AccountValidator::validateSource()', $array);
+ app('log')->debug('Now in AccountValidator::validateSource()', $array);
+
switch ($this->transactionType) {
default:
- Log::error(sprintf('AccountValidator::validateSource cannot handle "%s", so it will do a generic check.', $this->transactionType));
+ app('log')->error(sprintf('AccountValidator::validateSource cannot handle "%s", so it will do a generic check.', $this->transactionType));
$result = $this->validateGenericSource($array);
+
break;
+
case TransactionType::WITHDRAWAL:
$result = $this->validateWithdrawalSource($array);
+
break;
+
case TransactionType::DEPOSIT:
$result = $this->validateDepositSource($array);
+
break;
+
case TransactionType::TRANSFER:
$result = $this->validateTransferSource($array);
+
break;
+
case TransactionType::OPENING_BALANCE:
$result = $this->validateOBSource($array);
+
break;
+
case TransactionType::LIABILITY_CREDIT:
$result = $this->validateLCSource($array);
+
break;
case TransactionType::RECONCILIATION:
- Log::debug('Calling validateReconciliationSource');
+ app('log')->debug('Calling validateReconciliationSource');
$result = $this->validateReconciliationSource($array);
+
break;
}
return $result;
}
- /**
- * @param array $accountTypes
- *
- * @return bool
- */
protected function canCreateTypes(array $accountTypes): bool
{
- Log::debug('Can we create any of these types?', $accountTypes);
+ app('log')->debug('Can we create any of these types?', $accountTypes);
+
/** @var string $accountType */
foreach ($accountTypes as $accountType) {
if ($this->canCreateType($accountType)) {
- Log::debug(sprintf('YES, we can create a %s', $accountType));
+ app('log')->debug(sprintf('YES, we can create a %s', $accountType));
return true;
}
}
- Log::debug('NO, we cant create any of those.');
+ app('log')->debug('NO, we cant create any of those.');
return false;
}
- /**
- * @param string $accountType
- *
- * @return bool
- */
protected function canCreateType(string $accountType): bool
{
$canCreate = [AccountType::EXPENSE, AccountType::REVENUE, AccountType::INITIAL_BALANCE, AccountType::LIABILITY_CREDIT];
@@ -265,15 +247,15 @@ class AccountValidator
}
/**
- * @param array $validTypes
- * @param array $data
- * @param bool $inverse
+ * It's a long and fairly complex method, but I don't mind.
*
- * @return Account|null
+ * @SuppressWarnings(PHPMD.CyclomaticComplexity)
+ * @SuppressWarnings(PHPMD.BooleanArgumentFlag)
+ * @SuppressWarnings(PHPMD.NPathComplexity)
*/
protected function findExistingAccount(array $validTypes, array $data, bool $inverse = false): ?Account
{
- Log::debug('Now in findExistingAccount', $data);
+ app('log')->debug('Now in findExistingAccount', $data);
app('log')->debug('The search will be reversed!');
$accountId = array_key_exists('id', $data) ? $data['id'] : null;
$accountIban = array_key_exists('iban', $data) ? $data['iban'] : null;
@@ -288,6 +270,7 @@ class AccountValidator
$check = $inverse ? !$check : $check; // reverse the validation check if necessary.
if ((null !== $first) && $check) {
app('log')->debug(sprintf('ID: Found %s account #%d ("%s", IBAN "%s")', $first->accountType->type, $first->id, $first->name, $first->iban ?? 'no iban'));
+
return $first;
}
}
@@ -300,6 +283,7 @@ class AccountValidator
$check = $inverse ? !$check : $check; // reverse the validation check if necessary.
if ((null !== $first) && $check) {
app('log')->debug(sprintf('Iban: Found %s account #%d ("%s", IBAN "%s")', $first->accountType->type, $first->id, $first->name, $first->iban ?? 'no iban'));
+
return $first;
}
}
@@ -312,6 +296,7 @@ class AccountValidator
$check = $inverse ? !$check : $check; // reverse the validation check if necessary.
if ((null !== $first) && $check) {
app('log')->debug(sprintf('Number: Found %s account #%d ("%s", IBAN "%s")', $first->accountType->type, $first->id, $first->name, $first->iban ?? 'no iban'));
+
return $first;
}
}
@@ -321,6 +306,7 @@ class AccountValidator
$first = $this->getRepository()->findByName($accountName, $validTypes);
if (null !== $first) {
app('log')->debug(sprintf('Name: Found %s account #%d ("%s", IBAN "%s")', $first->accountType->type, $first->id, $first->name, $first->iban ?? 'no iban'));
+
return $first;
}
}
@@ -329,10 +315,7 @@ class AccountValidator
return null;
}
- /**
- * @return AccountRepositoryInterface|UserGroupAccountRepositoryInterface
- */
- private function getRepository(): AccountRepositoryInterface | UserGroupAccountRepositoryInterface
+ private function getRepository(): AccountRepositoryInterface|UserGroupAccountRepositoryInterface
{
if ($this->useUserGroupRepository) {
return $this->userGroupAccountRepository;
diff --git a/app/Validation/Administration/ValidatesAdministrationAccess.php b/app/Validation/Administration/ValidatesAdministrationAccess.php
deleted file mode 100644
index ecd88233ec..0000000000
--- a/app/Validation/Administration/ValidatesAdministrationAccess.php
+++ /dev/null
@@ -1,107 +0,0 @@
-.
- */
-
-declare(strict_types=1);
-
-namespace FireflyIII\Validation\Administration;
-
-use FireflyIII\Enums\UserRoleEnum;
-use FireflyIII\Exceptions\FireflyException;
-use FireflyIII\Repositories\User\UserRepositoryInterface;
-use FireflyIII\User;
-use Illuminate\Auth\AuthenticationException;
-use Illuminate\Support\Facades\Log;
-use Illuminate\Validation\Validator;
-
-/**
- * @deprecated
- * Trait ValidatesAdministrationAccess
- */
-trait ValidatesAdministrationAccess
-{
- /**
- * @param Validator $validator
- * @param array $allowedRoles
- *
- * @return void
- * @throws AuthenticationException
- * @throws FireflyException
- * @deprecated
- */
- protected function validateAdministration(Validator $validator, array $allowedRoles): void
- {
- throw new FireflyException('deprecated method, must be done through user.');
- Log::debug('Now in validateAdministration()');
- if (!auth()->check()) {
- Log::error('User is not authenticated.');
- throw new AuthenticationException('No access to validateAdministration() method.');
- }
- /** @var User $user */
- $user = auth()->user();
- // get data from request:
- $data = $validator->getData();
- // check if user is part of this administration
- $administrationId = (int)($data['administration_id'] ?? $user->getAdministrationId());
- // safety catch:
- if (0 === $administrationId) {
- Log::error('validateAdministration ran into empty administration ID.');
- throw new AuthenticationException('Cannot validate administration.');
- }
- // grab the group:
- $repository = app(UserRepositoryInterface::class);
-
- // collect the user's roles in this group:
- $array = $repository->getRolesInGroup($user, $administrationId);
- if (0 === count($array)) {
- Log::error(sprintf('User #%d ("%s") has no membership in group #%d.', $user->id, $user->email, $administrationId));
- $validator->errors()->add('administration', (string)trans('validation.no_access_user_group'));
- return;
- }
- if (in_array(UserRoleEnum::OWNER->value, $array, true)) {
- Log::debug('User is owner of this administration.');
- return;
- }
- if (in_array(UserRoleEnum::OWNER->value, $array, true)) {
- Log::debug('User has full access to this administration.');
- return;
- }
- $access = true;
- foreach ($allowedRoles as $allowedRole) {
- if (!in_array($allowedRole, $array, true)) {
- $access = false;
- }
- }
- if (false === $access) {
- Log::error(
- sprintf(
- 'User #%d has memberships [%s] to group #%d but needs [%s].',
- $user->id,
- join(', ', $array),
- $administrationId,
- join(', ', $allowedRoles)
- )
- );
- $validator->errors()->add('administration', (string)trans('validation.no_access_user_group'));
- }
- }
-}
diff --git a/app/Validation/Api/Data/Bulk/ValidatesBulkTransactionQuery.php b/app/Validation/Api/Data/Bulk/ValidatesBulkTransactionQuery.php
index 4e1637fca7..6494d4d05a 100644
--- a/app/Validation/Api/Data/Bulk/ValidatesBulkTransactionQuery.php
+++ b/app/Validation/Api/Data/Bulk/ValidatesBulkTransactionQuery.php
@@ -26,18 +26,9 @@ namespace FireflyIII\Validation\Api\Data\Bulk;
use FireflyIII\Repositories\Account\AccountRepositoryInterface;
use Illuminate\Validation\Validator;
-use JsonException;
-/**
- *
- */
trait ValidatesBulkTransactionQuery
{
- /**
- * @param Validator $validator
- *
- * @throws JsonException
- */
protected function validateTransactionQuery(Validator $validator): void
{
$data = $validator->getData();
@@ -49,9 +40,9 @@ trait ValidatesBulkTransactionQuery
) {
// find both accounts, must be same type.
// already validated: belongs to this user.
- $repository = app(AccountRepositoryInterface::class);
- $source = $repository->find((int)$json['where']['account_id']);
- $dest = $repository->find((int)$json['update']['account_id']);
+ $repository = app(AccountRepositoryInterface::class);
+ $source = $repository->find((int)$json['where']['account_id']);
+ $dest = $repository->find((int)$json['update']['account_id']);
if (null === $source) {
$validator->errors()->add('query', sprintf((string)trans('validation.invalid_query_data'), 'where', 'account_id'));
@@ -73,8 +64,8 @@ trait ValidatesBulkTransactionQuery
$sourceCurrency = $repository->getAccountCurrency($source);
$destCurrency = $repository->getAccountCurrency($dest);
if (
- $sourceCurrency !== null
- && $destCurrency !== null
+ null !== $sourceCurrency
+ && null !== $destCurrency
&& $sourceCurrency->id !== $destCurrency->id
) {
$validator->errors()->add('query', (string)trans('validation.invalid_query_currency'));
diff --git a/app/Validation/AutoBudget/ValidatesAutoBudgetRequest.php b/app/Validation/AutoBudget/ValidatesAutoBudgetRequest.php
index e641f9a406..2c994fb960 100644
--- a/app/Validation/AutoBudget/ValidatesAutoBudgetRequest.php
+++ b/app/Validation/AutoBudget/ValidatesAutoBudgetRequest.php
@@ -31,12 +31,14 @@ use Illuminate\Validation\Validator;
trait ValidatesAutoBudgetRequest
{
/**
- * @param Validator $validator
+ * @SuppressWarnings(PHPMD.NPathComplexity)
*/
protected function validateAutoBudgetAmount(Validator $validator): void
{
$data = $validator->getData();
$type = $data['auto_budget_type'] ?? '';
+
+ /** @var null|float|int|string $amount */
$amount = array_key_exists('auto_budget_amount', $data) ? $data['auto_budget_amount'] : null;
$period = array_key_exists('auto_budget_period', $data) ? $data['auto_budget_period'] : null;
$currencyId = array_key_exists('auto_budget_currency_id', $data) ? (int)$data['auto_budget_currency_id'] : null;
@@ -47,6 +49,11 @@ trait ValidatesAutoBudgetRequest
if ('' === $type || 0 === $type) {
return;
}
+ // TODO lots of duplicates with number validator.
+ // TODO should be present at more places, stop scientific notification
+ if (str_contains(strtoupper((string)$amount), 'E')) {
+ $amount = '';
+ }
// basic float check:
if (!is_numeric($amount)) {
$validator->errors()->add('auto_budget_amount', (string)trans('validation.amount_required_for_auto_budget'));
@@ -54,9 +61,6 @@ trait ValidatesAutoBudgetRequest
return;
}
- if ('' === $amount) {
- $validator->errors()->add('auto_budget_amount', (string)trans('validation.amount_required_for_auto_budget'));
- }
if (1 !== bccomp((string)$amount, '0')) {
$validator->errors()->add('auto_budget_amount', (string)trans('validation.auto_budget_amount_positive'));
}
@@ -69,7 +73,6 @@ trait ValidatesAutoBudgetRequest
// too big amount
if ((int)$amount > 268435456) {
$validator->errors()->add('auto_budget_amount', (string)trans('validation.amount_required_for_auto_budget'));
- return;
}
}
}
diff --git a/app/Validation/CurrencyValidation.php b/app/Validation/CurrencyValidation.php
index ea963a6ff8..c792b0a866 100644
--- a/app/Validation/CurrencyValidation.php
+++ b/app/Validation/CurrencyValidation.php
@@ -34,57 +34,62 @@ use Illuminate\Validation\Validator;
*/
trait CurrencyValidation
{
- public const TEST = 'Test';
+ public const string TEST = 'Test';
/**
* If the transactions contain foreign amounts, there must also be foreign currency information.
- *
- * @param Validator $validator
*/
protected function validateForeignCurrencyInformation(Validator $validator): void
{
if ($validator->errors()->count() > 0) {
return;
}
- Log::debug('Now in validateForeignCurrencyInformation()');
+ app('log')->debug('Now in validateForeignCurrencyInformation()');
$transactions = $this->getTransactionsArray($validator);
foreach ($transactions as $index => $transaction) {
if (!is_array($transaction)) {
continue;
}
- // if foreign amount is present, then the currency must be as well.
- if (array_key_exists('foreign_amount', $transaction)
- && !(array_key_exists('foreign_currency_id', $transaction)
- || array_key_exists(
- 'foreign_currency_code',
- $transaction
- ))
- && 0 !== bccomp('0', $transaction['foreign_amount'])
- ) {
- $validator->errors()->add(
- 'transactions.' . $index . '.foreign_amount',
- (string)trans('validation.require_currency_info')
- );
+
+ if (!array_key_exists('foreign_amount', $transaction) && !array_key_exists('foreign_currency_id', $transaction) && !array_key_exists('foreign_currency_code', $transaction)) {
+ Log::debug('validateForeignCurrencyInformation: no foreign currency information present at all.');
+
+ continue;
}
- // if the currency is present, then the amount must be present as well.
- if ((array_key_exists('foreign_currency_id', $transaction) || array_key_exists('foreign_currency_code', $transaction))
- && !array_key_exists(
- 'foreign_amount',
- $transaction
- )) {
- $validator->errors()->add(
- 'transactions.' . $index . '.foreign_amount',
- (string)trans('validation.require_currency_amount')
- );
+ $foreignAmount = (string)($transaction['foreign_amount'] ?? '');
+ $foreignId = $transaction['foreign_currency_id'] ?? null;
+ $foreignCode = $transaction['foreign_currency_code'] ?? null;
+ if ('' === $foreignAmount) {
+ Log::debug('validateForeignCurrencyInformation: foreign amount is "".');
+ if (
+ (array_key_exists('foreign_currency_id', $transaction) || array_key_exists('foreign_currency_code', $transaction))
+ && (null !== $foreignId || null !== $foreignCode)
+ ) {
+ $validator->errors()->add('transactions.'.$index.'.foreign_amount', (string)trans('validation.require_currency_amount'));
+ $validator->errors()->add('transactions.'.$index.'.foreign_currency_id', (string)trans('validation.require_currency_amount'));
+ $validator->errors()->add('transactions.'.$index.'.foreign_currency_code', (string)trans('validation.require_currency_amount'));
+ }
+
+ continue;
+ }
+
+ $compare = bccomp('0', $foreignAmount);
+ if (-1 === $compare) {
+ Log::debug('validateForeignCurrencyInformation: array contains foreign amount info.');
+ if (!array_key_exists('foreign_currency_id', $transaction) && !array_key_exists('foreign_currency_code', $transaction)) {
+ Log::debug('validateForeignCurrencyInformation: array contains NO foreign currency info.');
+ $validator->errors()->add('transactions.'.$index.'.foreign_amount', (string)trans('validation.require_currency_info'));
+ }
+ }
+ if (0 === $compare && ('' !== (string)$foreignId || '' !== (string)$foreignCode)) {
+ Log::debug('validateForeignCurrencyInformation: array contains foreign currency info, but zero amount.');
+ $validator->errors()->add('transactions.'.$index.'.foreign_currency_id', (string)trans('validation.require_currency_amount'));
+ $validator->errors()->add('transactions.'.$index.'.foreign_currency_code', (string)trans('validation.require_currency_amount'));
+ $validator->errors()->add('transactions.'.$index.'.foreign_amount', (string)trans('validation.require_currency_amount'));
}
}
}
- /**
- * @param Validator $validator
- *
- * @return array
- */
abstract protected function getTransactionsArray(Validator $validator): array;
}
diff --git a/app/Validation/FireflyValidator.php b/app/Validation/FireflyValidator.php
index 02e6b4ef5f..891fcc6163 100644
--- a/app/Validation/FireflyValidator.php
+++ b/app/Validation/FireflyValidator.php
@@ -23,8 +23,6 @@ declare(strict_types=1);
namespace FireflyIII\Validation;
-use Config;
-use DB;
use FireflyIII\Exceptions\FireflyException;
use FireflyIII\Models\Account;
use FireflyIII\Models\AccountMeta;
@@ -36,22 +34,16 @@ use FireflyIII\Repositories\Bill\BillRepositoryInterface;
use FireflyIII\Repositories\Budget\BudgetRepositoryInterface;
use FireflyIII\Repositories\PiggyBank\PiggyBankRepositoryInterface;
use FireflyIII\Services\Password\Verifier;
-use FireflyIII\Support\Facades\Preferences;
use FireflyIII\Support\ParseDateString;
-use FireflyIII\TransactionRules\Triggers\TriggerInterface;
use FireflyIII\User;
-use Google2FA;
-use Illuminate\Support\Facades\Log;
use Illuminate\Validation\Validator;
use PragmaRX\Google2FA\Exceptions\IncompatibleWithGoogleAuthenticatorException;
use PragmaRX\Google2FA\Exceptions\InvalidCharactersException;
use PragmaRX\Google2FA\Exceptions\SecretKeyTooShortException;
-use ValueError;
-
-use function is_string;
/**
* Class FireflyValidator.
+ * TODO all of these validations must become separate classes.
*/
class FireflyValidator extends Validator
{
@@ -59,25 +51,30 @@ class FireflyValidator extends Validator
* @param mixed $attribute
* @param mixed $value
*
- * @return bool
* @throws IncompatibleWithGoogleAuthenticatorException
* @throws InvalidCharactersException
* @throws SecretKeyTooShortException
+ *
+ * @SuppressWarnings(PHPMD.UnusedFormalParameter)
*/
public function validate2faCode($attribute, $value): bool
{
if (!is_string($value) || 6 !== strlen($value)) {
return false;
}
- $user = auth()->user();
+ $user = auth()->user();
if (null === $user) {
- Log::error('No user during validate2faCode');
+ app('log')->error('No user during validate2faCode');
+
return false;
}
- $secretPreference = Preferences::get('temp-mfa-secret');
+ $secretPreference = app('preferences')->get('temp-mfa-secret');
$secret = $secretPreference?->data ?? '';
+ if (is_array($secret)) {
+ $secret = '';
+ }
- return Google2FA::verifyKey($secret, $value);
+ return (bool)\Google2FA::verifyKey((string)$secret, $value);
}
/**
@@ -85,7 +82,7 @@ class FireflyValidator extends Validator
* @param mixed $value
* @param mixed $parameters
*
- * @return bool
+ * @SuppressWarnings(PHPMD.UnusedFormalParameter)
*/
public function validateBelongsToUser($attribute, $value, $parameters): bool
{
@@ -94,7 +91,7 @@ class FireflyValidator extends Validator
if (0 === (int)$value) {
return true;
}
- $count = DB::table($parameters[0])->where('user_id', auth()->user()->id)->where($field, $value)->count();
+ $count = \DB::table($parameters[0])->where('user_id', auth()->user()->id)->where($field, $value)->count();
return 1 === $count;
}
@@ -103,16 +100,13 @@ class FireflyValidator extends Validator
* @param mixed $attribute
* @param mixed $value
*
- * @return bool
+ * @SuppressWarnings(PHPMD.UnusedFormalParameter)
*/
public function validateBic($attribute, $value): bool
{
$regex = '/^[a-z]{6}[0-9a-z]{2}([0-9a-z]{3})?\z/i';
$result = preg_match($regex, $value);
- if (false === $result) {
- return false;
- }
- if (0 === $result) {
+ if (false === $result || 0 === $result) {
return false;
}
@@ -120,10 +114,8 @@ class FireflyValidator extends Validator
}
/**
- * @param mixed $attribute
- * @param mixed $value
- *
- * @return bool
+ * @SuppressWarnings(PHPMD.UnusedFormalParameter)
+ * @SuppressWarnings(PHPMD.ExcessiveMethodLength)
*/
public function validateIban(mixed $attribute, mixed $value): bool
{
@@ -186,52 +178,25 @@ class FireflyValidator extends Validator
$value = strtoupper($value);
// replace characters outside of ASCI range.
- $value = iconv('UTF-8', 'ASCII//TRANSLIT//IGNORE', $value);
+ $value = (string)iconv('UTF-8', 'ASCII//TRANSLIT//IGNORE', $value);
$search = [' ', 'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J', 'K', 'L', 'M', 'N', 'O', 'P', 'Q', 'R', 'S', 'T', 'U', 'V', 'W', 'X', 'Y', 'Z'];
- $replace = [
- '',
- '10',
- '11',
- '12',
- '13',
- '14',
- '15',
- '16',
- '17',
- '18',
- '19',
- '20',
- '21',
- '22',
- '23',
- '24',
- '25',
- '26',
- '27',
- '28',
- '29',
- '30',
- '31',
- '32',
- '33',
- '34',
- '35',
- ];
+ $replace = ['', '10', '11', '12', '13', '14', '15', '16', '17', '18', '19', '20', '21', '22', '23', '24', '25', '26', '27', '28', '29', '30', '31', '32', '33', '34', '35'];
// take
- $first = substr($value, 0, 4);
- $last = substr($value, 4);
- $iban = $last . $first;
- $iban = trim(str_replace($search, $replace, $iban));
- if (0 === strlen($iban)) {
+ $first = substr($value, 0, 4);
+ $last = substr($value, 4);
+ $iban = $last.$first;
+ $iban = trim(str_replace($search, $replace, $iban));
+ if ('' === $iban) {
return false;
}
+
try {
$checksum = bcmod($iban, '97');
- } catch (ValueError $e) {
+ } catch (\ValueError $e) { // @phpstan-ignore-line
$message = sprintf('Could not validate IBAN check value "%s" (IBAN "%s")', $iban, $value);
- Log::error($message);
- Log::error($e->getTraceAsString());
+ app('log')->error($message);
+ app('log')->error($e->getTraceAsString());
return false;
}
@@ -244,7 +209,7 @@ class FireflyValidator extends Validator
* @param mixed $value
* @param mixed $parameters
*
- * @return bool
+ * @SuppressWarnings(PHPMD.UnusedFormalParameter)
*/
public function validateLess($attribute, $value, $parameters): bool
{
@@ -259,7 +224,7 @@ class FireflyValidator extends Validator
* @param mixed $value
* @param mixed $parameters
*
- * @return bool
+ * @SuppressWarnings(PHPMD.UnusedFormalParameter)
*/
public function validateMore($attribute, $value, $parameters): bool
{
@@ -274,7 +239,7 @@ class FireflyValidator extends Validator
* @param mixed $value
* @param mixed $parameters
*
- * @return bool
+ * @SuppressWarnings(PHPMD.UnusedFormalParameter)
*/
public function validateMustExist($attribute, $value, $parameters): bool
{
@@ -283,24 +248,17 @@ class FireflyValidator extends Validator
if (0 === (int)$value) {
return true;
}
- $count = DB::table($parameters[0])->where($field, $value)->count();
+ $count = \DB::table($parameters[0])->where($field, $value)->count();
return 1 === $count;
}
- /**
- * @param string $attribute
- *
- * @param string|null $value
- *
- * @return bool
- */
public function validateRuleActionValue(string $attribute, string $value = null): bool
{
// first, get the index from this string:
- $value = $value ?? '';
- $parts = explode('.', $attribute);
- $index = (int)($parts[1] ?? '0');
+ $value ??= '';
+ $parts = explode('.', $attribute);
+ $index = (int)($parts[1] ?? '0');
// get the name of the trigger from the data array:
$actionType = $this->data['actions'][$index]['type'] ?? 'invalid';
@@ -360,17 +318,12 @@ class FireflyValidator extends Validator
/**
* $attribute has the format triggers.%d.value.
- *
- * @param string $attribute
- * @param string|null $value
- *
- * @return bool
*/
public function validateRuleTriggerValue(string $attribute, string $value = null): bool
{
// first, get the index from this string:
- $parts = explode('.', $attribute);
- $index = (int)($parts[1] ?? '0');
+ $parts = explode('.', $attribute);
+ $index = (int)($parts[1] ?? '0');
// get the name of the trigger from the data array:
$triggerType = $this->data['triggers'][$index]['type'] ?? 'invalid';
@@ -381,13 +334,29 @@ class FireflyValidator extends Validator
}
// these trigger types need a numerical check:
- $numerical = ['amount_less', 'amount_more', 'amount_exactly'];
+ $numerical = ['amount_less', 'amount_more', 'amount_exactly'];
if (in_array($triggerType, $numerical, true)) {
return is_numeric($value);
}
+ // these triggers need just the word "true":
+ // TODO create a helper to automatically return these.
+ $needTrue = [
+ 'reconciled', 'has_attachments', 'has_any_category', 'has_any_budget', 'has_any_bill', 'has_any_tag', 'any_notes', 'any_external_url', 'has_no_attachments', 'has_no_category', 'has_no_budget', 'has_no_bill', 'has_no_tag', 'no_notes', 'no_external_url',
+ 'source_is_cash',
+ 'destination_is_cash',
+ 'account_is_cash',
+ 'exists',
+ 'no_external_id',
+ 'any_external_id',
+ ];
+ if (in_array($triggerType, $needTrue, true)) {
+ return 'true' === $value;
+ }
+
// these trigger types need a simple strlen check:
- $length = [
+ // TODO create a helper to automatically return these.
+ $length = [
'source_account_starts',
'source_account_ends',
'source_account_is',
@@ -414,25 +383,29 @@ class FireflyValidator extends Validator
}
// check if it's an existing account.
+ // TODO create a helper to automatically return these.
if (in_array($triggerType, ['destination_account_id', 'source_account_id'], true)) {
return is_numeric($value) && (int)$value > 0;
}
// check transaction type.
+ // TODO create a helper to automatically return these.
if ('transaction_type' === $triggerType) {
$count = TransactionType::where('type', ucfirst($value))->count();
return 1 === $count;
}
- // if the type is date, the simply try to parse it and throw error when it's bad.
+ // if the type is date, then simply try to parse it and throw error when it's bad.
+ // TODO create a helper to automatically return these.
if (in_array($triggerType, ['date_is', 'created_on', 'updated_on', 'date_before', 'date_after'], true)) {
/** @var ParseDateString $parser */
$parser = app(ParseDateString::class);
+
try {
$parser->parseDate($value);
} catch (FireflyException $e) {
- Log::error($e->getMessage());
+ app('log')->error($e->getMessage());
return false;
}
@@ -445,7 +418,7 @@ class FireflyValidator extends Validator
* @param mixed $attribute
* @param mixed $value
*
- * @return bool
+ * @SuppressWarnings(PHPMD.UnusedFormalParameter)
*/
public function validateSecurePassword($attribute, $value): bool
{
@@ -468,72 +441,70 @@ class FireflyValidator extends Validator
* @param mixed $value
* @param mixed $parameters
*
- * @return bool
+ * @SuppressWarnings(PHPMD.UnusedFormalParameter)
*/
public function validateUniqueAccountForUser($attribute, $value, $parameters): bool
{
// because a user does not have to be logged in (tests and what-not).
if (!auth()->check()) {
- Log::debug('validateUniqueAccountForUser::anon');
+ app('log')->debug('validateUniqueAccountForUser::anon');
+
return $this->validateAccountAnonymously();
}
if (array_key_exists('objectType', $this->data)) {
- Log::debug('validateUniqueAccountForUser::typeString');
+ app('log')->debug('validateUniqueAccountForUser::typeString');
+
return $this->validateByAccountTypeString($value, $parameters, $this->data['objectType']);
}
if (array_key_exists('type', $this->data)) {
- Log::debug('validateUniqueAccountForUser::typeString');
+ app('log')->debug('validateUniqueAccountForUser::typeString');
+
return $this->validateByAccountTypeString($value, $parameters, (string)$this->data['type']);
}
if (array_key_exists('account_type_id', $this->data)) {
- Log::debug('validateUniqueAccountForUser::typeId');
+ app('log')->debug('validateUniqueAccountForUser::typeId');
+
return $this->validateByAccountTypeId($value, $parameters);
}
$parameterId = $parameters[0] ?? null;
if (null !== $parameterId) {
- Log::debug('validateUniqueAccountForUser::paramId');
+ app('log')->debug('validateUniqueAccountForUser::paramId');
+
return $this->validateByParameterId((int)$parameterId, $value);
}
if (array_key_exists('id', $this->data)) {
- Log::debug('validateUniqueAccountForUser::accountId');
+ app('log')->debug('validateUniqueAccountForUser::accountId');
+
return $this->validateByAccountId($value);
}
// without type, just try to validate the name.
- Log::debug('validateUniqueAccountForUser::accountName');
+ app('log')->debug('validateUniqueAccountForUser::accountName');
+
return $this->validateByAccountName($value);
}
- /**
- * @return bool
- */
private function validateAccountAnonymously(): bool
{
if (!array_key_exists('user_id', $this->data)) {
return false;
}
- $user = User::find($this->data['user_id']);
- $type = AccountType::find($this->data['account_type_id'])->first();
- $value = $this->data['name'];
+ /** @var User $user */
+ $user = User::find($this->data['user_id']);
+ $type = AccountType::find($this->data['account_type_id'])->first();
+ $value = $this->data['name'];
- /** @var Account|null $result */
+ /** @var null|Account $result */
$result = $user->accounts()->where('account_type_id', $type->id)->where('name', $value)->first();
return null === $result;
}
- /**
- * @param string $value
- * @param array $parameters
- * @param string $type
- *
- * @return bool
- */
private function validateByAccountTypeString(string $value, array $parameters, string $type): bool
{
- /** @var array|null $search */
- $search = Config::get('firefly.accountTypeByIdentifier.' . $type);
+ /** @var null|array $search */
+ $search = \Config::get('firefly.accountTypeByIdentifier.'.$type);
if (null === $search) {
return false;
@@ -542,81 +513,75 @@ class FireflyValidator extends Validator
$accountTypes = AccountType::whereIn('type', $search)->get();
$ignore = (int)($parameters[0] ?? 0.0);
$accountTypeIds = $accountTypes->pluck('id')->toArray();
- /** @var Account|null $result */
- $result = auth()->user()->accounts()->whereIn('account_type_id', $accountTypeIds)->where('id', '!=', $ignore)
- ->where('name', $value)
- ->first();
+
+ /** @var null|Account $result */
+ $result = auth()->user()->accounts()->whereIn('account_type_id', $accountTypeIds)->where('id', '!=', $ignore)
+ ->where('name', $value)
+ ->first()
+ ;
+
return null === $result;
}
/**
* @param mixed $value
* @param mixed $parameters
- *
- * @return bool
*/
private function validateByAccountTypeId($value, $parameters): bool
{
$type = AccountType::find($this->data['account_type_id'])->first();
$ignore = (int)($parameters[0] ?? 0.0);
- /** @var Account|null $result */
+ /** @var null|Account $result */
$result = auth()->user()->accounts()->where('account_type_id', $type->id)->where('id', '!=', $ignore)
- ->where('name', $value)
- ->first();
+ ->where('name', $value)
+ ->first()
+ ;
return null === $result;
}
/**
- * @param int $accountId
* @param mixed $value
- *
- * @return bool
*/
private function validateByParameterId(int $accountId, $value): bool
{
/** @var Account $existingAccount */
$existingAccount = Account::find($accountId);
- $type = $existingAccount->accountType;
- $ignore = $existingAccount->id;
+ $type = $existingAccount->accountType;
+ $ignore = $existingAccount->id;
- $entry = auth()->user()->accounts()->where('account_type_id', $type->id)->where('id', '!=', $ignore)
- ->where('name', $value)
- ->first();
+ $entry = auth()->user()->accounts()->where('account_type_id', $type->id)->where('id', '!=', $ignore)
+ ->where('name', $value)
+ ->first()
+ ;
return null === $entry;
}
/**
* @param mixed $value
- *
- * @return bool
*/
private function validateByAccountId($value): bool
{
/** @var Account $existingAccount */
$existingAccount = Account::find($this->data['id']);
- $type = $existingAccount->accountType;
- $ignore = $existingAccount->id;
+ $type = $existingAccount->accountType;
+ $ignore = $existingAccount->id;
- $entry = auth()->user()->accounts()->where('account_type_id', $type->id)->where('id', '!=', $ignore)
- ->where('name', $value)
- ->first();
+ $entry = auth()->user()->accounts()->where('account_type_id', $type->id)->where('id', '!=', $ignore)
+ ->where('name', $value)
+ ->first()
+ ;
return null === $entry;
}
- /**
- * @param string $value
- *
- * @return bool
- */
private function validateByAccountName(string $value): bool
{
- return auth()->user()->accounts()->where('name', $value)->count() === 0;
+ return 0 === auth()->user()->accounts()->where('name', $value)->count();
}
/**
@@ -624,7 +589,7 @@ class FireflyValidator extends Validator
* @param mixed $value
* @param mixed $parameters
*
- * @return bool
+ * @SuppressWarnings(PHPMD.UnusedFormalParameter)
*/
public function validateUniqueAccountNumberForUser($attribute, $value, $parameters): bool
{
@@ -633,18 +598,19 @@ class FireflyValidator extends Validator
$accountId = (int)($parameters[0] ?? 0.0);
}
- $query = AccountMeta::leftJoin('accounts', 'accounts.id', '=', 'account_meta.account_id')
- ->whereNull('accounts.deleted_at')
- ->where('accounts.user_id', auth()->user()->id)
- ->where('account_meta.name', 'account_number')
- ->where('account_meta.data', json_encode($value));
+ $query = AccountMeta::leftJoin('accounts', 'accounts.id', '=', 'account_meta.account_id')
+ ->whereNull('accounts.deleted_at')
+ ->where('accounts.user_id', auth()->user()->id)
+ ->where('account_meta.name', 'account_number')
+ ->where('account_meta.data', json_encode($value))
+ ;
if ($accountId > 0) {
// exclude current account from check.
$query->where('account_meta.account_id', '!=', $accountId);
}
- $set = $query->get(['account_meta.*']);
- $count = $set->count();
+ $set = $query->get(['account_meta.*']);
+ $count = $set->count();
if (0 === $count) {
return true;
}
@@ -652,67 +618,52 @@ class FireflyValidator extends Validator
// pretty much impossible but still.
return false;
}
- $type = $this->data['objectType'] ?? 'unknown';
+ $type = $this->data['objectType'] ?? 'unknown';
if ('expense' !== $type && 'revenue' !== $type) {
app('log')->warning(sprintf('Account number "%s" is not unique and account type "%s" cannot share its account number.', $value, $type));
+
return false;
}
- Log::debug(sprintf('Account number "%s" is not unique but account type "%s" may share its account number.', $value, $type));
+ app('log')->debug(sprintf('Account number "%s" is not unique but account type "%s" may share its account number.', $value, $type));
+
// one other account with this account number.
/** @var AccountMeta $entry */
foreach ($set as $entry) {
$otherAccount = $entry->account;
$otherType = (string)config(sprintf('firefly.shortNamesByFullName.%s', $otherAccount->accountType->type));
if (('expense' === $otherType || 'revenue' === $otherType) && $otherType !== $type) {
- Log::debug(sprintf('The other account with this account number is a "%s" so return true.', $otherType));
+ app('log')->debug(sprintf('The other account with this account number is a "%s" so return true.', $otherType));
+
return true;
}
- Log::debug(sprintf('The other account with this account number is a "%s" so return false.', $otherType));
+ app('log')->debug(sprintf('The other account with this account number is a "%s" so return false.', $otherType));
}
+
return false;
}
/**
- * @param $attribute
- * @param $value
- *
- * @return bool
+ * @SuppressWarnings(PHPMD.UnusedFormalParameter)
*/
- public function validateUniqueCurrencyCode($attribute, $value): bool
+ public function validateUniqueCurrencyCode(?string $attribute, ?string $value): bool
{
return $this->validateUniqueCurrency('code', (string)$attribute, (string)$value);
}
/**
- * @param string $field
- * @param string $attribute
- * @param string $value
- *
- * @return bool
+ * @SuppressWarnings(PHPMD.UnusedFormalParameter)
*/
public function validateUniqueCurrency(string $field, string $attribute, string $value): bool
{
- return 0 === DB::table('transaction_currencies')->where($field, $value)->whereNull('deleted_at')->count();
+ return 0 === \DB::table('transaction_currencies')->where($field, $value)->whereNull('deleted_at')->count();
}
- /**
- * @param $attribute
- * @param $value
- *
- * @return bool
- */
- public function validateUniqueCurrencyName($attribute, $value): bool
+ public function validateUniqueCurrencyName(?string $attribute, ?string $value): bool
{
return $this->validateUniqueCurrency('name', (string)$attribute, (string)$value);
}
- /**
- * @param $attribute
- * @param $value
- *
- * @return bool
- */
- public function validateUniqueCurrencySymbol($attribute, $value): bool
+ public function validateUniqueCurrencySymbol(?string $attribute, ?string $value): bool
{
return $this->validateUniqueCurrency('symbol', (string)$attribute, (string)$value);
}
@@ -722,7 +673,7 @@ class FireflyValidator extends Validator
* @param mixed $parameters
* @param mixed $something
*
- * @return bool
+ * @SuppressWarnings(PHPMD.UnusedFormalParameter)
*/
public function validateUniqueExistingWebhook($value, $parameters, $something): bool
{
@@ -736,8 +687,8 @@ class FireflyValidator extends Validator
if (auth()->check()) {
// get existing webhook value:
if (0 !== $existingId) {
- /** @var Webhook|null $webhook */
- $webhook = auth()->user()->webhooks()->find($existingId);
+ /** @var null|Webhook $webhook */
+ $webhook = auth()->user()->webhooks()->find($existingId);
if (null === $webhook) {
return false;
}
@@ -755,18 +706,18 @@ class FireflyValidator extends Validator
$userId = auth()->user()->id;
return 0 === Webhook::whereUserId($userId)
- ->where('trigger', $trigger)
- ->where('response', $response)
- ->where('delivery', $delivery)
- ->where('id', '!=', $existingId)
- ->where('url', $url)->count();
+ ->where('trigger', $trigger)
+ ->where('response', $response)
+ ->where('delivery', $delivery)
+ ->where('id', '!=', $existingId)
+ ->where('url', $url)->count()
+ ;
}
return false;
}
/**
- *
* Validate an object and its uniqueness. Checks for encryption / encrypted values as well.
*
* parameter 0: the table
@@ -777,29 +728,31 @@ class FireflyValidator extends Validator
* @param mixed $value
* @param mixed $parameters
*
- * @return bool
+ * @SuppressWarnings(PHPMD.UnusedFormalParameter)
*/
public function validateUniqueObjectForUser($attribute, $value, $parameters): bool
{
[$table, $field] = $parameters;
- $exclude = (int)($parameters[2] ?? 0.0);
+ $exclude = (int)($parameters[2] ?? 0.0);
/*
* If other data (in $this->getData()) contains
* ID field, set that field to be the $exclude.
*/
- $data = $this->getData();
+ $data = $this->getData();
if (!array_key_exists(2, $parameters) && array_key_exists('id', $data) && (int)$data['id'] > 0) {
$exclude = (int)$data['id'];
}
// get entries from table
- $result = DB::table($table)->where('user_id', auth()->user()->id)->whereNull('deleted_at')
- ->where('id', '!=', $exclude)
- ->where($field, $value)
- ->first([$field]);
+ $result = \DB::table($table)->where('user_id', auth()->user()->id)->whereNull('deleted_at')
+ ->where('id', '!=', $exclude)
+ ->where($field, $value)
+ ->first([$field])
+ ;
if (null === $result) {
return true; // not found, so true.
}
+
// found, so not unique.
return false;
}
@@ -809,15 +762,16 @@ class FireflyValidator extends Validator
* @param mixed $value
* @param mixed $parameters
*
- * @return bool
+ * @SuppressWarnings(PHPMD.UnusedFormalParameter)
*/
public function validateUniqueObjectGroup($attribute, $value, $parameters): bool
{
$exclude = $parameters[0] ?? null;
- $query = DB::table('object_groups')
- ->whereNull('object_groups.deleted_at')
- ->where('object_groups.user_id', auth()->user()->id)
- ->where('object_groups.title', $value);
+ $query = \DB::table('object_groups')
+ ->whereNull('object_groups.deleted_at')
+ ->where('object_groups.user_id', auth()->user()->id)
+ ->where('object_groups.title', $value)
+ ;
if (null !== $exclude) {
$query->where('object_groups.id', '!=', (int)$exclude);
}
@@ -830,13 +784,14 @@ class FireflyValidator extends Validator
* @param mixed $value
* @param mixed $parameters
*
- * @return bool
+ * @SuppressWarnings(PHPMD.UnusedFormalParameter)
*/
public function validateUniquePiggyBankForUser($attribute, $value, $parameters): bool
{
$exclude = $parameters[0] ?? null;
- $query = DB::table('piggy_banks')->whereNull('piggy_banks.deleted_at')
- ->leftJoin('accounts', 'accounts.id', '=', 'piggy_banks.account_id')->where('accounts.user_id', auth()->user()->id);
+ $query = \DB::table('piggy_banks')->whereNull('piggy_banks.deleted_at')
+ ->leftJoin('accounts', 'accounts.id', '=', 'piggy_banks.account_id')->where('accounts.user_id', auth()->user()->id)
+ ;
if (null !== $exclude) {
$query->where('piggy_banks.id', '!=', (int)$exclude);
}
@@ -849,7 +804,7 @@ class FireflyValidator extends Validator
* @param mixed $value
* @param mixed $parameters
*
- * @return bool
+ * @SuppressWarnings(PHPMD.UnusedFormalParameter)
*/
public function validateUniqueWebhook($value, $parameters): bool
{
@@ -859,17 +814,18 @@ class FireflyValidator extends Validator
$deliveries = Webhook::getDeliveriesForValidation();
// integers
- $trigger = $triggers[$this->data['trigger']] ?? 0;
- $response = $responses[$this->data['response']] ?? 0;
- $delivery = $deliveries[$this->data['delivery']] ?? 0;
- $url = $this->data['url'];
- $userId = auth()->user()->id;
+ $trigger = $triggers[$this->data['trigger']] ?? 0;
+ $response = $responses[$this->data['response']] ?? 0;
+ $delivery = $deliveries[$this->data['delivery']] ?? 0;
+ $url = $this->data['url'];
+ $userId = auth()->user()->id;
return 0 === Webhook::whereUserId($userId)
- ->where('trigger', $trigger)
- ->where('response', $response)
- ->where('delivery', $delivery)
- ->where('url', $url)->count();
+ ->where('trigger', $trigger)
+ ->where('response', $response)
+ ->where('delivery', $delivery)
+ ->where('url', $url)->count()
+ ;
}
return false;
diff --git a/app/Validation/GroupValidation.php b/app/Validation/GroupValidation.php
index df704c4658..c79fbc6539 100644
--- a/app/Validation/GroupValidation.php
+++ b/app/Validation/GroupValidation.php
@@ -25,8 +25,8 @@ declare(strict_types=1);
namespace FireflyIII\Validation;
use FireflyIII\Exceptions\FireflyException;
+use FireflyIII\Models\Transaction;
use FireflyIII\Models\TransactionGroup;
-use Illuminate\Support\Facades\Log;
use Illuminate\Validation\Validator;
/**
@@ -37,7 +37,10 @@ use Illuminate\Validation\Validator;
trait GroupValidation
{
/**
- * @param Validator $validator
+ * A catch when users submit splits with no source or destination info at all.
+ *
+ * TODO This should prevent errors down the road but I'm not yet sure what I'm validating here
+ * TODO so I disabled this on 2023-10-22 to see if it causes any issues.
*
* @throws FireflyException
*/
@@ -54,7 +57,8 @@ trait GroupValidation
'source_number',
'destination_number',
];
- /** @var array $transaction */
+
+ /** @var null|array $transaction */
foreach ($transactions as $index => $transaction) {
if (!is_array($transaction)) {
throw new FireflyException('Invalid data submitted: transaction is not array.');
@@ -81,30 +85,56 @@ trait GroupValidation
// only an issue if there is no transaction_journal_id
}
- /**
- * @param Validator $validator
- *
- * @return array
- */
abstract protected function getTransactionsArray(Validator $validator): array;
+ protected function preventUpdateReconciled(Validator $validator, TransactionGroup $transactionGroup): void
+ {
+ app('log')->debug(sprintf('Now in %s', __METHOD__));
+
+ $count = Transaction::leftJoin('transaction_journals', 'transaction_journals.id', 'transactions.transaction_journal_id')
+ ->leftJoin('transaction_groups', 'transaction_groups.id', 'transaction_journals.transaction_group_id')
+ ->where('transaction_journals.transaction_group_id', $transactionGroup->id)
+ ->where('transactions.reconciled', 1)->where('transactions.amount', '<', 0)->count('transactions.id')
+ ;
+ if (0 === $count) {
+ app('log')->debug(sprintf('Transaction is not reconciled, done with %s', __METHOD__));
+
+ return;
+ }
+ $data = $validator->getData();
+ $forbidden = ['amount', 'foreign_amount', 'currency_code', 'currency_id', 'foreign_currency_code', 'foreign_currency_id',
+ 'source_id', 'source_name', 'source_number', 'source_iban',
+ 'destination_id', 'destination_name', 'destination_number', 'destination_iban',
+ ];
+ foreach ($data['transactions'] as $index => $row) {
+ foreach ($forbidden as $key) {
+ if (array_key_exists($key, $row)) {
+ $validator->errors()->add(
+ sprintf('transactions.%d.%s', $index, $key),
+ (string)trans('validation.reconciled_forbidden_field', ['field' => $key])
+ );
+ }
+ }
+ }
+
+ app('log')->debug(sprintf('Done with %s', __METHOD__));
+ }
+
/**
* Adds an error to the "description" field when the user has submitted no descriptions and no
* journal description.
- *
- * @param Validator $validator
*/
protected function validateDescriptions(Validator $validator): void
{
if ($validator->errors()->count() > 0) {
return;
}
- Log::debug('Now in GroupValidation::validateDescriptions()');
+ app('log')->debug('Now in GroupValidation::validateDescriptions()');
$transactions = $this->getTransactionsArray($validator);
$validDescriptions = 0;
foreach ($transactions as $transaction) {
if ('' !== (string)($transaction['description'] ?? null)) {
- $validDescriptions++;
+ ++$validDescriptions;
}
}
@@ -117,19 +147,16 @@ trait GroupValidation
}
}
- /**
- * @param Validator $validator
- */
protected function validateGroupDescription(Validator $validator): void
{
if ($validator->errors()->count() > 0) {
return;
}
- Log::debug('Now in validateGroupDescription()');
+ app('log')->debug('Now in validateGroupDescription()');
$data = $validator->getData();
$transactions = $this->getTransactionsArray($validator);
- $groupTitle = $data['group_title'] ?? '';
+ $groupTitle = $data['group_title'] ?? '';
if ('' === $groupTitle && count($transactions) > 1) {
$validator->errors()->add('group_title', (string)trans('validation.group_title_mandatory'));
}
@@ -139,21 +166,19 @@ trait GroupValidation
* This method validates if the user has submitted transaction journal ID's for each array they submit, if they've
* submitted more than 1 transaction journal. This check is necessary because Firefly III isn't able to distinguish
* between journals without the ID.
- *
- * @param Validator $validator
- * @param TransactionGroup $transactionGroup
*/
protected function validateJournalIds(Validator $validator, TransactionGroup $transactionGroup): void
{
- Log::debug(sprintf('Now in GroupValidation::validateJournalIds(%d)', $transactionGroup->id));
+ app('log')->debug(sprintf('Now in GroupValidation::validateJournalIds(%d)', $transactionGroup->id));
$transactions = $this->getTransactionsArray($validator);
if (count($transactions) < 2) {
// no need for validation.
- Log::debug(sprintf('%d transaction(s) in submission, can skip this check.', count($transactions)));
+ app('log')->debug(sprintf('%d transaction(s) in submission, can skip this check.', count($transactions)));
return;
}
+
// check each array:
/**
* @var int $index
@@ -166,12 +191,6 @@ trait GroupValidation
/**
* Do the validation required by validateJournalIds.
- *
- * @param Validator $validator
- * @param int $index
- * @param array $transaction
- * @param TransactionGroup $transactionGroup
- *
*/
private function validateJournalId(Validator $validator, int $index, array $transaction, TransactionGroup $transactionGroup): void
{
@@ -179,15 +198,15 @@ trait GroupValidation
if (array_key_exists('transaction_journal_id', $transaction)) {
$journalId = $transaction['transaction_journal_id'];
}
- Log::debug(sprintf('Now in validateJournalId(%d, %d)', $index, $journalId));
+ app('log')->debug(sprintf('Now in validateJournalId(%d, %d)', $index, $journalId));
if (0 === $journalId || '' === $journalId || '0' === $journalId) {
- Log::debug('Submitted 0, will accept to be used in a new transaction.');
+ app('log')->debug('Submitted 0, will accept to be used in a new transaction.');
return;
}
$journalId = (int)$journalId;
$count = $transactionGroup->transactionJournals()->where('transaction_journals.id', $journalId)->count();
- if (null === $journalId || 0 === $count) {
+ if (0 === $journalId || 0 === $count) {
app('log')->warning(sprintf('Transaction group #%d has %d journals with ID %d', $transactionGroup->id, $count, $journalId));
app('log')->warning('Invalid submission: Each split must have transaction_journal_id (either valid ID or 0).');
$validator->errors()->add(sprintf('transactions.%d.source_name', $index), (string)trans('validation.need_id_in_edit'));
diff --git a/app/Validation/RecurrenceValidation.php b/app/Validation/RecurrenceValidation.php
index 6dabcbf60d..f2ae1aa188 100644
--- a/app/Validation/RecurrenceValidation.php
+++ b/app/Validation/RecurrenceValidation.php
@@ -26,15 +26,12 @@ namespace FireflyIII\Validation;
use Carbon\Carbon;
use FireflyIII\Models\Recurrence;
use FireflyIII\Models\RecurrenceTransaction;
-use Illuminate\Support\Facades\Log;
use Illuminate\Validation\Validator;
-use InvalidArgumentException;
/**
* Trait RecurrenceValidation
*
* Contains advanced validation rules used in validation of new and existing recurrences.
- *
*/
trait RecurrenceValidation
{
@@ -42,28 +39,28 @@ trait RecurrenceValidation
* Validate account information input for recurrences which are being updated.
*
* TODO Must always trigger when the type of the recurrence changes.
- *
- * @param Validator $validator
*/
public function valUpdateAccountInfo(Validator $validator): void
{
- $data = $validator->getData();
+ $data = $validator->getData();
- $transactionType = $data['type'] ?? 'invalid';
+ $transactionType = $data['type'] ?? 'invalid';
// grab model from parameter and try to set the transaction type from it
if ('invalid' === $transactionType) {
- Log::debug('Type is invalid but we will search for it.');
- /** @var Recurrence $recurrence */
- $recurrence = $this->route()->parameter('recurrence');
+ app('log')->debug('Type is invalid but we will search for it.');
+
+ /** @var null|Recurrence $recurrence */
+ $recurrence = $this->route()?->parameter('recurrence');
if (null !== $recurrence) {
- Log::debug('There is a recurrence in the route.');
+ app('log')->debug('There is a recurrence in the route.');
+
// ok so we have a recurrence should be able to extract type somehow.
- /** @var RecurrenceTransaction|null $first */
+ /** @var null|RecurrenceTransaction $first */
$first = $recurrence->recurrenceTransactions()->first();
if (null !== $first) {
- $transactionType = $first->transactionType ? $first->transactionType->type : 'withdrawal';
- Log::debug(sprintf('Determined type to be %s.', $transactionType));
+ $transactionType = null !== $first->transactionType ? $first->transactionType->type : 'withdrawal';
+ app('log')->debug(sprintf('Determined type to be %s.', $transactionType));
}
if (null === $first) {
app('log')->warning('Just going to assume type is a withdrawal.');
@@ -72,14 +69,14 @@ trait RecurrenceValidation
}
}
- $transactions = $data['transactions'] ?? [];
+ $transactions = $data['transactions'] ?? [];
/** @var AccountValidator $accountValidator */
$accountValidator = app(AccountValidator::class);
- Log::debug(sprintf('Going to loop %d transaction(s)', count($transactions)));
+ app('log')->debug(sprintf('Going to loop %d transaction(s)', count($transactions)));
foreach ($transactions as $index => $transaction) {
- $transactionType = $transaction['type'] ?? $transactionType;
+ $transactionType = $transaction['type'] ?? $transactionType;
$accountValidator->setTransactionType($transactionType);
if (
@@ -91,9 +88,9 @@ trait RecurrenceValidation
continue;
}
// validate source account.
- $sourceId = array_key_exists('source_id', $transaction) ? (int)$transaction['source_id'] : null;
- $sourceName = $transaction['source_name'] ?? null;
- $validSource = $accountValidator->validateSource(['id' => $sourceId, 'name' => $sourceName]);
+ $sourceId = array_key_exists('source_id', $transaction) ? (int)$transaction['source_id'] : null;
+ $sourceName = $transaction['source_name'] ?? null;
+ $validSource = $accountValidator->validateSource(['id' => $sourceId, 'name' => $sourceName]);
// do something with result:
if (false === $validSource) {
@@ -105,7 +102,7 @@ trait RecurrenceValidation
// validate destination account
$destinationId = array_key_exists('destination_id', $transaction) ? (int)$transaction['destination_id'] : null;
$destinationName = $transaction['destination_name'] ?? null;
- $validDestination = $accountValidator->validateDestination(['id' => $destinationId, 'name' => $destinationName,]);
+ $validDestination = $accountValidator->validateDestination(['id' => $destinationId, 'name' => $destinationName]);
// do something with result:
if (false === $validDestination) {
$validator->errors()->add(sprintf('transactions.%d.destination_id', $index), $accountValidator->destError);
@@ -118,8 +115,6 @@ trait RecurrenceValidation
/**
* Adds an error to the validator when there are no repetitions in the array of data.
- *
- * @param Validator $validator
*/
public function validateOneRepetition(Validator $validator): void
{
@@ -133,8 +128,6 @@ trait RecurrenceValidation
/**
* Adds an error to the validator when there are no repetitions in the array of data.
- *
- * @param Validator $validator
*/
public function validateOneRepetitionUpdate(Validator $validator): void
{
@@ -152,8 +145,6 @@ trait RecurrenceValidation
/**
* Validates that the recurrence has valid repetition information. It either doesn't stop,
* or stops after X times or at X date. Not both of them.,
- *
- * @param Validator $validator
*/
public function validateRecurrenceRepetition(Validator $validator): void
{
@@ -167,12 +158,7 @@ trait RecurrenceValidation
}
}
- /**
- * @param Validator $validator
- *
- * @return void
- */
- public function validateRecurringConfig(Validator $validator)
+ public function validateRecurringConfig(Validator $validator): void
{
$data = $validator->getData();
$reps = array_key_exists('nr_of_repetitions', $data) ? (int)$data['nr_of_repetitions'] : null;
@@ -190,9 +176,6 @@ trait RecurrenceValidation
}
}
- /**
- * @param Validator $validator
- */
public function validateRepetitionMoment(Validator $validator): void
{
$data = $validator->getData();
@@ -202,6 +185,7 @@ trait RecurrenceValidation
return;
}
+
/**
* @var int $index
* @var array $repetition
@@ -213,27 +197,36 @@ trait RecurrenceValidation
if (null === $repetition['moment']) {
$repetition['moment'] = '';
}
- $repetition['moment'] = $repetition['moment'] ?? 'invalid';
switch ($repetition['type'] ?? 'empty') {
default:
$validator->errors()->add(sprintf('repetitions.%d.type', $index), (string)trans('validation.valid_recurrence_rep_type'));
return;
+
case 'daily':
$this->validateDaily($validator, $index, (string)$repetition['moment']);
+
break;
+
case 'monthly':
$this->validateMonthly($validator, $index, (int)$repetition['moment']);
+
break;
+
case 'ndom':
$this->validateNdom($validator, $index, (string)$repetition['moment']);
+
break;
+
case 'weekly':
$this->validateWeekly($validator, $index, (int)$repetition['moment']);
+
break;
+
case 'yearly':
$this->validateYearly($validator, $index, (string)$repetition['moment']);
+
break;
}
}
@@ -241,10 +234,6 @@ trait RecurrenceValidation
/**
* If the repetition type is daily, the moment should be empty.
- *
- * @param Validator $validator
- * @param int $index
- * @param string $moment
*/
protected function validateDaily(Validator $validator, int $index, string $moment): void
{
@@ -255,10 +244,6 @@ trait RecurrenceValidation
/**
* If the repetition type is monthly, the moment should be a day between 1-31 (inclusive).
- *
- * @param Validator $validator
- * @param int $index
- * @param int $dayOfMonth
*/
protected function validateMonthly(Validator $validator, int $index, int $dayOfMonth): void
{
@@ -270,10 +255,6 @@ trait RecurrenceValidation
/**
* If the repetition type is "ndom", the first part must be between 1-5 (inclusive), for the week in the month,
* and the second one must be between 1-7 (inclusive) for the day of the week.
- *
- * @param Validator $validator
- * @param int $index
- * @param string $moment
*/
protected function validateNdom(Validator $validator, int $index, string $moment): void
{
@@ -283,8 +264,8 @@ trait RecurrenceValidation
return;
}
- $nthDay = (int)($parameters[0] ?? 0.0);
- $dayOfWeek = (int)($parameters[1] ?? 0.0);
+ $nthDay = (int)($parameters[0] ?? 0.0);
+ $dayOfWeek = (int)($parameters[1] ?? 0.0);
if ($nthDay < 1 || $nthDay > 5) {
$validator->errors()->add(sprintf('repetitions.%d.moment', $index), (string)trans('validation.valid_recurrence_rep_moment'));
@@ -297,10 +278,6 @@ trait RecurrenceValidation
/**
* If the repetition type is weekly, the moment should be a day between 1-7 (inclusive).
- *
- * @param Validator $validator
- * @param int $index
- * @param int $dayOfWeek
*/
protected function validateWeekly(Validator $validator, int $index, int $dayOfWeek): void
{
@@ -311,72 +288,64 @@ trait RecurrenceValidation
/**
* If the repetition type is yearly, the moment should be a valid date.
- *
- * @param Validator $validator
- * @param int $index
- * @param string $moment
*/
protected function validateYearly(Validator $validator, int $index, string $moment): void
{
try {
Carbon::createFromFormat('Y-m-d', $moment);
- } catch (InvalidArgumentException $e) {
- Log::debug(sprintf('Invalid argument for Carbon: %s', $e->getMessage()));
+ } catch (\InvalidArgumentException $e) { // @phpstan-ignore-line
+ app('log')->debug(sprintf('Invalid argument for Carbon: %s', $e->getMessage()));
$validator->errors()->add(sprintf('repetitions.%d.moment', $index), (string)trans('validation.valid_recurrence_rep_moment'));
}
}
/**
- * @param Recurrence $recurrence
- * @param Validator $validator
- *
- * @return void
+ * @SuppressWarnings(PHPMD.NPathComplexity)
*/
protected function validateTransactionId(Recurrence $recurrence, Validator $validator): void
{
- Log::debug('Now in validateTransactionId');
+ app('log')->debug('Now in validateTransactionId');
$transactions = $this->getTransactionData();
$submittedTrCount = count($transactions);
- //$recurrence = $validator->get
- if (null === $transactions) {
- Log::warning('[a] User submitted no transactions.');
- $validator->errors()->add('transactions', (string)trans('validation.at_least_one_transaction'));
- return;
- }
if (0 === $submittedTrCount) {
- Log::warning('[b] User submitted no transactions.');
+ app('log')->warning('[b] User submitted no transactions.');
$validator->errors()->add('transactions', (string)trans('validation.at_least_one_transaction'));
+
return;
}
- $originalTrCount = $recurrence->recurrenceTransactions()->count();
+ $originalTrCount = $recurrence->recurrenceTransactions()->count();
if (1 === $submittedTrCount && 1 === $originalTrCount) {
- $first = $transactions[0]; // can safely assume index 0.
+ $first = $transactions[0]; // can safely assume index 0.
if (!array_key_exists('id', $first)) {
- Log::debug('Single count and no ID, done.');
+ app('log')->debug('Single count and no ID, done.');
+
return; // home safe!
}
- $id = $first['id'];
+ $id = $first['id'];
if ('' === (string)$id) {
- Log::debug('Single count and empty ID, done.');
+ app('log')->debug('Single count and empty ID, done.');
+
return; // home safe!
}
$integer = (int)$id;
$secondCount = $recurrence->recurrenceTransactions()->where('recurrences_transactions.id', $integer)->count();
- Log::debug(sprintf('Result of ID count: %d', $secondCount));
+ app('log')->debug(sprintf('Result of ID count: %d', $secondCount));
if (0 === $secondCount) {
$validator->errors()->add('transactions.0.id', (string)trans('validation.id_does_not_match', ['id' => $integer]));
}
- Log::debug('Single ID validation done.');
+ app('log')->debug('Single ID validation done.');
+
return;
}
- Log::debug('Multi ID validation.');
- $idsMandatory = false;
+ app('log')->debug('Multi ID validation.');
+ $idsMandatory = false;
if ($submittedTrCount < $originalTrCount) {
- Log::debug(sprintf('User submits %d transaction, recurrence has %d transactions. All entries must have ID.', $submittedTrCount, $originalTrCount));
+ app('log')->debug(sprintf('User submits %d transaction, recurrence has %d transactions. All entries must have ID.', $submittedTrCount, $originalTrCount));
$idsMandatory = true;
}
+
/**
* Loop all transactions submitted by the user.
* If the user has submitted fewer transactions than the original recurrence has, all submitted entries must have an ID.
@@ -388,41 +357,44 @@ trait RecurrenceValidation
* 2. If the user submits more transactions than already present, count the number of existing transactions. At least those must be matched. After that, submit as many as you like.
* 3. If the user submits the same number of transactions as already present, all but one must have an ID.
*/
- $unmatchedIds = 0;
+ $unmatchedIds = 0;
foreach ($transactions as $index => $transaction) {
- Log::debug(sprintf('Now at %d/%d', $index + 1, $submittedTrCount));
+ app('log')->debug(sprintf('Now at %d/%d', $index + 1, $submittedTrCount));
if (!is_array($transaction)) {
- Log::warning('Not an array. Give error.');
+ app('log')->warning('Not an array. Give error.');
$validator->errors()->add(sprintf('transactions.%d.id', $index), (string)trans('validation.at_least_one_transaction'));
+
return;
}
if (!array_key_exists('id', $transaction) && $idsMandatory) {
- Log::warning('ID is mandatory but array has no ID.');
+ app('log')->warning('ID is mandatory but array has no ID.');
$validator->errors()->add(sprintf('transactions.%d.id', $index), (string)trans('validation.need_id_to_match'));
+
return;
}
if (array_key_exists('id', $transaction)) { // don't matter if $idsMandatory
- Log::debug('Array has ID.');
+ app('log')->debug('Array has ID.');
$idCount = $recurrence->recurrenceTransactions()->where('recurrences_transactions.id', (int)$transaction['id'])->count();
if (0 === $idCount) {
- Log::debug('ID does not exist or no match. Count another unmatched ID.');
- $unmatchedIds++;
+ app('log')->debug('ID does not exist or no match. Count another unmatched ID.');
+ ++$unmatchedIds;
}
}
if (!array_key_exists('id', $transaction) && !$idsMandatory) {
- Log::debug('Array has no ID but was not mandatory at this point.');
- $unmatchedIds++;
+ app('log')->debug('Array has no ID but was not mandatory at this point.');
+ ++$unmatchedIds;
}
}
// if too many don't match, but you haven't submitted more than already present:
- $maxUnmatched = max(1, $submittedTrCount - $originalTrCount);
- Log::debug(sprintf('Submitted: %d. Original: %d. User can submit %d unmatched transactions.', $submittedTrCount, $originalTrCount, $maxUnmatched));
+ $maxUnmatched = max(1, $submittedTrCount - $originalTrCount);
+ app('log')->debug(sprintf('Submitted: %d. Original: %d. User can submit %d unmatched transactions.', $submittedTrCount, $originalTrCount, $maxUnmatched));
if ($unmatchedIds > $maxUnmatched) {
- Log::warning(sprintf('Too many unmatched transactions (%d).', $unmatchedIds));
+ app('log')->warning(sprintf('Too many unmatched transactions (%d).', $unmatchedIds));
$validator->errors()->add('transactions.0.id', (string)trans('validation.too_many_unmatched'));
+
return;
}
- Log::debug('Done with ID validation.');
+ app('log')->debug('Done with ID validation.');
}
}
diff --git a/app/Validation/TransactionValidation.php b/app/Validation/TransactionValidation.php
index e1850fa9df..63a2adace3 100644
--- a/app/Validation/TransactionValidation.php
+++ b/app/Validation/TransactionValidation.php
@@ -33,7 +33,6 @@ use FireflyIII\Models\TransactionType;
use FireflyIII\Models\UserGroup;
use FireflyIII\Repositories\Account\AccountRepositoryInterface;
use FireflyIII\User;
-use Illuminate\Support\Facades\Log;
use Illuminate\Validation\Validator;
/**
@@ -45,25 +44,22 @@ trait TransactionValidation
* Validates the given account information. Switches on given transaction type.
*
* Inclusion of user and/or group is optional.
- *
- * @param Validator $validator
- * @param User|null $user
- * @param UserGroup|null $userGroup
*/
public function validateAccountInformation(Validator $validator, User $user = null, UserGroup $userGroup = null): void
{
if ($validator->errors()->count() > 0) {
return;
}
- Log::debug('Now in validateAccountInformation (TransactionValidation) ()');
+ app('log')->debug('Now in validateAccountInformation (TransactionValidation) ()');
$transactions = $this->getTransactionsArray($validator);
$data = $validator->getData();
$transactionType = $data['type'] ?? 'invalid';
- Log::debug(sprintf('Going to loop %d transaction(s)', count($transactions)));
+ app('log')->debug(sprintf('Going to loop %d transaction(s)', count($transactions)));
+
/**
- * @var int $index
- * @var array $transaction
+ * @var null|int $index
+ * @var array $transaction
*/
foreach ($transactions as $index => $transaction) {
$transaction['user'] = $user;
@@ -75,44 +71,31 @@ trait TransactionValidation
}
}
- /**
- * @param Validator $validator
- *
- * @return array
- */
protected function getTransactionsArray(Validator $validator): array
{
- Log::debug('Now in getTransactionsArray');
+ app('log')->debug('Now in getTransactionsArray');
$data = $validator->getData();
$transactions = [];
- if (is_array($data) && array_key_exists('transactions', $data) && is_array($data['transactions'])) {
- Log::debug('Transactions key exists and is array.');
+ if (array_key_exists('transactions', $data) && is_array($data['transactions'])) {
+ app('log')->debug('Transactions key exists and is array.');
$transactions = $data['transactions'];
}
- if (is_array($data) && array_key_exists('transactions', $data) && !is_array($data['transactions'])) {
- Log::debug(sprintf('Transactions key exists but is NOT array, its a %s', gettype($data['transactions'])));
+ if (array_key_exists('transactions', $data) && !is_array($data['transactions'])) {
+ app('log')->debug(sprintf('Transactions key exists but is NOT array, its a %s', gettype($data['transactions'])));
}
- // should be impossible to hit this:
- if (!is_countable($transactions)) {
- Log::error(sprintf('Transactions array is not countable, because its a %s', gettype($transactions)));
- return [];
- }
- //Log::debug('Returning transactions.', $transactions);
return $transactions;
}
/**
- * @param Validator $validator
- * @param int $index
- * @param string $transactionType
- * @param array $transaction
+ * @SuppressWarnings(PHPMD.NPathComplexity)
*/
protected function validateSingleAccount(Validator $validator, int $index, string $transactionType, array $transaction): void
{
app('log')->debug(sprintf('Now in validateSingleAccount(%d)', $index));
+
/** @var AccountValidator $accountValidator */
- $accountValidator = app(AccountValidator::class);
+ $accountValidator = app(AccountValidator::class);
if (array_key_exists('user', $transaction) && null !== $transaction['user']) {
$accountValidator->setUser($transaction['user']);
@@ -121,21 +104,21 @@ trait TransactionValidation
$accountValidator->setUserGroup($transaction['user_group']);
}
- $transactionType = $transaction['type'] ?? $transactionType;
+ $transactionType = $transaction['type'] ?? $transactionType;
$accountValidator->setTransactionType($transactionType);
// validate source account.
- $sourceId = array_key_exists('source_id', $transaction) ? (int)$transaction['source_id'] : null;
- $sourceName = array_key_exists('source_name', $transaction) ? (string)$transaction['source_name'] : null;
- $sourceIban = array_key_exists('source_iban', $transaction) ? (string)$transaction['source_iban'] : null;
- $sourceNumber = array_key_exists('source_number', $transaction) ? (string)$transaction['source_number'] : null;
- $source = [
+ $sourceId = array_key_exists('source_id', $transaction) ? (int)$transaction['source_id'] : null;
+ $sourceName = array_key_exists('source_name', $transaction) ? (string)$transaction['source_name'] : null;
+ $sourceIban = array_key_exists('source_iban', $transaction) ? (string)$transaction['source_iban'] : null;
+ $sourceNumber = array_key_exists('source_number', $transaction) ? (string)$transaction['source_number'] : null;
+ $source = [
'id' => $sourceId,
'name' => $sourceName,
'iban' => $sourceIban,
'number' => $sourceNumber,
];
- $validSource = $accountValidator->validateSource($source);
+ $validSource = $accountValidator->validateSource($source);
// do something with result:
if (false === $validSource) {
@@ -169,31 +152,25 @@ trait TransactionValidation
}
/**
- * @param Validator $validator
- * @param string $transactionType
- * @param int $index
- * @param array $source
- * @param array $destination
- *
- * @return void
+ * @SuppressWarnings(PHPMD.ExcessiveParameterList)
*/
protected function sanityCheckReconciliation(Validator $validator, string $transactionType, int $index, array $source, array $destination): void
{
- Log::debug('Now in sanityCheckReconciliation');
- if (TransactionType::RECONCILIATION === ucfirst($transactionType) &&
- null === $source['id'] && null === $source['name'] && null === $destination['id'] && null === $destination['name']
+ app('log')->debug('Now in sanityCheckReconciliation');
+ if (TransactionType::RECONCILIATION === ucfirst($transactionType)
+ && null === $source['id'] && null === $source['name'] && null === $destination['id'] && null === $destination['name']
) {
- Log::debug('Both are NULL, error!');
+ app('log')->debug('Both are NULL, error!');
$validator->errors()->add(sprintf('transactions.%d.source_id', $index), trans('validation.reconciliation_either_account'));
$validator->errors()->add(sprintf('transactions.%d.source_name', $index), trans('validation.reconciliation_either_account'));
$validator->errors()->add(sprintf('transactions.%d.destination_id', $index), trans('validation.reconciliation_either_account'));
$validator->errors()->add(sprintf('transactions.%d.destination_name', $index), trans('validation.reconciliation_either_account'));
}
- if (TransactionType::RECONCILIATION === $transactionType &&
- (null !== $source['id'] || null !== $source['name']) &&
- (null !== $destination['id'] || null !== $destination['name'])) {
- Log::debug('Both are not NULL, error!');
+ if (TransactionType::RECONCILIATION === $transactionType
+ && (null !== $source['id'] || null !== $source['name'])
+ && (null !== $destination['id'] || null !== $destination['name'])) {
+ app('log')->debug('Both are not NULL, error!');
$validator->errors()->add(sprintf('transactions.%d.source_id', $index), trans('validation.reconciliation_either_account'));
$validator->errors()->add(sprintf('transactions.%d.source_name', $index), trans('validation.reconciliation_either_account'));
$validator->errors()->add(sprintf('transactions.%d.destination_id', $index), trans('validation.reconciliation_either_account'));
@@ -204,13 +181,8 @@ trait TransactionValidation
/**
* TODO describe this method.
*
- * @param Validator $validator
- * @param AccountValidator $accountValidator
- * @param array $transaction
- * @param string $transactionType
- * @param int $index
- *
- * @return void
+ * @SuppressWarnings(PHPMD.ExcessiveParameterList)
+ * @SuppressWarnings(PHPMD.NPathComplexity)
*/
private function sanityCheckForeignCurrency(
Validator $validator,
@@ -219,31 +191,34 @@ trait TransactionValidation
string $transactionType,
int $index
): void {
- Log::debug('Now in sanityCheckForeignCurrency()');
+ app('log')->debug('Now in sanityCheckForeignCurrency()');
if (0 !== $validator->errors()->count()) {
- Log::debug('Already have errors, return');
+ app('log')->debug('Already have errors, return');
+
return;
}
if (null === $accountValidator->source) {
- Log::debug('No source, return');
+ app('log')->debug('No source, return');
+
return;
}
if (null === $accountValidator->destination) {
- Log::debug('No destination, return');
+ app('log')->debug('No destination, return');
+
return;
}
- $source = $accountValidator->source;
- $destination = $accountValidator->destination;
+ $source = $accountValidator->source;
+ $destination = $accountValidator->destination;
- Log::debug(sprintf('Source: #%d "%s (%s)"', $source->id, $source->name, $source->accountType->type));
- Log::debug(sprintf('Destination: #%d "%s" (%s)', $destination->id, $destination->name, $source->accountType->type));
+ app('log')->debug(sprintf('Source: #%d "%s (%s)"', $source->id, $source->name, $source->accountType->type));
+ app('log')->debug(sprintf('Destination: #%d "%s" (%s)', $destination->id, $destination->name, $source->accountType->type));
if (!$this->isLiabilityOrAsset($source) || !$this->isLiabilityOrAsset($destination)) {
- Log::debug('Any account must be liability or asset account to continue.');
+ app('log')->debug('Any account must be liability or asset account to continue.');
+
return;
}
-
/** @var AccountRepositoryInterface $accountRepository */
$accountRepository = app(AccountRepositoryInterface::class);
$defaultCurrency = app('amount')->getDefaultCurrency();
@@ -251,16 +226,17 @@ trait TransactionValidation
$destinationCurrency = $accountRepository->getAccountCurrency($destination) ?? $defaultCurrency;
// if both accounts have the same currency, continue.
if ($sourceCurrency->code === $destinationCurrency->code) {
- Log::debug('Both accounts have the same currency, continue.');
+ app('log')->debug('Both accounts have the same currency, continue.');
+
return;
}
- Log::debug(sprintf('Source account expects %s', $sourceCurrency->code));
- Log::debug(sprintf('Destination account expects %s', $destinationCurrency->code));
+ app('log')->debug(sprintf('Source account expects %s', $sourceCurrency->code));
+ app('log')->debug(sprintf('Destination account expects %s', $destinationCurrency->code));
- Log::debug(sprintf('Amount is %s', $transaction['amount']));
+ app('log')->debug(sprintf('Amount is %s', $transaction['amount']));
if (TransactionType::DEPOSIT === ucfirst($transactionType)) {
- Log::debug(sprintf('Processing as a "%s"', $transactionType));
+ app('log')->debug(sprintf('Processing as a "%s"', $transactionType));
// use case: deposit from liability account to an asset account
// the foreign amount must be in the currency of the source
// the amount must be in the currency of the destination
@@ -268,20 +244,22 @@ trait TransactionValidation
// no foreign currency information is present:
if (!$this->hasForeignCurrencyInfo($transaction)) {
$validator->errors()->add(sprintf('transactions.%d.foreign_amount', $index), (string)trans('validation.require_foreign_currency'));
+
return;
}
// wrong currency information is present
$foreignCurrencyCode = $transaction['foreign_currency_code'] ?? false;
$foreignCurrencyId = (int)($transaction['foreign_currency_id'] ?? 0);
- Log::debug(sprintf('Foreign currency code seems to be #%d "%s"', $foreignCurrencyId, $foreignCurrencyCode), $transaction);
- if ($foreignCurrencyCode !== $sourceCurrency->code && $foreignCurrencyId !== (int)$sourceCurrency->id) {
+ app('log')->debug(sprintf('Foreign currency code seems to be #%d "%s"', $foreignCurrencyId, $foreignCurrencyCode), $transaction);
+ if ($foreignCurrencyCode !== $sourceCurrency->code && $foreignCurrencyId !== $sourceCurrency->id) {
$validator->errors()->add(sprintf('transactions.%d.foreign_currency_code', $index), (string)trans('validation.require_foreign_src'));
+
return;
}
}
if (TransactionType::TRANSFER === ucfirst($transactionType) || TransactionType::WITHDRAWAL === ucfirst($transactionType)) {
- Log::debug(sprintf('Processing as a "%s"', $transactionType));
+ app('log')->debug(sprintf('Processing as a "%s"', $transactionType));
// use case: withdrawal from asset account to a liability account.
// the foreign amount must be in the currency of the destination
// the amount must be in the currency of the source
@@ -293,61 +271,44 @@ trait TransactionValidation
// no foreign currency information is present:
if (!$this->hasForeignCurrencyInfo($transaction)) {
$validator->errors()->add(sprintf('transactions.%d.foreign_amount', $index), (string)trans('validation.require_foreign_currency'));
+
return;
}
// wrong currency information is present
$foreignCurrencyCode = $transaction['foreign_currency_code'] ?? false;
$foreignCurrencyId = (int)($transaction['foreign_currency_id'] ?? 0);
- Log::debug(sprintf('Foreign currency code seems to be #%d "%s"', $foreignCurrencyId, $foreignCurrencyCode), $transaction);
- if ($foreignCurrencyCode !== $destinationCurrency->code && $foreignCurrencyId !== (int)$destinationCurrency->id) {
- Log::debug(sprintf('No match on code, "%s" vs "%s"', $foreignCurrencyCode, $destinationCurrency->code));
- Log::debug(sprintf('No match on ID, #%d vs #%d', $foreignCurrencyId, $destinationCurrency->id));
+ app('log')->debug(sprintf('Foreign currency code seems to be #%d "%s"', $foreignCurrencyId, $foreignCurrencyCode), $transaction);
+ if ($foreignCurrencyCode !== $destinationCurrency->code && $foreignCurrencyId !== $destinationCurrency->id) {
+ app('log')->debug(sprintf('No match on code, "%s" vs "%s"', $foreignCurrencyCode, $destinationCurrency->code));
+ app('log')->debug(sprintf('No match on ID, #%d vs #%d', $foreignCurrencyId, $destinationCurrency->id));
$validator->errors()->add(sprintf('transactions.%d.foreign_amount', $index), (string)trans('validation.require_foreign_dest'));
}
}
}
- /**
- * @param Account $account
- *
- * @return bool
- */
private function isLiabilityOrAsset(Account $account): bool
{
return $this->isLiability($account) || $this->isAsset($account);
}
- /**
- * @param Account $account
- *
- * @return bool
- */
private function isLiability(Account $account): bool
{
- $type = $account->accountType?->type;
+ $type = $account->accountType->type;
if (in_array($type, config('firefly.valid_liabilities'), true)) {
return true;
}
+
return false;
}
- /**
- * @param Account $account
- *
- * @return bool
- */
private function isAsset(Account $account): bool
{
- $type = $account->accountType?->type;
- return $type === AccountType::ASSET;
+ $type = $account->accountType->type;
+
+ return AccountType::ASSET === $type;
}
- /**
- * @param array $transaction
- *
- * @return bool
- */
private function hasForeignCurrencyInfo(array $transaction): bool
{
if (!array_key_exists('foreign_currency_code', $transaction) && !array_key_exists('foreign_currency_id', $transaction)) {
@@ -359,28 +320,32 @@ trait TransactionValidation
if ('' === $transaction['foreign_amount']) {
return false;
}
- if (bccomp('0', $transaction['foreign_amount']) === 0) {
+ if (0 === bccomp('0', (string)$transaction['foreign_amount'])) {
return false;
}
+
return true;
}
/**
* Validates the given account information. Switches on given transaction type.
*
- * @param Validator $validator
- * @param TransactionGroup $transactionGroup
- *
* @throws FireflyException
*/
public function validateAccountInformationUpdate(Validator $validator, TransactionGroup $transactionGroup): void
{
- Log::debug('Now in validateAccountInformationUpdate()');
+ app('log')->debug('Now in validateAccountInformationUpdate()');
+ if ($validator->errors()->count() > 0) {
+ app('log')->debug('Validator already has errors, so return.');
+
+ return;
+ }
+
$transactions = $this->getTransactionsArray($validator);
/**
- * @var int $index
- * @var array $transaction
+ * @var null|int $index
+ * @var array $transaction
*/
foreach ($transactions as $index => $transaction) {
if (!is_int($index)) {
@@ -390,15 +355,9 @@ trait TransactionValidation
}
}
- /**
- * @param Validator $validator
- * @param int $index
- * @param array $transaction
- * @param TransactionGroup $transactionGroup
- */
protected function validateSingleUpdate(Validator $validator, int $index, array $transaction, TransactionGroup $transactionGroup): void
{
- Log::debug('Now validating single account update in validateSingleUpdate()');
+ app('log')->debug('Now validating single account update in validateSingleUpdate()');
// if no account types are given, just skip the check.
if (
@@ -406,10 +365,11 @@ trait TransactionValidation
&& !array_key_exists('source_name', $transaction)
&& !array_key_exists('destination_id', $transaction)
&& !array_key_exists('destination_name', $transaction)) {
- Log::debug('No account data has been submitted so will not validating account info.');
+ app('log')->debug('No account data has been submitted so will not validating account info.');
return;
}
+
// create validator:
/** @var AccountValidator $accountValidator */
$accountValidator = app(AccountValidator::class);
@@ -419,12 +379,12 @@ trait TransactionValidation
// validate if the submitted source ID/name/iban/number are valid
if (
- array_key_exists('source_id', $transaction) ||
- array_key_exists('source_name', $transaction) ||
- array_key_exists('source_iban', $transaction) ||
- array_key_exists('source_number', $transaction)
+ array_key_exists('source_id', $transaction)
+ || array_key_exists('source_name', $transaction)
+ || array_key_exists('source_iban', $transaction)
+ || array_key_exists('source_number', $transaction)
) {
- Log::debug('Will try to validate source account information.');
+ app('log')->debug('Will try to validate source account information.');
$sourceId = (int)($transaction['source_id'] ?? 0);
$sourceName = $transaction['source_name'] ?? null;
$sourceIban = $transaction['source_iban'] ?? null;
@@ -443,25 +403,24 @@ trait TransactionValidation
return;
}
- Log::debug('Source account info is valid.');
+ app('log')->debug('Source account info is valid.');
}
if (
- array_key_exists('destination_id', $transaction) ||
- array_key_exists('destination_name', $transaction) ||
- array_key_exists('destination_iban', $transaction) ||
- array_key_exists('destination_number', $transaction)
-
+ array_key_exists('destination_id', $transaction)
+ || array_key_exists('destination_name', $transaction)
+ || array_key_exists('destination_iban', $transaction)
+ || array_key_exists('destination_number', $transaction)
) {
- Log::debug('Will try to validate destination account information.');
+ app('log')->debug('Will try to validate destination account information.');
// at this point the validator may not have a source account, because it was never submitted for validation.
// must add it ourselves or the validator can never check if the destination is correct.
// the $transaction array must have a journal id or it's just one, this was validated before.
if (null === $accountValidator->source) {
- Log::debug('Account validator has no source account, must find it.');
+ app('log')->debug('Account validator has no source account, must find it.');
$source = $this->getOriginalSource($transaction, $transactionGroup);
if (null !== $source) {
- Log::debug('Found a source!');
+ app('log')->debug('Found a source!');
$accountValidator->source = $source;
}
}
@@ -477,40 +436,29 @@ trait TransactionValidation
$validator->errors()->add(sprintf('transactions.%d.destination_id', $index), $accountValidator->destError);
$validator->errors()->add(sprintf('transactions.%d.destination_name', $index), $accountValidator->destError);
}
- Log::debug('Destination account info is valid.');
+ app('log')->debug('Destination account info is valid.');
}
- Log::debug('Done with validateSingleUpdate().');
+ app('log')->debug('Done with validateSingleUpdate().');
}
- /**
- * @param TransactionGroup $group
- * @param array $transactions
- *
- * @return string
- */
private function getTransactionType(TransactionGroup $group, array $transactions): string
{
- return $transactions[0]['type'] ?? strtolower($group->transactionJournals()->first()->transactionType->type);
+ return $transactions[0]['type'] ?? strtolower((string)$group->transactionJournals()->first()?->transactionType->type);
}
- /**
- * @param array $transaction
- * @param TransactionGroup $transactionGroup
- *
- * @return Account|null
- */
private function getOriginalSource(array $transaction, TransactionGroup $transactionGroup): ?Account
{
if (1 === $transactionGroup->transactionJournals->count()) {
$journal = $transactionGroup->transactionJournals->first();
- return $journal->transactions()->where('amount', '<', 0)->first()->account;
+ return $journal?->transactions()->where('amount', '<', 0)->first()?->account;
}
+
/** @var TransactionJournal $journal */
foreach ($transactionGroup->transactionJournals as $journal) {
$journalId = (int)($transaction['transaction_journal_id'] ?? 0);
- if ((int)$journal->id === $journalId) {
- return $journal->transactions()->where('amount', '<', 0)->first()->account;
+ if ($journal->id === $journalId) {
+ return $journal->transactions()->where('amount', '<', 0)->first()?->account;
}
}
@@ -519,12 +467,10 @@ trait TransactionValidation
/**
* Adds an error to the validator when there are no transactions in the array of data.
- *
- * @param Validator $validator
*/
public function validateOneRecurrenceTransaction(Validator $validator): void
{
- Log::debug('Now in validateOneRecurrenceTransaction()');
+ app('log')->debug('Now in validateOneRecurrenceTransaction()');
$transactions = $this->getTransactionsArray($validator);
// need at least one transaction
@@ -535,40 +481,36 @@ trait TransactionValidation
/**
* Adds an error to the validator when there are no transactions in the array of data.
- *
- * @param Validator $validator
*/
public function validateOneTransaction(Validator $validator): void
{
- Log::debug('Now in validateOneTransaction');
+ app('log')->debug('Now in validateOneTransaction');
if ($validator->errors()->count() > 0) {
- Log::debug('Validator already has errors, so return.');
+ app('log')->debug('Validator already has errors, so return.');
+
return;
}
$transactions = $this->getTransactionsArray($validator);
// need at least one transaction
if (0 === count($transactions)) {
$validator->errors()->add('transactions.0.description', (string)trans('validation.at_least_one_transaction'));
- Log::debug('Added error: at_least_one_transaction.');
+ app('log')->debug('Added error: at_least_one_transaction.');
return;
}
- Log::debug('Added NO errors.');
+ app('log')->debug('Added NO errors.');
}
- /**
- * @param Validator $validator
- */
public function validateTransactionArray(Validator $validator): void
{
if ($validator->errors()->count() > 0) {
return;
}
$transactions = $this->getTransactionsArray($validator);
- foreach ($transactions as $key => $value) {
+ foreach (array_keys($transactions) as $key) {
if (!is_int($key)) {
$validator->errors()->add('transactions.0.description', (string)trans('validation.at_least_one_transaction'));
- Log::debug('Added error: at_least_one_transaction.');
+ app('log')->debug('Added error: at_least_one_transaction.');
return;
}
@@ -577,28 +519,26 @@ trait TransactionValidation
/**
* All types of splits must be equal.
- *
- * @param Validator $validator
*/
public function validateTransactionTypes(Validator $validator): void
{
if ($validator->errors()->count() > 0) {
return;
}
- Log::debug('Now in validateTransactionTypes()');
+ app('log')->debug('Now in validateTransactionTypes()');
$transactions = $this->getTransactionsArray($validator);
- $types = [];
+ $types = [];
foreach ($transactions as $transaction) {
$types[] = $transaction['type'] ?? 'invalid';
}
- $unique = array_unique($types);
+ $unique = array_unique($types);
if (count($unique) > 1) {
$validator->errors()->add('transactions.0.type', (string)trans('validation.transaction_types_equal'));
return;
}
- $first = $unique[0] ?? 'invalid';
+ $first = $unique[0] ?? 'invalid';
if ('invalid' === $first) {
$validator->errors()->add('transactions.0.type', (string)trans('validation.invalid_transaction_type'));
}
@@ -606,40 +546,34 @@ trait TransactionValidation
/**
* All types of splits must be equal.
- *
- * @param Validator $validator
*/
public function validateTransactionTypesForUpdate(Validator $validator): void
{
- Log::debug('Now in validateTransactionTypesForUpdate()');
+ app('log')->debug('Now in validateTransactionTypesForUpdate()');
$transactions = $this->getTransactionsArray($validator);
$types = [];
foreach ($transactions as $transaction) {
$originalType = $this->getOriginalType((int)($transaction['transaction_journal_id'] ?? 0));
// if type is not set, fall back to the type of the journal, if one is given.
- $types[] = $transaction['type'] ?? $originalType;
+ $types[] = $transaction['type'] ?? $originalType;
}
- $unique = array_unique($types);
+ $unique = array_unique($types);
if (count($unique) > 1) {
app('log')->warning('Add error for mismatch transaction types.');
$validator->errors()->add('transactions.0.type', (string)trans('validation.transaction_types_equal'));
return;
}
- Log::debug('No errors in validateTransactionTypesForUpdate()');
+ app('log')->debug('No errors in validateTransactionTypesForUpdate()');
}
- /**
- * @param int $journalId
- *
- * @return string
- */
private function getOriginalType(int $journalId): string
{
if (0 === $journalId) {
return 'invalid';
}
- /** @var TransactionJournal|null $journal */
+
+ /** @var null|TransactionJournal $journal */
$journal = TransactionJournal::with(['transactionType'])->find($journalId);
if (null !== $journal) {
return strtolower($journal->transactionType->type);
@@ -648,74 +582,79 @@ trait TransactionValidation
return 'invalid';
}
- /**
- * @param Validator $validator
- */
private function validateEqualAccounts(Validator $validator): void
{
if ($validator->errors()->count() > 0) {
return;
}
- Log::debug('Now in validateEqualAccounts()');
+ app('log')->debug('Now in validateEqualAccounts()');
$transactions = $this->getTransactionsArray($validator);
// needs to be split
if (count($transactions) < 2) {
return;
}
- $type = $transactions[0]['type'] ?? 'withdrawal';
- $sources = [];
- $dests = [];
+ $type = $transactions[0]['type'] ?? 'withdrawal';
+ $sources = [];
+ $dests = [];
foreach ($transactions as $transaction) {
$sources[] = sprintf('%d-%s', $transaction['source_id'] ?? 0, $transaction['source_name'] ?? '');
$dests[] = sprintf('%d-%s', $transaction['destination_id'] ?? 0, $transaction['destination_name'] ?? '');
}
- $sources = array_unique($sources);
- $dests = array_unique($dests);
+ $sources = array_unique($sources);
+ $dests = array_unique($dests);
+
switch ($type) {
default:
case 'withdrawal':
if (count($sources) > 1) {
$validator->errors()->add('transactions.0.source_id', (string)trans('validation.all_accounts_equal'));
}
+
break;
+
case 'deposit':
if (count($dests) > 1) {
$validator->errors()->add('transactions.0.destination_id', (string)trans('validation.all_accounts_equal'));
}
+
break;
- case'transfer':
+
+ case 'transfer':
if (count($sources) > 1 || count($dests) > 1) {
$validator->errors()->add('transactions.0.source_id', (string)trans('validation.all_accounts_equal'));
$validator->errors()->add('transactions.0.destination_id', (string)trans('validation.all_accounts_equal'));
}
+
break;
}
}
- /**
- * @param Validator $validator
- * @param TransactionGroup $transactionGroup
- */
private function validateEqualAccountsForUpdate(Validator $validator, TransactionGroup $transactionGroup): void
{
- Log::debug('Now in validateEqualAccountsForUpdate()');
- $transactions = $this->getTransactionsArray($validator);
-
- if (2 !== count($transactions)) {
- Log::debug('Less than 2 transactions, do nothing.');
+ if ($validator->errors()->count() > 0) {
+ app('log')->debug('Validator already has errors, so return.');
return;
}
- $type = $this->getTransactionType($transactionGroup, $transactions);
+
+ app('log')->debug('Now in validateEqualAccountsForUpdate()');
+ $transactions = $this->getTransactionsArray($validator);
+
+ if (2 !== count($transactions)) {
+ app('log')->debug('Less than 2 transactions, do nothing.');
+
+ return;
+ }
+ $type = $this->getTransactionType($transactionGroup, $transactions);
// compare source IDs, destination IDs, source names and destination names.
// I think I can get away with one combination being equal, as long as the rest
// of the code picks up on this as well.
// either way all fields must be blank or all equal
// but if IDs are equal don't bother with the names.
- $comparison = $this->collectComparisonData($transactions);
- $result = $this->compareAccountData($type, $comparison);
+ $comparison = $this->collectComparisonData($transactions);
+ $result = $this->compareAccountData($type, $comparison);
if (false === $result) {
if ('withdrawal' === $type) {
$validator->errors()->add('transactions.0.source_id', (string)trans('validation.all_accounts_equal'));
@@ -731,24 +670,20 @@ trait TransactionValidation
return;
}
- Log::debug('No errors found in validateEqualAccountsForUpdate');
+ app('log')->debug('No errors found in validateEqualAccountsForUpdate');
}
- /**
- * @param array $transactions
- *
- * @return array
- */
private function collectComparisonData(array $transactions): array
{
$fields = ['source_id', 'destination_id', 'source_name', 'destination_name'];
$comparison = [];
foreach ($fields as $field) {
$comparison[$field] = [];
+
/** @var array $transaction */
foreach ($transactions as $transaction) {
// source or destination may be omitted. If this is the case, use the original source / destination name + ID.
- $originalData = $this->getOriginalData((int)($transaction['transaction_journal_id'] ?? 0));
+ $originalData = $this->getOriginalData((int)($transaction['transaction_journal_id'] ?? 0));
// get field.
$comparison[$field][] = $transaction[$field] ?? $originalData[$field];
@@ -758,14 +693,9 @@ trait TransactionValidation
return $comparison;
}
- /**
- * @param int $journalId
- *
- * @return array
- */
private function getOriginalData(int $journalId): array
{
- $return = [
+ $return = [
'source_id' => 0,
'source_name' => '',
'destination_id' => 0,
@@ -774,15 +704,17 @@ trait TransactionValidation
if (0 === $journalId) {
return $return;
}
- /** @var Transaction $source */
- $source = Transaction::where('transaction_journal_id', $journalId)->where('amount', '<', 0)->with(['account'])->first();
+
+ /** @var null|Transaction $source */
+ $source = Transaction::where('transaction_journal_id', $journalId)->where('amount', '<', 0)->with(['account'])->first();
if (null !== $source) {
$return['source_id'] = $source->account_id;
$return['source_name'] = $source->account->name;
}
- /** @var Transaction $destination */
+
+ /** @var null|Transaction $destination */
$destination = Transaction::where('transaction_journal_id', $journalId)->where('amount', '>', 0)->with(['account'])->first();
- if (null !== $source) {
+ if (null !== $destination) {
$return['destination_id'] = $destination->account_id;
$return['destination_name'] = $destination->account->name;
}
@@ -790,12 +722,6 @@ trait TransactionValidation
return $return;
}
- /**
- * @param string $type
- * @param array $comparison
- *
- * @return bool
- */
private function compareAccountData(string $type, array $comparison): bool
{
return match ($type) {
@@ -805,11 +731,6 @@ trait TransactionValidation
};
}
- /**
- * @param array $comparison
- *
- * @return bool
- */
private function compareAccountDataWithdrawal(array $comparison): bool
{
if ($this->arrayEqual($comparison['source_id'])) {
@@ -824,21 +745,11 @@ trait TransactionValidation
return false;
}
- /**
- * @param array $array
- *
- * @return bool
- */
private function arrayEqual(array $array): bool
{
return 1 === count(array_unique($array));
}
- /**
- * @param array $comparison
- *
- * @return bool
- */
private function compareAccountDataDeposit(array $comparison): bool
{
if ($this->arrayEqual($comparison['destination_id'])) {
@@ -853,11 +764,6 @@ trait TransactionValidation
return false;
}
- /**
- * @param array $comparison
- *
- * @return bool
- */
private function compareAccountDataTransfer(array $comparison): bool
{
if ($this->arrayEqual($comparison['source_id'])) {
diff --git a/bootstrap/app.php b/bootstrap/app.php
index b7cac40a4c..f17a7fe025 100644
--- a/bootstrap/app.php
+++ b/bootstrap/app.php
@@ -37,13 +37,14 @@ bcscale(12);
if (!function_exists('envNonEmpty')) {
/**
* @param string $key
- * @param null $default
+ * @param string|int|bool|null $default
*
* @return mixed|null
*/
- function envNonEmpty(string $key, $default = null) {
+ function envNonEmpty(string $key, string|int|bool|null $default = null)
+ {
$result = env($key, $default);
- if (is_string($result) && '' === $result) {
+ if ('' === $result) {
$result = $default;
}
@@ -58,13 +59,14 @@ if (!function_exists('stringIsEqual')) {
*
* @return bool
*/
- function stringIsEqual(string $left, string $right): bool {
+ function stringIsEqual(string $left, string $right): bool
+ {
return $left === $right;
}
}
$app = new Illuminate\Foundation\Application(
- realpath(__DIR__ . '/../')
+ (string)realpath(__DIR__ . '/../')
);
/*
diff --git a/changelog.md b/changelog.md
index c28367f30d..555f6dea65 100644
--- a/changelog.md
+++ b/changelog.md
@@ -3,6 +3,259 @@
All notable changes to this project will be documented in this file.
This project adheres to [Semantic Versioning](http://semver.org/).
+## 6.1.10 - 2024-03-03
+
+### Added
+
+- Add missing translations for rule page.
+
+### Changed
+
+- The update checker can also deal with development releases
+- Rule actions no longer complain when the category is already set
+
+### Removed
+
+- Unused translation on budget page
+
+### Fixed
+
+- [Issue 8521](https://github.com/firefly-iii/firefly-iii/issues/8521) (Total buget bar is missing when using SQLite) reported by @matlink
+- [Issue 8544](https://github.com/firefly-iii/firefly-iii/issues/8544) (Recurring transaction calendar preview is not working properly) reported by @Maxco10
+- [Issue 8555](https://github.com/firefly-iii/firefly-iii/issues/8555) (Has no budget becomes has no category) reported by @Weiming-Hu
+- [Discussion 8557](https://github.com/orgs/firefly-iii/discussions/8557) ("Delete ALL your transactions" also removes all asset opening balance information) started by @digitlength
+- [Issue 8575](https://github.com/firefly-iii/firefly-iii/issues/8575) (Creating rule from bill no longer pre-fills triggers and actions) reported by @jpelgrom
+- [Issue 8578](https://github.com/firefly-iii/firefly-iii/issues/8578) (Display Bug: foreign currency is red & negative in deposits) reported by @dreautall
+- Errors in incoming webhook URLs are properly caught
+
+### Security
+
+- Improved Host header validation to prevent a potential attack, reported by Raqib Iskenderli
+
+## 6.1.9 - 2024-02-06
+
+### Fixed
+
+- [Issue 8499](https://github.com/firefly-iii/firefly-iii/issues/8499) (Wrong version number after update to v6.1.8) reported by @memo-567
+- [Issue 8501](https://github.com/firefly-iii/firefly-iii/issues/8501) (Bulk delete page links to wrong tx) reported by @likuilin
+
+## 6.1.8 - 2024-02-04
+
+### Added
+
+- Added a trigger for v2 layouts that helps with debugging.
+- [Issue 8431](https://github.com/firefly-iii/firefly-iii/issues/8431) (The Opening/ Virtual Balance must less than or equal 100001709) reported by @binhtran1604
+- [Issue 8457](https://github.com/firefly-iii/firefly-iii/issues/8457) (Budgets - missing summary from the bottom) reported by @g7xtr
+
+### Removed
+
+- Reference to the "huntr" bug bounty platform, which is now some shitty AI scam.
+
+### Fixed
+
+- [PR 8432](https://github.com/firefly-iii/firefly-iii/pull/8432) (Update favicons.twig) reported by @stevietv
+- [Issue 8433](https://github.com/firefly-iii/firefly-iii/issues/8433) (may be a wrong calculation) reported by @PterX
+- [Issue 8442](https://github.com/firefly-iii/firefly-iii/issues/8442) (v6.1.7 - Not expected this period) reported by @poudenes
+- [Discussion 8445](https://github.com/orgs/firefly-iii/discussions/8445) (Offering to Contribute to Firefly Documentation) reported by @poupouproject
+- [Issue 8446](https://github.com/firefly-iii/firefly-iii/issues/8446) (There is an extra X ending symbol here) reported by @PterX
+- [Issue 8467](https://github.com/firefly-iii/firefly-iii/issues/8467) (API Endpoint /data/export/rules produces errorneous CSV output) reported by @not1q84-1
+- [Issue 8472](https://github.com/firefly-iii/firefly-iii/issues/8472) (When left to spend is 0, the info box is red) reported by @nicosomb
+- [Issue 8471](https://github.com/firefly-iii/firefly-iii/issues/8471) (Left to spend is not the same on dashboard and on budget page) reported by @nicosomb
+- [PR 8477](https://github.com/firefly-iii/firefly-iii/pull/8477) (Bump actions/checkout from 3 to 4) reported by @dependabot[bot]
+- [Issue 8497](https://github.com/firefly-iii/firefly-iii/issues/8497) (has_any_category:false not possible as a rule) reported by @shrippen
+
+### Security
+
+- [GHSA-29w6-c52g-m8jc](https://github.com/firefly-iii/firefly-iii/security/advisories/GHSA-29w6-c52g-m8jc) Demo users could trick each other into downloading poisoned CSV files, reported by @red5us
+
+## 6.1.7 - 2024-01-21
+
+### Added
+
+- Layout `v2` has some new features
+- [Issue 8369](https://github.com/firefly-iii/firefly-iii/issues/8369) (Additional reconcile link) reported by @chevdor
+
+### Fixed
+
+- [Issue 8352](https://github.com/firefly-iii/firefly-iii/issues/8352) (Modifying the direction of a transfer between liabilities yields no effect) reported by @Ezwen
+- [PR 8370](https://github.com/firefly-iii/firefly-iii/pull/8370) (Fix various typos) reported by @luzpaz
+- [Issue 8377](https://github.com/firefly-iii/firefly-iii/issues/8377) (Query on multiple tags returns duplicates) reported by @chevdor
+- [Issue 8374](https://github.com/firefly-iii/firefly-iii/issues/8374) (Error Graph Income vs. expenses Reports page) reported by @nicolopozzato
+- [Issue 8390](https://github.com/firefly-iii/firefly-iii/issues/8390) (Rule with destination_account_is 'not' is never returning a result.) reported by @EricVanCaenenberghe
+- [Issue 8349](https://github.com/firefly-iii/firefly-iii/issues/8349) (Currencies not saving correctly) reported by @r1bas4
+- [Issue 8418](https://github.com/firefly-iii/firefly-iii/issues/8418) (Unable to create rule with trigger having type has_no_budget via the API ) reported by @tailg8nj
+- [Issue 8425](https://github.com/firefly-iii/firefly-iii/issues/8425) (Error from the net-worth endpoint with `Trailing data`.) reported by @chevdor
+- [Issue 8427](https://github.com/firefly-iii/firefly-iii/issues/8427) (Broken batch application of non-strict rules with triggers with stop processing) reported by @alexschlueter
+- Various Carbon `createFromFormat` issues fixed.
+
+## 6.1.6 - 2024-01-07
+
+### Fixed
+
+- Type validation error
+
+## 6.1.5 - 2024-01-07
+
+### Added
+
+- More audit logs
+- Sanity check in date ranges
+- More uniform length and size validations
+
+### Changed
+
+- Slightly changed text, thanks @maureenferreira!
+
+### Fixed
+
+- [Issue 8328](https://github.com/firefly-iii/firefly-iii/issues/8328) Some extra fixes for non-zero foreign amounts
+- Updated links in `.env.example`, thanks @lemuelroberto!
+
+## 6.1.4 - 2024-01-03
+
+### Fixed
+
+- [Issue 8328](https://github.com/firefly-iii/firefly-iii/issues/8328) Asking for non-zero foreign amount despite not being used
+
+## 6.1.3 - 2024-01-03
+
+### Fixed
+
+- [Issue 8326](https://github.com/firefly-iii/firefly-iii/issues/8326) Asking for non-zero foreign amount despite not being used
+
+## 6.1.2 - 2024-01-03
+
+### Changed
+
+- [Issue 8304](https://github.com/firefly-iii/firefly-iii/issues/8304) Several issues with searching for and displaying of tag-related transactions
+
+### Removed
+
+- Double reference to webhooks in the menu
+
+### Fixed
+
+- [Issue 8297](https://github.com/firefly-iii/firefly-iii/issues/8297) Division by zero
+- [Issue 8320](https://github.com/firefly-iii/firefly-iii/issues/8320) nullpointer in new layout
+- [Issue 8321](https://github.com/firefly-iii/firefly-iii/issues/8321) Networth checkbox for expense and revenue accounts removed
+- Long date ranges will throw an error
+-
+- Max sizes and reasonable limits for most numbers and strings
+- Links in readme to documentation.
+
+### Security
+
+- Webhooks now properly disabled in the UI.
+- [Issue 8322](https://github.com/firefly-iii/firefly-iii/issues/8322) Duplicate detection did not distinguish between users
+
+## 6.1.1 - 2023-12-27
+
+### Changed
+
+- Rule overview is lower in height.
+
+### Removed
+
+- Removed fixed sidebar again
+
+### Fixed
+
+- Nullpointer in rule trigger render code
+- [Issue 8272](https://github.com/firefly-iii/firefly-iii/issues/8272) The sum for expected bills in a group includes unexpected bills as well
+- [Issue 8273](https://github.com/firefly-iii/firefly-iii/issues/8273) Frontpage preferences indicate all accounts are shown on the frontpage, even when not true
+- [Issue 8274](https://github.com/firefly-iii/firefly-iii/issues/8274) Semi specific dates do not work correctly with the "Transaction date is.." rule trigger
+- [Issue 8277](https://github.com/firefly-iii/firefly-iii/issues/8277) Expected bill next month, but shown as not expected
+- [Issue 8278](https://github.com/firefly-iii/firefly-iii/issues/8278) Net worth is empty in the dashboard due to division by zero
+- [Issue 8281](https://github.com/firefly-iii/firefly-iii/issues/8281) Database CPU utilization after v6.1.0 upgrade
+- [Issue 8291](https://github.com/firefly-iii/firefly-iii/issues/8291) Multiple "Any tag is" (negated or not) rule triggers don't all apply in strict mode
+
+### Security
+
+- HTML Injection Vulnerability in webhooks code, discovered by @stefan-schiller-sonarsource from Sonar. Thanks!
+
+### API
+
+- [Issue 8282](https://github.com/firefly-iii/firefly-iii/issues/8282) Update transaction via API does not update the "updated_at" parameter
+
+## 6.1.0 - 2023-12-17
+
+> ⚠️⚠️ This release required **PHP 8.3.0** and will not work on earlier releases of PHP ⚠️⚠️
+
+### Added
+
+- [Issue 7571](https://github.com/firefly-iii/firefly-iii/issues/7571) More tag search options
+- [Issue 7781](https://github.com/firefly-iii/firefly-iii/issues/7781) Nice wrapper script for artisan commands
+- UI also supports time for transactions
+
+### Changed
+
+- ⚠️⚠️ Requires PHP8.3 ⚠️⚠️
+- [Issue 8148](https://github.com/firefly-iii/firefly-iii/issues/8148) Slovenian language updates
+- [Issue 8023](https://github.com/firefly-iii/firefly-iii/issues/8023) Top bar is now fixed in place
+- Completely rewrote the documentation.
+
+### Deprecated
+
+- ⚠️⚠️ Removed support for PHP 8.2 ⚠️⚠️
+
+### Fixed
+
+- [Issue 8106](https://github.com/firefly-iii/firefly-iii/issues/8106) [issue 8195](https://github.com/firefly-iii/firefly-iii/issues/8195) [issue 8163](https://github.com/firefly-iii/firefly-iii/issues/8163) Various changes and fixes to bill date calculation
+- [Issue 8137](https://github.com/firefly-iii/firefly-iii/issues/8137) Fix uneven amount error from cron job
+- [Issue 8192](https://github.com/firefly-iii/firefly-iii/issues/8192) No matching transactions found.Rule with trigger NOT Transaction is reconciled returns
+- [Issue 8207](https://github.com/firefly-iii/firefly-iii/issues/8207) Broken links, thanks @Maxco10!
+- [Issue 8138](https://github.com/firefly-iii/firefly-iii/issues/8138) Reconciled transactions can't be "store(d) as new"
+- [Issue 7716](https://github.com/firefly-iii/firefly-iii/issues/7716) Removed bar in budget overview
+- [Issue 8251](https://github.com/firefly-iii/firefly-iii/issues/8251) Removing a budget would not remove available budget
+
+### API
+
+- [Issue 8022](https://github.com/firefly-iii/firefly-iii/issues/8022) API chart expansions
+- [Issue 8106](https://github.com/firefly-iii/firefly-iii/issues/8106) API reports empty string instead of NULL
+
+## 6.0.30 - 2023-10-29
+
+### Fixed
+
+- Missing method after refactoring.
+
+## 6.0.29 - 2023-10-29
+
+### Fixed
+
+- Null pointer in bill overview
+
+## 6.0.28 - 2023-10-29
+
+### Added
+
+- [Issue 8076](https://github.com/firefly-iii/firefly-iii/issues/8076) Added a "Clone and edit"-button
+- [Issue 7204](https://github.com/firefly-iii/firefly-iii/issues/7204) Added the ability to customize the URL protocol types Firefly III accepts
+- [Issue 8098](https://github.com/firefly-iii/firefly-iii/issues/8098) More tests in the navigation class, thanks @tonicospinelli!
+
+### Changed
+
+- Refactored the Actions of GitHub
+- The transaction currencies are now linked to users, and can be enabled per user
+- A few upgrade commands are refactored
+- You can no longer edit vital parts of reconciled transactions
+
+### Deprecated
+
+- Remove old v3 layout.
+
+### Fixed
+
+- Bad math in the order of piggy banks
+- [Issue 8084](https://github.com/firefly-iii/firefly-iii/issues/8084) @JoSchrader fixed an issue with a duplicate button
+- [Issue 8103](https://github.com/firefly-iii/firefly-iii/issues/8103) Bulk edit would not accept transaction descriptions longer than 255 characters
+- [Issue 8099](https://github.com/firefly-iii/firefly-iii/issues/8099) The bill index would never skip the number of periods you indicated
+- [Issue 8069](https://github.com/firefly-iii/firefly-iii/issues/8069) Rule descriptions would always "1" as description. Thanks @Maxco10!
+
+### API
+
+- API will no longer accept changes to amount and account fields for reconciled transactions
+
## v6.0.27 - 2023-10-16
### Added
@@ -252,7 +505,7 @@ This project adheres to [Semantic Versioning](http://semver.org/).
- 🇰🇷 Korean translations!
- A new "adjusted" auto-budget type that will correct itself after
- spending. [Read more](https://docs.firefly-iii.org/firefly-iii/financial-concepts/organizing/#adjusted-and-correct-for-overspending)
+ spending. [Read more](https://docs.firefly-iii.org/xfirefly-iii/financial-concepts/organizing/#adjusted-and-correct-for-overspending)
- [Issue 6631](https://github.com/firefly-iii/firefly-iii/issues/6631) Can now link withdrawals and deposits to piggy
banks, thanks @ChrisWin22!
@@ -465,10 +718,7 @@ This project adheres to [Semantic Versioning](http://semver.org/).
This is release
-*
-
-*6.0.0
-** of Firefly III.
+**6.0.0** of Firefly III.
### Warnings
@@ -1045,7 +1295,7 @@ https://api-docs.firefly-iii.org/.
- ⚠️ This is the last release that supports PHP 8.0
- 👍 Want to try the new v3 layout? At your own risk, browse to `/v3/`.
-Please refer to the [documentation](https://docs.firefly-iii.org/firefly-iii/) and support channels if you run into
+Please refer to the [documentation](https://docs.firefly-iii.org/xfirefly-iii/) and support channels if you run into
problems:
- [Gitter.im](https://gitter.im/firefly-iii/firefly-iii)
@@ -1123,6 +1373,6 @@ problems:
# Full change log
-Can be found here: https://docs.firefly-iii.org/firefly-iii/about-firefly-iii/changelog/
+Can be found here: https://docs.firefly-iii.org/references/firefly-iii/changelog/
diff --git a/composer.json b/composer.json
index d83366f6dc..82186beb6c 100644
--- a/composer.json
+++ b/composer.json
@@ -1,194 +1,198 @@
{
- "name": "grumpydictator/firefly-iii",
- "description": "Firefly III: a personal finances manager.",
- "keywords": [
- "finance",
- "finances",
- "manager",
- "management",
- "euro",
- "dollar",
- "laravel",
- "money",
- "currency",
- "financials",
- "financial",
- "budgets",
- "administration",
- "tool",
- "tooling",
- "help",
- "helper",
- "assistant",
- "planning",
- "organizing",
- "bills",
- "personal finance",
- "budgets",
- "budgeting",
- "budgeting tool",
- "budgeting application",
- "transactions",
- "self hosted",
- "self-hosted",
- "transfers",
- "management"
- ],
- "license": "AGPL-3.0-or-later",
- "homepage": "https://github.com/firefly-iii/firefly-iii",
- "type": "project",
- "readme": "readme.md",
- "authors": [
- {
- "name": "James Cole",
- "email": "james@firefly-iii.org",
- "homepage": "https://github.com/firefly-iii",
- "role": "Developer"
- }
- ],
- "support": {
- "email": "james@firefly-iii.org",
- "issues": "https://github.com/firefly-iii/firefly-iii/issues",
- "forum": "https://gitter.im/firefly-iii/firefly-iii",
- "wiki": "https://github.com/firefly-iii/help/wiki",
- "source": "https://github.com/firefly-iii/firefly-iii",
- "docs": "https://docs.firefly-iii.org/"
- },
- "funding": [
- {
- "type": "patreon",
- "url": "https://www.patreon.com/JC5"
+ "name": "grumpydictator/firefly-iii",
+ "description": "Firefly III: a personal finances manager.",
+ "keywords": [
+ "finance",
+ "finances",
+ "manager",
+ "management",
+ "euro",
+ "dollar",
+ "laravel",
+ "money",
+ "currency",
+ "financials",
+ "financial",
+ "budgets",
+ "administration",
+ "tool",
+ "tooling",
+ "help",
+ "helper",
+ "assistant",
+ "planning",
+ "organizing",
+ "bills",
+ "personal finance",
+ "budgets",
+ "budgeting",
+ "budgeting tool",
+ "budgeting application",
+ "transactions",
+ "self hosted",
+ "self-hosted",
+ "transfers",
+ "management"
+ ],
+ "license": "AGPL-3.0-or-later",
+ "homepage": "https://github.com/firefly-iii/firefly-iii",
+ "type": "project",
+ "readme": "readme.md",
+ "authors": [
+ {
+ "name": "James Cole",
+ "email": "james@firefly-iii.org",
+ "homepage": "https://github.com/firefly-iii",
+ "role": "Developer"
+ }
+ ],
+ "support": {
+ "email": "james@firefly-iii.org",
+ "issues": "https://github.com/firefly-iii/firefly-iii/issues",
+ "forum": "https://gitter.im/firefly-iii/firefly-iii",
+ "wiki": "https://github.com/firefly-iii/help/wiki",
+ "source": "https://github.com/firefly-iii/firefly-iii",
+ "docs": "https://docs.firefly-iii.org/"
},
- {
- "type": "github",
- "url": "https://github.com/sponsors/JC5"
- }
- ],
- "require": {
- "php": ">=8.2",
- "ext-bcmath": "*",
- "ext-curl": "*",
- "ext-fileinfo": "*",
- "ext-iconv": "*",
- "ext-intl": "*",
- "ext-json": "*",
- "ext-mbstring": "*",
- "ext-openssl": "*",
- "ext-pdo": "*",
- "ext-session": "*",
- "ext-simplexml": "*",
- "ext-sodium": "*",
- "ext-tokenizer": "*",
- "ext-xml": "*",
- "ext-xmlwriter": "*",
- "bacon/bacon-qr-code": "2.*",
- "diglactic/laravel-breadcrumbs": "^8.1",
- "doctrine/dbal": "3.*",
- "gdbots/query-parser": "^3.0",
- "guzzlehttp/guzzle": "^7.8",
- "jc5/google2fa-laravel": "^2.0",
- "jc5/recovery": "^2",
- "laravel/framework": "^10",
- "laravel/passport": "11.*",
- "laravel/sanctum": "^3.3",
- "laravel/slack-notification-channel": "^3.0",
- "laravel/ui": "^4.2",
- "league/commonmark": "2.*",
- "league/csv": "^9.10",
- "league/fractal": "0.*",
- "nunomaduro/collision": "^7.7",
- "pragmarx/google2fa": "^8.0",
- "predis/predis": "^2.2",
- "psr/log": "<4",
- "ramsey/uuid": "^4.7",
- "rcrowe/twigbridge": "^0.14",
- "spatie/laravel-html": "^3.2",
- "spatie/laravel-ignition": "^2",
- "spatie/period": "^2.4",
- "symfony/expression-language": "^6.3",
- "symfony/http-client": "^6.3",
- "symfony/mailgun-mailer": "^6.3",
- "therobfonz/laravel-mandrill-driver": "^5.0"
- },
- "require-dev": {
- "barryvdh/laravel-ide-helper": "2.*",
- "ergebnis/phpstan-rules": "^2.1",
- "fakerphp/faker": "1.*",
- "filp/whoops": "2.*",
- "mockery/mockery": "1.*",
- "nunomaduro/larastan": "^2.6",
- "phpstan/phpstan": "^1.10",
- "phpstan/phpstan-deprecation-rules": "^1.1",
- "phpstan/phpstan-strict-rules": "^1.4",
- "phpunit/phpunit": "^10",
- "thecodingmachine/phpstan-strict-rules": "^1.0"
- },
- "suggest": {
- },
- "autoload": {
- "psr-4": {
- "FireflyIII\\": "app/",
- "Domain\\": "domain/",
- "Database\\Factories\\": "database/factories/",
- "Database\\Seeders\\": "database/seeders/"
- }
- },
- "autoload-dev": {
- "psr-4": {
- "Tests\\": "tests/"
- }
- },
- "extra": {
- "laravel": {
- "dont-discover": []
- }
- },
- "scripts": {
- "post-root-package-install": [
- "@php -r \"file_exists('.env') || copy('.env.example', '.env');\""
+ "funding": [
+ {
+ "type": "patreon",
+ "url": "https://www.patreon.com/JC5"
+ },
+ {
+ "type": "github",
+ "url": "https://github.com/sponsors/JC5"
+ }
],
- "post-create-project-cmd": [
- "@php artisan key:generate"
- ],
- "post-autoload-dump": [
- "Illuminate\\Foundation\\ComposerScripts::postAutoloadDump"
- ],
- "post-update-cmd": [
- "@php artisan config:clear",
- "@php artisan route:clear",
- "@php artisan twig:clean",
- "@php artisan view:clear",
- "@php artisan clear-compiled",
- "@php artisan cache:clear",
- "@php artisan firefly-iii:upgrade-database",
- "@php artisan firefly-iii:correct-database",
- "@php artisan firefly-iii:report-integrity",
- "@php artisan passport:install",
- "@php artisan firefly:instructions update"
- ],
- "post-install-cmd": [
- "@php artisan firefly:instructions install",
- "@php artisan firefly-iii:verify-security-alerts"
- ],
- "unit-test": [
- "@php vendor/bin/phpunit -c phpunit.xml --testsuite unit --no-coverage"
- ],
- "integration-test": [
- "@php vendor/bin/phpunit -c phpunit.xml --testsuite integration --no-coverage"
- ],
- "coverage": [
- "@php vendor/bin/phpunit -c phpunit.xml --testsuite unit"
- ]
- },
- "config": {
- "platform": {
- "php": "8.2"
+ "require": {
+ "php": ">=8.3",
+ "ext-bcmath": "*",
+ "ext-curl": "*",
+ "ext-fileinfo": "*",
+ "ext-iconv": "*",
+ "ext-intl": "*",
+ "ext-json": "*",
+ "ext-mbstring": "*",
+ "ext-openssl": "*",
+ "ext-pdo": "*",
+ "ext-session": "*",
+ "ext-simplexml": "*",
+ "ext-sodium": "*",
+ "ext-tokenizer": "*",
+ "ext-xml": "*",
+ "ext-xmlwriter": "*",
+ "bacon/bacon-qr-code": "2.*",
+ "diglactic/laravel-breadcrumbs": "^8.1",
+ "doctrine/dbal": "3.*",
+ "gdbots/query-parser": "^3.0",
+ "guzzlehttp/guzzle": "^7.8",
+ "jc5/google2fa-laravel": "^2.0",
+ "jc5/recovery": "^2",
+ "laravel/framework": "^10",
+ "laravel/passport": "11.*",
+ "laravel/sanctum": "^3.3",
+ "laravel/slack-notification-channel": "^3.0",
+ "laravel/ui": "^4.2",
+ "league/commonmark": "2.*",
+ "league/csv": "^9.10",
+ "league/fractal": "0.*",
+ "nunomaduro/collision": "^7.7",
+ "pragmarx/google2fa": "^8.0",
+ "predis/predis": "^2.2",
+ "psr/log": "<4",
+ "ramsey/uuid": "^4.7",
+ "rcrowe/twigbridge": "^0.14",
+ "spatie/laravel-html": "^3.2",
+ "spatie/laravel-ignition": "^2",
+ "spatie/period": "^2.4",
+ "symfony/expression-language": "^6.4",
+ "symfony/http-client": "^7.0",
+ "symfony/mailgun-mailer": "^7.0",
+ "therobfonz/laravel-mandrill-driver": "^5.0"
},
- "preferred-install": "dist",
- "sort-packages": true,
- "optimize-autoloader": true,
- "allow-plugins": {
- "composer/package-versions-deprecated": true
+ "require-dev": {
+ "barryvdh/laravel-debugbar": "^3.9",
+ "barryvdh/laravel-ide-helper": "2.*",
+ "ergebnis/phpstan-rules": "^2.1",
+ "fakerphp/faker": "1.*",
+ "filp/whoops": "2.*",
+ "larastan/larastan": "^2",
+ "mockery/mockery": "1.*",
+ "phpstan/extension-installer": "^1.3",
+ "phpstan/phpstan": "^1.10",
+ "phpstan/phpstan-deprecation-rules": "^1.1",
+ "phpstan/phpstan-strict-rules": "^1.4",
+ "phpunit/phpunit": "^10",
+ "thecodingmachine/phpstan-strict-rules": "^1.0"
+ },
+ "suggest": {},
+ "autoload": {
+ "psr-4": {
+ "FireflyIII\\": "app/",
+ "Domain\\": "domain/",
+ "Database\\Factories\\": "database/factories/",
+ "Database\\Seeders\\": "database/seeders/"
+ }
+ },
+ "autoload-dev": {
+ "psr-4": {
+ "Tests\\": "tests/"
+ }
+ },
+ "extra": {
+ "laravel": {
+ "dont-discover": []
+ },
+ "phpstan": {
+ "includes": [
+ "extension.neon"
+ ]
+ }
+ },
+ "scripts": {
+ "post-root-package-install": [
+ "@php -r \"file_exists('.env') || copy('.env.example', '.env');\""
+ ],
+ "post-create-project-cmd": [
+ "@php artisan key:generate"
+ ],
+ "post-autoload-dump": [
+ "Illuminate\\Foundation\\ComposerScripts::postAutoloadDump"
+ ],
+ "post-update-cmd": [
+ "@php artisan config:clear",
+ "@php artisan route:clear",
+ "@php artisan twig:clean",
+ "@php artisan view:clear",
+ "@php artisan clear-compiled",
+ "@php artisan cache:clear",
+ "@php artisan firefly-iii:upgrade-database",
+ "@php artisan firefly-iii:correct-database",
+ "@php artisan firefly-iii:report-integrity",
+ "@php artisan passport:install",
+ "@php artisan firefly:instructions update"
+ ],
+ "post-install-cmd": [
+ "@php artisan firefly:instructions install",
+ "@php artisan firefly-iii:verify-security-alerts"
+ ],
+ "unit-test": [
+ "@php vendor/bin/phpunit -c phpunit.xml --testsuite unit --no-coverage"
+ ],
+ "integration-test": [
+ "@php vendor/bin/phpunit -c phpunit.xml --testsuite integration --no-coverage"
+ ],
+ "coverage": [
+ "@php vendor/bin/phpunit -c phpunit.xml"
+ ]
+ },
+ "config": {
+ "preferred-install": "dist",
+ "sort-packages": true,
+ "optimize-autoloader": true,
+ "allow-plugins": {
+ "composer/package-versions-deprecated": true,
+ "phpstan/extension-installer": true
+ }
}
- }
}
diff --git a/composer.lock b/composer.lock
index ae7655de64..1b9a6fd3f5 100644
--- a/composer.lock
+++ b/composer.lock
@@ -4,7 +4,7 @@
"Read more about it at https://getcomposer.org/doc/01-basic-usage.md#installing-dependencies",
"This file is @generated automatically"
],
- "content-hash": "2dd09680aeb9e09c15bc6f6f19666952",
+ "content-hash": "1046ba3997e4bfc3802e62f157cd311b",
"packages": [
{
"name": "bacon/bacon-qr-code",
@@ -115,6 +115,75 @@
],
"time": "2023-01-15T23:15:59+00:00"
},
+ {
+ "name": "carbonphp/carbon-doctrine-types",
+ "version": "2.1.0",
+ "source": {
+ "type": "git",
+ "url": "https://github.com/CarbonPHP/carbon-doctrine-types.git",
+ "reference": "99f76ffa36cce3b70a4a6abce41dba15ca2e84cb"
+ },
+ "dist": {
+ "type": "zip",
+ "url": "https://api.github.com/repos/CarbonPHP/carbon-doctrine-types/zipball/99f76ffa36cce3b70a4a6abce41dba15ca2e84cb",
+ "reference": "99f76ffa36cce3b70a4a6abce41dba15ca2e84cb",
+ "shasum": ""
+ },
+ "require": {
+ "php": "^7.4 || ^8.0"
+ },
+ "conflict": {
+ "doctrine/dbal": "<3.7.0 || >=4.0.0"
+ },
+ "require-dev": {
+ "doctrine/dbal": "^3.7.0",
+ "nesbot/carbon": "^2.71.0 || ^3.0.0",
+ "phpunit/phpunit": "^10.3"
+ },
+ "type": "library",
+ "autoload": {
+ "psr-4": {
+ "Carbon\\Doctrine\\": "src/Carbon/Doctrine/"
+ }
+ },
+ "notification-url": "https://packagist.org/downloads/",
+ "license": [
+ "MIT"
+ ],
+ "authors": [
+ {
+ "name": "KyleKatarn",
+ "email": "kylekatarnls@gmail.com"
+ }
+ ],
+ "description": "Types to use Carbon in Doctrine",
+ "keywords": [
+ "carbon",
+ "date",
+ "datetime",
+ "doctrine",
+ "time"
+ ],
+ "support": {
+ "issues": "https://github.com/CarbonPHP/carbon-doctrine-types/issues",
+ "source": "https://github.com/CarbonPHP/carbon-doctrine-types/tree/2.1.0"
+ },
+ "funding": [
+ {
+ "url": "https://github.com/kylekatarnls",
+ "type": "github"
+ },
+ {
+ "url": "https://opencollective.com/Carbon",
+ "type": "open_collective"
+ },
+ {
+ "url": "https://tidelift.com/funding/github/packagist/nesbot/carbon",
+ "type": "tidelift"
+ }
+ ],
+ "time": "2023-12-11T17:09:12+00:00"
+ },
{
"name": "dasprid/enum",
"version": "1.0.5",
@@ -473,16 +542,16 @@
},
{
"name": "doctrine/dbal",
- "version": "3.7.1",
+ "version": "3.8.2",
"source": {
"type": "git",
"url": "https://github.com/doctrine/dbal.git",
- "reference": "5b7bd66c9ff58c04c5474ab85edce442f8081cb2"
+ "reference": "a19a1d05ca211f41089dffcc387733a6875196cb"
},
"dist": {
"type": "zip",
- "url": "https://api.github.com/repos/doctrine/dbal/zipball/5b7bd66c9ff58c04c5474ab85edce442f8081cb2",
- "reference": "5b7bd66c9ff58c04c5474ab85edce442f8081cb2",
+ "url": "https://api.github.com/repos/doctrine/dbal/zipball/a19a1d05ca211f41089dffcc387733a6875196cb",
+ "reference": "a19a1d05ca211f41089dffcc387733a6875196cb",
"shasum": ""
},
"require": {
@@ -498,14 +567,14 @@
"doctrine/coding-standard": "12.0.0",
"fig/log-test": "^1",
"jetbrains/phpstorm-stubs": "2023.1",
- "phpstan/phpstan": "1.10.35",
+ "phpstan/phpstan": "1.10.57",
"phpstan/phpstan-strict-rules": "^1.5",
- "phpunit/phpunit": "9.6.13",
+ "phpunit/phpunit": "9.6.16",
"psalm/plugin-phpunit": "0.18.4",
"slevomat/coding-standard": "8.13.1",
- "squizlabs/php_codesniffer": "3.7.2",
- "symfony/cache": "^5.4|^6.0",
- "symfony/console": "^4.4|^5.4|^6.0",
+ "squizlabs/php_codesniffer": "3.8.1",
+ "symfony/cache": "^5.4|^6.0|^7.0",
+ "symfony/console": "^4.4|^5.4|^6.0|^7.0",
"vimeo/psalm": "4.30.0"
},
"suggest": {
@@ -566,7 +635,7 @@
],
"support": {
"issues": "https://github.com/doctrine/dbal/issues",
- "source": "https://github.com/doctrine/dbal/tree/3.7.1"
+ "source": "https://github.com/doctrine/dbal/tree/3.8.2"
},
"funding": [
{
@@ -582,20 +651,20 @@
"type": "tidelift"
}
],
- "time": "2023-10-06T05:06:20+00:00"
+ "time": "2024-02-12T18:36:36+00:00"
},
{
"name": "doctrine/deprecations",
- "version": "1.1.2",
+ "version": "1.1.3",
"source": {
"type": "git",
"url": "https://github.com/doctrine/deprecations.git",
- "reference": "4f2d4f2836e7ec4e7a8625e75c6aa916004db931"
+ "reference": "dfbaa3c2d2e9a9df1118213f3b8b0c597bb99fab"
},
"dist": {
"type": "zip",
- "url": "https://api.github.com/repos/doctrine/deprecations/zipball/4f2d4f2836e7ec4e7a8625e75c6aa916004db931",
- "reference": "4f2d4f2836e7ec4e7a8625e75c6aa916004db931",
+ "url": "https://api.github.com/repos/doctrine/deprecations/zipball/dfbaa3c2d2e9a9df1118213f3b8b0c597bb99fab",
+ "reference": "dfbaa3c2d2e9a9df1118213f3b8b0c597bb99fab",
"shasum": ""
},
"require": {
@@ -627,9 +696,9 @@
"homepage": "https://www.doctrine-project.org/",
"support": {
"issues": "https://github.com/doctrine/deprecations/issues",
- "source": "https://github.com/doctrine/deprecations/tree/1.1.2"
+ "source": "https://github.com/doctrine/deprecations/tree/1.1.3"
},
- "time": "2023-09-27T20:04:15+00:00"
+ "time": "2024-01-30T19:34:25+00:00"
},
{
"name": "doctrine/event-manager",
@@ -724,16 +793,16 @@
},
{
"name": "doctrine/inflector",
- "version": "2.0.8",
+ "version": "2.0.10",
"source": {
"type": "git",
"url": "https://github.com/doctrine/inflector.git",
- "reference": "f9301a5b2fb1216b2b08f02ba04dc45423db6bff"
+ "reference": "5817d0659c5b50c9b950feb9af7b9668e2c436bc"
},
"dist": {
"type": "zip",
- "url": "https://api.github.com/repos/doctrine/inflector/zipball/f9301a5b2fb1216b2b08f02ba04dc45423db6bff",
- "reference": "f9301a5b2fb1216b2b08f02ba04dc45423db6bff",
+ "url": "https://api.github.com/repos/doctrine/inflector/zipball/5817d0659c5b50c9b950feb9af7b9668e2c436bc",
+ "reference": "5817d0659c5b50c9b950feb9af7b9668e2c436bc",
"shasum": ""
},
"require": {
@@ -795,7 +864,7 @@
],
"support": {
"issues": "https://github.com/doctrine/inflector/issues",
- "source": "https://github.com/doctrine/inflector/tree/2.0.8"
+ "source": "https://github.com/doctrine/inflector/tree/2.0.10"
},
"funding": [
{
@@ -811,31 +880,31 @@
"type": "tidelift"
}
],
- "time": "2023-06-16T13:40:37+00:00"
+ "time": "2024-02-18T20:23:39+00:00"
},
{
"name": "doctrine/lexer",
- "version": "3.0.0",
+ "version": "3.0.1",
"source": {
"type": "git",
"url": "https://github.com/doctrine/lexer.git",
- "reference": "84a527db05647743d50373e0ec53a152f2cde568"
+ "reference": "31ad66abc0fc9e1a1f2d9bc6a42668d2fbbcd6dd"
},
"dist": {
"type": "zip",
- "url": "https://api.github.com/repos/doctrine/lexer/zipball/84a527db05647743d50373e0ec53a152f2cde568",
- "reference": "84a527db05647743d50373e0ec53a152f2cde568",
+ "url": "https://api.github.com/repos/doctrine/lexer/zipball/31ad66abc0fc9e1a1f2d9bc6a42668d2fbbcd6dd",
+ "reference": "31ad66abc0fc9e1a1f2d9bc6a42668d2fbbcd6dd",
"shasum": ""
},
"require": {
"php": "^8.1"
},
"require-dev": {
- "doctrine/coding-standard": "^10",
- "phpstan/phpstan": "^1.9",
- "phpunit/phpunit": "^9.5",
+ "doctrine/coding-standard": "^12",
+ "phpstan/phpstan": "^1.10",
+ "phpunit/phpunit": "^10.5",
"psalm/plugin-phpunit": "^0.18.3",
- "vimeo/psalm": "^5.0"
+ "vimeo/psalm": "^5.21"
},
"type": "library",
"autoload": {
@@ -872,7 +941,7 @@
],
"support": {
"issues": "https://github.com/doctrine/lexer/issues",
- "source": "https://github.com/doctrine/lexer/tree/3.0.0"
+ "source": "https://github.com/doctrine/lexer/tree/3.0.1"
},
"funding": [
{
@@ -888,7 +957,7 @@
"type": "tidelift"
}
],
- "time": "2022-12-15T16:57:16+00:00"
+ "time": "2024-02-05T11:56:58+00:00"
},
{
"name": "dragonmantank/cron-expression",
@@ -1073,16 +1142,16 @@
},
{
"name": "filp/whoops",
- "version": "2.15.3",
+ "version": "2.15.4",
"source": {
"type": "git",
"url": "https://github.com/filp/whoops.git",
- "reference": "c83e88a30524f9360b11f585f71e6b17313b7187"
+ "reference": "a139776fa3f5985a50b509f2a02ff0f709d2a546"
},
"dist": {
"type": "zip",
- "url": "https://api.github.com/repos/filp/whoops/zipball/c83e88a30524f9360b11f585f71e6b17313b7187",
- "reference": "c83e88a30524f9360b11f585f71e6b17313b7187",
+ "url": "https://api.github.com/repos/filp/whoops/zipball/a139776fa3f5985a50b509f2a02ff0f709d2a546",
+ "reference": "a139776fa3f5985a50b509f2a02ff0f709d2a546",
"shasum": ""
},
"require": {
@@ -1132,7 +1201,7 @@
],
"support": {
"issues": "https://github.com/filp/whoops/issues",
- "source": "https://github.com/filp/whoops/tree/2.15.3"
+ "source": "https://github.com/filp/whoops/tree/2.15.4"
},
"funding": [
{
@@ -1140,20 +1209,20 @@
"type": "github"
}
],
- "time": "2023-07-13T12:00:00+00:00"
+ "time": "2023-11-03T12:00:00+00:00"
},
{
"name": "firebase/php-jwt",
- "version": "v6.9.0",
+ "version": "v6.10.0",
"source": {
"type": "git",
"url": "https://github.com/firebase/php-jwt.git",
- "reference": "f03270e63eaccf3019ef0f32849c497385774e11"
+ "reference": "a49db6f0a5033aef5143295342f1c95521b075ff"
},
"dist": {
"type": "zip",
- "url": "https://api.github.com/repos/firebase/php-jwt/zipball/f03270e63eaccf3019ef0f32849c497385774e11",
- "reference": "f03270e63eaccf3019ef0f32849c497385774e11",
+ "url": "https://api.github.com/repos/firebase/php-jwt/zipball/a49db6f0a5033aef5143295342f1c95521b075ff",
+ "reference": "a49db6f0a5033aef5143295342f1c95521b075ff",
"shasum": ""
},
"require": {
@@ -1201,9 +1270,9 @@
],
"support": {
"issues": "https://github.com/firebase/php-jwt/issues",
- "source": "https://github.com/firebase/php-jwt/tree/v6.9.0"
+ "source": "https://github.com/firebase/php-jwt/tree/v6.10.0"
},
- "time": "2023-10-05T00:24:42+00:00"
+ "time": "2023-12-01T16:26:39+00:00"
},
{
"name": "fruitcake/php-cors",
@@ -1317,24 +1386,24 @@
},
{
"name": "graham-campbell/result-type",
- "version": "v1.1.1",
+ "version": "v1.1.2",
"source": {
"type": "git",
"url": "https://github.com/GrahamCampbell/Result-Type.git",
- "reference": "672eff8cf1d6fe1ef09ca0f89c4b287d6a3eb831"
+ "reference": "fbd48bce38f73f8a4ec8583362e732e4095e5862"
},
"dist": {
"type": "zip",
- "url": "https://api.github.com/repos/GrahamCampbell/Result-Type/zipball/672eff8cf1d6fe1ef09ca0f89c4b287d6a3eb831",
- "reference": "672eff8cf1d6fe1ef09ca0f89c4b287d6a3eb831",
+ "url": "https://api.github.com/repos/GrahamCampbell/Result-Type/zipball/fbd48bce38f73f8a4ec8583362e732e4095e5862",
+ "reference": "fbd48bce38f73f8a4ec8583362e732e4095e5862",
"shasum": ""
},
"require": {
"php": "^7.2.5 || ^8.0",
- "phpoption/phpoption": "^1.9.1"
+ "phpoption/phpoption": "^1.9.2"
},
"require-dev": {
- "phpunit/phpunit": "^8.5.32 || ^9.6.3 || ^10.0.12"
+ "phpunit/phpunit": "^8.5.34 || ^9.6.13 || ^10.4.2"
},
"type": "library",
"autoload": {
@@ -1363,7 +1432,7 @@
],
"support": {
"issues": "https://github.com/GrahamCampbell/Result-Type/issues",
- "source": "https://github.com/GrahamCampbell/Result-Type/tree/v1.1.1"
+ "source": "https://github.com/GrahamCampbell/Result-Type/tree/v1.1.2"
},
"funding": [
{
@@ -1375,20 +1444,20 @@
"type": "tidelift"
}
],
- "time": "2023-02-25T20:23:15+00:00"
+ "time": "2023-11-12T22:16:48+00:00"
},
{
"name": "guzzlehttp/guzzle",
- "version": "7.8.0",
+ "version": "7.8.1",
"source": {
"type": "git",
"url": "https://github.com/guzzle/guzzle.git",
- "reference": "1110f66a6530a40fe7aea0378fe608ee2b2248f9"
+ "reference": "41042bc7ab002487b876a0683fc8dce04ddce104"
},
"dist": {
"type": "zip",
- "url": "https://api.github.com/repos/guzzle/guzzle/zipball/1110f66a6530a40fe7aea0378fe608ee2b2248f9",
- "reference": "1110f66a6530a40fe7aea0378fe608ee2b2248f9",
+ "url": "https://api.github.com/repos/guzzle/guzzle/zipball/41042bc7ab002487b876a0683fc8dce04ddce104",
+ "reference": "41042bc7ab002487b876a0683fc8dce04ddce104",
"shasum": ""
},
"require": {
@@ -1403,11 +1472,11 @@
"psr/http-client-implementation": "1.0"
},
"require-dev": {
- "bamarni/composer-bin-plugin": "^1.8.1",
+ "bamarni/composer-bin-plugin": "^1.8.2",
"ext-curl": "*",
"php-http/client-integration-tests": "dev-master#2c025848417c1135031fdf9c728ee53d0a7ceaee as 3.0.999",
"php-http/message-factory": "^1.1",
- "phpunit/phpunit": "^8.5.29 || ^9.5.23",
+ "phpunit/phpunit": "^8.5.36 || ^9.6.15",
"psr/log": "^1.1 || ^2.0 || ^3.0"
},
"suggest": {
@@ -1485,7 +1554,7 @@
],
"support": {
"issues": "https://github.com/guzzle/guzzle/issues",
- "source": "https://github.com/guzzle/guzzle/tree/7.8.0"
+ "source": "https://github.com/guzzle/guzzle/tree/7.8.1"
},
"funding": [
{
@@ -1501,28 +1570,28 @@
"type": "tidelift"
}
],
- "time": "2023-08-27T10:20:53+00:00"
+ "time": "2023-12-03T20:35:24+00:00"
},
{
"name": "guzzlehttp/promises",
- "version": "2.0.1",
+ "version": "2.0.2",
"source": {
"type": "git",
"url": "https://github.com/guzzle/promises.git",
- "reference": "111166291a0f8130081195ac4556a5587d7f1b5d"
+ "reference": "bbff78d96034045e58e13dedd6ad91b5d1253223"
},
"dist": {
"type": "zip",
- "url": "https://api.github.com/repos/guzzle/promises/zipball/111166291a0f8130081195ac4556a5587d7f1b5d",
- "reference": "111166291a0f8130081195ac4556a5587d7f1b5d",
+ "url": "https://api.github.com/repos/guzzle/promises/zipball/bbff78d96034045e58e13dedd6ad91b5d1253223",
+ "reference": "bbff78d96034045e58e13dedd6ad91b5d1253223",
"shasum": ""
},
"require": {
"php": "^7.2.5 || ^8.0"
},
"require-dev": {
- "bamarni/composer-bin-plugin": "^1.8.1",
- "phpunit/phpunit": "^8.5.29 || ^9.5.23"
+ "bamarni/composer-bin-plugin": "^1.8.2",
+ "phpunit/phpunit": "^8.5.36 || ^9.6.15"
},
"type": "library",
"extra": {
@@ -1568,7 +1637,7 @@
],
"support": {
"issues": "https://github.com/guzzle/promises/issues",
- "source": "https://github.com/guzzle/promises/tree/2.0.1"
+ "source": "https://github.com/guzzle/promises/tree/2.0.2"
},
"funding": [
{
@@ -1584,20 +1653,20 @@
"type": "tidelift"
}
],
- "time": "2023-08-03T15:11:55+00:00"
+ "time": "2023-12-03T20:19:20+00:00"
},
{
"name": "guzzlehttp/psr7",
- "version": "2.6.1",
+ "version": "2.6.2",
"source": {
"type": "git",
"url": "https://github.com/guzzle/psr7.git",
- "reference": "be45764272e8873c72dbe3d2edcfdfcc3bc9f727"
+ "reference": "45b30f99ac27b5ca93cb4831afe16285f57b8221"
},
"dist": {
"type": "zip",
- "url": "https://api.github.com/repos/guzzle/psr7/zipball/be45764272e8873c72dbe3d2edcfdfcc3bc9f727",
- "reference": "be45764272e8873c72dbe3d2edcfdfcc3bc9f727",
+ "url": "https://api.github.com/repos/guzzle/psr7/zipball/45b30f99ac27b5ca93cb4831afe16285f57b8221",
+ "reference": "45b30f99ac27b5ca93cb4831afe16285f57b8221",
"shasum": ""
},
"require": {
@@ -1611,9 +1680,9 @@
"psr/http-message-implementation": "1.0"
},
"require-dev": {
- "bamarni/composer-bin-plugin": "^1.8.1",
+ "bamarni/composer-bin-plugin": "^1.8.2",
"http-interop/http-factory-tests": "^0.9",
- "phpunit/phpunit": "^8.5.29 || ^9.5.23"
+ "phpunit/phpunit": "^8.5.36 || ^9.6.15"
},
"suggest": {
"laminas/laminas-httphandlerrunner": "Emit PSR-7 responses"
@@ -1684,7 +1753,7 @@
],
"support": {
"issues": "https://github.com/guzzle/psr7/issues",
- "source": "https://github.com/guzzle/psr7/tree/2.6.1"
+ "source": "https://github.com/guzzle/psr7/tree/2.6.2"
},
"funding": [
{
@@ -1700,32 +1769,38 @@
"type": "tidelift"
}
],
- "time": "2023-08-27T10:13:57+00:00"
+ "time": "2023-12-03T20:05:35+00:00"
},
{
"name": "guzzlehttp/uri-template",
- "version": "v1.0.2",
+ "version": "v1.0.3",
"source": {
"type": "git",
"url": "https://github.com/guzzle/uri-template.git",
- "reference": "61bf437fc2197f587f6857d3ff903a24f1731b5d"
+ "reference": "ecea8feef63bd4fef1f037ecb288386999ecc11c"
},
"dist": {
"type": "zip",
- "url": "https://api.github.com/repos/guzzle/uri-template/zipball/61bf437fc2197f587f6857d3ff903a24f1731b5d",
- "reference": "61bf437fc2197f587f6857d3ff903a24f1731b5d",
+ "url": "https://api.github.com/repos/guzzle/uri-template/zipball/ecea8feef63bd4fef1f037ecb288386999ecc11c",
+ "reference": "ecea8feef63bd4fef1f037ecb288386999ecc11c",
"shasum": ""
},
"require": {
"php": "^7.2.5 || ^8.0",
- "symfony/polyfill-php80": "^1.17"
+ "symfony/polyfill-php80": "^1.24"
},
"require-dev": {
- "bamarni/composer-bin-plugin": "^1.8.1",
- "phpunit/phpunit": "^8.5.19 || ^9.5.8",
+ "bamarni/composer-bin-plugin": "^1.8.2",
+ "phpunit/phpunit": "^8.5.36 || ^9.6.15",
"uri-template/tests": "1.0.0"
},
"type": "library",
+ "extra": {
+ "bamarni-bin": {
+ "bin-links": true,
+ "forward-command": false
+ }
+ },
"autoload": {
"psr-4": {
"GuzzleHttp\\UriTemplate\\": "src"
@@ -1764,7 +1839,7 @@
],
"support": {
"issues": "https://github.com/guzzle/uri-template/issues",
- "source": "https://github.com/guzzle/uri-template/tree/v1.0.2"
+ "source": "https://github.com/guzzle/uri-template/tree/v1.0.3"
},
"funding": [
{
@@ -1780,7 +1855,7 @@
"type": "tidelift"
}
],
- "time": "2023-08-27T10:19:19+00:00"
+ "time": "2023-12-03T19:50:20+00:00"
},
{
"name": "jc5/google2fa-laravel",
@@ -1939,20 +2014,20 @@
},
{
"name": "laravel/framework",
- "version": "v10.28.0",
+ "version": "v10.46.0",
"source": {
"type": "git",
"url": "https://github.com/laravel/framework.git",
- "reference": "09137f50f715c1efc649788a26092dcb1ec4ab6e"
+ "reference": "5e95946a8283a8d5c015035793f9c61c297e937f"
},
"dist": {
"type": "zip",
- "url": "https://api.github.com/repos/laravel/framework/zipball/09137f50f715c1efc649788a26092dcb1ec4ab6e",
- "reference": "09137f50f715c1efc649788a26092dcb1ec4ab6e",
+ "url": "https://api.github.com/repos/laravel/framework/zipball/5e95946a8283a8d5c015035793f9c61c297e937f",
+ "reference": "5e95946a8283a8d5c015035793f9c61c297e937f",
"shasum": ""
},
"require": {
- "brick/math": "^0.9.3|^0.10.2|^0.11",
+ "brick/math": "^0.9.3|^0.10.2|^0.11|^0.12",
"composer-runtime-api": "^2.2",
"doctrine/inflector": "^2.0.5",
"dragonmantank/cron-expression": "^3.3.2",
@@ -1981,7 +2056,7 @@
"symfony/console": "^6.2",
"symfony/error-handler": "^6.2",
"symfony/finder": "^6.2",
- "symfony/http-foundation": "^6.2",
+ "symfony/http-foundation": "^6.4",
"symfony/http-kernel": "^6.2",
"symfony/mailer": "^6.2",
"symfony/mime": "^6.2",
@@ -1994,6 +2069,9 @@
"voku/portable-ascii": "^2.0"
},
"conflict": {
+ "carbonphp/carbon-doctrine-types": ">=3.0",
+ "doctrine/dbal": ">=4.0",
+ "phpunit/phpunit": ">=11.0.0",
"tightenco/collect": "<5.5.33"
},
"provide": {
@@ -2048,13 +2126,15 @@
"league/flysystem-read-only": "^3.3",
"league/flysystem-sftp-v3": "^3.0",
"mockery/mockery": "^1.5.1",
- "orchestra/testbench-core": "^8.12",
+ "nyholm/psr7": "^1.2",
+ "orchestra/testbench-core": "^8.18",
"pda/pheanstalk": "^4.0",
"phpstan/phpstan": "^1.4.7",
"phpunit/phpunit": "^10.0.7",
"predis/predis": "^2.0.2",
"symfony/cache": "^6.2",
- "symfony/http-client": "^6.2.4"
+ "symfony/http-client": "^6.2.4",
+ "symfony/psr-http-message-bridge": "^2.0"
},
"suggest": {
"ably/ably-php": "Required to use the Ably broadcast driver (^1.0).",
@@ -2103,6 +2183,7 @@
"files": [
"src/Illuminate/Collections/helpers.php",
"src/Illuminate/Events/functions.php",
+ "src/Illuminate/Filesystem/functions.php",
"src/Illuminate/Foundation/helpers.php",
"src/Illuminate/Support/helpers.php"
],
@@ -2135,20 +2216,20 @@
"issues": "https://github.com/laravel/framework/issues",
"source": "https://github.com/laravel/framework"
},
- "time": "2023-10-10T13:01:37+00:00"
+ "time": "2024-02-27T16:46:54+00:00"
},
{
"name": "laravel/passport",
- "version": "v11.9.1",
+ "version": "v11.10.5",
"source": {
"type": "git",
"url": "https://github.com/laravel/passport.git",
- "reference": "93bb9c36045fe5be2eaeacf35e836c00b392b761"
+ "reference": "4d81207941d6efc198857847d9e4c17520f28d75"
},
"dist": {
"type": "zip",
- "url": "https://api.github.com/repos/laravel/passport/zipball/93bb9c36045fe5be2eaeacf35e836c00b392b761",
- "reference": "93bb9c36045fe5be2eaeacf35e836c00b392b761",
+ "url": "https://api.github.com/repos/laravel/passport/zipball/4d81207941d6efc198857847d9e4c17520f28d75",
+ "reference": "4d81207941d6efc198857847d9e4c17520f28d75",
"shasum": ""
},
"require": {
@@ -2172,7 +2253,7 @@
},
"require-dev": {
"mockery/mockery": "^1.0",
- "orchestra/testbench": "^7.0|^8.0",
+ "orchestra/testbench": "^7.31|^8.11",
"phpstan/phpstan": "^1.10",
"phpunit/phpunit": "^9.3"
},
@@ -2213,27 +2294,27 @@
"issues": "https://github.com/laravel/passport/issues",
"source": "https://github.com/laravel/passport"
},
- "time": "2023-09-01T14:20:24+00:00"
+ "time": "2024-02-09T16:27:49+00:00"
},
{
"name": "laravel/prompts",
- "version": "v0.1.11",
+ "version": "v0.1.16",
"source": {
"type": "git",
"url": "https://github.com/laravel/prompts.git",
- "reference": "cce65a90e64712909ea1adc033e1d88de8455ffd"
+ "reference": "ca6872ab6aec3ab61db3a61f83a6caf764ec7781"
},
"dist": {
"type": "zip",
- "url": "https://api.github.com/repos/laravel/prompts/zipball/cce65a90e64712909ea1adc033e1d88de8455ffd",
- "reference": "cce65a90e64712909ea1adc033e1d88de8455ffd",
+ "url": "https://api.github.com/repos/laravel/prompts/zipball/ca6872ab6aec3ab61db3a61f83a6caf764ec7781",
+ "reference": "ca6872ab6aec3ab61db3a61f83a6caf764ec7781",
"shasum": ""
},
"require": {
"ext-mbstring": "*",
"illuminate/collections": "^10.0|^11.0",
"php": "^8.1",
- "symfony/console": "^6.2"
+ "symfony/console": "^6.2|^7.0"
},
"conflict": {
"illuminate/console": ">=10.17.0 <10.25.0",
@@ -2242,7 +2323,7 @@
"require-dev": {
"mockery/mockery": "^1.5",
"pestphp/pest": "^2.3",
- "phpstan/phpstan": "^1.10",
+ "phpstan/phpstan": "^1.11",
"phpstan/phpstan-mockery": "^1.1"
},
"suggest": {
@@ -2268,22 +2349,22 @@
],
"support": {
"issues": "https://github.com/laravel/prompts/issues",
- "source": "https://github.com/laravel/prompts/tree/v0.1.11"
+ "source": "https://github.com/laravel/prompts/tree/v0.1.16"
},
- "time": "2023-10-03T01:07:35+00:00"
+ "time": "2024-02-21T19:25:27+00:00"
},
{
"name": "laravel/sanctum",
- "version": "v3.3.1",
+ "version": "v3.3.3",
"source": {
"type": "git",
"url": "https://github.com/laravel/sanctum.git",
- "reference": "338f633e6487e76b255470d3373fbc29228aa971"
+ "reference": "8c104366459739f3ada0e994bcd3e6fd681ce3d5"
},
"dist": {
"type": "zip",
- "url": "https://api.github.com/repos/laravel/sanctum/zipball/338f633e6487e76b255470d3373fbc29228aa971",
- "reference": "338f633e6487e76b255470d3373fbc29228aa971",
+ "url": "https://api.github.com/repos/laravel/sanctum/zipball/8c104366459739f3ada0e994bcd3e6fd681ce3d5",
+ "reference": "8c104366459739f3ada0e994bcd3e6fd681ce3d5",
"shasum": ""
},
"require": {
@@ -2336,20 +2417,20 @@
"issues": "https://github.com/laravel/sanctum/issues",
"source": "https://github.com/laravel/sanctum"
},
- "time": "2023-09-07T15:46:33+00:00"
+ "time": "2023-12-19T18:44:48+00:00"
},
{
"name": "laravel/serializable-closure",
- "version": "v1.3.1",
+ "version": "v1.3.3",
"source": {
"type": "git",
"url": "https://github.com/laravel/serializable-closure.git",
- "reference": "e5a3057a5591e1cfe8183034b0203921abe2c902"
+ "reference": "3dbf8a8e914634c48d389c1234552666b3d43754"
},
"dist": {
"type": "zip",
- "url": "https://api.github.com/repos/laravel/serializable-closure/zipball/e5a3057a5591e1cfe8183034b0203921abe2c902",
- "reference": "e5a3057a5591e1cfe8183034b0203921abe2c902",
+ "url": "https://api.github.com/repos/laravel/serializable-closure/zipball/3dbf8a8e914634c48d389c1234552666b3d43754",
+ "reference": "3dbf8a8e914634c48d389c1234552666b3d43754",
"shasum": ""
},
"require": {
@@ -2396,34 +2477,34 @@
"issues": "https://github.com/laravel/serializable-closure/issues",
"source": "https://github.com/laravel/serializable-closure"
},
- "time": "2023-07-14T13:56:28+00:00"
+ "time": "2023-11-08T14:08:06+00:00"
},
{
"name": "laravel/slack-notification-channel",
- "version": "v3.0.1",
+ "version": "v3.2.0",
"source": {
"type": "git",
"url": "https://github.com/laravel/slack-notification-channel.git",
- "reference": "dc5742f91f10a5ec21d32541ceb509f1e8e4c94f"
+ "reference": "fc8d1873e3db63a480bc57aebb4bf5ec05332d91"
},
"dist": {
"type": "zip",
- "url": "https://api.github.com/repos/laravel/slack-notification-channel/zipball/dc5742f91f10a5ec21d32541ceb509f1e8e4c94f",
- "reference": "dc5742f91f10a5ec21d32541ceb509f1e8e4c94f",
+ "url": "https://api.github.com/repos/laravel/slack-notification-channel/zipball/fc8d1873e3db63a480bc57aebb4bf5ec05332d91",
+ "reference": "fc8d1873e3db63a480bc57aebb4bf5ec05332d91",
"shasum": ""
},
"require": {
"guzzlehttp/guzzle": "^7.0",
- "illuminate/http": "^9.0|^10.0",
- "illuminate/notifications": "^9.0|^10.0",
- "illuminate/support": "^9.0|^10.0",
+ "illuminate/http": "^9.0|^10.0|^11.0",
+ "illuminate/notifications": "^9.0|^10.0|^11.0",
+ "illuminate/support": "^9.0|^10.0|^11.0",
"php": "^8.0"
},
"require-dev": {
"mockery/mockery": "^1.0",
- "orchestra/testbench": "^7.0|^8.0",
+ "orchestra/testbench": "^7.0|^8.0|^9.0",
"phpstan/phpstan": "^1.10",
- "phpunit/phpunit": "^9.0"
+ "phpunit/phpunit": "^9.0|^10.4"
},
"type": "library",
"extra": {
@@ -2459,34 +2540,34 @@
],
"support": {
"issues": "https://github.com/laravel/slack-notification-channel/issues",
- "source": "https://github.com/laravel/slack-notification-channel/tree/v3.0.1"
+ "source": "https://github.com/laravel/slack-notification-channel/tree/v3.2.0"
},
- "time": "2023-07-25T21:12:45+00:00"
+ "time": "2024-01-15T20:07:45+00:00"
},
{
"name": "laravel/ui",
- "version": "v4.2.2",
+ "version": "v4.4.0",
"source": {
"type": "git",
"url": "https://github.com/laravel/ui.git",
- "reference": "a58ec468db4a340b33f3426c778784717a2c144b"
+ "reference": "7335d7049b2cde345c029e9d2de839b80af62bc0"
},
"dist": {
"type": "zip",
- "url": "https://api.github.com/repos/laravel/ui/zipball/a58ec468db4a340b33f3426c778784717a2c144b",
- "reference": "a58ec468db4a340b33f3426c778784717a2c144b",
+ "url": "https://api.github.com/repos/laravel/ui/zipball/7335d7049b2cde345c029e9d2de839b80af62bc0",
+ "reference": "7335d7049b2cde345c029e9d2de839b80af62bc0",
"shasum": ""
},
"require": {
- "illuminate/console": "^9.21|^10.0",
- "illuminate/filesystem": "^9.21|^10.0",
- "illuminate/support": "^9.21|^10.0",
- "illuminate/validation": "^9.21|^10.0",
+ "illuminate/console": "^9.21|^10.0|^11.0",
+ "illuminate/filesystem": "^9.21|^10.0|^11.0",
+ "illuminate/support": "^9.21|^10.0|^11.0",
+ "illuminate/validation": "^9.21|^10.0|^11.0",
"php": "^8.0"
},
"require-dev": {
- "orchestra/testbench": "^7.0|^8.0",
- "phpunit/phpunit": "^9.3"
+ "orchestra/testbench": "^7.0|^8.0|^9.0",
+ "phpunit/phpunit": "^9.3|^10.4"
},
"type": "library",
"extra": {
@@ -2521,40 +2602,40 @@
"ui"
],
"support": {
- "source": "https://github.com/laravel/ui/tree/v4.2.2"
+ "source": "https://github.com/laravel/ui/tree/v4.4.0"
},
- "time": "2023-05-09T19:47:28+00:00"
+ "time": "2024-01-12T15:56:45+00:00"
},
{
"name": "lcobucci/clock",
- "version": "3.1.0",
+ "version": "3.2.0",
"source": {
"type": "git",
"url": "https://github.com/lcobucci/clock.git",
- "reference": "30a854ceb22bd87d83a7a4563b3f6312453945fc"
+ "reference": "6f28b826ea01306b07980cb8320ab30b966cd715"
},
"dist": {
"type": "zip",
- "url": "https://api.github.com/repos/lcobucci/clock/zipball/30a854ceb22bd87d83a7a4563b3f6312453945fc",
- "reference": "30a854ceb22bd87d83a7a4563b3f6312453945fc",
+ "url": "https://api.github.com/repos/lcobucci/clock/zipball/6f28b826ea01306b07980cb8320ab30b966cd715",
+ "reference": "6f28b826ea01306b07980cb8320ab30b966cd715",
"shasum": ""
},
"require": {
- "php": "~8.2.0",
+ "php": "~8.2.0 || ~8.3.0",
"psr/clock": "^1.0"
},
"provide": {
"psr/clock-implementation": "1.0"
},
"require-dev": {
- "infection/infection": "^0.26",
- "lcobucci/coding-standard": "^10.0.0",
- "phpstan/extension-installer": "^1.2",
- "phpstan/phpstan": "^1.10.7",
+ "infection/infection": "^0.27",
+ "lcobucci/coding-standard": "^11.0.0",
+ "phpstan/extension-installer": "^1.3.1",
+ "phpstan/phpstan": "^1.10.25",
"phpstan/phpstan-deprecation-rules": "^1.1.3",
- "phpstan/phpstan-phpunit": "^1.3.10",
- "phpstan/phpstan-strict-rules": "^1.5.0",
- "phpunit/phpunit": "^10.0.17"
+ "phpstan/phpstan-phpunit": "^1.3.13",
+ "phpstan/phpstan-strict-rules": "^1.5.1",
+ "phpunit/phpunit": "^10.2.3"
},
"type": "library",
"autoload": {
@@ -2575,7 +2656,7 @@
"description": "Yet another clock abstraction",
"support": {
"issues": "https://github.com/lcobucci/clock/issues",
- "source": "https://github.com/lcobucci/clock/tree/3.1.0"
+ "source": "https://github.com/lcobucci/clock/tree/3.2.0"
},
"funding": [
{
@@ -2587,41 +2668,39 @@
"type": "patreon"
}
],
- "time": "2023-03-20T19:12:25+00:00"
+ "time": "2023-11-17T17:00:27+00:00"
},
{
"name": "lcobucci/jwt",
- "version": "5.0.0",
+ "version": "5.2.0",
"source": {
"type": "git",
"url": "https://github.com/lcobucci/jwt.git",
- "reference": "47bdb0e0b5d00c2f89ebe33e7e384c77e84e7c34"
+ "reference": "0ba88aed12c04bd2ed9924f500673f32b67a6211"
},
"dist": {
"type": "zip",
- "url": "https://api.github.com/repos/lcobucci/jwt/zipball/47bdb0e0b5d00c2f89ebe33e7e384c77e84e7c34",
- "reference": "47bdb0e0b5d00c2f89ebe33e7e384c77e84e7c34",
+ "url": "https://api.github.com/repos/lcobucci/jwt/zipball/0ba88aed12c04bd2ed9924f500673f32b67a6211",
+ "reference": "0ba88aed12c04bd2ed9924f500673f32b67a6211",
"shasum": ""
},
"require": {
- "ext-hash": "*",
- "ext-json": "*",
"ext-openssl": "*",
"ext-sodium": "*",
- "php": "~8.1.0 || ~8.2.0",
+ "php": "~8.1.0 || ~8.2.0 || ~8.3.0",
"psr/clock": "^1.0"
},
"require-dev": {
- "infection/infection": "^0.26.19",
+ "infection/infection": "^0.27.0",
"lcobucci/clock": "^3.0",
- "lcobucci/coding-standard": "^9.0",
- "phpbench/phpbench": "^1.2.8",
+ "lcobucci/coding-standard": "^11.0",
+ "phpbench/phpbench": "^1.2.9",
"phpstan/extension-installer": "^1.2",
- "phpstan/phpstan": "^1.10.3",
- "phpstan/phpstan-deprecation-rules": "^1.1.2",
- "phpstan/phpstan-phpunit": "^1.3.8",
+ "phpstan/phpstan": "^1.10.7",
+ "phpstan/phpstan-deprecation-rules": "^1.1.3",
+ "phpstan/phpstan-phpunit": "^1.3.10",
"phpstan/phpstan-strict-rules": "^1.5.0",
- "phpunit/phpunit": "^10.0.12"
+ "phpunit/phpunit": "^10.2.6"
},
"suggest": {
"lcobucci/clock": ">= 3.0"
@@ -2650,7 +2729,7 @@
],
"support": {
"issues": "https://github.com/lcobucci/jwt/issues",
- "source": "https://github.com/lcobucci/jwt/tree/5.0.0"
+ "source": "https://github.com/lcobucci/jwt/tree/5.2.0"
},
"funding": [
{
@@ -2662,20 +2741,20 @@
"type": "patreon"
}
],
- "time": "2023-02-25T21:35:16+00:00"
+ "time": "2023-11-20T21:17:42+00:00"
},
{
"name": "league/commonmark",
- "version": "2.4.1",
+ "version": "2.4.2",
"source": {
"type": "git",
"url": "https://github.com/thephpleague/commonmark.git",
- "reference": "3669d6d5f7a47a93c08ddff335e6d945481a1dd5"
+ "reference": "91c24291965bd6d7c46c46a12ba7492f83b1cadf"
},
"dist": {
"type": "zip",
- "url": "https://api.github.com/repos/thephpleague/commonmark/zipball/3669d6d5f7a47a93c08ddff335e6d945481a1dd5",
- "reference": "3669d6d5f7a47a93c08ddff335e6d945481a1dd5",
+ "url": "https://api.github.com/repos/thephpleague/commonmark/zipball/91c24291965bd6d7c46c46a12ba7492f83b1cadf",
+ "reference": "91c24291965bd6d7c46c46a12ba7492f83b1cadf",
"shasum": ""
},
"require": {
@@ -2688,7 +2767,7 @@
},
"require-dev": {
"cebe/markdown": "^1.0",
- "commonmark/cmark": "0.30.0",
+ "commonmark/cmark": "0.30.3",
"commonmark/commonmark.js": "0.30.0",
"composer/package-versions-deprecated": "^1.8",
"embed/embed": "^4.4",
@@ -2698,10 +2777,10 @@
"michelf/php-markdown": "^1.4 || ^2.0",
"nyholm/psr7": "^1.5",
"phpstan/phpstan": "^1.8.2",
- "phpunit/phpunit": "^9.5.21",
+ "phpunit/phpunit": "^9.5.21 || ^10.5.9 || ^11.0.0",
"scrutinizer/ocular": "^1.8.1",
- "symfony/finder": "^5.3 | ^6.0",
- "symfony/yaml": "^2.3 | ^3.0 | ^4.0 | ^5.0 | ^6.0",
+ "symfony/finder": "^5.3 | ^6.0 || ^7.0",
+ "symfony/yaml": "^2.3 | ^3.0 | ^4.0 | ^5.0 | ^6.0 || ^7.0",
"unleashedtech/php-coding-standard": "^3.1.1",
"vimeo/psalm": "^4.24.0 || ^5.0.0"
},
@@ -2768,7 +2847,7 @@
"type": "tidelift"
}
],
- "time": "2023-08-30T16:55:00+00:00"
+ "time": "2024-02-02T11:59:32+00:00"
},
{
"name": "league/config",
@@ -2854,35 +2933,36 @@
},
{
"name": "league/csv",
- "version": "9.11.0",
+ "version": "9.15.0",
"source": {
"type": "git",
"url": "https://github.com/thephpleague/csv.git",
- "reference": "33149c4bea4949aa4fa3d03fb11ed28682168b39"
+ "reference": "fa7e2441c0bc9b2360f4314fd6c954f7ff40d435"
},
"dist": {
"type": "zip",
- "url": "https://api.github.com/repos/thephpleague/csv/zipball/33149c4bea4949aa4fa3d03fb11ed28682168b39",
- "reference": "33149c4bea4949aa4fa3d03fb11ed28682168b39",
+ "url": "https://api.github.com/repos/thephpleague/csv/zipball/fa7e2441c0bc9b2360f4314fd6c954f7ff40d435",
+ "reference": "fa7e2441c0bc9b2360f4314fd6c954f7ff40d435",
"shasum": ""
},
"require": {
+ "ext-filter": "*",
"ext-json": "*",
"ext-mbstring": "*",
"php": "^8.1.2"
},
"require-dev": {
- "doctrine/collections": "^2.1.3",
+ "doctrine/collections": "^2.1.4",
"ext-dom": "*",
"ext-xdebug": "*",
"friendsofphp/php-cs-fixer": "^v3.22.0",
- "phpbench/phpbench": "^1.2.14",
- "phpstan/phpstan": "^1.10.26",
- "phpstan/phpstan-deprecation-rules": "^1.1.3",
- "phpstan/phpstan-phpunit": "^1.3.13",
- "phpstan/phpstan-strict-rules": "^1.5.1",
- "phpunit/phpunit": "^10.3.1",
- "symfony/var-dumper": "^6.3.3"
+ "phpbench/phpbench": "^1.2.15",
+ "phpstan/phpstan": "^1.10.57",
+ "phpstan/phpstan-deprecation-rules": "^1.1.4",
+ "phpstan/phpstan-phpunit": "^1.3.15",
+ "phpstan/phpstan-strict-rules": "^1.5.2",
+ "phpunit/phpunit": "^10.5.9",
+ "symfony/var-dumper": "^6.4.2"
},
"suggest": {
"ext-dom": "Required to use the XMLConverter and the HTMLConverter classes",
@@ -2938,7 +3018,7 @@
"type": "github"
}
],
- "time": "2023-09-23T10:09:54+00:00"
+ "time": "2024-02-20T20:00:00+00:00"
},
{
"name": "league/event",
@@ -2996,16 +3076,16 @@
},
{
"name": "league/flysystem",
- "version": "3.17.0",
+ "version": "3.24.0",
"source": {
"type": "git",
"url": "https://github.com/thephpleague/flysystem.git",
- "reference": "bd4c9b26849d82364119c68429541f1631fba94b"
+ "reference": "b25a361508c407563b34fac6f64a8a17a8819675"
},
"dist": {
"type": "zip",
- "url": "https://api.github.com/repos/thephpleague/flysystem/zipball/bd4c9b26849d82364119c68429541f1631fba94b",
- "reference": "bd4c9b26849d82364119c68429541f1631fba94b",
+ "url": "https://api.github.com/repos/thephpleague/flysystem/zipball/b25a361508c407563b34fac6f64a8a17a8819675",
+ "reference": "b25a361508c407563b34fac6f64a8a17a8819675",
"shasum": ""
},
"require": {
@@ -3025,7 +3105,7 @@
"require-dev": {
"async-aws/s3": "^1.5 || ^2.0",
"async-aws/simple-s3": "^1.1 || ^2.0",
- "aws/aws-sdk-php": "^3.220.0",
+ "aws/aws-sdk-php": "^3.295.10",
"composer/semver": "^3.0",
"ext-fileinfo": "*",
"ext-ftp": "*",
@@ -3033,10 +3113,10 @@
"friendsofphp/php-cs-fixer": "^3.5",
"google/cloud-storage": "^1.23",
"microsoft/azure-storage-blob": "^1.1",
- "phpseclib/phpseclib": "^3.0.14",
- "phpstan/phpstan": "^0.12.26",
+ "phpseclib/phpseclib": "^3.0.34",
+ "phpstan/phpstan": "^1.10",
"phpunit/phpunit": "^9.5.11|^10.0",
- "sabre/dav": "^4.3.1"
+ "sabre/dav": "^4.6.0"
},
"type": "library",
"autoload": {
@@ -3070,7 +3150,7 @@
],
"support": {
"issues": "https://github.com/thephpleague/flysystem/issues",
- "source": "https://github.com/thephpleague/flysystem/tree/3.17.0"
+ "source": "https://github.com/thephpleague/flysystem/tree/3.24.0"
},
"funding": [
{
@@ -3082,20 +3162,20 @@
"type": "github"
}
],
- "time": "2023-10-05T20:15:05+00:00"
+ "time": "2024-02-04T12:10:17+00:00"
},
{
"name": "league/flysystem-local",
- "version": "3.16.0",
+ "version": "3.23.1",
"source": {
"type": "git",
"url": "https://github.com/thephpleague/flysystem-local.git",
- "reference": "ec7383f25642e6fd4bb0c9554fc2311245391781"
+ "reference": "b884d2bf9b53bb4804a56d2df4902bb51e253f00"
},
"dist": {
"type": "zip",
- "url": "https://api.github.com/repos/thephpleague/flysystem-local/zipball/ec7383f25642e6fd4bb0c9554fc2311245391781",
- "reference": "ec7383f25642e6fd4bb0c9554fc2311245391781",
+ "url": "https://api.github.com/repos/thephpleague/flysystem-local/zipball/b884d2bf9b53bb4804a56d2df4902bb51e253f00",
+ "reference": "b884d2bf9b53bb4804a56d2df4902bb51e253f00",
"shasum": ""
},
"require": {
@@ -3130,7 +3210,7 @@
],
"support": {
"issues": "https://github.com/thephpleague/flysystem-local/issues",
- "source": "https://github.com/thephpleague/flysystem-local/tree/3.16.0"
+ "source": "https://github.com/thephpleague/flysystem-local/tree/3.23.1"
},
"funding": [
{
@@ -3142,7 +3222,7 @@
"type": "github"
}
],
- "time": "2023-08-30T10:23:59+00:00"
+ "time": "2024-01-26T18:25:23+00:00"
},
{
"name": "league/fractal",
@@ -3216,16 +3296,16 @@
},
{
"name": "league/mime-type-detection",
- "version": "1.13.0",
+ "version": "1.15.0",
"source": {
"type": "git",
"url": "https://github.com/thephpleague/mime-type-detection.git",
- "reference": "a6dfb1194a2946fcdc1f38219445234f65b35c96"
+ "reference": "ce0f4d1e8a6f4eb0ddff33f57c69c50fd09f4301"
},
"dist": {
"type": "zip",
- "url": "https://api.github.com/repos/thephpleague/mime-type-detection/zipball/a6dfb1194a2946fcdc1f38219445234f65b35c96",
- "reference": "a6dfb1194a2946fcdc1f38219445234f65b35c96",
+ "url": "https://api.github.com/repos/thephpleague/mime-type-detection/zipball/ce0f4d1e8a6f4eb0ddff33f57c69c50fd09f4301",
+ "reference": "ce0f4d1e8a6f4eb0ddff33f57c69c50fd09f4301",
"shasum": ""
},
"require": {
@@ -3256,7 +3336,7 @@
"description": "Mime-type detection for Flysystem",
"support": {
"issues": "https://github.com/thephpleague/mime-type-detection/issues",
- "source": "https://github.com/thephpleague/mime-type-detection/tree/1.13.0"
+ "source": "https://github.com/thephpleague/mime-type-detection/tree/1.15.0"
},
"funding": [
{
@@ -3268,7 +3348,7 @@
"type": "tidelift"
}
],
- "time": "2023-08-05T12:09:49+00:00"
+ "time": "2024-01-28T23:22:08+00:00"
},
{
"name": "league/oauth2-server",
@@ -3360,16 +3440,16 @@
},
{
"name": "league/uri",
- "version": "7.3.0",
+ "version": "7.4.0",
"source": {
"type": "git",
"url": "https://github.com/thephpleague/uri.git",
- "reference": "36743c3961bb82bf93da91917b6bced0358a8d45"
+ "reference": "bf414ba956d902f5d98bf9385fcf63954f09dce5"
},
"dist": {
"type": "zip",
- "url": "https://api.github.com/repos/thephpleague/uri/zipball/36743c3961bb82bf93da91917b6bced0358a8d45",
- "reference": "36743c3961bb82bf93da91917b6bced0358a8d45",
+ "url": "https://api.github.com/repos/thephpleague/uri/zipball/bf414ba956d902f5d98bf9385fcf63954f09dce5",
+ "reference": "bf414ba956d902f5d98bf9385fcf63954f09dce5",
"shasum": ""
},
"require": {
@@ -3438,7 +3518,7 @@
"docs": "https://uri.thephpleague.com",
"forum": "https://thephpleague.slack.com",
"issues": "https://github.com/thephpleague/uri-src/issues",
- "source": "https://github.com/thephpleague/uri/tree/7.3.0"
+ "source": "https://github.com/thephpleague/uri/tree/7.4.0"
},
"funding": [
{
@@ -3446,20 +3526,20 @@
"type": "github"
}
],
- "time": "2023-09-09T17:21:43+00:00"
+ "time": "2023-12-01T06:24:25+00:00"
},
{
"name": "league/uri-interfaces",
- "version": "7.3.0",
+ "version": "7.4.0",
"source": {
"type": "git",
"url": "https://github.com/thephpleague/uri-interfaces.git",
- "reference": "c409b60ed2245ff94c965a8c798a60166db53361"
+ "reference": "bd8c487ec236930f7bbc42b8d374fa882fbba0f3"
},
"dist": {
"type": "zip",
- "url": "https://api.github.com/repos/thephpleague/uri-interfaces/zipball/c409b60ed2245ff94c965a8c798a60166db53361",
- "reference": "c409b60ed2245ff94c965a8c798a60166db53361",
+ "url": "https://api.github.com/repos/thephpleague/uri-interfaces/zipball/bd8c487ec236930f7bbc42b8d374fa882fbba0f3",
+ "reference": "bd8c487ec236930f7bbc42b8d374fa882fbba0f3",
"shasum": ""
},
"require": {
@@ -3522,7 +3602,7 @@
"docs": "https://uri.thephpleague.com",
"forum": "https://thephpleague.slack.com",
"issues": "https://github.com/thephpleague/uri-src/issues",
- "source": "https://github.com/thephpleague/uri-interfaces/tree/7.3.0"
+ "source": "https://github.com/thephpleague/uri-interfaces/tree/7.4.0"
},
"funding": [
{
@@ -3530,20 +3610,20 @@
"type": "github"
}
],
- "time": "2023-09-09T17:21:43+00:00"
+ "time": "2023-11-24T15:40:42+00:00"
},
{
"name": "mailchimp/transactional",
- "version": "1.0.50",
+ "version": "1.0.59",
"source": {
"type": "git",
"url": "https://github.com/mailchimp/mailchimp-transactional-php.git",
- "reference": "701b00f538f36a2a5b138f880ab5eebbfeff4b7d"
+ "reference": "1783927027820dc1c624fd04abf5012a57f96feb"
},
"dist": {
"type": "zip",
- "url": "https://api.github.com/repos/mailchimp/mailchimp-transactional-php/zipball/701b00f538f36a2a5b138f880ab5eebbfeff4b7d",
- "reference": "701b00f538f36a2a5b138f880ab5eebbfeff4b7d",
+ "url": "https://api.github.com/repos/mailchimp/mailchimp-transactional-php/zipball/1783927027820dc1c624fd04abf5012a57f96feb",
+ "reference": "1783927027820dc1c624fd04abf5012a57f96feb",
"shasum": ""
},
"require": {
@@ -3582,22 +3662,22 @@
"swagger"
],
"support": {
- "source": "https://github.com/mailchimp/mailchimp-transactional-php/tree/v1.0.50"
+ "source": "https://github.com/mailchimp/mailchimp-transactional-php/tree/v1.0.59"
},
- "time": "2022-11-07T20:12:03+00:00"
+ "time": "2024-02-10T01:12:26+00:00"
},
{
"name": "monolog/monolog",
- "version": "3.4.0",
+ "version": "3.5.0",
"source": {
"type": "git",
"url": "https://github.com/Seldaek/monolog.git",
- "reference": "e2392369686d420ca32df3803de28b5d6f76867d"
+ "reference": "c915e2634718dbc8a4a15c61b0e62e7a44e14448"
},
"dist": {
"type": "zip",
- "url": "https://api.github.com/repos/Seldaek/monolog/zipball/e2392369686d420ca32df3803de28b5d6f76867d",
- "reference": "e2392369686d420ca32df3803de28b5d6f76867d",
+ "url": "https://api.github.com/repos/Seldaek/monolog/zipball/c915e2634718dbc8a4a15c61b0e62e7a44e14448",
+ "reference": "c915e2634718dbc8a4a15c61b0e62e7a44e14448",
"shasum": ""
},
"require": {
@@ -3673,7 +3753,7 @@
],
"support": {
"issues": "https://github.com/Seldaek/monolog/issues",
- "source": "https://github.com/Seldaek/monolog/tree/3.4.0"
+ "source": "https://github.com/Seldaek/monolog/tree/3.5.0"
},
"funding": [
{
@@ -3685,23 +3765,24 @@
"type": "tidelift"
}
],
- "time": "2023-06-21T08:46:11+00:00"
+ "time": "2023-10-27T15:32:31+00:00"
},
{
"name": "nesbot/carbon",
- "version": "2.71.0",
+ "version": "2.72.3",
"source": {
"type": "git",
"url": "https://github.com/briannesbitt/Carbon.git",
- "reference": "98276233188583f2ff845a0f992a235472d9466a"
+ "reference": "0c6fd108360c562f6e4fd1dedb8233b423e91c83"
},
"dist": {
"type": "zip",
- "url": "https://api.github.com/repos/briannesbitt/Carbon/zipball/98276233188583f2ff845a0f992a235472d9466a",
- "reference": "98276233188583f2ff845a0f992a235472d9466a",
+ "url": "https://api.github.com/repos/briannesbitt/Carbon/zipball/0c6fd108360c562f6e4fd1dedb8233b423e91c83",
+ "reference": "0c6fd108360c562f6e4fd1dedb8233b423e91c83",
"shasum": ""
},
"require": {
+ "carbonphp/carbon-doctrine-types": "*",
"ext-json": "*",
"php": "^7.1.8 || ^8.0",
"psr/clock": "^1.0",
@@ -3713,8 +3794,8 @@
"psr/clock-implementation": "1.0"
},
"require-dev": {
- "doctrine/dbal": "^2.0 || ^3.1.4",
- "doctrine/orm": "^2.7",
+ "doctrine/dbal": "^2.0 || ^3.1.4 || ^4.0",
+ "doctrine/orm": "^2.7 || ^3.0",
"friendsofphp/php-cs-fixer": "^3.0",
"kylekatarnls/multi-tester": "^2.0",
"ondrejmirtes/better-reflection": "*",
@@ -3791,35 +3872,35 @@
"type": "tidelift"
}
],
- "time": "2023-09-25T11:31:05+00:00"
+ "time": "2024-01-25T10:35:09+00:00"
},
{
"name": "nette/schema",
- "version": "v1.2.5",
+ "version": "v1.3.0",
"source": {
"type": "git",
"url": "https://github.com/nette/schema.git",
- "reference": "0462f0166e823aad657c9224d0f849ecac1ba10a"
+ "reference": "a6d3a6d1f545f01ef38e60f375d1cf1f4de98188"
},
"dist": {
"type": "zip",
- "url": "https://api.github.com/repos/nette/schema/zipball/0462f0166e823aad657c9224d0f849ecac1ba10a",
- "reference": "0462f0166e823aad657c9224d0f849ecac1ba10a",
+ "url": "https://api.github.com/repos/nette/schema/zipball/a6d3a6d1f545f01ef38e60f375d1cf1f4de98188",
+ "reference": "a6d3a6d1f545f01ef38e60f375d1cf1f4de98188",
"shasum": ""
},
"require": {
- "nette/utils": "^2.5.7 || ^3.1.5 || ^4.0",
- "php": "7.1 - 8.3"
+ "nette/utils": "^4.0",
+ "php": "8.1 - 8.3"
},
"require-dev": {
- "nette/tester": "^2.3 || ^2.4",
+ "nette/tester": "^2.4",
"phpstan/phpstan-nette": "^1.0",
- "tracy/tracy": "^2.7"
+ "tracy/tracy": "^2.8"
},
"type": "library",
"extra": {
"branch-alias": {
- "dev-master": "1.2-dev"
+ "dev-master": "1.3-dev"
}
},
"autoload": {
@@ -3851,22 +3932,22 @@
],
"support": {
"issues": "https://github.com/nette/schema/issues",
- "source": "https://github.com/nette/schema/tree/v1.2.5"
+ "source": "https://github.com/nette/schema/tree/v1.3.0"
},
- "time": "2023-10-05T20:37:59+00:00"
+ "time": "2023-12-11T11:54:22+00:00"
},
{
"name": "nette/utils",
- "version": "v4.0.2",
+ "version": "v4.0.4",
"source": {
"type": "git",
"url": "https://github.com/nette/utils.git",
- "reference": "cead6637226456b35e1175cc53797dd585d85545"
+ "reference": "d3ad0aa3b9f934602cb3e3902ebccf10be34d218"
},
"dist": {
"type": "zip",
- "url": "https://api.github.com/repos/nette/utils/zipball/cead6637226456b35e1175cc53797dd585d85545",
- "reference": "cead6637226456b35e1175cc53797dd585d85545",
+ "url": "https://api.github.com/repos/nette/utils/zipball/d3ad0aa3b9f934602cb3e3902ebccf10be34d218",
+ "reference": "d3ad0aa3b9f934602cb3e3902ebccf10be34d218",
"shasum": ""
},
"require": {
@@ -3937,9 +4018,9 @@
],
"support": {
"issues": "https://github.com/nette/utils/issues",
- "source": "https://github.com/nette/utils/tree/v4.0.2"
+ "source": "https://github.com/nette/utils/tree/v4.0.4"
},
- "time": "2023-09-19T11:58:07+00:00"
+ "time": "2024-01-17T16:50:36+00:00"
},
{
"name": "nunomaduro/collision",
@@ -4125,16 +4206,16 @@
},
{
"name": "nyholm/psr7",
- "version": "1.8.0",
+ "version": "1.8.1",
"source": {
"type": "git",
"url": "https://github.com/Nyholm/psr7.git",
- "reference": "3cb4d163b58589e47b35103e8e5e6a6a475b47be"
+ "reference": "aa5fc277a4f5508013d571341ade0c3886d4d00e"
},
"dist": {
"type": "zip",
- "url": "https://api.github.com/repos/Nyholm/psr7/zipball/3cb4d163b58589e47b35103e8e5e6a6a475b47be",
- "reference": "3cb4d163b58589e47b35103e8e5e6a6a475b47be",
+ "url": "https://api.github.com/repos/Nyholm/psr7/zipball/aa5fc277a4f5508013d571341ade0c3886d4d00e",
+ "reference": "aa5fc277a4f5508013d571341ade0c3886d4d00e",
"shasum": ""
},
"require": {
@@ -4187,7 +4268,7 @@
],
"support": {
"issues": "https://github.com/Nyholm/psr7/issues",
- "source": "https://github.com/Nyholm/psr7/tree/1.8.0"
+ "source": "https://github.com/Nyholm/psr7/tree/1.8.1"
},
"funding": [
{
@@ -4199,7 +4280,7 @@
"type": "github"
}
],
- "time": "2023-05-02T11:26:24+00:00"
+ "time": "2023-11-13T09:31:12+00:00"
},
{
"name": "paragonie/constant_time_encoding",
@@ -4320,16 +4401,16 @@
},
{
"name": "phpoption/phpoption",
- "version": "1.9.1",
+ "version": "1.9.2",
"source": {
"type": "git",
"url": "https://github.com/schmittjoh/php-option.git",
- "reference": "dd3a383e599f49777d8b628dadbb90cae435b87e"
+ "reference": "80735db690fe4fc5c76dfa7f9b770634285fa820"
},
"dist": {
"type": "zip",
- "url": "https://api.github.com/repos/schmittjoh/php-option/zipball/dd3a383e599f49777d8b628dadbb90cae435b87e",
- "reference": "dd3a383e599f49777d8b628dadbb90cae435b87e",
+ "url": "https://api.github.com/repos/schmittjoh/php-option/zipball/80735db690fe4fc5c76dfa7f9b770634285fa820",
+ "reference": "80735db690fe4fc5c76dfa7f9b770634285fa820",
"shasum": ""
},
"require": {
@@ -4337,7 +4418,7 @@
},
"require-dev": {
"bamarni/composer-bin-plugin": "^1.8.2",
- "phpunit/phpunit": "^8.5.32 || ^9.6.3 || ^10.0.12"
+ "phpunit/phpunit": "^8.5.34 || ^9.6.13 || ^10.4.2"
},
"type": "library",
"extra": {
@@ -4379,7 +4460,7 @@
],
"support": {
"issues": "https://github.com/schmittjoh/php-option/issues",
- "source": "https://github.com/schmittjoh/php-option/tree/1.9.1"
+ "source": "https://github.com/schmittjoh/php-option/tree/1.9.2"
},
"funding": [
{
@@ -4391,20 +4472,20 @@
"type": "tidelift"
}
],
- "time": "2023-02-25T19:38:58+00:00"
+ "time": "2023-11-12T21:59:55+00:00"
},
{
"name": "phpseclib/phpseclib",
- "version": "3.0.23",
+ "version": "3.0.36",
"source": {
"type": "git",
"url": "https://github.com/phpseclib/phpseclib.git",
- "reference": "866cc78fbd82462ffd880e3f65692afe928bed50"
+ "reference": "c2fb5136162d4be18fdd4da9980696f3aee96d7b"
},
"dist": {
"type": "zip",
- "url": "https://api.github.com/repos/phpseclib/phpseclib/zipball/866cc78fbd82462ffd880e3f65692afe928bed50",
- "reference": "866cc78fbd82462ffd880e3f65692afe928bed50",
+ "url": "https://api.github.com/repos/phpseclib/phpseclib/zipball/c2fb5136162d4be18fdd4da9980696f3aee96d7b",
+ "reference": "c2fb5136162d4be18fdd4da9980696f3aee96d7b",
"shasum": ""
},
"require": {
@@ -4485,7 +4566,7 @@
],
"support": {
"issues": "https://github.com/phpseclib/phpseclib/issues",
- "source": "https://github.com/phpseclib/phpseclib/tree/3.0.23"
+ "source": "https://github.com/phpseclib/phpseclib/tree/3.0.36"
},
"funding": [
{
@@ -4501,7 +4582,7 @@
"type": "tidelift"
}
],
- "time": "2023-09-18T17:22:01+00:00"
+ "time": "2024-02-26T05:13:14+00:00"
},
{
"name": "pragmarx/google2fa",
@@ -5341,16 +5422,16 @@
},
{
"name": "ramsey/uuid",
- "version": "4.7.4",
+ "version": "4.7.5",
"source": {
"type": "git",
"url": "https://github.com/ramsey/uuid.git",
- "reference": "60a4c63ab724854332900504274f6150ff26d286"
+ "reference": "5f0df49ae5ad6efb7afa69e6bfab4e5b1e080d8e"
},
"dist": {
"type": "zip",
- "url": "https://api.github.com/repos/ramsey/uuid/zipball/60a4c63ab724854332900504274f6150ff26d286",
- "reference": "60a4c63ab724854332900504274f6150ff26d286",
+ "url": "https://api.github.com/repos/ramsey/uuid/zipball/5f0df49ae5ad6efb7afa69e6bfab4e5b1e080d8e",
+ "reference": "5f0df49ae5ad6efb7afa69e6bfab4e5b1e080d8e",
"shasum": ""
},
"require": {
@@ -5417,7 +5498,7 @@
],
"support": {
"issues": "https://github.com/ramsey/uuid/issues",
- "source": "https://github.com/ramsey/uuid/tree/4.7.4"
+ "source": "https://github.com/ramsey/uuid/tree/4.7.5"
},
"funding": [
{
@@ -5429,7 +5510,7 @@
"type": "tidelift"
}
],
- "time": "2023-04-15T23:01:58+00:00"
+ "time": "2023-11-08T05:53:05+00:00"
},
{
"name": "rcrowe/twigbridge",
@@ -5571,35 +5652,34 @@
},
{
"name": "spatie/flare-client-php",
- "version": "1.4.2",
+ "version": "1.4.4",
"source": {
"type": "git",
"url": "https://github.com/spatie/flare-client-php.git",
- "reference": "5f2c6a7a0d2c1d90c12559dc7828fd942911a544"
+ "reference": "17082e780752d346c2db12ef5d6bee8e835e399c"
},
"dist": {
"type": "zip",
- "url": "https://api.github.com/repos/spatie/flare-client-php/zipball/5f2c6a7a0d2c1d90c12559dc7828fd942911a544",
- "reference": "5f2c6a7a0d2c1d90c12559dc7828fd942911a544",
+ "url": "https://api.github.com/repos/spatie/flare-client-php/zipball/17082e780752d346c2db12ef5d6bee8e835e399c",
+ "reference": "17082e780752d346c2db12ef5d6bee8e835e399c",
"shasum": ""
},
"require": {
- "illuminate/pipeline": "^8.0|^9.0|^10.0",
- "nesbot/carbon": "^2.62.1",
+ "illuminate/pipeline": "^8.0|^9.0|^10.0|^11.0",
"php": "^8.0",
"spatie/backtrace": "^1.5.2",
- "symfony/http-foundation": "^5.0|^6.0",
- "symfony/mime": "^5.2|^6.0",
- "symfony/process": "^5.2|^6.0",
- "symfony/var-dumper": "^5.2|^6.0"
+ "symfony/http-foundation": "^5.2|^6.0|^7.0",
+ "symfony/mime": "^5.2|^6.0|^7.0",
+ "symfony/process": "^5.2|^6.0|^7.0",
+ "symfony/var-dumper": "^5.2|^6.0|^7.0"
},
"require-dev": {
- "dms/phpunit-arraysubset-asserts": "^0.3.0",
- "pestphp/pest": "^1.20",
+ "dms/phpunit-arraysubset-asserts": "^0.5.0",
+ "pestphp/pest": "^1.20|^2.0",
"phpstan/extension-installer": "^1.1",
"phpstan/phpstan-deprecation-rules": "^1.0",
"phpstan/phpstan-phpunit": "^1.0",
- "spatie/phpunit-snapshot-assertions": "^4.0"
+ "spatie/phpunit-snapshot-assertions": "^4.0|^5.0"
},
"type": "library",
"extra": {
@@ -5629,7 +5709,7 @@
],
"support": {
"issues": "https://github.com/spatie/flare-client-php/issues",
- "source": "https://github.com/spatie/flare-client-php/tree/1.4.2"
+ "source": "https://github.com/spatie/flare-client-php/tree/1.4.4"
},
"funding": [
{
@@ -5637,20 +5717,20 @@
"type": "github"
}
],
- "time": "2023-07-28T08:07:24+00:00"
+ "time": "2024-01-31T14:18:45+00:00"
},
{
"name": "spatie/ignition",
- "version": "1.11.2",
+ "version": "1.12.0",
"source": {
"type": "git",
"url": "https://github.com/spatie/ignition.git",
- "reference": "48b23411ca4bfbc75c75dfc638b6b36159c375aa"
+ "reference": "5b6f801c605a593106b623e45ca41496a6e7d56d"
},
"dist": {
"type": "zip",
- "url": "https://api.github.com/repos/spatie/ignition/zipball/48b23411ca4bfbc75c75dfc638b6b36159c375aa",
- "reference": "48b23411ca4bfbc75c75dfc638b6b36159c375aa",
+ "url": "https://api.github.com/repos/spatie/ignition/zipball/5b6f801c605a593106b623e45ca41496a6e7d56d",
+ "reference": "5b6f801c605a593106b623e45ca41496a6e7d56d",
"shasum": ""
},
"require": {
@@ -5659,19 +5739,19 @@
"php": "^8.0",
"spatie/backtrace": "^1.5.3",
"spatie/flare-client-php": "^1.4.0",
- "symfony/console": "^5.4|^6.0",
- "symfony/var-dumper": "^5.4|^6.0"
+ "symfony/console": "^5.4|^6.0|^7.0",
+ "symfony/var-dumper": "^5.4|^6.0|^7.0"
},
"require-dev": {
- "illuminate/cache": "^9.52",
+ "illuminate/cache": "^9.52|^10.0|^11.0",
"mockery/mockery": "^1.4",
- "pestphp/pest": "^1.20",
+ "pestphp/pest": "^1.20|^2.0",
"phpstan/extension-installer": "^1.1",
"phpstan/phpstan-deprecation-rules": "^1.0",
"phpstan/phpstan-phpunit": "^1.0",
"psr/simple-cache-implementation": "*",
- "symfony/cache": "^6.0",
- "symfony/process": "^5.4|^6.0",
+ "symfony/cache": "^5.4|^6.0|^7.0",
+ "symfony/process": "^5.4|^6.0|^7.0",
"vlucas/phpdotenv": "^5.5"
},
"suggest": {
@@ -5720,20 +5800,20 @@
"type": "github"
}
],
- "time": "2023-09-19T15:29:52+00:00"
+ "time": "2024-01-03T15:49:39+00:00"
},
{
"name": "spatie/laravel-html",
- "version": "3.2.2",
+ "version": "3.5.0",
"source": {
"type": "git",
"url": "https://github.com/spatie/laravel-html.git",
- "reference": "f9dac9f250735dd01d80e023f5acf6f3d10d3b3f"
+ "reference": "ead179a8b6802647027486049f5209bd23b610a9"
},
"dist": {
"type": "zip",
- "url": "https://api.github.com/repos/spatie/laravel-html/zipball/f9dac9f250735dd01d80e023f5acf6f3d10d3b3f",
- "reference": "f9dac9f250735dd01d80e023f5acf6f3d10d3b3f",
+ "url": "https://api.github.com/repos/spatie/laravel-html/zipball/ead179a8b6802647027486049f5209bd23b610a9",
+ "reference": "ead179a8b6802647027486049f5209bd23b610a9",
"shasum": ""
},
"require": {
@@ -5790,7 +5870,7 @@
"spatie"
],
"support": {
- "source": "https://github.com/spatie/laravel-html/tree/3.2.2"
+ "source": "https://github.com/spatie/laravel-html/tree/3.5.0"
},
"funding": [
{
@@ -5798,39 +5878,39 @@
"type": "custom"
}
],
- "time": "2023-07-20T18:59:53+00:00"
+ "time": "2024-02-20T15:17:00+00:00"
},
{
"name": "spatie/laravel-ignition",
- "version": "2.3.1",
+ "version": "2.4.2",
"source": {
"type": "git",
"url": "https://github.com/spatie/laravel-ignition.git",
- "reference": "bf21cd15aa47fa4ec5d73bbc932005c70261efc8"
+ "reference": "351504f4570e32908839fc5a2dc53bf77d02f85e"
},
"dist": {
"type": "zip",
- "url": "https://api.github.com/repos/spatie/laravel-ignition/zipball/bf21cd15aa47fa4ec5d73bbc932005c70261efc8",
- "reference": "bf21cd15aa47fa4ec5d73bbc932005c70261efc8",
+ "url": "https://api.github.com/repos/spatie/laravel-ignition/zipball/351504f4570e32908839fc5a2dc53bf77d02f85e",
+ "reference": "351504f4570e32908839fc5a2dc53bf77d02f85e",
"shasum": ""
},
"require": {
"ext-curl": "*",
"ext-json": "*",
"ext-mbstring": "*",
- "illuminate/support": "^10.0",
+ "illuminate/support": "^10.0|^11.0",
"php": "^8.1",
"spatie/flare-client-php": "^1.3.5",
"spatie/ignition": "^1.9",
- "symfony/console": "^6.2.3",
- "symfony/var-dumper": "^6.2.3"
+ "symfony/console": "^6.2.3|^7.0",
+ "symfony/var-dumper": "^6.2.3|^7.0"
},
"require-dev": {
- "livewire/livewire": "^2.11",
+ "livewire/livewire": "^2.11|^3.3.5",
"mockery/mockery": "^1.5.1",
- "openai-php/client": "^0.3.4",
- "orchestra/testbench": "^8.0",
- "pestphp/pest": "^1.22.3",
+ "openai-php/client": "^0.8.1",
+ "orchestra/testbench": "^8.0|^9.0",
+ "pestphp/pest": "^2.30",
"phpstan/extension-installer": "^1.2",
"phpstan/phpstan-deprecation-rules": "^1.1.1",
"phpstan/phpstan-phpunit": "^1.3.3",
@@ -5890,7 +5970,7 @@
"type": "github"
}
],
- "time": "2023-10-09T12:55:26+00:00"
+ "time": "2024-02-09T16:08:40+00:00"
},
{
"name": "spatie/period",
@@ -6120,16 +6200,16 @@
},
{
"name": "symfony/console",
- "version": "v6.3.4",
+ "version": "v6.4.4",
"source": {
"type": "git",
"url": "https://github.com/symfony/console.git",
- "reference": "eca495f2ee845130855ddf1cf18460c38966c8b6"
+ "reference": "0d9e4eb5ad413075624378f474c4167ea202de78"
},
"dist": {
"type": "zip",
- "url": "https://api.github.com/repos/symfony/console/zipball/eca495f2ee845130855ddf1cf18460c38966c8b6",
- "reference": "eca495f2ee845130855ddf1cf18460c38966c8b6",
+ "url": "https://api.github.com/repos/symfony/console/zipball/0d9e4eb5ad413075624378f474c4167ea202de78",
+ "reference": "0d9e4eb5ad413075624378f474c4167ea202de78",
"shasum": ""
},
"require": {
@@ -6137,7 +6217,7 @@
"symfony/deprecation-contracts": "^2.5|^3",
"symfony/polyfill-mbstring": "~1.0",
"symfony/service-contracts": "^2.5|^3",
- "symfony/string": "^5.4|^6.0"
+ "symfony/string": "^5.4|^6.0|^7.0"
},
"conflict": {
"symfony/dependency-injection": "<5.4",
@@ -6151,12 +6231,16 @@
},
"require-dev": {
"psr/log": "^1|^2|^3",
- "symfony/config": "^5.4|^6.0",
- "symfony/dependency-injection": "^5.4|^6.0",
- "symfony/event-dispatcher": "^5.4|^6.0",
- "symfony/lock": "^5.4|^6.0",
- "symfony/process": "^5.4|^6.0",
- "symfony/var-dumper": "^5.4|^6.0"
+ "symfony/config": "^5.4|^6.0|^7.0",
+ "symfony/dependency-injection": "^5.4|^6.0|^7.0",
+ "symfony/event-dispatcher": "^5.4|^6.0|^7.0",
+ "symfony/http-foundation": "^6.4|^7.0",
+ "symfony/http-kernel": "^6.4|^7.0",
+ "symfony/lock": "^5.4|^6.0|^7.0",
+ "symfony/messenger": "^5.4|^6.0|^7.0",
+ "symfony/process": "^5.4|^6.0|^7.0",
+ "symfony/stopwatch": "^5.4|^6.0|^7.0",
+ "symfony/var-dumper": "^5.4|^6.0|^7.0"
},
"type": "library",
"autoload": {
@@ -6190,7 +6274,7 @@
"terminal"
],
"support": {
- "source": "https://github.com/symfony/console/tree/v6.3.4"
+ "source": "https://github.com/symfony/console/tree/v6.4.4"
},
"funding": [
{
@@ -6206,24 +6290,24 @@
"type": "tidelift"
}
],
- "time": "2023-08-16T10:10:12+00:00"
+ "time": "2024-02-22T20:27:10+00:00"
},
{
"name": "symfony/css-selector",
- "version": "v6.3.2",
+ "version": "v7.0.3",
"source": {
"type": "git",
"url": "https://github.com/symfony/css-selector.git",
- "reference": "883d961421ab1709877c10ac99451632a3d6fa57"
+ "reference": "ec60a4edf94e63b0556b6a0888548bb400a3a3be"
},
"dist": {
"type": "zip",
- "url": "https://api.github.com/repos/symfony/css-selector/zipball/883d961421ab1709877c10ac99451632a3d6fa57",
- "reference": "883d961421ab1709877c10ac99451632a3d6fa57",
+ "url": "https://api.github.com/repos/symfony/css-selector/zipball/ec60a4edf94e63b0556b6a0888548bb400a3a3be",
+ "reference": "ec60a4edf94e63b0556b6a0888548bb400a3a3be",
"shasum": ""
},
"require": {
- "php": ">=8.1"
+ "php": ">=8.2"
},
"type": "library",
"autoload": {
@@ -6255,7 +6339,7 @@
"description": "Converts CSS selectors to XPath expressions",
"homepage": "https://symfony.com",
"support": {
- "source": "https://github.com/symfony/css-selector/tree/v6.3.2"
+ "source": "https://github.com/symfony/css-selector/tree/v7.0.3"
},
"funding": [
{
@@ -6271,11 +6355,11 @@
"type": "tidelift"
}
],
- "time": "2023-07-12T16:00:22+00:00"
+ "time": "2024-01-23T15:02:46+00:00"
},
{
"name": "symfony/deprecation-contracts",
- "version": "v3.3.0",
+ "version": "v3.4.0",
"source": {
"type": "git",
"url": "https://github.com/symfony/deprecation-contracts.git",
@@ -6322,7 +6406,7 @@
"description": "A generic function and convention to trigger deprecation notices",
"homepage": "https://symfony.com",
"support": {
- "source": "https://github.com/symfony/deprecation-contracts/tree/v3.3.0"
+ "source": "https://github.com/symfony/deprecation-contracts/tree/v3.4.0"
},
"funding": [
{
@@ -6342,30 +6426,31 @@
},
{
"name": "symfony/error-handler",
- "version": "v6.3.5",
+ "version": "v6.4.4",
"source": {
"type": "git",
"url": "https://github.com/symfony/error-handler.git",
- "reference": "1f69476b64fb47105c06beef757766c376b548c4"
+ "reference": "c725219bdf2afc59423c32793d5019d2a904e13a"
},
"dist": {
"type": "zip",
- "url": "https://api.github.com/repos/symfony/error-handler/zipball/1f69476b64fb47105c06beef757766c376b548c4",
- "reference": "1f69476b64fb47105c06beef757766c376b548c4",
+ "url": "https://api.github.com/repos/symfony/error-handler/zipball/c725219bdf2afc59423c32793d5019d2a904e13a",
+ "reference": "c725219bdf2afc59423c32793d5019d2a904e13a",
"shasum": ""
},
"require": {
"php": ">=8.1",
"psr/log": "^1|^2|^3",
- "symfony/var-dumper": "^5.4|^6.0"
+ "symfony/var-dumper": "^5.4|^6.0|^7.0"
},
"conflict": {
- "symfony/deprecation-contracts": "<2.5"
+ "symfony/deprecation-contracts": "<2.5",
+ "symfony/http-kernel": "<6.4"
},
"require-dev": {
"symfony/deprecation-contracts": "^2.5|^3",
- "symfony/http-kernel": "^5.4|^6.0",
- "symfony/serializer": "^5.4|^6.0"
+ "symfony/http-kernel": "^6.4|^7.0",
+ "symfony/serializer": "^5.4|^6.0|^7.0"
},
"bin": [
"Resources/bin/patch-type-declarations"
@@ -6396,7 +6481,7 @@
"description": "Provides tools to manage errors and ease debugging PHP code",
"homepage": "https://symfony.com",
"support": {
- "source": "https://github.com/symfony/error-handler/tree/v6.3.5"
+ "source": "https://github.com/symfony/error-handler/tree/v6.4.4"
},
"funding": [
{
@@ -6412,28 +6497,28 @@
"type": "tidelift"
}
],
- "time": "2023-09-12T06:57:20+00:00"
+ "time": "2024-02-22T20:27:10+00:00"
},
{
"name": "symfony/event-dispatcher",
- "version": "v6.3.2",
+ "version": "v7.0.3",
"source": {
"type": "git",
"url": "https://github.com/symfony/event-dispatcher.git",
- "reference": "adb01fe097a4ee930db9258a3cc906b5beb5cf2e"
+ "reference": "834c28d533dd0636f910909d01b9ff45cc094b5e"
},
"dist": {
"type": "zip",
- "url": "https://api.github.com/repos/symfony/event-dispatcher/zipball/adb01fe097a4ee930db9258a3cc906b5beb5cf2e",
- "reference": "adb01fe097a4ee930db9258a3cc906b5beb5cf2e",
+ "url": "https://api.github.com/repos/symfony/event-dispatcher/zipball/834c28d533dd0636f910909d01b9ff45cc094b5e",
+ "reference": "834c28d533dd0636f910909d01b9ff45cc094b5e",
"shasum": ""
},
"require": {
- "php": ">=8.1",
+ "php": ">=8.2",
"symfony/event-dispatcher-contracts": "^2.5|^3"
},
"conflict": {
- "symfony/dependency-injection": "<5.4",
+ "symfony/dependency-injection": "<6.4",
"symfony/service-contracts": "<2.5"
},
"provide": {
@@ -6442,13 +6527,13 @@
},
"require-dev": {
"psr/log": "^1|^2|^3",
- "symfony/config": "^5.4|^6.0",
- "symfony/dependency-injection": "^5.4|^6.0",
- "symfony/error-handler": "^5.4|^6.0",
- "symfony/expression-language": "^5.4|^6.0",
- "symfony/http-foundation": "^5.4|^6.0",
+ "symfony/config": "^6.4|^7.0",
+ "symfony/dependency-injection": "^6.4|^7.0",
+ "symfony/error-handler": "^6.4|^7.0",
+ "symfony/expression-language": "^6.4|^7.0",
+ "symfony/http-foundation": "^6.4|^7.0",
"symfony/service-contracts": "^2.5|^3",
- "symfony/stopwatch": "^5.4|^6.0"
+ "symfony/stopwatch": "^6.4|^7.0"
},
"type": "library",
"autoload": {
@@ -6476,7 +6561,7 @@
"description": "Provides tools that allow your application components to communicate with each other by dispatching events and listening to them",
"homepage": "https://symfony.com",
"support": {
- "source": "https://github.com/symfony/event-dispatcher/tree/v6.3.2"
+ "source": "https://github.com/symfony/event-dispatcher/tree/v7.0.3"
},
"funding": [
{
@@ -6492,11 +6577,11 @@
"type": "tidelift"
}
],
- "time": "2023-07-06T06:56:43+00:00"
+ "time": "2024-01-23T15:02:46+00:00"
},
{
"name": "symfony/event-dispatcher-contracts",
- "version": "v3.3.0",
+ "version": "v3.4.0",
"source": {
"type": "git",
"url": "https://github.com/symfony/event-dispatcher-contracts.git",
@@ -6552,7 +6637,7 @@
"standards"
],
"support": {
- "source": "https://github.com/symfony/event-dispatcher-contracts/tree/v3.3.0"
+ "source": "https://github.com/symfony/event-dispatcher-contracts/tree/v3.4.0"
},
"funding": [
{
@@ -6572,21 +6657,21 @@
},
{
"name": "symfony/expression-language",
- "version": "v6.3.0",
+ "version": "v6.4.3",
"source": {
"type": "git",
"url": "https://github.com/symfony/expression-language.git",
- "reference": "6d560c4c80e7e328708efd923f93ad67e6a0c1c0"
+ "reference": "b4a4ae33fbb33a99d23c5698faaecadb76ad0fe4"
},
"dist": {
"type": "zip",
- "url": "https://api.github.com/repos/symfony/expression-language/zipball/6d560c4c80e7e328708efd923f93ad67e6a0c1c0",
- "reference": "6d560c4c80e7e328708efd923f93ad67e6a0c1c0",
+ "url": "https://api.github.com/repos/symfony/expression-language/zipball/b4a4ae33fbb33a99d23c5698faaecadb76ad0fe4",
+ "reference": "b4a4ae33fbb33a99d23c5698faaecadb76ad0fe4",
"shasum": ""
},
"require": {
"php": ">=8.1",
- "symfony/cache": "^5.4|^6.0",
+ "symfony/cache": "^5.4|^6.0|^7.0",
"symfony/deprecation-contracts": "^2.5|^3",
"symfony/service-contracts": "^2.5|^3"
},
@@ -6616,7 +6701,7 @@
"description": "Provides an engine that can compile and evaluate expressions",
"homepage": "https://symfony.com",
"support": {
- "source": "https://github.com/symfony/expression-language/tree/v6.3.0"
+ "source": "https://github.com/symfony/expression-language/tree/v6.4.3"
},
"funding": [
{
@@ -6632,27 +6717,27 @@
"type": "tidelift"
}
],
- "time": "2023-04-28T16:05:33+00:00"
+ "time": "2024-01-23T14:51:35+00:00"
},
{
"name": "symfony/finder",
- "version": "v6.3.5",
+ "version": "v6.4.0",
"source": {
"type": "git",
"url": "https://github.com/symfony/finder.git",
- "reference": "a1b31d88c0e998168ca7792f222cbecee47428c4"
+ "reference": "11d736e97f116ac375a81f96e662911a34cd50ce"
},
"dist": {
"type": "zip",
- "url": "https://api.github.com/repos/symfony/finder/zipball/a1b31d88c0e998168ca7792f222cbecee47428c4",
- "reference": "a1b31d88c0e998168ca7792f222cbecee47428c4",
+ "url": "https://api.github.com/repos/symfony/finder/zipball/11d736e97f116ac375a81f96e662911a34cd50ce",
+ "reference": "11d736e97f116ac375a81f96e662911a34cd50ce",
"shasum": ""
},
"require": {
"php": ">=8.1"
},
"require-dev": {
- "symfony/filesystem": "^6.0"
+ "symfony/filesystem": "^6.0|^7.0"
},
"type": "library",
"autoload": {
@@ -6680,7 +6765,7 @@
"description": "Finds files and directories via an intuitive fluent interface",
"homepage": "https://symfony.com",
"support": {
- "source": "https://github.com/symfony/finder/tree/v6.3.5"
+ "source": "https://github.com/symfony/finder/tree/v6.4.0"
},
"funding": [
{
@@ -6696,32 +6781,31 @@
"type": "tidelift"
}
],
- "time": "2023-09-26T12:56:25+00:00"
+ "time": "2023-10-31T17:30:12+00:00"
},
{
"name": "symfony/http-client",
- "version": "v6.3.5",
+ "version": "v7.0.4",
"source": {
"type": "git",
"url": "https://github.com/symfony/http-client.git",
- "reference": "213e564da4cbf61acc9728d97e666bcdb868c10d"
+ "reference": "8384876f49a2316a63f88a9cd12436de6936bee6"
},
"dist": {
"type": "zip",
- "url": "https://api.github.com/repos/symfony/http-client/zipball/213e564da4cbf61acc9728d97e666bcdb868c10d",
- "reference": "213e564da4cbf61acc9728d97e666bcdb868c10d",
+ "url": "https://api.github.com/repos/symfony/http-client/zipball/8384876f49a2316a63f88a9cd12436de6936bee6",
+ "reference": "8384876f49a2316a63f88a9cd12436de6936bee6",
"shasum": ""
},
"require": {
- "php": ">=8.1",
+ "php": ">=8.2",
"psr/log": "^1|^2|^3",
- "symfony/deprecation-contracts": "^2.5|^3",
"symfony/http-client-contracts": "^3",
"symfony/service-contracts": "^2.5|^3"
},
"conflict": {
"php-http/discovery": "<1.15",
- "symfony/http-foundation": "<6.3"
+ "symfony/http-foundation": "<6.4"
},
"provide": {
"php-http/async-client-implementation": "*",
@@ -6738,10 +6822,11 @@
"nyholm/psr7": "^1.0",
"php-http/httplug": "^1.0|^2.0",
"psr/http-client": "^1.0",
- "symfony/dependency-injection": "^5.4|^6.0",
- "symfony/http-kernel": "^5.4|^6.0",
- "symfony/process": "^5.4|^6.0",
- "symfony/stopwatch": "^5.4|^6.0"
+ "symfony/dependency-injection": "^6.4|^7.0",
+ "symfony/http-kernel": "^6.4|^7.0",
+ "symfony/messenger": "^6.4|^7.0",
+ "symfony/process": "^6.4|^7.0",
+ "symfony/stopwatch": "^6.4|^7.0"
},
"type": "library",
"autoload": {
@@ -6772,7 +6857,7 @@
"http"
],
"support": {
- "source": "https://github.com/symfony/http-client/tree/v6.3.5"
+ "source": "https://github.com/symfony/http-client/tree/v7.0.4"
},
"funding": [
{
@@ -6788,20 +6873,20 @@
"type": "tidelift"
}
],
- "time": "2023-09-29T15:57:12+00:00"
+ "time": "2024-02-15T11:33:06+00:00"
},
{
"name": "symfony/http-client-contracts",
- "version": "v3.3.0",
+ "version": "v3.4.0",
"source": {
"type": "git",
"url": "https://github.com/symfony/http-client-contracts.git",
- "reference": "3b66325d0176b4ec826bffab57c9037d759c31fb"
+ "reference": "1ee70e699b41909c209a0c930f11034b93578654"
},
"dist": {
"type": "zip",
- "url": "https://api.github.com/repos/symfony/http-client-contracts/zipball/3b66325d0176b4ec826bffab57c9037d759c31fb",
- "reference": "3b66325d0176b4ec826bffab57c9037d759c31fb",
+ "url": "https://api.github.com/repos/symfony/http-client-contracts/zipball/1ee70e699b41909c209a0c930f11034b93578654",
+ "reference": "1ee70e699b41909c209a0c930f11034b93578654",
"shasum": ""
},
"require": {
@@ -6850,7 +6935,7 @@
"standards"
],
"support": {
- "source": "https://github.com/symfony/http-client-contracts/tree/v3.3.0"
+ "source": "https://github.com/symfony/http-client-contracts/tree/v3.4.0"
},
"funding": [
{
@@ -6866,20 +6951,20 @@
"type": "tidelift"
}
],
- "time": "2023-05-23T14:45:45+00:00"
+ "time": "2023-07-30T20:28:31+00:00"
},
{
"name": "symfony/http-foundation",
- "version": "v6.3.5",
+ "version": "v6.4.4",
"source": {
"type": "git",
"url": "https://github.com/symfony/http-foundation.git",
- "reference": "b50f5e281d722cb0f4c296f908bacc3e2b721957"
+ "reference": "ebc713bc6e6f4b53f46539fc158be85dfcd77304"
},
"dist": {
"type": "zip",
- "url": "https://api.github.com/repos/symfony/http-foundation/zipball/b50f5e281d722cb0f4c296f908bacc3e2b721957",
- "reference": "b50f5e281d722cb0f4c296f908bacc3e2b721957",
+ "url": "https://api.github.com/repos/symfony/http-foundation/zipball/ebc713bc6e6f4b53f46539fc158be85dfcd77304",
+ "reference": "ebc713bc6e6f4b53f46539fc158be85dfcd77304",
"shasum": ""
},
"require": {
@@ -6889,17 +6974,17 @@
"symfony/polyfill-php83": "^1.27"
},
"conflict": {
- "symfony/cache": "<6.2"
+ "symfony/cache": "<6.3"
},
"require-dev": {
- "doctrine/dbal": "^2.13.1|^3.0",
+ "doctrine/dbal": "^2.13.1|^3|^4",
"predis/predis": "^1.1|^2.0",
- "symfony/cache": "^5.4|^6.0",
- "symfony/dependency-injection": "^5.4|^6.0",
- "symfony/expression-language": "^5.4|^6.0",
- "symfony/http-kernel": "^5.4.12|^6.0.12|^6.1.4",
- "symfony/mime": "^5.4|^6.0",
- "symfony/rate-limiter": "^5.2|^6.0"
+ "symfony/cache": "^6.3|^7.0",
+ "symfony/dependency-injection": "^5.4|^6.0|^7.0",
+ "symfony/expression-language": "^5.4|^6.0|^7.0",
+ "symfony/http-kernel": "^5.4.12|^6.0.12|^6.1.4|^7.0",
+ "symfony/mime": "^5.4|^6.0|^7.0",
+ "symfony/rate-limiter": "^5.4|^6.0|^7.0"
},
"type": "library",
"autoload": {
@@ -6927,7 +7012,7 @@
"description": "Defines an object-oriented layer for the HTTP specification",
"homepage": "https://symfony.com",
"support": {
- "source": "https://github.com/symfony/http-foundation/tree/v6.3.5"
+ "source": "https://github.com/symfony/http-foundation/tree/v6.4.4"
},
"funding": [
{
@@ -6943,29 +7028,29 @@
"type": "tidelift"
}
],
- "time": "2023-09-04T21:33:54+00:00"
+ "time": "2024-02-08T15:01:18+00:00"
},
{
"name": "symfony/http-kernel",
- "version": "v6.3.5",
+ "version": "v6.4.4",
"source": {
"type": "git",
"url": "https://github.com/symfony/http-kernel.git",
- "reference": "9f991a964368bee8d883e8d57ced4fe9fff04dfc"
+ "reference": "7a186f64a7f02787c04e8476538624d6aa888e42"
},
"dist": {
"type": "zip",
- "url": "https://api.github.com/repos/symfony/http-kernel/zipball/9f991a964368bee8d883e8d57ced4fe9fff04dfc",
- "reference": "9f991a964368bee8d883e8d57ced4fe9fff04dfc",
+ "url": "https://api.github.com/repos/symfony/http-kernel/zipball/7a186f64a7f02787c04e8476538624d6aa888e42",
+ "reference": "7a186f64a7f02787c04e8476538624d6aa888e42",
"shasum": ""
},
"require": {
"php": ">=8.1",
"psr/log": "^1|^2|^3",
"symfony/deprecation-contracts": "^2.5|^3",
- "symfony/error-handler": "^6.3",
- "symfony/event-dispatcher": "^5.4|^6.0",
- "symfony/http-foundation": "^6.3.4",
+ "symfony/error-handler": "^6.4|^7.0",
+ "symfony/event-dispatcher": "^5.4|^6.0|^7.0",
+ "symfony/http-foundation": "^6.4|^7.0",
"symfony/polyfill-ctype": "^1.8"
},
"conflict": {
@@ -6973,7 +7058,7 @@
"symfony/cache": "<5.4",
"symfony/config": "<6.1",
"symfony/console": "<5.4",
- "symfony/dependency-injection": "<6.3.4",
+ "symfony/dependency-injection": "<6.4",
"symfony/doctrine-bridge": "<5.4",
"symfony/form": "<5.4",
"symfony/http-client": "<5.4",
@@ -6983,7 +7068,7 @@
"symfony/translation": "<5.4",
"symfony/translation-contracts": "<2.5",
"symfony/twig-bridge": "<5.4",
- "symfony/validator": "<5.4",
+ "symfony/validator": "<6.4",
"symfony/var-dumper": "<6.3",
"twig/twig": "<2.13"
},
@@ -6992,26 +7077,26 @@
},
"require-dev": {
"psr/cache": "^1.0|^2.0|^3.0",
- "symfony/browser-kit": "^5.4|^6.0",
- "symfony/clock": "^6.2",
- "symfony/config": "^6.1",
- "symfony/console": "^5.4|^6.0",
- "symfony/css-selector": "^5.4|^6.0",
- "symfony/dependency-injection": "^6.3.4",
- "symfony/dom-crawler": "^5.4|^6.0",
- "symfony/expression-language": "^5.4|^6.0",
- "symfony/finder": "^5.4|^6.0",
+ "symfony/browser-kit": "^5.4|^6.0|^7.0",
+ "symfony/clock": "^6.2|^7.0",
+ "symfony/config": "^6.1|^7.0",
+ "symfony/console": "^5.4|^6.0|^7.0",
+ "symfony/css-selector": "^5.4|^6.0|^7.0",
+ "symfony/dependency-injection": "^6.4|^7.0",
+ "symfony/dom-crawler": "^5.4|^6.0|^7.0",
+ "symfony/expression-language": "^5.4|^6.0|^7.0",
+ "symfony/finder": "^5.4|^6.0|^7.0",
"symfony/http-client-contracts": "^2.5|^3",
- "symfony/process": "^5.4|^6.0",
- "symfony/property-access": "^5.4.5|^6.0.5",
- "symfony/routing": "^5.4|^6.0",
- "symfony/serializer": "^6.3",
- "symfony/stopwatch": "^5.4|^6.0",
- "symfony/translation": "^5.4|^6.0",
+ "symfony/process": "^5.4|^6.0|^7.0",
+ "symfony/property-access": "^5.4.5|^6.0.5|^7.0",
+ "symfony/routing": "^5.4|^6.0|^7.0",
+ "symfony/serializer": "^6.4.4|^7.0.4",
+ "symfony/stopwatch": "^5.4|^6.0|^7.0",
+ "symfony/translation": "^5.4|^6.0|^7.0",
"symfony/translation-contracts": "^2.5|^3",
- "symfony/uid": "^5.4|^6.0",
- "symfony/validator": "^6.3",
- "symfony/var-exporter": "^6.2",
+ "symfony/uid": "^5.4|^6.0|^7.0",
+ "symfony/validator": "^6.4|^7.0",
+ "symfony/var-exporter": "^6.2|^7.0",
"twig/twig": "^2.13|^3.0.4"
},
"type": "library",
@@ -7040,7 +7125,7 @@
"description": "Provides a structured process for converting a Request into a Response",
"homepage": "https://symfony.com",
"support": {
- "source": "https://github.com/symfony/http-kernel/tree/v6.3.5"
+ "source": "https://github.com/symfony/http-kernel/tree/v6.4.4"
},
"funding": [
{
@@ -7056,20 +7141,20 @@
"type": "tidelift"
}
],
- "time": "2023-09-30T06:37:04+00:00"
+ "time": "2024-02-27T06:32:13+00:00"
},
{
"name": "symfony/mailer",
- "version": "v6.3.5",
+ "version": "v6.4.4",
"source": {
"type": "git",
"url": "https://github.com/symfony/mailer.git",
- "reference": "d89611a7830d51b5e118bca38e390dea92f9ea06"
+ "reference": "791c5d31a8204cf3db0c66faab70282307f4376b"
},
"dist": {
"type": "zip",
- "url": "https://api.github.com/repos/symfony/mailer/zipball/d89611a7830d51b5e118bca38e390dea92f9ea06",
- "reference": "d89611a7830d51b5e118bca38e390dea92f9ea06",
+ "url": "https://api.github.com/repos/symfony/mailer/zipball/791c5d31a8204cf3db0c66faab70282307f4376b",
+ "reference": "791c5d31a8204cf3db0c66faab70282307f4376b",
"shasum": ""
},
"require": {
@@ -7077,8 +7162,8 @@
"php": ">=8.1",
"psr/event-dispatcher": "^1",
"psr/log": "^1|^2|^3",
- "symfony/event-dispatcher": "^5.4|^6.0",
- "symfony/mime": "^6.2",
+ "symfony/event-dispatcher": "^5.4|^6.0|^7.0",
+ "symfony/mime": "^6.2|^7.0",
"symfony/service-contracts": "^2.5|^3"
},
"conflict": {
@@ -7089,10 +7174,10 @@
"symfony/twig-bridge": "<6.2.1"
},
"require-dev": {
- "symfony/console": "^5.4|^6.0",
- "symfony/http-client": "^5.4|^6.0",
- "symfony/messenger": "^6.2",
- "symfony/twig-bridge": "^6.2"
+ "symfony/console": "^5.4|^6.0|^7.0",
+ "symfony/http-client": "^5.4|^6.0|^7.0",
+ "symfony/messenger": "^6.2|^7.0",
+ "symfony/twig-bridge": "^6.2|^7.0"
},
"type": "library",
"autoload": {
@@ -7120,7 +7205,7 @@
"description": "Helps sending emails",
"homepage": "https://symfony.com",
"support": {
- "source": "https://github.com/symfony/mailer/tree/v6.3.5"
+ "source": "https://github.com/symfony/mailer/tree/v6.4.4"
},
"funding": [
{
@@ -7136,32 +7221,32 @@
"type": "tidelift"
}
],
- "time": "2023-09-06T09:47:15+00:00"
+ "time": "2024-02-03T21:33:47+00:00"
},
{
"name": "symfony/mailgun-mailer",
- "version": "v6.3.5",
+ "version": "v7.0.4",
"source": {
"type": "git",
"url": "https://github.com/symfony/mailgun-mailer.git",
- "reference": "b467aba49c8240a71f7027c213d9d140ba1abce7"
+ "reference": "96df0d3815dc72367ecc38c4a82d8021f8bddd4e"
},
"dist": {
"type": "zip",
- "url": "https://api.github.com/repos/symfony/mailgun-mailer/zipball/b467aba49c8240a71f7027c213d9d140ba1abce7",
- "reference": "b467aba49c8240a71f7027c213d9d140ba1abce7",
+ "url": "https://api.github.com/repos/symfony/mailgun-mailer/zipball/96df0d3815dc72367ecc38c4a82d8021f8bddd4e",
+ "reference": "96df0d3815dc72367ecc38c4a82d8021f8bddd4e",
"shasum": ""
},
"require": {
- "php": ">=8.1",
- "symfony/mailer": "^5.4.21|^6.2.7"
+ "php": ">=8.2",
+ "symfony/mailer": "^6.4|^7.0"
},
"conflict": {
- "symfony/http-foundation": "<6.2"
+ "symfony/http-foundation": "<6.4"
},
"require-dev": {
- "symfony/http-client": "^5.4|^6.0",
- "symfony/webhook": "^6.3"
+ "symfony/http-client": "^6.4|^7.0",
+ "symfony/webhook": "^6.4|^7.0"
},
"type": "symfony-mailer-bridge",
"autoload": {
@@ -7189,7 +7274,7 @@
"description": "Symfony Mailgun Mailer Bridge",
"homepage": "https://symfony.com",
"support": {
- "source": "https://github.com/symfony/mailgun-mailer/tree/v6.3.5"
+ "source": "https://github.com/symfony/mailgun-mailer/tree/v7.0.4"
},
"funding": [
{
@@ -7205,20 +7290,20 @@
"type": "tidelift"
}
],
- "time": "2023-09-29T17:30:10+00:00"
+ "time": "2024-02-15T11:33:06+00:00"
},
{
"name": "symfony/mime",
- "version": "v6.3.5",
+ "version": "v6.4.3",
"source": {
"type": "git",
"url": "https://github.com/symfony/mime.git",
- "reference": "d5179eedf1cb2946dbd760475ebf05c251ef6a6e"
+ "reference": "5017e0a9398c77090b7694be46f20eb796262a34"
},
"dist": {
"type": "zip",
- "url": "https://api.github.com/repos/symfony/mime/zipball/d5179eedf1cb2946dbd760475ebf05c251ef6a6e",
- "reference": "d5179eedf1cb2946dbd760475ebf05c251ef6a6e",
+ "url": "https://api.github.com/repos/symfony/mime/zipball/5017e0a9398c77090b7694be46f20eb796262a34",
+ "reference": "5017e0a9398c77090b7694be46f20eb796262a34",
"shasum": ""
},
"require": {
@@ -7232,16 +7317,16 @@
"phpdocumentor/reflection-docblock": "<3.2.2",
"phpdocumentor/type-resolver": "<1.4.0",
"symfony/mailer": "<5.4",
- "symfony/serializer": "<6.2.13|>=6.3,<6.3.2"
+ "symfony/serializer": "<6.3.2"
},
"require-dev": {
"egulias/email-validator": "^2.1.10|^3.1|^4",
"league/html-to-markdown": "^5.0",
"phpdocumentor/reflection-docblock": "^3.0|^4.0|^5.0",
- "symfony/dependency-injection": "^5.4|^6.0",
- "symfony/property-access": "^5.4|^6.0",
- "symfony/property-info": "^5.4|^6.0",
- "symfony/serializer": "~6.2.13|^6.3.2"
+ "symfony/dependency-injection": "^5.4|^6.0|^7.0",
+ "symfony/property-access": "^5.4|^6.0|^7.0",
+ "symfony/property-info": "^5.4|^6.0|^7.0",
+ "symfony/serializer": "^6.3.2|^7.0"
},
"type": "library",
"autoload": {
@@ -7273,7 +7358,7 @@
"mime-type"
],
"support": {
- "source": "https://github.com/symfony/mime/tree/v6.3.5"
+ "source": "https://github.com/symfony/mime/tree/v6.4.3"
},
"funding": [
{
@@ -7289,20 +7374,20 @@
"type": "tidelift"
}
],
- "time": "2023-09-29T06:59:36+00:00"
+ "time": "2024-01-30T08:32:12+00:00"
},
{
"name": "symfony/polyfill-ctype",
- "version": "v1.28.0",
+ "version": "v1.29.0",
"source": {
"type": "git",
"url": "https://github.com/symfony/polyfill-ctype.git",
- "reference": "ea208ce43cbb04af6867b4fdddb1bdbf84cc28cb"
+ "reference": "ef4d7e442ca910c4764bce785146269b30cb5fc4"
},
"dist": {
"type": "zip",
- "url": "https://api.github.com/repos/symfony/polyfill-ctype/zipball/ea208ce43cbb04af6867b4fdddb1bdbf84cc28cb",
- "reference": "ea208ce43cbb04af6867b4fdddb1bdbf84cc28cb",
+ "url": "https://api.github.com/repos/symfony/polyfill-ctype/zipball/ef4d7e442ca910c4764bce785146269b30cb5fc4",
+ "reference": "ef4d7e442ca910c4764bce785146269b30cb5fc4",
"shasum": ""
},
"require": {
@@ -7316,9 +7401,6 @@
},
"type": "library",
"extra": {
- "branch-alias": {
- "dev-main": "1.28-dev"
- },
"thanks": {
"name": "symfony/polyfill",
"url": "https://github.com/symfony/polyfill"
@@ -7355,7 +7437,7 @@
"portable"
],
"support": {
- "source": "https://github.com/symfony/polyfill-ctype/tree/v1.28.0"
+ "source": "https://github.com/symfony/polyfill-ctype/tree/v1.29.0"
},
"funding": [
{
@@ -7371,20 +7453,20 @@
"type": "tidelift"
}
],
- "time": "2023-01-26T09:26:14+00:00"
+ "time": "2024-01-29T20:11:03+00:00"
},
{
"name": "symfony/polyfill-intl-grapheme",
- "version": "v1.28.0",
+ "version": "v1.29.0",
"source": {
"type": "git",
"url": "https://github.com/symfony/polyfill-intl-grapheme.git",
- "reference": "875e90aeea2777b6f135677f618529449334a612"
+ "reference": "32a9da87d7b3245e09ac426c83d334ae9f06f80f"
},
"dist": {
"type": "zip",
- "url": "https://api.github.com/repos/symfony/polyfill-intl-grapheme/zipball/875e90aeea2777b6f135677f618529449334a612",
- "reference": "875e90aeea2777b6f135677f618529449334a612",
+ "url": "https://api.github.com/repos/symfony/polyfill-intl-grapheme/zipball/32a9da87d7b3245e09ac426c83d334ae9f06f80f",
+ "reference": "32a9da87d7b3245e09ac426c83d334ae9f06f80f",
"shasum": ""
},
"require": {
@@ -7395,9 +7477,6 @@
},
"type": "library",
"extra": {
- "branch-alias": {
- "dev-main": "1.28-dev"
- },
"thanks": {
"name": "symfony/polyfill",
"url": "https://github.com/symfony/polyfill"
@@ -7436,7 +7515,7 @@
"shim"
],
"support": {
- "source": "https://github.com/symfony/polyfill-intl-grapheme/tree/v1.28.0"
+ "source": "https://github.com/symfony/polyfill-intl-grapheme/tree/v1.29.0"
},
"funding": [
{
@@ -7452,20 +7531,20 @@
"type": "tidelift"
}
],
- "time": "2023-01-26T09:26:14+00:00"
+ "time": "2024-01-29T20:11:03+00:00"
},
{
"name": "symfony/polyfill-intl-idn",
- "version": "v1.28.0",
+ "version": "v1.29.0",
"source": {
"type": "git",
"url": "https://github.com/symfony/polyfill-intl-idn.git",
- "reference": "ecaafce9f77234a6a449d29e49267ba10499116d"
+ "reference": "a287ed7475f85bf6f61890146edbc932c0fff919"
},
"dist": {
"type": "zip",
- "url": "https://api.github.com/repos/symfony/polyfill-intl-idn/zipball/ecaafce9f77234a6a449d29e49267ba10499116d",
- "reference": "ecaafce9f77234a6a449d29e49267ba10499116d",
+ "url": "https://api.github.com/repos/symfony/polyfill-intl-idn/zipball/a287ed7475f85bf6f61890146edbc932c0fff919",
+ "reference": "a287ed7475f85bf6f61890146edbc932c0fff919",
"shasum": ""
},
"require": {
@@ -7478,9 +7557,6 @@
},
"type": "library",
"extra": {
- "branch-alias": {
- "dev-main": "1.28-dev"
- },
"thanks": {
"name": "symfony/polyfill",
"url": "https://github.com/symfony/polyfill"
@@ -7523,7 +7599,7 @@
"shim"
],
"support": {
- "source": "https://github.com/symfony/polyfill-intl-idn/tree/v1.28.0"
+ "source": "https://github.com/symfony/polyfill-intl-idn/tree/v1.29.0"
},
"funding": [
{
@@ -7539,20 +7615,20 @@
"type": "tidelift"
}
],
- "time": "2023-01-26T09:30:37+00:00"
+ "time": "2024-01-29T20:11:03+00:00"
},
{
"name": "symfony/polyfill-intl-normalizer",
- "version": "v1.28.0",
+ "version": "v1.29.0",
"source": {
"type": "git",
"url": "https://github.com/symfony/polyfill-intl-normalizer.git",
- "reference": "8c4ad05dd0120b6a53c1ca374dca2ad0a1c4ed92"
+ "reference": "bc45c394692b948b4d383a08d7753968bed9a83d"
},
"dist": {
"type": "zip",
- "url": "https://api.github.com/repos/symfony/polyfill-intl-normalizer/zipball/8c4ad05dd0120b6a53c1ca374dca2ad0a1c4ed92",
- "reference": "8c4ad05dd0120b6a53c1ca374dca2ad0a1c4ed92",
+ "url": "https://api.github.com/repos/symfony/polyfill-intl-normalizer/zipball/bc45c394692b948b4d383a08d7753968bed9a83d",
+ "reference": "bc45c394692b948b4d383a08d7753968bed9a83d",
"shasum": ""
},
"require": {
@@ -7563,9 +7639,6 @@
},
"type": "library",
"extra": {
- "branch-alias": {
- "dev-main": "1.28-dev"
- },
"thanks": {
"name": "symfony/polyfill",
"url": "https://github.com/symfony/polyfill"
@@ -7607,7 +7680,7 @@
"shim"
],
"support": {
- "source": "https://github.com/symfony/polyfill-intl-normalizer/tree/v1.28.0"
+ "source": "https://github.com/symfony/polyfill-intl-normalizer/tree/v1.29.0"
},
"funding": [
{
@@ -7623,20 +7696,20 @@
"type": "tidelift"
}
],
- "time": "2023-01-26T09:26:14+00:00"
+ "time": "2024-01-29T20:11:03+00:00"
},
{
"name": "symfony/polyfill-mbstring",
- "version": "v1.28.0",
+ "version": "v1.29.0",
"source": {
"type": "git",
"url": "https://github.com/symfony/polyfill-mbstring.git",
- "reference": "42292d99c55abe617799667f454222c54c60e229"
+ "reference": "9773676c8a1bb1f8d4340a62efe641cf76eda7ec"
},
"dist": {
"type": "zip",
- "url": "https://api.github.com/repos/symfony/polyfill-mbstring/zipball/42292d99c55abe617799667f454222c54c60e229",
- "reference": "42292d99c55abe617799667f454222c54c60e229",
+ "url": "https://api.github.com/repos/symfony/polyfill-mbstring/zipball/9773676c8a1bb1f8d4340a62efe641cf76eda7ec",
+ "reference": "9773676c8a1bb1f8d4340a62efe641cf76eda7ec",
"shasum": ""
},
"require": {
@@ -7650,9 +7723,6 @@
},
"type": "library",
"extra": {
- "branch-alias": {
- "dev-main": "1.28-dev"
- },
"thanks": {
"name": "symfony/polyfill",
"url": "https://github.com/symfony/polyfill"
@@ -7690,7 +7760,7 @@
"shim"
],
"support": {
- "source": "https://github.com/symfony/polyfill-mbstring/tree/v1.28.0"
+ "source": "https://github.com/symfony/polyfill-mbstring/tree/v1.29.0"
},
"funding": [
{
@@ -7706,20 +7776,20 @@
"type": "tidelift"
}
],
- "time": "2023-07-28T09:04:16+00:00"
+ "time": "2024-01-29T20:11:03+00:00"
},
{
"name": "symfony/polyfill-php72",
- "version": "v1.28.0",
+ "version": "v1.29.0",
"source": {
"type": "git",
"url": "https://github.com/symfony/polyfill-php72.git",
- "reference": "70f4aebd92afca2f865444d30a4d2151c13c3179"
+ "reference": "861391a8da9a04cbad2d232ddd9e4893220d6e25"
},
"dist": {
"type": "zip",
- "url": "https://api.github.com/repos/symfony/polyfill-php72/zipball/70f4aebd92afca2f865444d30a4d2151c13c3179",
- "reference": "70f4aebd92afca2f865444d30a4d2151c13c3179",
+ "url": "https://api.github.com/repos/symfony/polyfill-php72/zipball/861391a8da9a04cbad2d232ddd9e4893220d6e25",
+ "reference": "861391a8da9a04cbad2d232ddd9e4893220d6e25",
"shasum": ""
},
"require": {
@@ -7727,9 +7797,6 @@
},
"type": "library",
"extra": {
- "branch-alias": {
- "dev-main": "1.28-dev"
- },
"thanks": {
"name": "symfony/polyfill",
"url": "https://github.com/symfony/polyfill"
@@ -7766,7 +7833,7 @@
"shim"
],
"support": {
- "source": "https://github.com/symfony/polyfill-php72/tree/v1.28.0"
+ "source": "https://github.com/symfony/polyfill-php72/tree/v1.29.0"
},
"funding": [
{
@@ -7782,20 +7849,20 @@
"type": "tidelift"
}
],
- "time": "2023-01-26T09:26:14+00:00"
+ "time": "2024-01-29T20:11:03+00:00"
},
{
"name": "symfony/polyfill-php80",
- "version": "v1.28.0",
+ "version": "v1.29.0",
"source": {
"type": "git",
"url": "https://github.com/symfony/polyfill-php80.git",
- "reference": "6caa57379c4aec19c0a12a38b59b26487dcfe4b5"
+ "reference": "87b68208d5c1188808dd7839ee1e6c8ec3b02f1b"
},
"dist": {
"type": "zip",
- "url": "https://api.github.com/repos/symfony/polyfill-php80/zipball/6caa57379c4aec19c0a12a38b59b26487dcfe4b5",
- "reference": "6caa57379c4aec19c0a12a38b59b26487dcfe4b5",
+ "url": "https://api.github.com/repos/symfony/polyfill-php80/zipball/87b68208d5c1188808dd7839ee1e6c8ec3b02f1b",
+ "reference": "87b68208d5c1188808dd7839ee1e6c8ec3b02f1b",
"shasum": ""
},
"require": {
@@ -7803,9 +7870,6 @@
},
"type": "library",
"extra": {
- "branch-alias": {
- "dev-main": "1.28-dev"
- },
"thanks": {
"name": "symfony/polyfill",
"url": "https://github.com/symfony/polyfill"
@@ -7849,7 +7913,7 @@
"shim"
],
"support": {
- "source": "https://github.com/symfony/polyfill-php80/tree/v1.28.0"
+ "source": "https://github.com/symfony/polyfill-php80/tree/v1.29.0"
},
"funding": [
{
@@ -7865,20 +7929,20 @@
"type": "tidelift"
}
],
- "time": "2023-01-26T09:26:14+00:00"
+ "time": "2024-01-29T20:11:03+00:00"
},
{
"name": "symfony/polyfill-php83",
- "version": "v1.28.0",
+ "version": "v1.29.0",
"source": {
"type": "git",
"url": "https://github.com/symfony/polyfill-php83.git",
- "reference": "b0f46ebbeeeda3e9d2faebdfbf4b4eae9b59fa11"
+ "reference": "86fcae159633351e5fd145d1c47de6c528f8caff"
},
"dist": {
"type": "zip",
- "url": "https://api.github.com/repos/symfony/polyfill-php83/zipball/b0f46ebbeeeda3e9d2faebdfbf4b4eae9b59fa11",
- "reference": "b0f46ebbeeeda3e9d2faebdfbf4b4eae9b59fa11",
+ "url": "https://api.github.com/repos/symfony/polyfill-php83/zipball/86fcae159633351e5fd145d1c47de6c528f8caff",
+ "reference": "86fcae159633351e5fd145d1c47de6c528f8caff",
"shasum": ""
},
"require": {
@@ -7887,9 +7951,6 @@
},
"type": "library",
"extra": {
- "branch-alias": {
- "dev-main": "1.28-dev"
- },
"thanks": {
"name": "symfony/polyfill",
"url": "https://github.com/symfony/polyfill"
@@ -7929,7 +7990,7 @@
"shim"
],
"support": {
- "source": "https://github.com/symfony/polyfill-php83/tree/v1.28.0"
+ "source": "https://github.com/symfony/polyfill-php83/tree/v1.29.0"
},
"funding": [
{
@@ -7945,20 +8006,20 @@
"type": "tidelift"
}
],
- "time": "2023-08-16T06:22:46+00:00"
+ "time": "2024-01-29T20:11:03+00:00"
},
{
"name": "symfony/polyfill-uuid",
- "version": "v1.28.0",
+ "version": "v1.29.0",
"source": {
"type": "git",
"url": "https://github.com/symfony/polyfill-uuid.git",
- "reference": "9c44518a5aff8da565c8a55dbe85d2769e6f630e"
+ "reference": "3abdd21b0ceaa3000ee950097bc3cf9efc137853"
},
"dist": {
"type": "zip",
- "url": "https://api.github.com/repos/symfony/polyfill-uuid/zipball/9c44518a5aff8da565c8a55dbe85d2769e6f630e",
- "reference": "9c44518a5aff8da565c8a55dbe85d2769e6f630e",
+ "url": "https://api.github.com/repos/symfony/polyfill-uuid/zipball/3abdd21b0ceaa3000ee950097bc3cf9efc137853",
+ "reference": "3abdd21b0ceaa3000ee950097bc3cf9efc137853",
"shasum": ""
},
"require": {
@@ -7972,9 +8033,6 @@
},
"type": "library",
"extra": {
- "branch-alias": {
- "dev-main": "1.28-dev"
- },
"thanks": {
"name": "symfony/polyfill",
"url": "https://github.com/symfony/polyfill"
@@ -8011,7 +8069,7 @@
"uuid"
],
"support": {
- "source": "https://github.com/symfony/polyfill-uuid/tree/v1.28.0"
+ "source": "https://github.com/symfony/polyfill-uuid/tree/v1.29.0"
},
"funding": [
{
@@ -8027,20 +8085,20 @@
"type": "tidelift"
}
],
- "time": "2023-01-26T09:26:14+00:00"
+ "time": "2024-01-29T20:11:03+00:00"
},
{
"name": "symfony/process",
- "version": "v6.3.4",
+ "version": "v6.4.4",
"source": {
"type": "git",
"url": "https://github.com/symfony/process.git",
- "reference": "0b5c29118f2e980d455d2e34a5659f4579847c54"
+ "reference": "710e27879e9be3395de2b98da3f52a946039f297"
},
"dist": {
"type": "zip",
- "url": "https://api.github.com/repos/symfony/process/zipball/0b5c29118f2e980d455d2e34a5659f4579847c54",
- "reference": "0b5c29118f2e980d455d2e34a5659f4579847c54",
+ "url": "https://api.github.com/repos/symfony/process/zipball/710e27879e9be3395de2b98da3f52a946039f297",
+ "reference": "710e27879e9be3395de2b98da3f52a946039f297",
"shasum": ""
},
"require": {
@@ -8072,7 +8130,7 @@
"description": "Executes commands in sub-processes",
"homepage": "https://symfony.com",
"support": {
- "source": "https://github.com/symfony/process/tree/v6.3.4"
+ "source": "https://github.com/symfony/process/tree/v6.4.4"
},
"funding": [
{
@@ -8088,7 +8146,7 @@
"type": "tidelift"
}
],
- "time": "2023-08-07T10:39:22+00:00"
+ "time": "2024-02-20T12:31:00+00:00"
},
{
"name": "symfony/psr-http-message-bridge",
@@ -8181,16 +8239,16 @@
},
{
"name": "symfony/routing",
- "version": "v6.3.5",
+ "version": "v6.4.3",
"source": {
"type": "git",
"url": "https://github.com/symfony/routing.git",
- "reference": "82616e59acd3e3d9c916bba798326cb7796d7d31"
+ "reference": "3b2957ad54902f0f544df83e3d58b38d7e8e5842"
},
"dist": {
"type": "zip",
- "url": "https://api.github.com/repos/symfony/routing/zipball/82616e59acd3e3d9c916bba798326cb7796d7d31",
- "reference": "82616e59acd3e3d9c916bba798326cb7796d7d31",
+ "url": "https://api.github.com/repos/symfony/routing/zipball/3b2957ad54902f0f544df83e3d58b38d7e8e5842",
+ "reference": "3b2957ad54902f0f544df83e3d58b38d7e8e5842",
"shasum": ""
},
"require": {
@@ -8206,11 +8264,11 @@
"require-dev": {
"doctrine/annotations": "^1.12|^2",
"psr/log": "^1|^2|^3",
- "symfony/config": "^6.2",
- "symfony/dependency-injection": "^5.4|^6.0",
- "symfony/expression-language": "^5.4|^6.0",
- "symfony/http-foundation": "^5.4|^6.0",
- "symfony/yaml": "^5.4|^6.0"
+ "symfony/config": "^6.2|^7.0",
+ "symfony/dependency-injection": "^5.4|^6.0|^7.0",
+ "symfony/expression-language": "^5.4|^6.0|^7.0",
+ "symfony/http-foundation": "^5.4|^6.0|^7.0",
+ "symfony/yaml": "^5.4|^6.0|^7.0"
},
"type": "library",
"autoload": {
@@ -8244,7 +8302,7 @@
"url"
],
"support": {
- "source": "https://github.com/symfony/routing/tree/v6.3.5"
+ "source": "https://github.com/symfony/routing/tree/v6.4.3"
},
"funding": [
{
@@ -8260,25 +8318,25 @@
"type": "tidelift"
}
],
- "time": "2023-09-20T16:05:51+00:00"
+ "time": "2024-01-30T13:55:02+00:00"
},
{
"name": "symfony/service-contracts",
- "version": "v3.3.0",
+ "version": "v3.4.1",
"source": {
"type": "git",
"url": "https://github.com/symfony/service-contracts.git",
- "reference": "40da9cc13ec349d9e4966ce18b5fbcd724ab10a4"
+ "reference": "fe07cbc8d837f60caf7018068e350cc5163681a0"
},
"dist": {
"type": "zip",
- "url": "https://api.github.com/repos/symfony/service-contracts/zipball/40da9cc13ec349d9e4966ce18b5fbcd724ab10a4",
- "reference": "40da9cc13ec349d9e4966ce18b5fbcd724ab10a4",
+ "url": "https://api.github.com/repos/symfony/service-contracts/zipball/fe07cbc8d837f60caf7018068e350cc5163681a0",
+ "reference": "fe07cbc8d837f60caf7018068e350cc5163681a0",
"shasum": ""
},
"require": {
"php": ">=8.1",
- "psr/container": "^2.0"
+ "psr/container": "^1.1|^2.0"
},
"conflict": {
"ext-psr": "<1.1|>=2"
@@ -8326,7 +8384,7 @@
"standards"
],
"support": {
- "source": "https://github.com/symfony/service-contracts/tree/v3.3.0"
+ "source": "https://github.com/symfony/service-contracts/tree/v3.4.1"
},
"funding": [
{
@@ -8342,24 +8400,24 @@
"type": "tidelift"
}
],
- "time": "2023-05-23T14:45:45+00:00"
+ "time": "2023-12-26T14:02:43+00:00"
},
{
"name": "symfony/string",
- "version": "v6.3.5",
+ "version": "v7.0.4",
"source": {
"type": "git",
"url": "https://github.com/symfony/string.git",
- "reference": "13d76d0fb049051ed12a04bef4f9de8715bea339"
+ "reference": "f5832521b998b0bec40bee688ad5de98d4cf111b"
},
"dist": {
"type": "zip",
- "url": "https://api.github.com/repos/symfony/string/zipball/13d76d0fb049051ed12a04bef4f9de8715bea339",
- "reference": "13d76d0fb049051ed12a04bef4f9de8715bea339",
+ "url": "https://api.github.com/repos/symfony/string/zipball/f5832521b998b0bec40bee688ad5de98d4cf111b",
+ "reference": "f5832521b998b0bec40bee688ad5de98d4cf111b",
"shasum": ""
},
"require": {
- "php": ">=8.1",
+ "php": ">=8.2",
"symfony/polyfill-ctype": "~1.8",
"symfony/polyfill-intl-grapheme": "~1.0",
"symfony/polyfill-intl-normalizer": "~1.0",
@@ -8369,11 +8427,11 @@
"symfony/translation-contracts": "<2.5"
},
"require-dev": {
- "symfony/error-handler": "^5.4|^6.0",
- "symfony/http-client": "^5.4|^6.0",
- "symfony/intl": "^6.2",
+ "symfony/error-handler": "^6.4|^7.0",
+ "symfony/http-client": "^6.4|^7.0",
+ "symfony/intl": "^6.4|^7.0",
"symfony/translation-contracts": "^2.5|^3.0",
- "symfony/var-exporter": "^5.4|^6.0"
+ "symfony/var-exporter": "^6.4|^7.0"
},
"type": "library",
"autoload": {
@@ -8412,7 +8470,7 @@
"utf8"
],
"support": {
- "source": "https://github.com/symfony/string/tree/v6.3.5"
+ "source": "https://github.com/symfony/string/tree/v7.0.4"
},
"funding": [
{
@@ -8428,20 +8486,20 @@
"type": "tidelift"
}
],
- "time": "2023-09-18T10:38:32+00:00"
+ "time": "2024-02-01T13:17:36+00:00"
},
{
"name": "symfony/translation",
- "version": "v6.3.3",
+ "version": "v6.4.4",
"source": {
"type": "git",
"url": "https://github.com/symfony/translation.git",
- "reference": "3ed078c54bc98bbe4414e1e9b2d5e85ed5a5c8bd"
+ "reference": "bce6a5a78e94566641b2594d17e48b0da3184a8e"
},
"dist": {
"type": "zip",
- "url": "https://api.github.com/repos/symfony/translation/zipball/3ed078c54bc98bbe4414e1e9b2d5e85ed5a5c8bd",
- "reference": "3ed078c54bc98bbe4414e1e9b2d5e85ed5a5c8bd",
+ "url": "https://api.github.com/repos/symfony/translation/zipball/bce6a5a78e94566641b2594d17e48b0da3184a8e",
+ "reference": "bce6a5a78e94566641b2594d17e48b0da3184a8e",
"shasum": ""
},
"require": {
@@ -8464,19 +8522,19 @@
"symfony/translation-implementation": "2.3|3.0"
},
"require-dev": {
- "nikic/php-parser": "^4.13",
+ "nikic/php-parser": "^4.18|^5.0",
"psr/log": "^1|^2|^3",
- "symfony/config": "^5.4|^6.0",
- "symfony/console": "^5.4|^6.0",
- "symfony/dependency-injection": "^5.4|^6.0",
- "symfony/finder": "^5.4|^6.0",
+ "symfony/config": "^5.4|^6.0|^7.0",
+ "symfony/console": "^5.4|^6.0|^7.0",
+ "symfony/dependency-injection": "^5.4|^6.0|^7.0",
+ "symfony/finder": "^5.4|^6.0|^7.0",
"symfony/http-client-contracts": "^2.5|^3.0",
- "symfony/http-kernel": "^5.4|^6.0",
- "symfony/intl": "^5.4|^6.0",
+ "symfony/http-kernel": "^5.4|^6.0|^7.0",
+ "symfony/intl": "^5.4|^6.0|^7.0",
"symfony/polyfill-intl-icu": "^1.21",
- "symfony/routing": "^5.4|^6.0",
+ "symfony/routing": "^5.4|^6.0|^7.0",
"symfony/service-contracts": "^2.5|^3",
- "symfony/yaml": "^5.4|^6.0"
+ "symfony/yaml": "^5.4|^6.0|^7.0"
},
"type": "library",
"autoload": {
@@ -8507,7 +8565,7 @@
"description": "Provides tools to internationalize your application",
"homepage": "https://symfony.com",
"support": {
- "source": "https://github.com/symfony/translation/tree/v6.3.3"
+ "source": "https://github.com/symfony/translation/tree/v6.4.4"
},
"funding": [
{
@@ -8523,20 +8581,20 @@
"type": "tidelift"
}
],
- "time": "2023-07-31T07:08:24+00:00"
+ "time": "2024-02-20T13:16:58+00:00"
},
{
"name": "symfony/translation-contracts",
- "version": "v3.3.0",
+ "version": "v3.4.1",
"source": {
"type": "git",
"url": "https://github.com/symfony/translation-contracts.git",
- "reference": "02c24deb352fb0d79db5486c0c79905a85e37e86"
+ "reference": "06450585bf65e978026bda220cdebca3f867fde7"
},
"dist": {
"type": "zip",
- "url": "https://api.github.com/repos/symfony/translation-contracts/zipball/02c24deb352fb0d79db5486c0c79905a85e37e86",
- "reference": "02c24deb352fb0d79db5486c0c79905a85e37e86",
+ "url": "https://api.github.com/repos/symfony/translation-contracts/zipball/06450585bf65e978026bda220cdebca3f867fde7",
+ "reference": "06450585bf65e978026bda220cdebca3f867fde7",
"shasum": ""
},
"require": {
@@ -8585,7 +8643,7 @@
"standards"
],
"support": {
- "source": "https://github.com/symfony/translation-contracts/tree/v3.3.0"
+ "source": "https://github.com/symfony/translation-contracts/tree/v3.4.1"
},
"funding": [
{
@@ -8601,20 +8659,20 @@
"type": "tidelift"
}
],
- "time": "2023-05-30T17:17:10+00:00"
+ "time": "2023-12-26T14:02:43+00:00"
},
{
"name": "symfony/uid",
- "version": "v6.3.0",
+ "version": "v6.4.3",
"source": {
"type": "git",
"url": "https://github.com/symfony/uid.git",
- "reference": "01b0f20b1351d997711c56f1638f7a8c3061e384"
+ "reference": "1d31267211cc3a2fff32bcfc7c1818dac41b6fc0"
},
"dist": {
"type": "zip",
- "url": "https://api.github.com/repos/symfony/uid/zipball/01b0f20b1351d997711c56f1638f7a8c3061e384",
- "reference": "01b0f20b1351d997711c56f1638f7a8c3061e384",
+ "url": "https://api.github.com/repos/symfony/uid/zipball/1d31267211cc3a2fff32bcfc7c1818dac41b6fc0",
+ "reference": "1d31267211cc3a2fff32bcfc7c1818dac41b6fc0",
"shasum": ""
},
"require": {
@@ -8622,7 +8680,7 @@
"symfony/polyfill-uuid": "^1.15"
},
"require-dev": {
- "symfony/console": "^5.4|^6.0"
+ "symfony/console": "^5.4|^6.0|^7.0"
},
"type": "library",
"autoload": {
@@ -8659,7 +8717,7 @@
"uuid"
],
"support": {
- "source": "https://github.com/symfony/uid/tree/v6.3.0"
+ "source": "https://github.com/symfony/uid/tree/v6.4.3"
},
"funding": [
{
@@ -8675,20 +8733,20 @@
"type": "tidelift"
}
],
- "time": "2023-04-08T07:25:02+00:00"
+ "time": "2024-01-23T14:51:35+00:00"
},
{
"name": "symfony/var-dumper",
- "version": "v6.3.5",
+ "version": "v6.4.4",
"source": {
"type": "git",
"url": "https://github.com/symfony/var-dumper.git",
- "reference": "3d9999376be5fea8de47752837a3e1d1c5f69ef5"
+ "reference": "b439823f04c98b84d4366c79507e9da6230944b1"
},
"dist": {
"type": "zip",
- "url": "https://api.github.com/repos/symfony/var-dumper/zipball/3d9999376be5fea8de47752837a3e1d1c5f69ef5",
- "reference": "3d9999376be5fea8de47752837a3e1d1c5f69ef5",
+ "url": "https://api.github.com/repos/symfony/var-dumper/zipball/b439823f04c98b84d4366c79507e9da6230944b1",
+ "reference": "b439823f04c98b84d4366c79507e9da6230944b1",
"shasum": ""
},
"require": {
@@ -8701,10 +8759,11 @@
},
"require-dev": {
"ext-iconv": "*",
- "symfony/console": "^5.4|^6.0",
- "symfony/http-kernel": "^5.4|^6.0",
- "symfony/process": "^5.4|^6.0",
- "symfony/uid": "^5.4|^6.0",
+ "symfony/console": "^5.4|^6.0|^7.0",
+ "symfony/error-handler": "^6.3|^7.0",
+ "symfony/http-kernel": "^5.4|^6.0|^7.0",
+ "symfony/process": "^5.4|^6.0|^7.0",
+ "symfony/uid": "^5.4|^6.0|^7.0",
"twig/twig": "^2.13|^3.0.4"
},
"bin": [
@@ -8743,7 +8802,7 @@
"dump"
],
"support": {
- "source": "https://github.com/symfony/var-dumper/tree/v6.3.5"
+ "source": "https://github.com/symfony/var-dumper/tree/v6.4.4"
},
"funding": [
{
@@ -8759,7 +8818,7 @@
"type": "tidelift"
}
],
- "time": "2023-09-12T10:11:35+00:00"
+ "time": "2024-02-15T11:23:52+00:00"
},
{
"name": "symfony/var-exporter",
@@ -8899,23 +8958,23 @@
},
{
"name": "tijsverkoyen/css-to-inline-styles",
- "version": "2.2.6",
+ "version": "v2.2.7",
"source": {
"type": "git",
"url": "https://github.com/tijsverkoyen/CssToInlineStyles.git",
- "reference": "c42125b83a4fa63b187fdf29f9c93cb7733da30c"
+ "reference": "83ee6f38df0a63106a9e4536e3060458b74ccedb"
},
"dist": {
"type": "zip",
- "url": "https://api.github.com/repos/tijsverkoyen/CssToInlineStyles/zipball/c42125b83a4fa63b187fdf29f9c93cb7733da30c",
- "reference": "c42125b83a4fa63b187fdf29f9c93cb7733da30c",
+ "url": "https://api.github.com/repos/tijsverkoyen/CssToInlineStyles/zipball/83ee6f38df0a63106a9e4536e3060458b74ccedb",
+ "reference": "83ee6f38df0a63106a9e4536e3060458b74ccedb",
"shasum": ""
},
"require": {
"ext-dom": "*",
"ext-libxml": "*",
"php": "^5.5 || ^7.0 || ^8.0",
- "symfony/css-selector": "^2.7 || ^3.0 || ^4.0 || ^5.0 || ^6.0"
+ "symfony/css-selector": "^2.7 || ^3.0 || ^4.0 || ^5.0 || ^6.0 || ^7.0"
},
"require-dev": {
"phpunit/phpunit": "^4.8.35 || ^5.7 || ^6.0 || ^7.5 || ^8.5.21 || ^9.5.10"
@@ -8946,32 +9005,33 @@
"homepage": "https://github.com/tijsverkoyen/CssToInlineStyles",
"support": {
"issues": "https://github.com/tijsverkoyen/CssToInlineStyles/issues",
- "source": "https://github.com/tijsverkoyen/CssToInlineStyles/tree/2.2.6"
+ "source": "https://github.com/tijsverkoyen/CssToInlineStyles/tree/v2.2.7"
},
- "time": "2023-01-03T09:29:04+00:00"
+ "time": "2023-12-08T13:03:43+00:00"
},
{
"name": "twig/twig",
- "version": "v3.7.1",
+ "version": "v3.8.0",
"source": {
"type": "git",
"url": "https://github.com/twigphp/Twig.git",
- "reference": "a0ce373a0ca3bf6c64b9e3e2124aca502ba39554"
+ "reference": "9d15f0ac07f44dc4217883ec6ae02fd555c6f71d"
},
"dist": {
"type": "zip",
- "url": "https://api.github.com/repos/twigphp/Twig/zipball/a0ce373a0ca3bf6c64b9e3e2124aca502ba39554",
- "reference": "a0ce373a0ca3bf6c64b9e3e2124aca502ba39554",
+ "url": "https://api.github.com/repos/twigphp/Twig/zipball/9d15f0ac07f44dc4217883ec6ae02fd555c6f71d",
+ "reference": "9d15f0ac07f44dc4217883ec6ae02fd555c6f71d",
"shasum": ""
},
"require": {
"php": ">=7.2.5",
"symfony/polyfill-ctype": "^1.8",
- "symfony/polyfill-mbstring": "^1.3"
+ "symfony/polyfill-mbstring": "^1.3",
+ "symfony/polyfill-php80": "^1.22"
},
"require-dev": {
"psr/container": "^1.0|^2.0",
- "symfony/phpunit-bridge": "^5.4.9|^6.3"
+ "symfony/phpunit-bridge": "^5.4.9|^6.3|^7.0"
},
"type": "library",
"autoload": {
@@ -9007,7 +9067,7 @@
],
"support": {
"issues": "https://github.com/twigphp/Twig/issues",
- "source": "https://github.com/twigphp/Twig/tree/v3.7.1"
+ "source": "https://github.com/twigphp/Twig/tree/v3.8.0"
},
"funding": [
{
@@ -9019,35 +9079,35 @@
"type": "tidelift"
}
],
- "time": "2023-08-28T11:09:02+00:00"
+ "time": "2023-11-21T18:54:41+00:00"
},
{
"name": "vlucas/phpdotenv",
- "version": "v5.5.0",
+ "version": "v5.6.0",
"source": {
"type": "git",
"url": "https://github.com/vlucas/phpdotenv.git",
- "reference": "1a7ea2afc49c3ee6d87061f5a233e3a035d0eae7"
+ "reference": "2cf9fb6054c2bb1d59d1f3817706ecdb9d2934c4"
},
"dist": {
"type": "zip",
- "url": "https://api.github.com/repos/vlucas/phpdotenv/zipball/1a7ea2afc49c3ee6d87061f5a233e3a035d0eae7",
- "reference": "1a7ea2afc49c3ee6d87061f5a233e3a035d0eae7",
+ "url": "https://api.github.com/repos/vlucas/phpdotenv/zipball/2cf9fb6054c2bb1d59d1f3817706ecdb9d2934c4",
+ "reference": "2cf9fb6054c2bb1d59d1f3817706ecdb9d2934c4",
"shasum": ""
},
"require": {
"ext-pcre": "*",
- "graham-campbell/result-type": "^1.0.2",
- "php": "^7.1.3 || ^8.0",
- "phpoption/phpoption": "^1.8",
- "symfony/polyfill-ctype": "^1.23",
- "symfony/polyfill-mbstring": "^1.23.1",
- "symfony/polyfill-php80": "^1.23.1"
+ "graham-campbell/result-type": "^1.1.2",
+ "php": "^7.2.5 || ^8.0",
+ "phpoption/phpoption": "^1.9.2",
+ "symfony/polyfill-ctype": "^1.24",
+ "symfony/polyfill-mbstring": "^1.24",
+ "symfony/polyfill-php80": "^1.24"
},
"require-dev": {
- "bamarni/composer-bin-plugin": "^1.4.1",
+ "bamarni/composer-bin-plugin": "^1.8.2",
"ext-filter": "*",
- "phpunit/phpunit": "^7.5.20 || ^8.5.30 || ^9.5.25"
+ "phpunit/phpunit": "^8.5.34 || ^9.6.13 || ^10.4.2"
},
"suggest": {
"ext-filter": "Required to use the boolean validator."
@@ -9059,7 +9119,7 @@
"forward-command": true
},
"branch-alias": {
- "dev-master": "5.5-dev"
+ "dev-master": "5.6-dev"
}
},
"autoload": {
@@ -9091,7 +9151,7 @@
],
"support": {
"issues": "https://github.com/vlucas/phpdotenv/issues",
- "source": "https://github.com/vlucas/phpdotenv/tree/v5.5.0"
+ "source": "https://github.com/vlucas/phpdotenv/tree/v5.6.0"
},
"funding": [
{
@@ -9103,7 +9163,7 @@
"type": "tidelift"
}
],
- "time": "2022-10-16T01:01:54+00:00"
+ "time": "2023-11-12T22:43:29+00:00"
},
{
"name": "voku/portable-ascii",
@@ -9240,41 +9300,125 @@
],
"packages-dev": [
{
- "name": "barryvdh/laravel-ide-helper",
- "version": "v2.13.0",
+ "name": "barryvdh/laravel-debugbar",
+ "version": "v3.10.6",
"source": {
"type": "git",
- "url": "https://github.com/barryvdh/laravel-ide-helper.git",
- "reference": "81d5b223ff067a1f38e14c100997e153b837fe4a"
+ "url": "https://github.com/barryvdh/laravel-debugbar.git",
+ "reference": "1fcb37307ebb32207dce16fa160a92b14d8b671f"
},
"dist": {
"type": "zip",
- "url": "https://api.github.com/repos/barryvdh/laravel-ide-helper/zipball/81d5b223ff067a1f38e14c100997e153b837fe4a",
- "reference": "81d5b223ff067a1f38e14c100997e153b837fe4a",
+ "url": "https://api.github.com/repos/barryvdh/laravel-debugbar/zipball/1fcb37307ebb32207dce16fa160a92b14d8b671f",
+ "reference": "1fcb37307ebb32207dce16fa160a92b14d8b671f",
+ "shasum": ""
+ },
+ "require": {
+ "illuminate/routing": "^9|^10|^11",
+ "illuminate/session": "^9|^10|^11",
+ "illuminate/support": "^9|^10|^11",
+ "maximebf/debugbar": "~1.20.1",
+ "php": "^8.0",
+ "symfony/finder": "^6|^7"
+ },
+ "require-dev": {
+ "mockery/mockery": "^1.3.3",
+ "orchestra/testbench-dusk": "^5|^6|^7|^8|^9",
+ "phpunit/phpunit": "^9.6|^10.5",
+ "squizlabs/php_codesniffer": "^3.5"
+ },
+ "type": "library",
+ "extra": {
+ "branch-alias": {
+ "dev-master": "3.10-dev"
+ },
+ "laravel": {
+ "providers": [
+ "Barryvdh\\Debugbar\\ServiceProvider"
+ ],
+ "aliases": {
+ "Debugbar": "Barryvdh\\Debugbar\\Facades\\Debugbar"
+ }
+ }
+ },
+ "autoload": {
+ "files": [
+ "src/helpers.php"
+ ],
+ "psr-4": {
+ "Barryvdh\\Debugbar\\": "src/"
+ }
+ },
+ "notification-url": "https://packagist.org/downloads/",
+ "license": [
+ "MIT"
+ ],
+ "authors": [
+ {
+ "name": "Barry vd. Heuvel",
+ "email": "barryvdh@gmail.com"
+ }
+ ],
+ "description": "PHP Debugbar integration for Laravel",
+ "keywords": [
+ "debug",
+ "debugbar",
+ "laravel",
+ "profiler",
+ "webprofiler"
+ ],
+ "support": {
+ "issues": "https://github.com/barryvdh/laravel-debugbar/issues",
+ "source": "https://github.com/barryvdh/laravel-debugbar/tree/v3.10.6"
+ },
+ "funding": [
+ {
+ "url": "https://fruitcake.nl",
+ "type": "custom"
+ },
+ {
+ "url": "https://github.com/barryvdh",
+ "type": "github"
+ }
+ ],
+ "time": "2024-03-01T14:41:13+00:00"
+ },
+ {
+ "name": "barryvdh/laravel-ide-helper",
+ "version": "v2.15.1",
+ "source": {
+ "type": "git",
+ "url": "https://github.com/barryvdh/laravel-ide-helper.git",
+ "reference": "77831852bb7bc54f287246d32eb91274eaf87f8b"
+ },
+ "dist": {
+ "type": "zip",
+ "url": "https://api.github.com/repos/barryvdh/laravel-ide-helper/zipball/77831852bb7bc54f287246d32eb91274eaf87f8b",
+ "reference": "77831852bb7bc54f287246d32eb91274eaf87f8b",
"shasum": ""
},
"require": {
"barryvdh/reflection-docblock": "^2.0.6",
"composer/class-map-generator": "^1.0",
- "doctrine/dbal": "^2.6 || ^3",
+ "doctrine/dbal": "^2.6 || ^3.1.4",
"ext-json": "*",
- "illuminate/console": "^8 || ^9 || ^10",
- "illuminate/filesystem": "^8 || ^9 || ^10",
- "illuminate/support": "^8 || ^9 || ^10",
- "nikic/php-parser": "^4.7",
- "php": "^7.3 || ^8.0",
+ "illuminate/console": "^9 || ^10",
+ "illuminate/filesystem": "^9 || ^10",
+ "illuminate/support": "^9 || ^10",
+ "nikic/php-parser": "^4.18 || ^5",
+ "php": "^8.0",
"phpdocumentor/type-resolver": "^1.1.0"
},
"require-dev": {
"ext-pdo_sqlite": "*",
- "friendsofphp/php-cs-fixer": "^2",
- "illuminate/config": "^8 || ^9 || ^10",
- "illuminate/view": "^8 || ^9 || ^10",
+ "friendsofphp/php-cs-fixer": "^3",
+ "illuminate/config": "^9 || ^10",
+ "illuminate/view": "^9 || ^10",
"mockery/mockery": "^1.4",
- "orchestra/testbench": "^6 || ^7 || ^8",
- "phpunit/phpunit": "^8.5 || ^9",
- "spatie/phpunit-snapshot-assertions": "^3 || ^4",
- "vimeo/psalm": "^3.12"
+ "orchestra/testbench": "^7 || ^8",
+ "phpunit/phpunit": "^9",
+ "spatie/phpunit-snapshot-assertions": "^4",
+ "vimeo/psalm": "^5.4"
},
"suggest": {
"illuminate/events": "Required for automatic helper generation (^6|^7|^8|^9|^10)."
@@ -9282,7 +9426,7 @@
"type": "library",
"extra": {
"branch-alias": {
- "dev-master": "2.12-dev"
+ "dev-master": "2.15-dev"
},
"laravel": {
"providers": [
@@ -9319,7 +9463,7 @@
],
"support": {
"issues": "https://github.com/barryvdh/laravel-ide-helper/issues",
- "source": "https://github.com/barryvdh/laravel-ide-helper/tree/v2.13.0"
+ "source": "https://github.com/barryvdh/laravel-ide-helper/tree/v2.15.1"
},
"funding": [
{
@@ -9331,7 +9475,7 @@
"type": "github"
}
],
- "time": "2023-02-04T13:56:40+00:00"
+ "time": "2024-02-15T14:23:20+00:00"
},
{
"name": "barryvdh/reflection-docblock",
@@ -9531,39 +9675,38 @@
},
{
"name": "ergebnis/phpstan-rules",
- "version": "2.1.0",
+ "version": "2.2.0",
"source": {
"type": "git",
"url": "https://github.com/ergebnis/phpstan-rules.git",
- "reference": "119e229c48688946450ccca9f1c57c9ca4fb6f02"
+ "reference": "2e9946491d39ea1eb043738309895e08f025a7a0"
},
"dist": {
"type": "zip",
- "url": "https://api.github.com/repos/ergebnis/phpstan-rules/zipball/119e229c48688946450ccca9f1c57c9ca4fb6f02",
- "reference": "119e229c48688946450ccca9f1c57c9ca4fb6f02",
+ "url": "https://api.github.com/repos/ergebnis/phpstan-rules/zipball/2e9946491d39ea1eb043738309895e08f025a7a0",
+ "reference": "2e9946491d39ea1eb043738309895e08f025a7a0",
"shasum": ""
},
"require": {
"ext-mbstring": "*",
- "nikic/php-parser": "^4.2.3",
+ "nikic/php-parser": "^4.2.3 || ^5.0.0",
"php": "~8.1.0 || ~8.2.0 || ~8.3.0",
"phpstan/phpstan": "^1.10.21"
},
"require-dev": {
- "doctrine/orm": "^2.16.1",
- "ergebnis/composer-normalize": "^2.35.0",
- "ergebnis/license": "^2.1.0",
- "ergebnis/php-cs-fixer-config": "^5.13.0",
- "ergebnis/phpunit-slow-test-detector": "^2.3.0",
- "infection/infection": "~0.27.0",
- "nette/di": "^3.1.3",
+ "doctrine/orm": "^3.0.0",
+ "ergebnis/composer-normalize": "^2.42.0",
+ "ergebnis/license": "^2.4.0",
+ "ergebnis/php-cs-fixer-config": "^6.22.0",
+ "ergebnis/phpunit-slow-test-detector": "^2.10.0",
+ "nette/di": "^3.2.0",
"phpstan/phpstan-deprecation-rules": "^1.1.4",
- "phpstan/phpstan-strict-rules": "^1.1.0",
- "phpunit/phpunit": "^10.3.2",
+ "phpstan/phpstan-strict-rules": "^1.5.2",
+ "phpunit/phpunit": "^10.5.10",
"psalm/plugin-phpunit": "~0.18.4",
- "psr/container": "^1.1.2",
- "rector/rector": "~0.17.13",
- "vimeo/psalm": "^5.14.1"
+ "psr/container": "^2.0.2",
+ "rector/rector": "^1.0.0",
+ "vimeo/psalm": "^5.21.1"
},
"type": "phpstan-extension",
"extra": {
@@ -9585,34 +9728,35 @@
"authors": [
{
"name": "Andreas Möller",
- "email": "am@localheinz.com"
+ "email": "am@localheinz.com",
+ "homepage": "https://localheinz.com"
}
],
- "description": "Provides additional rules for phpstan/phpstan.",
+ "description": "Provides rules for phpstan/phpstan.",
"homepage": "https://github.com/ergebnis/phpstan-rules",
"keywords": [
"PHPStan",
- "phpstan-extreme-rules",
"phpstan-rules"
],
"support": {
"issues": "https://github.com/ergebnis/phpstan-rules/issues",
+ "security": "https://github.com/ergebnis/phpstan-rules/blob/main/.github/SECURITY.md",
"source": "https://github.com/ergebnis/phpstan-rules"
},
- "time": "2023-08-17T10:28:37+00:00"
+ "time": "2024-02-07T17:49:28+00:00"
},
{
"name": "fakerphp/faker",
- "version": "v1.23.0",
+ "version": "v1.23.1",
"source": {
"type": "git",
"url": "https://github.com/FakerPHP/Faker.git",
- "reference": "e3daa170d00fde61ea7719ef47bb09bb8f1d9b01"
+ "reference": "bfb4fe148adbf78eff521199619b93a52ae3554b"
},
"dist": {
"type": "zip",
- "url": "https://api.github.com/repos/FakerPHP/Faker/zipball/e3daa170d00fde61ea7719ef47bb09bb8f1d9b01",
- "reference": "e3daa170d00fde61ea7719ef47bb09bb8f1d9b01",
+ "url": "https://api.github.com/repos/FakerPHP/Faker/zipball/bfb4fe148adbf78eff521199619b93a52ae3554b",
+ "reference": "bfb4fe148adbf78eff521199619b93a52ae3554b",
"shasum": ""
},
"require": {
@@ -9638,11 +9782,6 @@
"ext-mbstring": "Required for multibyte Unicode string functionality."
},
"type": "library",
- "extra": {
- "branch-alias": {
- "dev-main": "v1.21-dev"
- }
- },
"autoload": {
"psr-4": {
"Faker\\": "src/Faker/"
@@ -9665,9 +9804,9 @@
],
"support": {
"issues": "https://github.com/FakerPHP/Faker/issues",
- "source": "https://github.com/FakerPHP/Faker/tree/v1.23.0"
+ "source": "https://github.com/FakerPHP/Faker/tree/v1.23.1"
},
- "time": "2023-06-12T08:44:38+00:00"
+ "time": "2024-01-02T13:46:09+00:00"
},
{
"name": "hamcrest/hamcrest-php",
@@ -9721,17 +9860,185 @@
"time": "2020-07-09T08:09:16+00:00"
},
{
- "name": "mockery/mockery",
- "version": "1.6.6",
+ "name": "larastan/larastan",
+ "version": "v2.9.2",
"source": {
"type": "git",
- "url": "https://github.com/mockery/mockery.git",
- "reference": "b8e0bb7d8c604046539c1115994632c74dcb361e"
+ "url": "https://github.com/larastan/larastan.git",
+ "reference": "a79b46b96060504b400890674b83f66aa7f5db6d"
},
"dist": {
"type": "zip",
- "url": "https://api.github.com/repos/mockery/mockery/zipball/b8e0bb7d8c604046539c1115994632c74dcb361e",
- "reference": "b8e0bb7d8c604046539c1115994632c74dcb361e",
+ "url": "https://api.github.com/repos/larastan/larastan/zipball/a79b46b96060504b400890674b83f66aa7f5db6d",
+ "reference": "a79b46b96060504b400890674b83f66aa7f5db6d",
+ "shasum": ""
+ },
+ "require": {
+ "ext-json": "*",
+ "illuminate/console": "^9.52.16 || ^10.28.0 || ^11.0",
+ "illuminate/container": "^9.52.16 || ^10.28.0 || ^11.0",
+ "illuminate/contracts": "^9.52.16 || ^10.28.0 || ^11.0",
+ "illuminate/database": "^9.52.16 || ^10.28.0 || ^11.0",
+ "illuminate/http": "^9.52.16 || ^10.28.0 || ^11.0",
+ "illuminate/pipeline": "^9.52.16 || ^10.28.0 || ^11.0",
+ "illuminate/support": "^9.52.16 || ^10.28.0 || ^11.0",
+ "php": "^8.0.2",
+ "phpmyadmin/sql-parser": "^5.8.2",
+ "phpstan/phpstan": "^1.10.50"
+ },
+ "require-dev": {
+ "doctrine/coding-standard": "^12.0",
+ "nikic/php-parser": "^4.17.1",
+ "orchestra/canvas": "^7.11.1 || ^8.11.0 || ^9.0.0",
+ "orchestra/testbench": "^7.33.0 || ^8.13.0 || ^9.0.0",
+ "phpunit/phpunit": "^9.6.13 || ^10.5"
+ },
+ "suggest": {
+ "orchestra/testbench": "Using Larastan for analysing a package needs Testbench"
+ },
+ "type": "phpstan-extension",
+ "extra": {
+ "branch-alias": {
+ "dev-master": "2.0-dev"
+ },
+ "phpstan": {
+ "includes": [
+ "extension.neon"
+ ]
+ }
+ },
+ "autoload": {
+ "psr-4": {
+ "Larastan\\Larastan\\": "src/"
+ }
+ },
+ "notification-url": "https://packagist.org/downloads/",
+ "license": [
+ "MIT"
+ ],
+ "authors": [
+ {
+ "name": "Can Vural",
+ "email": "can9119@gmail.com"
+ },
+ {
+ "name": "Nuno Maduro",
+ "email": "enunomaduro@gmail.com"
+ }
+ ],
+ "description": "Larastan - Discover bugs in your code without running it. A phpstan/phpstan wrapper for Laravel",
+ "keywords": [
+ "PHPStan",
+ "code analyse",
+ "code analysis",
+ "larastan",
+ "laravel",
+ "package",
+ "php",
+ "static analysis"
+ ],
+ "support": {
+ "issues": "https://github.com/larastan/larastan/issues",
+ "source": "https://github.com/larastan/larastan/tree/v2.9.2"
+ },
+ "funding": [
+ {
+ "url": "https://www.paypal.com/paypalme/enunomaduro",
+ "type": "custom"
+ },
+ {
+ "url": "https://github.com/canvural",
+ "type": "github"
+ },
+ {
+ "url": "https://github.com/nunomaduro",
+ "type": "github"
+ },
+ {
+ "url": "https://www.patreon.com/nunomaduro",
+ "type": "patreon"
+ }
+ ],
+ "time": "2024-02-27T03:16:03+00:00"
+ },
+ {
+ "name": "maximebf/debugbar",
+ "version": "v1.20.2",
+ "source": {
+ "type": "git",
+ "url": "https://github.com/maximebf/php-debugbar.git",
+ "reference": "484625c23a4fa4f303617f29fcacd42951c9c01d"
+ },
+ "dist": {
+ "type": "zip",
+ "url": "https://api.github.com/repos/maximebf/php-debugbar/zipball/484625c23a4fa4f303617f29fcacd42951c9c01d",
+ "reference": "484625c23a4fa4f303617f29fcacd42951c9c01d",
+ "shasum": ""
+ },
+ "require": {
+ "php": "^7.1|^8",
+ "psr/log": "^1|^2|^3",
+ "symfony/var-dumper": "^4|^5|^6|^7"
+ },
+ "require-dev": {
+ "phpunit/phpunit": ">=7.5.20 <10.0",
+ "twig/twig": "^1.38|^2.7|^3.0"
+ },
+ "suggest": {
+ "kriswallsmith/assetic": "The best way to manage assets",
+ "monolog/monolog": "Log using Monolog",
+ "predis/predis": "Redis storage"
+ },
+ "type": "library",
+ "extra": {
+ "branch-alias": {
+ "dev-master": "1.20-dev"
+ }
+ },
+ "autoload": {
+ "psr-4": {
+ "DebugBar\\": "src/DebugBar/"
+ }
+ },
+ "notification-url": "https://packagist.org/downloads/",
+ "license": [
+ "MIT"
+ ],
+ "authors": [
+ {
+ "name": "Maxime Bouroumeau-Fuseau",
+ "email": "maxime.bouroumeau@gmail.com",
+ "homepage": "http://maximebf.com"
+ },
+ {
+ "name": "Barry vd. Heuvel",
+ "email": "barryvdh@gmail.com"
+ }
+ ],
+ "description": "Debug bar in the browser for php application",
+ "homepage": "https://github.com/maximebf/php-debugbar",
+ "keywords": [
+ "debug",
+ "debugbar"
+ ],
+ "support": {
+ "issues": "https://github.com/maximebf/php-debugbar/issues",
+ "source": "https://github.com/maximebf/php-debugbar/tree/v1.20.2"
+ },
+ "time": "2024-02-15T10:49:09+00:00"
+ },
+ {
+ "name": "mockery/mockery",
+ "version": "1.6.7",
+ "source": {
+ "type": "git",
+ "url": "https://github.com/mockery/mockery.git",
+ "reference": "0cc058854b3195ba21dc6b1f7b1f60f4ef3a9c06"
+ },
+ "dist": {
+ "type": "zip",
+ "url": "https://api.github.com/repos/mockery/mockery/zipball/0cc058854b3195ba21dc6b1f7b1f60f4ef3a9c06",
+ "reference": "0cc058854b3195ba21dc6b1f7b1f60f4ef3a9c06",
"shasum": ""
},
"require": {
@@ -9744,9 +10051,7 @@
},
"require-dev": {
"phpunit/phpunit": "^8.5 || ^9.6.10",
- "psalm/plugin-phpunit": "^0.18.4",
- "symplify/easy-coding-standard": "^11.5.0",
- "vimeo/psalm": "^4.30"
+ "symplify/easy-coding-standard": "^12.0.8"
},
"type": "library",
"autoload": {
@@ -9803,7 +10108,7 @@
"security": "https://github.com/mockery/mockery/security/advisories",
"source": "https://github.com/mockery/mockery"
},
- "time": "2023-08-09T00:03:52+00:00"
+ "time": "2023-12-10T02:24:34+00:00"
},
{
"name": "myclabs/deep-copy",
@@ -9866,25 +10171,27 @@
},
{
"name": "nikic/php-parser",
- "version": "v4.17.1",
+ "version": "v5.0.1",
"source": {
"type": "git",
"url": "https://github.com/nikic/PHP-Parser.git",
- "reference": "a6303e50c90c355c7eeee2c4a8b27fe8dc8fef1d"
+ "reference": "2218c2252c874a4624ab2f613d86ac32d227bc69"
},
"dist": {
"type": "zip",
- "url": "https://api.github.com/repos/nikic/PHP-Parser/zipball/a6303e50c90c355c7eeee2c4a8b27fe8dc8fef1d",
- "reference": "a6303e50c90c355c7eeee2c4a8b27fe8dc8fef1d",
+ "url": "https://api.github.com/repos/nikic/PHP-Parser/zipball/2218c2252c874a4624ab2f613d86ac32d227bc69",
+ "reference": "2218c2252c874a4624ab2f613d86ac32d227bc69",
"shasum": ""
},
"require": {
+ "ext-ctype": "*",
+ "ext-json": "*",
"ext-tokenizer": "*",
- "php": ">=7.0"
+ "php": ">=7.4"
},
"require-dev": {
"ircmaxell/php-yacc": "^0.0.7",
- "phpunit/phpunit": "^6.5 || ^7.0 || ^8.0 || ^9.0"
+ "phpunit/phpunit": "^7.0 || ^8.0 || ^9.0"
},
"bin": [
"bin/php-parse"
@@ -9892,7 +10199,7 @@
"type": "library",
"extra": {
"branch-alias": {
- "dev-master": "4.9-dev"
+ "dev-master": "5.0-dev"
}
},
"autoload": {
@@ -9916,105 +10223,9 @@
],
"support": {
"issues": "https://github.com/nikic/PHP-Parser/issues",
- "source": "https://github.com/nikic/PHP-Parser/tree/v4.17.1"
+ "source": "https://github.com/nikic/PHP-Parser/tree/v5.0.1"
},
- "time": "2023-08-13T19:53:39+00:00"
- },
- {
- "name": "nunomaduro/larastan",
- "version": "v2.6.4",
- "source": {
- "type": "git",
- "url": "https://github.com/nunomaduro/larastan.git",
- "reference": "6c5e8820f3db6397546f3ce48520af9d312aed27"
- },
- "dist": {
- "type": "zip",
- "url": "https://api.github.com/repos/nunomaduro/larastan/zipball/6c5e8820f3db6397546f3ce48520af9d312aed27",
- "reference": "6c5e8820f3db6397546f3ce48520af9d312aed27",
- "shasum": ""
- },
- "require": {
- "ext-json": "*",
- "illuminate/console": "^9.47.0 || ^10.0.0",
- "illuminate/container": "^9.47.0 || ^10.0.0",
- "illuminate/contracts": "^9.47.0 || ^10.0.0",
- "illuminate/database": "^9.47.0 || ^10.0.0",
- "illuminate/http": "^9.47.0 || ^10.0.0",
- "illuminate/pipeline": "^9.47.0 || ^10.0.0",
- "illuminate/support": "^9.47.0 || ^10.0.0",
- "php": "^8.0.2",
- "phpmyadmin/sql-parser": "^5.6.0",
- "phpstan/phpstan": "~1.10.6"
- },
- "require-dev": {
- "nikic/php-parser": "^4.15.2",
- "orchestra/testbench": "^7.19.0 || ^8.0.0",
- "phpunit/phpunit": "^9.5.27"
- },
- "suggest": {
- "orchestra/testbench": "Using Larastan for analysing a package needs Testbench"
- },
- "type": "phpstan-extension",
- "extra": {
- "branch-alias": {
- "dev-master": "2.0-dev"
- },
- "phpstan": {
- "includes": [
- "extension.neon"
- ]
- }
- },
- "autoload": {
- "psr-4": {
- "NunoMaduro\\Larastan\\": "src/"
- }
- },
- "notification-url": "https://packagist.org/downloads/",
- "license": [
- "MIT"
- ],
- "authors": [
- {
- "name": "Nuno Maduro",
- "email": "enunomaduro@gmail.com"
- }
- ],
- "description": "Larastan - Discover bugs in your code without running it. A phpstan/phpstan wrapper for Laravel",
- "keywords": [
- "PHPStan",
- "code analyse",
- "code analysis",
- "larastan",
- "laravel",
- "package",
- "php",
- "static analysis"
- ],
- "support": {
- "issues": "https://github.com/nunomaduro/larastan/issues",
- "source": "https://github.com/nunomaduro/larastan/tree/v2.6.4"
- },
- "funding": [
- {
- "url": "https://www.paypal.com/paypalme/enunomaduro",
- "type": "custom"
- },
- {
- "url": "https://github.com/canvural",
- "type": "github"
- },
- {
- "url": "https://github.com/nunomaduro",
- "type": "github"
- },
- {
- "url": "https://www.patreon.com/nunomaduro",
- "type": "patreon"
- }
- ],
- "time": "2023-07-29T12:13:13+00:00"
+ "time": "2024-02-21T19:24:10+00:00"
},
{
"name": "phar-io/manifest",
@@ -10182,21 +10393,21 @@
},
{
"name": "phpdocumentor/type-resolver",
- "version": "1.7.3",
+ "version": "1.8.2",
"source": {
"type": "git",
"url": "https://github.com/phpDocumentor/TypeResolver.git",
- "reference": "3219c6ee25c9ea71e3d9bbaf39c67c9ebd499419"
+ "reference": "153ae662783729388a584b4361f2545e4d841e3c"
},
"dist": {
"type": "zip",
- "url": "https://api.github.com/repos/phpDocumentor/TypeResolver/zipball/3219c6ee25c9ea71e3d9bbaf39c67c9ebd499419",
- "reference": "3219c6ee25c9ea71e3d9bbaf39c67c9ebd499419",
+ "url": "https://api.github.com/repos/phpDocumentor/TypeResolver/zipball/153ae662783729388a584b4361f2545e4d841e3c",
+ "reference": "153ae662783729388a584b4361f2545e4d841e3c",
"shasum": ""
},
"require": {
"doctrine/deprecations": "^1.0",
- "php": "^7.4 || ^8.0",
+ "php": "^7.3 || ^8.0",
"phpdocumentor/reflection-common": "^2.0",
"phpstan/phpdoc-parser": "^1.13"
},
@@ -10234,22 +10445,22 @@
"description": "A PSR-5 based resolver of Class names, Types and Structural Element Names",
"support": {
"issues": "https://github.com/phpDocumentor/TypeResolver/issues",
- "source": "https://github.com/phpDocumentor/TypeResolver/tree/1.7.3"
+ "source": "https://github.com/phpDocumentor/TypeResolver/tree/1.8.2"
},
- "time": "2023-08-12T11:01:26+00:00"
+ "time": "2024-02-23T11:10:43+00:00"
},
{
"name": "phpmyadmin/sql-parser",
- "version": "5.8.2",
+ "version": "5.9.0",
"source": {
"type": "git",
"url": "https://github.com/phpmyadmin/sql-parser.git",
- "reference": "f1720ae19abe6294cb5599594a8a57bc3c8cc287"
+ "reference": "011fa18a4e55591fac6545a821921dd1d61c6984"
},
"dist": {
"type": "zip",
- "url": "https://api.github.com/repos/phpmyadmin/sql-parser/zipball/f1720ae19abe6294cb5599594a8a57bc3c8cc287",
- "reference": "f1720ae19abe6294cb5599594a8a57bc3c8cc287",
+ "url": "https://api.github.com/repos/phpmyadmin/sql-parser/zipball/011fa18a4e55591fac6545a821921dd1d61c6984",
+ "reference": "011fa18a4e55591fac6545a821921dd1d61c6984",
"shasum": ""
},
"require": {
@@ -10280,6 +10491,7 @@
"bin": [
"bin/highlight-query",
"bin/lint-query",
+ "bin/sql-parser",
"bin/tokenize-query"
],
"type": "library",
@@ -10323,20 +10535,64 @@
"type": "other"
}
],
- "time": "2023-09-19T12:34:29+00:00"
+ "time": "2024-01-20T20:34:02+00:00"
},
{
- "name": "phpstan/phpdoc-parser",
- "version": "1.24.2",
+ "name": "phpstan/extension-installer",
+ "version": "1.3.1",
"source": {
"type": "git",
- "url": "https://github.com/phpstan/phpdoc-parser.git",
- "reference": "bcad8d995980440892759db0c32acae7c8e79442"
+ "url": "https://github.com/phpstan/extension-installer.git",
+ "reference": "f45734bfb9984c6c56c4486b71230355f066a58a"
},
"dist": {
"type": "zip",
- "url": "https://api.github.com/repos/phpstan/phpdoc-parser/zipball/bcad8d995980440892759db0c32acae7c8e79442",
- "reference": "bcad8d995980440892759db0c32acae7c8e79442",
+ "url": "https://api.github.com/repos/phpstan/extension-installer/zipball/f45734bfb9984c6c56c4486b71230355f066a58a",
+ "reference": "f45734bfb9984c6c56c4486b71230355f066a58a",
+ "shasum": ""
+ },
+ "require": {
+ "composer-plugin-api": "^2.0",
+ "php": "^7.2 || ^8.0",
+ "phpstan/phpstan": "^1.9.0"
+ },
+ "require-dev": {
+ "composer/composer": "^2.0",
+ "php-parallel-lint/php-parallel-lint": "^1.2.0",
+ "phpstan/phpstan-strict-rules": "^0.11 || ^0.12 || ^1.0"
+ },
+ "type": "composer-plugin",
+ "extra": {
+ "class": "PHPStan\\ExtensionInstaller\\Plugin"
+ },
+ "autoload": {
+ "psr-4": {
+ "PHPStan\\ExtensionInstaller\\": "src/"
+ }
+ },
+ "notification-url": "https://packagist.org/downloads/",
+ "license": [
+ "MIT"
+ ],
+ "description": "Composer plugin for automatic installation of PHPStan extensions",
+ "support": {
+ "issues": "https://github.com/phpstan/extension-installer/issues",
+ "source": "https://github.com/phpstan/extension-installer/tree/1.3.1"
+ },
+ "time": "2023-05-24T08:59:17+00:00"
+ },
+ {
+ "name": "phpstan/phpdoc-parser",
+ "version": "1.26.0",
+ "source": {
+ "type": "git",
+ "url": "https://github.com/phpstan/phpdoc-parser.git",
+ "reference": "231e3186624c03d7e7c890ec662b81e6b0405227"
+ },
+ "dist": {
+ "type": "zip",
+ "url": "https://api.github.com/repos/phpstan/phpdoc-parser/zipball/231e3186624c03d7e7c890ec662b81e6b0405227",
+ "reference": "231e3186624c03d7e7c890ec662b81e6b0405227",
"shasum": ""
},
"require": {
@@ -10368,22 +10624,22 @@
"description": "PHPDoc parser with support for nullable, intersection and generic types",
"support": {
"issues": "https://github.com/phpstan/phpdoc-parser/issues",
- "source": "https://github.com/phpstan/phpdoc-parser/tree/1.24.2"
+ "source": "https://github.com/phpstan/phpdoc-parser/tree/1.26.0"
},
- "time": "2023-09-26T12:28:12+00:00"
+ "time": "2024-02-23T16:05:55+00:00"
},
{
"name": "phpstan/phpstan",
- "version": "1.10.38",
+ "version": "1.10.59",
"source": {
"type": "git",
"url": "https://github.com/phpstan/phpstan.git",
- "reference": "5302bb402c57f00fb3c2c015bac86e0827e4b691"
+ "reference": "e607609388d3a6d418a50a49f7940e8086798281"
},
"dist": {
"type": "zip",
- "url": "https://api.github.com/repos/phpstan/phpstan/zipball/5302bb402c57f00fb3c2c015bac86e0827e4b691",
- "reference": "5302bb402c57f00fb3c2c015bac86e0827e4b691",
+ "url": "https://api.github.com/repos/phpstan/phpstan/zipball/e607609388d3a6d418a50a49f7940e8086798281",
+ "reference": "e607609388d3a6d418a50a49f7940e8086798281",
"shasum": ""
},
"require": {
@@ -10432,7 +10688,7 @@
"type": "tidelift"
}
],
- "time": "2023-10-06T14:19:14+00:00"
+ "time": "2024-02-20T13:59:13+00:00"
},
{
"name": "phpstan/phpstan-deprecation-rules",
@@ -10484,21 +10740,21 @@
},
{
"name": "phpstan/phpstan-strict-rules",
- "version": "1.5.1",
+ "version": "1.5.2",
"source": {
"type": "git",
"url": "https://github.com/phpstan/phpstan-strict-rules.git",
- "reference": "b21c03d4f6f3a446e4311155f4be9d65048218e6"
+ "reference": "7a50e9662ee9f3942e4aaaf3d603653f60282542"
},
"dist": {
"type": "zip",
- "url": "https://api.github.com/repos/phpstan/phpstan-strict-rules/zipball/b21c03d4f6f3a446e4311155f4be9d65048218e6",
- "reference": "b21c03d4f6f3a446e4311155f4be9d65048218e6",
+ "url": "https://api.github.com/repos/phpstan/phpstan-strict-rules/zipball/7a50e9662ee9f3942e4aaaf3d603653f60282542",
+ "reference": "7a50e9662ee9f3942e4aaaf3d603653f60282542",
"shasum": ""
},
"require": {
"php": "^7.2 || ^8.0",
- "phpstan/phpstan": "^1.10"
+ "phpstan/phpstan": "^1.10.34"
},
"require-dev": {
"nikic/php-parser": "^4.13.0",
@@ -10527,29 +10783,29 @@
"description": "Extra strict and opinionated rules for PHPStan",
"support": {
"issues": "https://github.com/phpstan/phpstan-strict-rules/issues",
- "source": "https://github.com/phpstan/phpstan-strict-rules/tree/1.5.1"
+ "source": "https://github.com/phpstan/phpstan-strict-rules/tree/1.5.2"
},
- "time": "2023-03-29T14:47:40+00:00"
+ "time": "2023-10-30T14:35:06+00:00"
},
{
"name": "phpunit/php-code-coverage",
- "version": "10.1.7",
+ "version": "10.1.12",
"source": {
"type": "git",
"url": "https://github.com/sebastianbergmann/php-code-coverage.git",
- "reference": "355324ca4980b8916c18b9db29f3ef484078f26e"
+ "reference": "842f72662d6b9edda84c4b6f13885fd9cd53dc63"
},
"dist": {
"type": "zip",
- "url": "https://api.github.com/repos/sebastianbergmann/php-code-coverage/zipball/355324ca4980b8916c18b9db29f3ef484078f26e",
- "reference": "355324ca4980b8916c18b9db29f3ef484078f26e",
+ "url": "https://api.github.com/repos/sebastianbergmann/php-code-coverage/zipball/842f72662d6b9edda84c4b6f13885fd9cd53dc63",
+ "reference": "842f72662d6b9edda84c4b6f13885fd9cd53dc63",
"shasum": ""
},
"require": {
"ext-dom": "*",
"ext-libxml": "*",
"ext-xmlwriter": "*",
- "nikic/php-parser": "^4.15",
+ "nikic/php-parser": "^4.18 || ^5.0",
"php": ">=8.1",
"phpunit/php-file-iterator": "^4.0",
"phpunit/php-text-template": "^3.0",
@@ -10599,7 +10855,7 @@
"support": {
"issues": "https://github.com/sebastianbergmann/php-code-coverage/issues",
"security": "https://github.com/sebastianbergmann/php-code-coverage/security/policy",
- "source": "https://github.com/sebastianbergmann/php-code-coverage/tree/10.1.7"
+ "source": "https://github.com/sebastianbergmann/php-code-coverage/tree/10.1.12"
},
"funding": [
{
@@ -10607,7 +10863,7 @@
"type": "github"
}
],
- "time": "2023-10-04T15:34:17+00:00"
+ "time": "2024-03-02T07:22:05+00:00"
},
{
"name": "phpunit/php-file-iterator",
@@ -10854,16 +11110,16 @@
},
{
"name": "phpunit/phpunit",
- "version": "10.4.1",
+ "version": "10.5.11",
"source": {
"type": "git",
"url": "https://github.com/sebastianbergmann/phpunit.git",
- "reference": "62bd7af13d282deeb95650077d28ba3600ca321c"
+ "reference": "0d968f6323deb3dbfeba5bfd4929b9415eb7a9a4"
},
"dist": {
"type": "zip",
- "url": "https://api.github.com/repos/sebastianbergmann/phpunit/zipball/62bd7af13d282deeb95650077d28ba3600ca321c",
- "reference": "62bd7af13d282deeb95650077d28ba3600ca321c",
+ "url": "https://api.github.com/repos/sebastianbergmann/phpunit/zipball/0d968f6323deb3dbfeba5bfd4929b9415eb7a9a4",
+ "reference": "0d968f6323deb3dbfeba5bfd4929b9415eb7a9a4",
"shasum": ""
},
"require": {
@@ -10903,7 +11159,7 @@
"type": "library",
"extra": {
"branch-alias": {
- "dev-main": "10.4-dev"
+ "dev-main": "10.5-dev"
}
},
"autoload": {
@@ -10935,7 +11191,7 @@
"support": {
"issues": "https://github.com/sebastianbergmann/phpunit/issues",
"security": "https://github.com/sebastianbergmann/phpunit/security/policy",
- "source": "https://github.com/sebastianbergmann/phpunit/tree/10.4.1"
+ "source": "https://github.com/sebastianbergmann/phpunit/tree/10.5.11"
},
"funding": [
{
@@ -10951,20 +11207,20 @@
"type": "tidelift"
}
],
- "time": "2023-10-08T05:01:11+00:00"
+ "time": "2024-02-25T14:05:00+00:00"
},
{
"name": "sebastian/cli-parser",
- "version": "2.0.0",
+ "version": "2.0.1",
"source": {
"type": "git",
"url": "https://github.com/sebastianbergmann/cli-parser.git",
- "reference": "efdc130dbbbb8ef0b545a994fd811725c5282cae"
+ "reference": "c34583b87e7b7a8055bf6c450c2c77ce32a24084"
},
"dist": {
"type": "zip",
- "url": "https://api.github.com/repos/sebastianbergmann/cli-parser/zipball/efdc130dbbbb8ef0b545a994fd811725c5282cae",
- "reference": "efdc130dbbbb8ef0b545a994fd811725c5282cae",
+ "url": "https://api.github.com/repos/sebastianbergmann/cli-parser/zipball/c34583b87e7b7a8055bf6c450c2c77ce32a24084",
+ "reference": "c34583b87e7b7a8055bf6c450c2c77ce32a24084",
"shasum": ""
},
"require": {
@@ -10999,7 +11255,8 @@
"homepage": "https://github.com/sebastianbergmann/cli-parser",
"support": {
"issues": "https://github.com/sebastianbergmann/cli-parser/issues",
- "source": "https://github.com/sebastianbergmann/cli-parser/tree/2.0.0"
+ "security": "https://github.com/sebastianbergmann/cli-parser/security/policy",
+ "source": "https://github.com/sebastianbergmann/cli-parser/tree/2.0.1"
},
"funding": [
{
@@ -11007,7 +11264,7 @@
"type": "github"
}
],
- "time": "2023-02-03T06:58:15+00:00"
+ "time": "2024-03-02T07:12:49+00:00"
},
{
"name": "sebastian/code-unit",
@@ -11199,20 +11456,20 @@
},
{
"name": "sebastian/complexity",
- "version": "3.1.0",
+ "version": "3.2.0",
"source": {
"type": "git",
"url": "https://github.com/sebastianbergmann/complexity.git",
- "reference": "68cfb347a44871f01e33ab0ef8215966432f6957"
+ "reference": "68ff824baeae169ec9f2137158ee529584553799"
},
"dist": {
"type": "zip",
- "url": "https://api.github.com/repos/sebastianbergmann/complexity/zipball/68cfb347a44871f01e33ab0ef8215966432f6957",
- "reference": "68cfb347a44871f01e33ab0ef8215966432f6957",
+ "url": "https://api.github.com/repos/sebastianbergmann/complexity/zipball/68ff824baeae169ec9f2137158ee529584553799",
+ "reference": "68ff824baeae169ec9f2137158ee529584553799",
"shasum": ""
},
"require": {
- "nikic/php-parser": "^4.10",
+ "nikic/php-parser": "^4.18 || ^5.0",
"php": ">=8.1"
},
"require-dev": {
@@ -11221,7 +11478,7 @@
"type": "library",
"extra": {
"branch-alias": {
- "dev-main": "3.1-dev"
+ "dev-main": "3.2-dev"
}
},
"autoload": {
@@ -11245,7 +11502,7 @@
"support": {
"issues": "https://github.com/sebastianbergmann/complexity/issues",
"security": "https://github.com/sebastianbergmann/complexity/security/policy",
- "source": "https://github.com/sebastianbergmann/complexity/tree/3.1.0"
+ "source": "https://github.com/sebastianbergmann/complexity/tree/3.2.0"
},
"funding": [
{
@@ -11253,20 +11510,20 @@
"type": "github"
}
],
- "time": "2023-09-28T11:50:59+00:00"
+ "time": "2023-12-21T08:37:17+00:00"
},
{
"name": "sebastian/diff",
- "version": "5.0.3",
+ "version": "5.1.1",
"source": {
"type": "git",
"url": "https://github.com/sebastianbergmann/diff.git",
- "reference": "912dc2fbe3e3c1e7873313cc801b100b6c68c87b"
+ "reference": "c41e007b4b62af48218231d6c2275e4c9b975b2e"
},
"dist": {
"type": "zip",
- "url": "https://api.github.com/repos/sebastianbergmann/diff/zipball/912dc2fbe3e3c1e7873313cc801b100b6c68c87b",
- "reference": "912dc2fbe3e3c1e7873313cc801b100b6c68c87b",
+ "url": "https://api.github.com/repos/sebastianbergmann/diff/zipball/c41e007b4b62af48218231d6c2275e4c9b975b2e",
+ "reference": "c41e007b4b62af48218231d6c2275e4c9b975b2e",
"shasum": ""
},
"require": {
@@ -11274,12 +11531,12 @@
},
"require-dev": {
"phpunit/phpunit": "^10.0",
- "symfony/process": "^4.2 || ^5"
+ "symfony/process": "^6.4"
},
"type": "library",
"extra": {
"branch-alias": {
- "dev-main": "5.0-dev"
+ "dev-main": "5.1-dev"
}
},
"autoload": {
@@ -11312,7 +11569,7 @@
"support": {
"issues": "https://github.com/sebastianbergmann/diff/issues",
"security": "https://github.com/sebastianbergmann/diff/security/policy",
- "source": "https://github.com/sebastianbergmann/diff/tree/5.0.3"
+ "source": "https://github.com/sebastianbergmann/diff/tree/5.1.1"
},
"funding": [
{
@@ -11320,7 +11577,7 @@
"type": "github"
}
],
- "time": "2023-05-01T07:48:21+00:00"
+ "time": "2024-03-02T07:15:17+00:00"
},
{
"name": "sebastian/environment",
@@ -11388,16 +11645,16 @@
},
{
"name": "sebastian/exporter",
- "version": "5.1.1",
+ "version": "5.1.2",
"source": {
"type": "git",
"url": "https://github.com/sebastianbergmann/exporter.git",
- "reference": "64f51654862e0f5e318db7e9dcc2292c63cdbddc"
+ "reference": "955288482d97c19a372d3f31006ab3f37da47adf"
},
"dist": {
"type": "zip",
- "url": "https://api.github.com/repos/sebastianbergmann/exporter/zipball/64f51654862e0f5e318db7e9dcc2292c63cdbddc",
- "reference": "64f51654862e0f5e318db7e9dcc2292c63cdbddc",
+ "url": "https://api.github.com/repos/sebastianbergmann/exporter/zipball/955288482d97c19a372d3f31006ab3f37da47adf",
+ "reference": "955288482d97c19a372d3f31006ab3f37da47adf",
"shasum": ""
},
"require": {
@@ -11454,7 +11711,7 @@
"support": {
"issues": "https://github.com/sebastianbergmann/exporter/issues",
"security": "https://github.com/sebastianbergmann/exporter/security/policy",
- "source": "https://github.com/sebastianbergmann/exporter/tree/5.1.1"
+ "source": "https://github.com/sebastianbergmann/exporter/tree/5.1.2"
},
"funding": [
{
@@ -11462,20 +11719,20 @@
"type": "github"
}
],
- "time": "2023-09-24T13:22:09+00:00"
+ "time": "2024-03-02T07:17:12+00:00"
},
{
"name": "sebastian/global-state",
- "version": "6.0.1",
+ "version": "6.0.2",
"source": {
"type": "git",
"url": "https://github.com/sebastianbergmann/global-state.git",
- "reference": "7ea9ead78f6d380d2a667864c132c2f7b83055e4"
+ "reference": "987bafff24ecc4c9ac418cab1145b96dd6e9cbd9"
},
"dist": {
"type": "zip",
- "url": "https://api.github.com/repos/sebastianbergmann/global-state/zipball/7ea9ead78f6d380d2a667864c132c2f7b83055e4",
- "reference": "7ea9ead78f6d380d2a667864c132c2f7b83055e4",
+ "url": "https://api.github.com/repos/sebastianbergmann/global-state/zipball/987bafff24ecc4c9ac418cab1145b96dd6e9cbd9",
+ "reference": "987bafff24ecc4c9ac418cab1145b96dd6e9cbd9",
"shasum": ""
},
"require": {
@@ -11509,14 +11766,14 @@
}
],
"description": "Snapshotting of global state",
- "homepage": "http://www.github.com/sebastianbergmann/global-state",
+ "homepage": "https://www.github.com/sebastianbergmann/global-state",
"keywords": [
"global state"
],
"support": {
"issues": "https://github.com/sebastianbergmann/global-state/issues",
"security": "https://github.com/sebastianbergmann/global-state/security/policy",
- "source": "https://github.com/sebastianbergmann/global-state/tree/6.0.1"
+ "source": "https://github.com/sebastianbergmann/global-state/tree/6.0.2"
},
"funding": [
{
@@ -11524,24 +11781,24 @@
"type": "github"
}
],
- "time": "2023-07-19T07:19:23+00:00"
+ "time": "2024-03-02T07:19:19+00:00"
},
{
"name": "sebastian/lines-of-code",
- "version": "2.0.1",
+ "version": "2.0.2",
"source": {
"type": "git",
"url": "https://github.com/sebastianbergmann/lines-of-code.git",
- "reference": "649e40d279e243d985aa8fb6e74dd5bb28dc185d"
+ "reference": "856e7f6a75a84e339195d48c556f23be2ebf75d0"
},
"dist": {
"type": "zip",
- "url": "https://api.github.com/repos/sebastianbergmann/lines-of-code/zipball/649e40d279e243d985aa8fb6e74dd5bb28dc185d",
- "reference": "649e40d279e243d985aa8fb6e74dd5bb28dc185d",
+ "url": "https://api.github.com/repos/sebastianbergmann/lines-of-code/zipball/856e7f6a75a84e339195d48c556f23be2ebf75d0",
+ "reference": "856e7f6a75a84e339195d48c556f23be2ebf75d0",
"shasum": ""
},
"require": {
- "nikic/php-parser": "^4.10",
+ "nikic/php-parser": "^4.18 || ^5.0",
"php": ">=8.1"
},
"require-dev": {
@@ -11574,7 +11831,7 @@
"support": {
"issues": "https://github.com/sebastianbergmann/lines-of-code/issues",
"security": "https://github.com/sebastianbergmann/lines-of-code/security/policy",
- "source": "https://github.com/sebastianbergmann/lines-of-code/tree/2.0.1"
+ "source": "https://github.com/sebastianbergmann/lines-of-code/tree/2.0.2"
},
"funding": [
{
@@ -11582,7 +11839,7 @@
"type": "github"
}
],
- "time": "2023-08-31T09:25:50+00:00"
+ "time": "2023-12-21T08:38:20+00:00"
},
{
"name": "sebastian/object-enumerator",
@@ -11925,16 +12182,16 @@
},
{
"name": "theseer/tokenizer",
- "version": "1.2.1",
+ "version": "1.2.2",
"source": {
"type": "git",
"url": "https://github.com/theseer/tokenizer.git",
- "reference": "34a41e998c2183e22995f158c581e7b5e755ab9e"
+ "reference": "b2ad5003ca10d4ee50a12da31de12a5774ba6b96"
},
"dist": {
"type": "zip",
- "url": "https://api.github.com/repos/theseer/tokenizer/zipball/34a41e998c2183e22995f158c581e7b5e755ab9e",
- "reference": "34a41e998c2183e22995f158c581e7b5e755ab9e",
+ "url": "https://api.github.com/repos/theseer/tokenizer/zipball/b2ad5003ca10d4ee50a12da31de12a5774ba6b96",
+ "reference": "b2ad5003ca10d4ee50a12da31de12a5774ba6b96",
"shasum": ""
},
"require": {
@@ -11963,7 +12220,7 @@
"description": "A small library for converting tokenized PHP source code into XML and potentially other formats",
"support": {
"issues": "https://github.com/theseer/tokenizer/issues",
- "source": "https://github.com/theseer/tokenizer/tree/1.2.1"
+ "source": "https://github.com/theseer/tokenizer/tree/1.2.2"
},
"funding": [
{
@@ -11971,7 +12228,7 @@
"type": "github"
}
],
- "time": "2021-07-28T10:34:58+00:00"
+ "time": "2023-11-20T00:12:19+00:00"
}
],
"aliases": [],
@@ -11980,7 +12237,7 @@
"prefer-stable": false,
"prefer-lowest": false,
"platform": {
- "php": ">=8.2",
+ "php": ">=8.3",
"ext-bcmath": "*",
"ext-curl": "*",
"ext-fileinfo": "*",
@@ -11998,8 +12255,5 @@
"ext-xmlwriter": "*"
},
"platform-dev": [],
- "platform-overrides": {
- "php": "8.2"
- },
- "plugin-api-version": "2.3.0"
+ "plugin-api-version": "2.6.0"
}
diff --git a/config/app.php b/config/app.php
index a7c44efb4e..a22045103c 100644
--- a/config/app.php
+++ b/config/app.php
@@ -21,6 +21,25 @@
declare(strict_types=1);
+use FireflyIII\Providers\AccountServiceProvider;
+use FireflyIII\Providers\AdminServiceProvider;
+use FireflyIII\Providers\AppServiceProvider;
+use FireflyIII\Providers\AttachmentServiceProvider;
+use FireflyIII\Providers\BillServiceProvider;
+use FireflyIII\Providers\BudgetServiceProvider;
+use FireflyIII\Providers\CategoryServiceProvider;
+use FireflyIII\Providers\CurrencyServiceProvider;
+use FireflyIII\Providers\EventServiceProvider;
+use FireflyIII\Providers\FireflyServiceProvider;
+use FireflyIII\Providers\JournalServiceProvider;
+use FireflyIII\Providers\PiggyBankServiceProvider;
+use FireflyIII\Providers\RecurringServiceProvider;
+use FireflyIII\Providers\RouteServiceProvider;
+use FireflyIII\Providers\RuleGroupServiceProvider;
+use FireflyIII\Providers\RuleServiceProvider;
+use FireflyIII\Providers\SearchServiceProvider;
+use FireflyIII\Providers\SessionServiceProvider;
+use FireflyIII\Providers\TagServiceProvider;
use FireflyIII\Support\Facades\AccountForm;
use FireflyIII\Support\Facades\Amount;
use FireflyIII\Support\Facades\CurrencyForm;
@@ -31,10 +50,71 @@ use FireflyIII\Support\Facades\PiggyBankForm;
use FireflyIII\Support\Facades\Preferences;
use FireflyIII\Support\Facades\RuleForm;
use FireflyIII\Support\Facades\Steam;
+use Illuminate\Auth\AuthServiceProvider;
+use Illuminate\Auth\Passwords\PasswordResetServiceProvider;
+use Illuminate\Broadcasting\BroadcastServiceProvider;
+use Illuminate\Bus\BusServiceProvider;
+use Illuminate\Cache\CacheServiceProvider;
+use Illuminate\Cookie\CookieServiceProvider;
+use Illuminate\Database\DatabaseServiceProvider;
+use Illuminate\Database\Eloquent\Model;
+use Illuminate\Encryption\EncryptionServiceProvider;
+use Illuminate\Filesystem\FilesystemServiceProvider;
+use Illuminate\Foundation\Providers\ConsoleSupportServiceProvider;
+use Illuminate\Foundation\Providers\FoundationServiceProvider;
+use Illuminate\Hashing\HashServiceProvider;
+use Illuminate\Mail\MailServiceProvider;
+use Illuminate\Notifications\NotificationServiceProvider;
+use Illuminate\Pagination\PaginationServiceProvider;
+use Illuminate\Pipeline\PipelineServiceProvider;
+use Illuminate\Queue\QueueServiceProvider;
+use Illuminate\Redis\RedisServiceProvider;
+use Illuminate\Support\Arr;
+use Illuminate\Support\Facades\App;
+use Illuminate\Support\Facades\Artisan;
+use Illuminate\Support\Facades\Auth;
+use Illuminate\Support\Facades\Blade;
+use Illuminate\Support\Facades\Broadcast;
+use Illuminate\Support\Facades\Bus;
+use Illuminate\Support\Facades\Cache;
+use Illuminate\Support\Facades\Config;
+use Illuminate\Support\Facades\Cookie;
+use Illuminate\Support\Facades\Crypt;
+use Illuminate\Support\Facades\DB;
+use Illuminate\Support\Facades\Event;
+use Illuminate\Support\Facades\File;
+use Illuminate\Support\Facades\Gate;
+use Illuminate\Support\Facades\Hash;
+use Illuminate\Support\Facades\Http;
+use Illuminate\Support\Facades\Lang;
+use Illuminate\Support\Facades\Log;
+use Illuminate\Support\Facades\Mail;
+use Illuminate\Support\Facades\Notification;
+use Illuminate\Support\Facades\Password;
+use Illuminate\Support\Facades\Queue;
+use Illuminate\Support\Facades\Redirect;
+use Illuminate\Support\Facades\Redis;
+use Illuminate\Support\Facades\Request;
+use Illuminate\Support\Facades\Response;
+use Illuminate\Support\Facades\Route;
+use Illuminate\Support\Facades\Schema;
+use Illuminate\Support\Facades\Session;
+use Illuminate\Support\Facades\Storage;
+use Illuminate\Support\Facades\URL;
+use Illuminate\Support\Facades\Validator;
+use Illuminate\Support\Facades\View;
+use Illuminate\Support\Str;
+use Illuminate\Translation\TranslationServiceProvider;
+use Illuminate\Validation\ValidationServiceProvider;
+use Illuminate\View\ViewServiceProvider;
+use PragmaRX\Google2FALaravel\Facade;
+use Spatie\Html\Facades\Html;
+use TwigBridge\Facade\Twig;
+use TwigBridge\ServiceProvider;
return [
'name' => envNonEmpty('APP_NAME', 'Firefly III'),
- 'env' => envNonEmpty('APP_ENV', 'local'),
+ 'env' => envNonEmpty('APP_ENV', 'production'),
'debug' => env('APP_DEBUG', false),
'url' => envNonEmpty('APP_URL', 'http://localhost'),
'timezone' => envNonEmpty('TZ', 'UTC'),
@@ -43,104 +123,95 @@ return [
'key' => env('APP_KEY'),
'cipher' => 'AES-256-CBC',
'providers' => [
+ // Laravel Framework Service Providers...
+ AuthServiceProvider::class,
+ BroadcastServiceProvider::class,
+ BusServiceProvider::class,
+ CacheServiceProvider::class,
+ ConsoleSupportServiceProvider::class,
+ CookieServiceProvider::class,
+ DatabaseServiceProvider::class,
+ EncryptionServiceProvider::class,
+ FilesystemServiceProvider::class,
+ FoundationServiceProvider::class,
+ HashServiceProvider::class,
+ MailServiceProvider::class,
+ NotificationServiceProvider::class,
+ PaginationServiceProvider::class,
+ PipelineServiceProvider::class,
+ QueueServiceProvider::class,
+ RedisServiceProvider::class,
+ PasswordResetServiceProvider::class,
+ SessionServiceProvider::class,
+ TranslationServiceProvider::class,
+ ValidationServiceProvider::class,
+ ViewServiceProvider::class,
- /*
- * Laravel Framework Service Providers...
- */
- Illuminate\Auth\AuthServiceProvider::class,
- Illuminate\Broadcasting\BroadcastServiceProvider::class,
- Illuminate\Bus\BusServiceProvider::class,
- Illuminate\Cache\CacheServiceProvider::class,
- Illuminate\Foundation\Providers\ConsoleSupportServiceProvider::class,
- Illuminate\Cookie\CookieServiceProvider::class,
- Illuminate\Database\DatabaseServiceProvider::class,
- Illuminate\Encryption\EncryptionServiceProvider::class,
- Illuminate\Filesystem\FilesystemServiceProvider::class,
- Illuminate\Foundation\Providers\FoundationServiceProvider::class,
- Illuminate\Hashing\HashServiceProvider::class,
- Illuminate\Mail\MailServiceProvider::class,
- Illuminate\Notifications\NotificationServiceProvider::class,
- Illuminate\Pagination\PaginationServiceProvider::class,
- Illuminate\Pipeline\PipelineServiceProvider::class,
- Illuminate\Queue\QueueServiceProvider::class,
- Illuminate\Redis\RedisServiceProvider::class,
- Illuminate\Auth\Passwords\PasswordResetServiceProvider::class,
- FireflyIII\Providers\SessionServiceProvider::class,
- Illuminate\Translation\TranslationServiceProvider::class,
- Illuminate\Validation\ValidationServiceProvider::class,
- Illuminate\View\ViewServiceProvider::class,
+ // Package Service Providers...
- /*
- * Package Service Providers...
- */
-
- /*
- * Application Service Providers...
- */
- FireflyIII\Providers\AppServiceProvider::class,
+ // Application Service Providers...
+ AppServiceProvider::class,
FireflyIII\Providers\AuthServiceProvider::class,
// FireflyIII\Providers\BroadcastServiceProvider::class,
- FireflyIII\Providers\EventServiceProvider::class,
- FireflyIII\Providers\RouteServiceProvider::class,
+ EventServiceProvider::class,
+ RouteServiceProvider::class,
// own stuff:
PragmaRX\Google2FALaravel\ServiceProvider::class,
- TwigBridge\ServiceProvider::class,
+ ServiceProvider::class,
- /*
- * More service providers.
- */
- FireflyIII\Providers\AccountServiceProvider::class,
- FireflyIII\Providers\AttachmentServiceProvider::class,
- FireflyIII\Providers\BillServiceProvider::class,
- FireflyIII\Providers\BudgetServiceProvider::class,
- FireflyIII\Providers\CategoryServiceProvider::class,
- FireflyIII\Providers\CurrencyServiceProvider::class,
- FireflyIII\Providers\FireflyServiceProvider::class,
- FireflyIII\Providers\JournalServiceProvider::class,
- FireflyIII\Providers\PiggyBankServiceProvider::class,
- FireflyIII\Providers\RuleServiceProvider::class,
- FireflyIII\Providers\RuleGroupServiceProvider::class,
- FireflyIII\Providers\SearchServiceProvider::class,
- FireflyIII\Providers\TagServiceProvider::class,
- FireflyIII\Providers\AdminServiceProvider::class,
- FireflyIII\Providers\RecurringServiceProvider::class,
+ // More service providers.
+ AccountServiceProvider::class,
+ AttachmentServiceProvider::class,
+ BillServiceProvider::class,
+ BudgetServiceProvider::class,
+ CategoryServiceProvider::class,
+ CurrencyServiceProvider::class,
+ FireflyServiceProvider::class,
+ JournalServiceProvider::class,
+ PiggyBankServiceProvider::class,
+ RuleServiceProvider::class,
+ RuleGroupServiceProvider::class,
+ SearchServiceProvider::class,
+ TagServiceProvider::class,
+ AdminServiceProvider::class,
+ RecurringServiceProvider::class,
],
'aliases' => [
- 'App' => Illuminate\Support\Facades\App::class,
- 'Artisan' => Illuminate\Support\Facades\Artisan::class,
- 'Auth' => Illuminate\Support\Facades\Auth::class,
- 'Blade' => Illuminate\Support\Facades\Blade::class,
- 'Broadcast' => Illuminate\Support\Facades\Broadcast::class,
- 'Bus' => Illuminate\Support\Facades\Bus::class,
- 'Cache' => Illuminate\Support\Facades\Cache::class,
- 'Config' => Illuminate\Support\Facades\Config::class,
- 'Cookie' => Illuminate\Support\Facades\Cookie::class,
- 'Crypt' => Illuminate\Support\Facades\Crypt::class,
- 'DB' => Illuminate\Support\Facades\DB::class,
- 'Eloquent' => Illuminate\Database\Eloquent\Model::class,
- 'Event' => Illuminate\Support\Facades\Event::class,
- 'File' => Illuminate\Support\Facades\File::class,
- 'Gate' => Illuminate\Support\Facades\Gate::class,
- 'Hash' => Illuminate\Support\Facades\Hash::class,
- 'Lang' => Illuminate\Support\Facades\Lang::class,
- 'Log' => Illuminate\Support\Facades\Log::class,
- 'Mail' => Illuminate\Support\Facades\Mail::class,
- 'Notification' => Illuminate\Support\Facades\Notification::class,
- 'Password' => Illuminate\Support\Facades\Password::class,
- 'Queue' => Illuminate\Support\Facades\Queue::class,
- 'Redirect' => Illuminate\Support\Facades\Redirect::class,
- 'Redis' => Illuminate\Support\Facades\Redis::class,
- 'Request' => Illuminate\Support\Facades\Request::class,
- 'Response' => Illuminate\Support\Facades\Response::class,
- 'Route' => Illuminate\Support\Facades\Route::class,
- 'Schema' => Illuminate\Support\Facades\Schema::class,
- 'Session' => Illuminate\Support\Facades\Session::class,
- 'Storage' => Illuminate\Support\Facades\Storage::class,
- 'URL' => Illuminate\Support\Facades\URL::class,
- 'Validator' => Illuminate\Support\Facades\Validator::class,
- 'View' => Illuminate\Support\Facades\View::class,
- 'Html' => Spatie\Html\Facades\Html::class,
+ 'App' => App::class,
+ 'Artisan' => Artisan::class,
+ 'Auth' => Auth::class,
+ 'Blade' => Blade::class,
+ 'Broadcast' => Broadcast::class,
+ 'Bus' => Bus::class,
+ 'Cache' => Cache::class,
+ 'Config' => Config::class,
+ 'Cookie' => Cookie::class,
+ 'Crypt' => Crypt::class,
+ 'DB' => DB::class,
+ 'Eloquent' => Model::class,
+ 'Event' => Event::class,
+ 'File' => File::class,
+ 'Gate' => Gate::class,
+ 'Hash' => Hash::class,
+ 'Lang' => Lang::class,
+ 'Log' => Log::class,
+ 'Mail' => Mail::class,
+ 'Notification' => Notification::class,
+ 'Password' => Password::class,
+ 'Queue' => Queue::class,
+ 'Redirect' => Redirect::class,
+ 'Redis' => Redis::class,
+ 'Request' => Request::class,
+ 'Response' => Response::class,
+ 'Route' => Route::class,
+ 'Schema' => Schema::class,
+ 'Session' => Session::class,
+ 'Storage' => Storage::class,
+ 'URL' => URL::class,
+ 'Validator' => Validator::class,
+ 'View' => View::class,
+ 'Html' => Html::class,
'Preferences' => Preferences::class,
'FireflyConfig' => FireflyConfig::class,
'Navigation' => Navigation::class,
@@ -151,15 +222,15 @@ return [
'AccountForm' => AccountForm::class,
'PiggyBankForm' => PiggyBankForm::class,
'RuleForm' => RuleForm::class,
- 'Google2FA' => PragmaRX\Google2FALaravel\Facade::class,
- 'Twig' => TwigBridge\Facade\Twig::class,
+ 'Google2FA' => Facade::class,
+ 'Twig' => Twig::class,
- 'Arr' => Illuminate\Support\Arr::class,
- 'Http' => Illuminate\Support\Facades\Http::class,
- 'Str' => Illuminate\Support\Str::class,
+ 'Arr' => Arr::class,
+ 'Http' => Http::class,
+ 'Str' => Str::class,
],
- 'asset_url' => env('ASSET_URL', null),
+ 'asset_url' => env('ASSET_URL', null),
/*
|--------------------------------------------------------------------------
@@ -172,6 +243,5 @@ return [
|
*/
- 'faker_locale' => 'en_US',
-
+ 'faker_locale' => 'en_US',
];
diff --git a/config/auth.php b/config/auth.php
index c645307e39..523a326e2f 100644
--- a/config/auth.php
+++ b/config/auth.php
@@ -20,9 +20,10 @@
*/
declare(strict_types=1);
+use FireflyIII\User;
if ('ldap' === strtolower((string)env('AUTHENTICATION_GUARD'))) {
- die('LDAP is no longer supported by Firefly III v5.7+. Sorry about that. You will have to switch to "remote_user_guard", and use tools like Authelia or Keycloak to use LDAP together with Firefly III.');
+ exit('LDAP is no longer supported by Firefly III v5.7+. Sorry about that. You will have to switch to "remote_user_guard", and use tools like Authelia or Keycloak to use LDAP together with Firefly III.');
}
return [
@@ -37,12 +38,12 @@ return [
|
*/
- 'defaults' => [
+ 'defaults' => [
'guard' => envNonEmpty('AUTHENTICATION_GUARD', 'web'),
'passwords' => 'users',
],
- 'guard_header' => envNonEmpty('AUTHENTICATION_GUARD_HEADER', 'REMOTE_USER'),
- 'guard_email' => envNonEmpty('AUTHENTICATION_GUARD_EMAIL', null),
+ 'guard_header' => envNonEmpty('AUTHENTICATION_GUARD_HEADER', 'REMOTE_USER'),
+ 'guard_email' => envNonEmpty('AUTHENTICATION_GUARD_EMAIL', null),
/*
|--------------------------------------------------------------------------
@@ -61,7 +62,7 @@ return [
|
*/
- 'guards' => [
+ 'guards' => [
'web' => [
'driver' => 'session',
'provider' => 'users',
@@ -93,14 +94,14 @@ return [
|
*/
- 'providers' => [
+ 'providers' => [
'users' => [
'driver' => 'eloquent',
- 'model' => FireflyIII\User::class,
+ 'model' => User::class,
],
'remote_user_provider' => [
'driver' => 'remote_user_provider',
- 'model' => FireflyIII\User::class,
+ 'model' => User::class,
],
],
@@ -119,7 +120,7 @@ return [
|
*/
- 'passwords' => [
+ 'passwords' => [
'users' => [
'provider' => 'users',
'table' => 'password_resets',
@@ -139,5 +140,4 @@ return [
*/
'password_timeout' => 10800,
-
];
diff --git a/config/breadcrumbs.php b/config/breadcrumbs.php
index 0cfb2b1185..d725919eb6 100644
--- a/config/breadcrumbs.php
+++ b/config/breadcrumbs.php
@@ -21,9 +21,10 @@
*/
declare(strict_types=1);
+use Diglactic\Breadcrumbs\Generator;
+use Diglactic\Breadcrumbs\Manager;
return [
-
/*
|--------------------------------------------------------------------------
| View Name
@@ -47,7 +48,7 @@ return [
|
*/
- 'view' => 'partials/layout/breadcrumbs',
+ 'view' => 'partials/layout/breadcrumbs',
/*
|--------------------------------------------------------------------------
@@ -91,9 +92,8 @@ return [
*/
// Manager
- 'manager-class' => Diglactic\Breadcrumbs\Manager::class,
+ 'manager-class' => Manager::class,
// Generator
- 'generator-class' => Diglactic\Breadcrumbs\Generator::class,
-
+ 'generator-class' => Generator::class,
];
diff --git a/config/broadcasting.php b/config/broadcasting.php
index 933bd64870..fb84f4aa64 100644
--- a/config/broadcasting.php
+++ b/config/broadcasting.php
@@ -35,7 +35,7 @@ return [
|
*/
- 'default' => env('BROADCAST_DRIVER', 'null'),
+ 'default' => env('BROADCAST_DRIVER', 'null'),
/*
|--------------------------------------------------------------------------
@@ -49,43 +49,40 @@ return [
*/
'connections' => [
-
'pusher' => [
- 'driver' => 'pusher',
- 'key' => env('PUSHER_APP_KEY'),
- 'secret' => env('PUSHER_APP_SECRET'),
- 'app_id' => env('PUSHER_APP_ID'),
- 'options' => [
- 'cluster' => env('PUSHER_APP_CLUSTER'),
- 'host' => env('PUSHER_HOST') ?: 'api-'.env('PUSHER_APP_CLUSTER', 'mt1').'.pusher.com',
- 'port' => env('PUSHER_PORT', 443),
- 'scheme' => env('PUSHER_SCHEME', 'https'),
+ 'driver' => 'pusher',
+ 'key' => env('PUSHER_APP_KEY'),
+ 'secret' => env('PUSHER_APP_SECRET'),
+ 'app_id' => env('PUSHER_APP_ID'),
+ 'options' => [
+ 'cluster' => env('PUSHER_APP_CLUSTER'),
+ 'host' => null !== env('PUSHER_HOST') ? env('PUSHER_HOST') : 'api-'.env('PUSHER_APP_CLUSTER', 'mt1').'.pusher.com',
+ 'port' => env('PUSHER_PORT', 443),
+ 'scheme' => env('PUSHER_SCHEME', 'https'),
'encrypted' => true,
- 'useTLS' => env('PUSHER_SCHEME', 'https') === 'https',
+ 'useTLS' => 'https' === env('PUSHER_SCHEME', 'https'),
],
'client_options' => [
// Guzzle client options: https://docs.guzzlephp.org/en/stable/request-options.html
],
],
- 'ably' => [
+ 'ably' => [
'driver' => 'ably',
- 'key' => env('ABLY_KEY'),
+ 'key' => env('ABLY_KEY'),
],
- 'redis' => [
- 'driver' => 'redis',
+ 'redis' => [
+ 'driver' => 'redis',
'connection' => 'default',
],
- 'log' => [
+ 'log' => [
'driver' => 'log',
],
- 'null' => [
+ 'null' => [
'driver' => 'null',
],
-
],
-
];
diff --git a/config/cache.php b/config/cache.php
index d28d9d6882..94cc4d9f14 100644
--- a/config/cache.php
+++ b/config/cache.php
@@ -48,24 +48,23 @@ return [
|
*/
- 'stores' => [
-
- 'apc' => [
+ 'stores' => [
+ 'apc' => [
'driver' => 'apc',
],
- 'array' => [
+ 'array' => [
'driver' => 'array',
'serialize' => false,
],
- 'database' => [
+ 'database' => [
'driver' => 'database',
'table' => 'cache',
'connection' => null,
],
- 'file' => [
+ 'file' => [
'driver' => 'file',
'path' => storage_path('framework/cache/data'),
],
@@ -89,11 +88,11 @@ return [
],
],
- 'redis' => [
+ 'redis' => [
'driver' => 'redis',
'connection' => 'default',
],
- 'dynamodb' => [
+ 'dynamodb' => [
'driver' => 'dynamodb',
'key' => env('AWS_ACCESS_KEY_ID'),
'secret' => env('AWS_SECRET_ACCESS_KEY'),
@@ -114,5 +113,5 @@ return [
|
*/
- 'prefix' => env('CACHE_PREFIX', 'firefly'),
+ 'prefix' => env('CACHE_PREFIX', 'firefly'),
];
diff --git a/config/cer.php b/config/cer.php
index 7445ea37bd..30b0ebb70a 100644
--- a/config/cer.php
+++ b/config/cer.php
@@ -23,7 +23,6 @@
declare(strict_types=1);
return [
-
'url' => 'https://ff3exchangerates.z6.web.core.windows.net',
'enabled' => true,
'download_enabled' => env('ENABLE_EXTERNAL_RATES', false),
@@ -35,7 +34,6 @@ return [
// all rates are from EUR to $currency:
'rates' => [
-
// europa
'EUR' => 1,
'HUF' => 387.9629,
diff --git a/config/cors.php b/config/cors.php
index 69da8e5802..a921cdfc57 100644
--- a/config/cors.php
+++ b/config/cors.php
@@ -1,6 +1,5 @@
['api/*', 'sanctum/csrf-cookie'],
+ 'paths' => ['api/*', 'sanctum/csrf-cookie'],
- 'allowed_methods' => ['*'],
+ 'allowed_methods' => ['*'],
- 'allowed_origins' => ['*'],
+ 'allowed_origins' => ['*'],
'allowed_origins_patterns' => ['*'],
- 'allowed_headers' => ['*'],
+ 'allowed_headers' => ['*'],
- 'exposed_headers' => [],
+ 'exposed_headers' => [],
- 'max_age' => 0,
-
- 'supports_credentials' => false,
+ 'max_age' => 0,
+ 'supports_credentials' => false,
];
diff --git a/config/database.php b/config/database.php
index cb181adbd7..67410f7f7d 100644
--- a/config/database.php
+++ b/config/database.php
@@ -23,12 +23,12 @@ declare(strict_types=1);
use Illuminate\Support\Str;
-$databaseUrl = getenv('DATABASE_URL');
-$host = '';
-$username = '';
-$password = '';
-$database = '';
-$port = '';
+$databaseUrl = getenv('DATABASE_URL');
+$host = '';
+$username = '';
+$password = '';
+$database = '';
+$port = '';
if (false !== $databaseUrl) {
$options = parse_url($databaseUrl);
@@ -39,9 +39,7 @@ if (false !== $databaseUrl) {
$database = substr($options['path'] ?? '/firefly', 1);
}
-/*
- * Get SSL parameters from .env file.
- */
+// Get SSL parameters from .env file.
$mysql_ssl_ca_dir = envNonEmpty('MYSQL_SSL_CAPATH', null);
$mysql_ssl_ca_file = envNonEmpty('MYSQL_SSL_CA', null);
$mysql_ssl_cert = envNonEmpty('MYSQL_SSL_CERT', null);
@@ -49,9 +47,9 @@ $mysql_ssl_key = envNonEmpty('MYSQL_SSL_KEY', null);
$mysql_ssl_ciphers = envNonEmpty('MYSQL_SSL_CIPHER', null);
$mysql_ssl_verify = envNonEmpty('MYSQL_SSL_VERIFY_SERVER_CERT', null);
-$mySqlSSLOptions = [];
-$useSSL = envNonEmpty('MYSQL_USE_SSL', false);
-if (false !== $useSSL && null !== $useSSL) {
+$mySqlSSLOptions = [];
+$useSSL = envNonEmpty('MYSQL_USE_SSL', false);
+if (false !== $useSSL && null !== $useSSL && '' !== $useSSL) {
if (null !== $mysql_ssl_ca_dir) {
$mySqlSSLOptions[PDO::MYSQL_ATTR_SSL_CAPATH] = $mysql_ssl_ca_dir;
}
@@ -121,7 +119,6 @@ return [
'charset' => 'utf8',
'prefix' => '',
],
-
],
'migrations' => 'migrations',
/*
@@ -138,7 +135,7 @@ return [
'client' => env('REDIS_CLIENT', 'predis'),
'options' => [
'cluster' => env('REDIS_CLUSTER', 'predis'),
- 'prefix' => env('REDIS_PREFIX', Str::slug(env('APP_NAME', 'laravel'), '_') . '_database_'),
+ // 'prefix' => env('REDIS_PREFIX', Str::slug(env('APP_NAME', 'laravel'), '_') . '_database_'),
],
'default' => [
'scheme' => envNonEmpty('REDIS_SCHEME', 'tcp'),
@@ -161,5 +158,4 @@ return [
'database' => env('REDIS_CACHE_DB', '1'),
],
],
-
];
diff --git a/config/debugbar.php b/config/debugbar.php
deleted file mode 100644
index 7441f1af5d..0000000000
--- a/config/debugbar.php
+++ /dev/null
@@ -1,223 +0,0 @@
-.
- */
-
-declare(strict_types=1);
-
-return [
- /*
- |--------------------------------------------------------------------------
- | Debugbar Settings
- |--------------------------------------------------------------------------
- |
- | Debugbar is enabled by default, when debug is set to true in app.php.
- | You can override the value by setting enable to true or false instead of null.
- |
- | You can provide an array of URI's that must be ignored (eg. 'api/*')
- |
- */
-
- 'enabled' => env('DEBUGBAR_ENABLED', null),
- 'except' => [
- 'telescope*',
- ],
-
- /*
- |--------------------------------------------------------------------------
- | Storage settings
- |--------------------------------------------------------------------------
- |
- | DebugBar stores data for session/ajax requests.
- | You can disable this, so the debugbar stores data in headers/session,
- | but this can cause problems with large data collectors.
- | By default, file storage (in the storage folder) is used. Redis and PDO
- | can also be used. For PDO, run the package migrations first.
- |
- */
- 'storage' => [
- 'enabled' => true,
- 'driver' => 'file', // redis, file, pdo, custom
- 'path' => storage_path('debugbar'), // For file driver
- 'connection' => null, // Leave null for default connection (Redis/PDO)
- 'provider' => '', // Instance of StorageInterface for custom driver
- ],
-
- /*
- |--------------------------------------------------------------------------
- | Vendors
- |--------------------------------------------------------------------------
- |
- | Vendor files are included by default, but can be set to false.
- | This can also be set to 'js' or 'css', to only include javascript or css vendor files.
- | Vendor files are for css: font-awesome (including fonts) and highlight.js (css files)
- | and for js: jquery and and highlight.js
- | So if you want syntax highlighting, set it to true.
- | jQuery is set to not conflict with existing jQuery scripts.
- |
- */
-
- 'include_vendors' => true,
-
- /*
- |--------------------------------------------------------------------------
- | Capture Ajax Requests
- |--------------------------------------------------------------------------
- |
- | The Debugbar can capture Ajax requests and display them. If you don't want this (ie. because of errors),
- | you can use this option to disable sending the data through the headers.
- |
- | Optionally, you can also send ServerTiming headers on ajax requests for the Chrome DevTools.
- */
-
- 'capture_ajax' => true,
- 'add_ajax_timing' => false,
-
- /*
- |--------------------------------------------------------------------------
- | Custom Error Handler for Deprecated warnings
- |--------------------------------------------------------------------------
- |
- | When enabled, the Debugbar shows deprecated warnings for Symfony components
- | in the Messages tab.
- |
- */
- 'error_handler' => true,
-
- /*
- |--------------------------------------------------------------------------
- | Clockwork integration
- |--------------------------------------------------------------------------
- |
- | The Debugbar can emulate the Clockwork headers, so you can use the Chrome
- | Extension, without the server-side code. It uses Debugbar collectors instead.
- |
- */
- 'clockwork' => false,
-
- /*
- |--------------------------------------------------------------------------
- | DataCollectors
- |--------------------------------------------------------------------------
- |
- | Enable/disable DataCollectors
- |
- */
-
- 'collectors' => [
- 'phpinfo' => true, // Php version
- 'messages' => true, // Messages
- 'time' => true, // Time Datalogger
- 'memory' => true, // Memory usage
- 'exceptions' => true, // Exception displayer
- 'log' => true, // Logs from Monolog (merged in messages if enabled)
- 'db' => true, // Show database (PDO) queries and bindings
- 'views' => true, // Views with their data
- 'route' => true, // Current route information
- 'auth' => true, // Display Laravel authentication status
- 'gate' => true, // Display Laravel Gate checks
- 'session' => true, // Display session data
- 'symfony_request' => true, // Only one can be enabled..
- 'mail' => true, // Catch mail messages
- 'laravel' => false, // Laravel version and environment
- 'events' => true, // All events fired
- 'default_request' => false, // Regular or special Symfony request logger
- 'logs' => false, // Add the latest log messages
- 'files' => false, // Show the included files
- 'config' => false, // Display config settings
- 'cache' => true, // Display cache events
- 'models' => false, // Display models
- ],
-
- /*
- |--------------------------------------------------------------------------
- | Extra options
- |--------------------------------------------------------------------------
- |
- | Configure some DataCollectors
- |
- */
-
- 'options' => [
- 'auth' => [
- 'show_name' => true, // Also show the users name/email in the debugbar
- ],
- 'db' => [
- 'with_params' => true, // Render SQL with the parameters substituted
- 'backtrace' => true, // Use a backtrace to find the origin of the query in your files.
- 'timeline' => false, // Add the queries to the timeline
- 'explain' => [ // Show EXPLAIN output on queries
- 'enabled' => false,
- 'types' => ['SELECT'],
- // // workaround ['SELECT'] only. https://github.com/barryvdh/laravel-debugbar/issues/888 ['SELECT', 'INSERT', 'UPDATE', 'DELETE']; for MySQL 5.6.3+
- ],
- 'hints' => true, // Show hints for common mistakes
- ],
- 'mail' => [
- 'full_log' => false,
- ],
- 'views' => [
- 'data' => true, //Note: Can slow down the application, because the data can be quite large..
- ],
- 'route' => [
- 'label' => true, // show complete route on bar
- ],
- 'logs' => [
- 'file' => null,
- ],
- 'cache' => [
- 'values' => true, // collect cache values
- ],
- ],
-
- /*
- |--------------------------------------------------------------------------
- | Inject Debugbar in Response
- |--------------------------------------------------------------------------
- |
- | Usually, the debugbar is added just before