From 27336e0721327d9995d25e58d08357635ba5a128 Mon Sep 17 00:00:00 2001 From: James Cole Date: Sat, 1 Nov 2025 21:02:35 +0100 Subject: [PATCH 01/29] Fix argument order in piggy bank error message. --- app/TransactionRules/Actions/UpdatePiggyBank.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/TransactionRules/Actions/UpdatePiggyBank.php b/app/TransactionRules/Actions/UpdatePiggyBank.php index 7a0bd2daaf..628200c599 100644 --- a/app/TransactionRules/Actions/UpdatePiggyBank.php +++ b/app/TransactionRules/Actions/UpdatePiggyBank.php @@ -239,7 +239,7 @@ class UpdatePiggyBank implements ActionInterface if (false === $repository->canAddAmount($piggyBank, $account, $amount)) { Log::warning(sprintf('Cannot add %s to piggy bank.', $amount)); $currency = $accountRepository->getAccountCurrency($account) ?? Amount::getPrimaryCurrency(); - event(new RuleActionFailedOnArray($this->action, $array, trans('rules.cannot_add_to_piggy', ['amount' => Amount::formatAnything($amount, $currency, false), 'name' => $piggyBank->name]))); + event(new RuleActionFailedOnArray($this->action, $array, trans('rules.cannot_add_to_piggy', ['amount' => Amount::formatAnything($currency, $amount, false), 'name' => $piggyBank->name]))); return; } From e99a37bae341d65655d18234e88191d56dd4dcf6 Mon Sep 17 00:00:00 2001 From: James Cole Date: Sun, 2 Nov 2025 04:51:15 +0100 Subject: [PATCH 02/29] Fix #11157 --- app/Support/CacheProperties.php | 2 ++ changelog.md | 6 ++++++ 2 files changed, 8 insertions(+) diff --git a/app/Support/CacheProperties.php b/app/Support/CacheProperties.php index e22808ea06..5365656511 100644 --- a/app/Support/CacheProperties.php +++ b/app/Support/CacheProperties.php @@ -24,6 +24,7 @@ declare(strict_types=1); namespace FireflyIII\Support; use Carbon\Carbon; +use FireflyIII\Support\Facades\Steam; use Illuminate\Support\Collection; use Illuminate\Support\Facades\Cache; use JsonException; @@ -44,6 +45,7 @@ class CacheProperties if (auth()->check()) { $this->addProperty(auth()->user()->id); $this->addProperty(app('preferences')->lastActivity()); + $this->addProperty(Steam::anonymous()); } } diff --git a/changelog.md b/changelog.md index a46c12dadf..6e5ca8fd73 100644 --- a/changelog.md +++ b/changelog.md @@ -3,6 +3,12 @@ All notable changes to this project will be documented in this file. This project adheres to [Semantic Versioning](http://semver.org/). +## 6.4.5 - 2025-11-xx + +### Fixed + +- #11157 + ## 6.4.4 - 2025-11-02 ### Added From ffe0f39f6a8176bb67af395acb26fe898abbf8e2 Mon Sep 17 00:00:00 2001 From: JC5 Date: Sun, 2 Nov 2025 05:06:47 +0100 Subject: [PATCH 03/29] =?UTF-8?q?=F0=9F=A4=96=20Auto=20commit=20for=20rele?= =?UTF-8?q?ase=20'develop'=20on=202025-11-02?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- changelog.md | 2 +- config/firefly.php | 4 +- package-lock.json | 214 ++++++++++++++++++++++----------------------- 3 files changed, 110 insertions(+), 110 deletions(-) diff --git a/changelog.md b/changelog.md index 6e5ca8fd73..f3edb0b596 100644 --- a/changelog.md +++ b/changelog.md @@ -7,7 +7,7 @@ This project adheres to [Semantic Versioning](http://semver.org/). ### Fixed -- #11157 +- [Issue 11157](https://github.com/firefly-iii/firefly-iii/issues/11157) (Redacted amounts misbehave with Reports) reported by @barreeeiroo ## 6.4.4 - 2025-11-02 diff --git a/config/firefly.php b/config/firefly.php index f1a4d387ae..634cf70045 100644 --- a/config/firefly.php +++ b/config/firefly.php @@ -78,8 +78,8 @@ return [ 'running_balance_column' => env('USE_RUNNING_BALANCE', false), // see cer.php for exchange rates feature flag. ], - 'version' => '6.4.4', - 'build_time' => 1762026349, + 'version' => 'develop/2025-11-02', + 'build_time' => 1762056298, 'api_version' => '2.1.0', // field is no longer used. 'db_version' => 28, // field is no longer used. diff --git a/package-lock.json b/package-lock.json index aa5a1032bc..e7e72c82ed 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1693,9 +1693,9 @@ "license": "MIT" }, "node_modules/@esbuild/aix-ppc64": { - "version": "0.25.11", - "resolved": "https://registry.npmjs.org/@esbuild/aix-ppc64/-/aix-ppc64-0.25.11.tgz", - "integrity": "sha512-Xt1dOL13m8u0WE8iplx9Ibbm+hFAO0GsU2P34UNoDGvZYkY8ifSiy6Zuc1lYxfG7svWE2fzqCUmFp5HCn51gJg==", + "version": "0.25.12", + "resolved": "https://registry.npmjs.org/@esbuild/aix-ppc64/-/aix-ppc64-0.25.12.tgz", + "integrity": "sha512-Hhmwd6CInZ3dwpuGTF8fJG6yoWmsToE+vYgD4nytZVxcu1ulHpUQRAB1UJ8+N1Am3Mz4+xOByoQoSZf4D+CpkA==", "cpu": [ "ppc64" ], @@ -1710,9 +1710,9 @@ } }, "node_modules/@esbuild/android-arm": { - "version": "0.25.11", - "resolved": "https://registry.npmjs.org/@esbuild/android-arm/-/android-arm-0.25.11.tgz", - "integrity": "sha512-uoa7dU+Dt3HYsethkJ1k6Z9YdcHjTrSb5NUy66ZfZaSV8hEYGD5ZHbEMXnqLFlbBflLsl89Zke7CAdDJ4JI+Gg==", + "version": "0.25.12", + "resolved": "https://registry.npmjs.org/@esbuild/android-arm/-/android-arm-0.25.12.tgz", + "integrity": "sha512-VJ+sKvNA/GE7Ccacc9Cha7bpS8nyzVv0jdVgwNDaR4gDMC/2TTRc33Ip8qrNYUcpkOHUT5OZ0bUcNNVZQ9RLlg==", "cpu": [ "arm" ], @@ -1727,9 +1727,9 @@ } }, "node_modules/@esbuild/android-arm64": { - "version": "0.25.11", - "resolved": "https://registry.npmjs.org/@esbuild/android-arm64/-/android-arm64-0.25.11.tgz", - "integrity": "sha512-9slpyFBc4FPPz48+f6jyiXOx/Y4v34TUeDDXJpZqAWQn/08lKGeD8aDp9TMn9jDz2CiEuHwfhRmGBvpnd/PWIQ==", + "version": "0.25.12", + "resolved": "https://registry.npmjs.org/@esbuild/android-arm64/-/android-arm64-0.25.12.tgz", + "integrity": "sha512-6AAmLG7zwD1Z159jCKPvAxZd4y/VTO0VkprYy+3N2FtJ8+BQWFXU+OxARIwA46c5tdD9SsKGZ/1ocqBS/gAKHg==", "cpu": [ "arm64" ], @@ -1744,9 +1744,9 @@ } }, "node_modules/@esbuild/android-x64": { - "version": "0.25.11", - "resolved": "https://registry.npmjs.org/@esbuild/android-x64/-/android-x64-0.25.11.tgz", - "integrity": "sha512-Sgiab4xBjPU1QoPEIqS3Xx+R2lezu0LKIEcYe6pftr56PqPygbB7+szVnzoShbx64MUupqoE0KyRlN7gezbl8g==", + "version": "0.25.12", + "resolved": "https://registry.npmjs.org/@esbuild/android-x64/-/android-x64-0.25.12.tgz", + "integrity": "sha512-5jbb+2hhDHx5phYR2By8GTWEzn6I9UqR11Kwf22iKbNpYrsmRB18aX/9ivc5cabcUiAT/wM+YIZ6SG9QO6a8kg==", "cpu": [ "x64" ], @@ -1761,9 +1761,9 @@ } }, "node_modules/@esbuild/darwin-arm64": { - "version": "0.25.11", - "resolved": "https://registry.npmjs.org/@esbuild/darwin-arm64/-/darwin-arm64-0.25.11.tgz", - "integrity": "sha512-VekY0PBCukppoQrycFxUqkCojnTQhdec0vevUL/EDOCnXd9LKWqD/bHwMPzigIJXPhC59Vd1WFIL57SKs2mg4w==", + "version": "0.25.12", + "resolved": "https://registry.npmjs.org/@esbuild/darwin-arm64/-/darwin-arm64-0.25.12.tgz", + "integrity": "sha512-N3zl+lxHCifgIlcMUP5016ESkeQjLj/959RxxNYIthIg+CQHInujFuXeWbWMgnTo4cp5XVHqFPmpyu9J65C1Yg==", "cpu": [ "arm64" ], @@ -1778,9 +1778,9 @@ } }, "node_modules/@esbuild/darwin-x64": { - "version": "0.25.11", - "resolved": "https://registry.npmjs.org/@esbuild/darwin-x64/-/darwin-x64-0.25.11.tgz", - "integrity": "sha512-+hfp3yfBalNEpTGp9loYgbknjR695HkqtY3d3/JjSRUyPg/xd6q+mQqIb5qdywnDxRZykIHs3axEqU6l1+oWEQ==", + "version": "0.25.12", + "resolved": "https://registry.npmjs.org/@esbuild/darwin-x64/-/darwin-x64-0.25.12.tgz", + "integrity": "sha512-HQ9ka4Kx21qHXwtlTUVbKJOAnmG1ipXhdWTmNXiPzPfWKpXqASVcWdnf2bnL73wgjNrFXAa3yYvBSd9pzfEIpA==", "cpu": [ "x64" ], @@ -1795,9 +1795,9 @@ } }, "node_modules/@esbuild/freebsd-arm64": { - "version": "0.25.11", - "resolved": "https://registry.npmjs.org/@esbuild/freebsd-arm64/-/freebsd-arm64-0.25.11.tgz", - "integrity": "sha512-CmKjrnayyTJF2eVuO//uSjl/K3KsMIeYeyN7FyDBjsR3lnSJHaXlVoAK8DZa7lXWChbuOk7NjAc7ygAwrnPBhA==", + "version": "0.25.12", + "resolved": "https://registry.npmjs.org/@esbuild/freebsd-arm64/-/freebsd-arm64-0.25.12.tgz", + "integrity": "sha512-gA0Bx759+7Jve03K1S0vkOu5Lg/85dou3EseOGUes8flVOGxbhDDh/iZaoek11Y8mtyKPGF3vP8XhnkDEAmzeg==", "cpu": [ "arm64" ], @@ -1812,9 +1812,9 @@ } }, "node_modules/@esbuild/freebsd-x64": { - "version": "0.25.11", - "resolved": "https://registry.npmjs.org/@esbuild/freebsd-x64/-/freebsd-x64-0.25.11.tgz", - "integrity": "sha512-Dyq+5oscTJvMaYPvW3x3FLpi2+gSZTCE/1ffdwuM6G1ARang/mb3jvjxs0mw6n3Lsw84ocfo9CrNMqc5lTfGOw==", + "version": "0.25.12", + "resolved": "https://registry.npmjs.org/@esbuild/freebsd-x64/-/freebsd-x64-0.25.12.tgz", + "integrity": "sha512-TGbO26Yw2xsHzxtbVFGEXBFH0FRAP7gtcPE7P5yP7wGy7cXK2oO7RyOhL5NLiqTlBh47XhmIUXuGciXEqYFfBQ==", "cpu": [ "x64" ], @@ -1829,9 +1829,9 @@ } }, "node_modules/@esbuild/linux-arm": { - "version": "0.25.11", - "resolved": "https://registry.npmjs.org/@esbuild/linux-arm/-/linux-arm-0.25.11.tgz", - "integrity": "sha512-TBMv6B4kCfrGJ8cUPo7vd6NECZH/8hPpBHHlYI3qzoYFvWu2AdTvZNuU/7hsbKWqu/COU7NIK12dHAAqBLLXgw==", + "version": "0.25.12", + "resolved": "https://registry.npmjs.org/@esbuild/linux-arm/-/linux-arm-0.25.12.tgz", + "integrity": "sha512-lPDGyC1JPDou8kGcywY0YILzWlhhnRjdof3UlcoqYmS9El818LLfJJc3PXXgZHrHCAKs/Z2SeZtDJr5MrkxtOw==", "cpu": [ "arm" ], @@ -1846,9 +1846,9 @@ } }, "node_modules/@esbuild/linux-arm64": { - "version": "0.25.11", - "resolved": "https://registry.npmjs.org/@esbuild/linux-arm64/-/linux-arm64-0.25.11.tgz", - "integrity": "sha512-Qr8AzcplUhGvdyUF08A1kHU3Vr2O88xxP0Tm8GcdVOUm25XYcMPp2YqSVHbLuXzYQMf9Bh/iKx7YPqECs6ffLA==", + "version": "0.25.12", + "resolved": "https://registry.npmjs.org/@esbuild/linux-arm64/-/linux-arm64-0.25.12.tgz", + "integrity": "sha512-8bwX7a8FghIgrupcxb4aUmYDLp8pX06rGh5HqDT7bB+8Rdells6mHvrFHHW2JAOPZUbnjUpKTLg6ECyzvas2AQ==", "cpu": [ "arm64" ], @@ -1863,9 +1863,9 @@ } }, "node_modules/@esbuild/linux-ia32": { - "version": "0.25.11", - "resolved": "https://registry.npmjs.org/@esbuild/linux-ia32/-/linux-ia32-0.25.11.tgz", - "integrity": "sha512-TmnJg8BMGPehs5JKrCLqyWTVAvielc615jbkOirATQvWWB1NMXY77oLMzsUjRLa0+ngecEmDGqt5jiDC6bfvOw==", + "version": "0.25.12", + "resolved": "https://registry.npmjs.org/@esbuild/linux-ia32/-/linux-ia32-0.25.12.tgz", + "integrity": "sha512-0y9KrdVnbMM2/vG8KfU0byhUN+EFCny9+8g202gYqSSVMonbsCfLjUO+rCci7pM0WBEtz+oK/PIwHkzxkyharA==", "cpu": [ "ia32" ], @@ -1880,9 +1880,9 @@ } }, "node_modules/@esbuild/linux-loong64": { - "version": "0.25.11", - "resolved": "https://registry.npmjs.org/@esbuild/linux-loong64/-/linux-loong64-0.25.11.tgz", - "integrity": "sha512-DIGXL2+gvDaXlaq8xruNXUJdT5tF+SBbJQKbWy/0J7OhU8gOHOzKmGIlfTTl6nHaCOoipxQbuJi7O++ldrxgMw==", + "version": "0.25.12", + "resolved": "https://registry.npmjs.org/@esbuild/linux-loong64/-/linux-loong64-0.25.12.tgz", + "integrity": "sha512-h///Lr5a9rib/v1GGqXVGzjL4TMvVTv+s1DPoxQdz7l/AYv6LDSxdIwzxkrPW438oUXiDtwM10o9PmwS/6Z0Ng==", "cpu": [ "loong64" ], @@ -1897,9 +1897,9 @@ } }, "node_modules/@esbuild/linux-mips64el": { - "version": "0.25.11", - "resolved": "https://registry.npmjs.org/@esbuild/linux-mips64el/-/linux-mips64el-0.25.11.tgz", - "integrity": "sha512-Osx1nALUJu4pU43o9OyjSCXokFkFbyzjXb6VhGIJZQ5JZi8ylCQ9/LFagolPsHtgw6himDSyb5ETSfmp4rpiKQ==", + "version": "0.25.12", + "resolved": "https://registry.npmjs.org/@esbuild/linux-mips64el/-/linux-mips64el-0.25.12.tgz", + "integrity": "sha512-iyRrM1Pzy9GFMDLsXn1iHUm18nhKnNMWscjmp4+hpafcZjrr2WbT//d20xaGljXDBYHqRcl8HnxbX6uaA/eGVw==", "cpu": [ "mips64el" ], @@ -1914,9 +1914,9 @@ } }, "node_modules/@esbuild/linux-ppc64": { - "version": "0.25.11", - "resolved": "https://registry.npmjs.org/@esbuild/linux-ppc64/-/linux-ppc64-0.25.11.tgz", - "integrity": "sha512-nbLFgsQQEsBa8XSgSTSlrnBSrpoWh7ioFDUmwo158gIm5NNP+17IYmNWzaIzWmgCxq56vfr34xGkOcZ7jX6CPw==", + "version": "0.25.12", + "resolved": "https://registry.npmjs.org/@esbuild/linux-ppc64/-/linux-ppc64-0.25.12.tgz", + "integrity": "sha512-9meM/lRXxMi5PSUqEXRCtVjEZBGwB7P/D4yT8UG/mwIdze2aV4Vo6U5gD3+RsoHXKkHCfSxZKzmDssVlRj1QQA==", "cpu": [ "ppc64" ], @@ -1931,9 +1931,9 @@ } }, "node_modules/@esbuild/linux-riscv64": { - "version": "0.25.11", - "resolved": "https://registry.npmjs.org/@esbuild/linux-riscv64/-/linux-riscv64-0.25.11.tgz", - "integrity": "sha512-HfyAmqZi9uBAbgKYP1yGuI7tSREXwIb438q0nqvlpxAOs3XnZ8RsisRfmVsgV486NdjD7Mw2UrFSw51lzUk1ww==", + "version": "0.25.12", + "resolved": "https://registry.npmjs.org/@esbuild/linux-riscv64/-/linux-riscv64-0.25.12.tgz", + "integrity": "sha512-Zr7KR4hgKUpWAwb1f3o5ygT04MzqVrGEGXGLnj15YQDJErYu/BGg+wmFlIDOdJp0PmB0lLvxFIOXZgFRrdjR0w==", "cpu": [ "riscv64" ], @@ -1948,9 +1948,9 @@ } }, "node_modules/@esbuild/linux-s390x": { - "version": "0.25.11", - "resolved": "https://registry.npmjs.org/@esbuild/linux-s390x/-/linux-s390x-0.25.11.tgz", - "integrity": "sha512-HjLqVgSSYnVXRisyfmzsH6mXqyvj0SA7pG5g+9W7ESgwA70AXYNpfKBqh1KbTxmQVaYxpzA/SvlB9oclGPbApw==", + "version": "0.25.12", + "resolved": "https://registry.npmjs.org/@esbuild/linux-s390x/-/linux-s390x-0.25.12.tgz", + "integrity": "sha512-MsKncOcgTNvdtiISc/jZs/Zf8d0cl/t3gYWX8J9ubBnVOwlk65UIEEvgBORTiljloIWnBzLs4qhzPkJcitIzIg==", "cpu": [ "s390x" ], @@ -1965,9 +1965,9 @@ } }, "node_modules/@esbuild/linux-x64": { - "version": "0.25.11", - "resolved": "https://registry.npmjs.org/@esbuild/linux-x64/-/linux-x64-0.25.11.tgz", - "integrity": "sha512-HSFAT4+WYjIhrHxKBwGmOOSpphjYkcswF449j6EjsjbinTZbp8PJtjsVK1XFJStdzXdy/jaddAep2FGY+wyFAQ==", + "version": "0.25.12", + "resolved": "https://registry.npmjs.org/@esbuild/linux-x64/-/linux-x64-0.25.12.tgz", + "integrity": "sha512-uqZMTLr/zR/ed4jIGnwSLkaHmPjOjJvnm6TVVitAa08SLS9Z0VM8wIRx7gWbJB5/J54YuIMInDquWyYvQLZkgw==", "cpu": [ "x64" ], @@ -1982,9 +1982,9 @@ } }, "node_modules/@esbuild/netbsd-arm64": { - "version": "0.25.11", - "resolved": "https://registry.npmjs.org/@esbuild/netbsd-arm64/-/netbsd-arm64-0.25.11.tgz", - "integrity": "sha512-hr9Oxj1Fa4r04dNpWr3P8QKVVsjQhqrMSUzZzf+LZcYjZNqhA3IAfPQdEh1FLVUJSiu6sgAwp3OmwBfbFgG2Xg==", + "version": "0.25.12", + "resolved": "https://registry.npmjs.org/@esbuild/netbsd-arm64/-/netbsd-arm64-0.25.12.tgz", + "integrity": "sha512-xXwcTq4GhRM7J9A8Gv5boanHhRa/Q9KLVmcyXHCTaM4wKfIpWkdXiMog/KsnxzJ0A1+nD+zoecuzqPmCRyBGjg==", "cpu": [ "arm64" ], @@ -1999,9 +1999,9 @@ } }, "node_modules/@esbuild/netbsd-x64": { - "version": "0.25.11", - "resolved": "https://registry.npmjs.org/@esbuild/netbsd-x64/-/netbsd-x64-0.25.11.tgz", - "integrity": "sha512-u7tKA+qbzBydyj0vgpu+5h5AeudxOAGncb8N6C9Kh1N4n7wU1Xw1JDApsRjpShRpXRQlJLb9wY28ELpwdPcZ7A==", + "version": "0.25.12", + "resolved": "https://registry.npmjs.org/@esbuild/netbsd-x64/-/netbsd-x64-0.25.12.tgz", + "integrity": "sha512-Ld5pTlzPy3YwGec4OuHh1aCVCRvOXdH8DgRjfDy/oumVovmuSzWfnSJg+VtakB9Cm0gxNO9BzWkj6mtO1FMXkQ==", "cpu": [ "x64" ], @@ -2016,9 +2016,9 @@ } }, "node_modules/@esbuild/openbsd-arm64": { - "version": "0.25.11", - "resolved": "https://registry.npmjs.org/@esbuild/openbsd-arm64/-/openbsd-arm64-0.25.11.tgz", - "integrity": "sha512-Qq6YHhayieor3DxFOoYM1q0q1uMFYb7cSpLD2qzDSvK1NAvqFi8Xgivv0cFC6J+hWVw2teCYltyy9/m/14ryHg==", + "version": "0.25.12", + "resolved": "https://registry.npmjs.org/@esbuild/openbsd-arm64/-/openbsd-arm64-0.25.12.tgz", + "integrity": "sha512-fF96T6KsBo/pkQI950FARU9apGNTSlZGsv1jZBAlcLL1MLjLNIWPBkj5NlSz8aAzYKg+eNqknrUJ24QBybeR5A==", "cpu": [ "arm64" ], @@ -2033,9 +2033,9 @@ } }, "node_modules/@esbuild/openbsd-x64": { - "version": "0.25.11", - "resolved": "https://registry.npmjs.org/@esbuild/openbsd-x64/-/openbsd-x64-0.25.11.tgz", - "integrity": "sha512-CN+7c++kkbrckTOz5hrehxWN7uIhFFlmS/hqziSFVWpAzpWrQoAG4chH+nN3Be+Kzv/uuo7zhX716x3Sn2Jduw==", + "version": "0.25.12", + "resolved": "https://registry.npmjs.org/@esbuild/openbsd-x64/-/openbsd-x64-0.25.12.tgz", + "integrity": "sha512-MZyXUkZHjQxUvzK7rN8DJ3SRmrVrke8ZyRusHlP+kuwqTcfWLyqMOE3sScPPyeIXN/mDJIfGXvcMqCgYKekoQw==", "cpu": [ "x64" ], @@ -2050,9 +2050,9 @@ } }, "node_modules/@esbuild/openharmony-arm64": { - "version": "0.25.11", - "resolved": "https://registry.npmjs.org/@esbuild/openharmony-arm64/-/openharmony-arm64-0.25.11.tgz", - "integrity": "sha512-rOREuNIQgaiR+9QuNkbkxubbp8MSO9rONmwP5nKncnWJ9v5jQ4JxFnLu4zDSRPf3x4u+2VN4pM4RdyIzDty/wQ==", + "version": "0.25.12", + "resolved": "https://registry.npmjs.org/@esbuild/openharmony-arm64/-/openharmony-arm64-0.25.12.tgz", + "integrity": "sha512-rm0YWsqUSRrjncSXGA7Zv78Nbnw4XL6/dzr20cyrQf7ZmRcsovpcRBdhD43Nuk3y7XIoW2OxMVvwuRvk9XdASg==", "cpu": [ "arm64" ], @@ -2067,9 +2067,9 @@ } }, "node_modules/@esbuild/sunos-x64": { - "version": "0.25.11", - "resolved": "https://registry.npmjs.org/@esbuild/sunos-x64/-/sunos-x64-0.25.11.tgz", - "integrity": "sha512-nq2xdYaWxyg9DcIyXkZhcYulC6pQ2FuCgem3LI92IwMgIZ69KHeY8T4Y88pcwoLIjbed8n36CyKoYRDygNSGhA==", + "version": "0.25.12", + "resolved": "https://registry.npmjs.org/@esbuild/sunos-x64/-/sunos-x64-0.25.12.tgz", + "integrity": "sha512-3wGSCDyuTHQUzt0nV7bocDy72r2lI33QL3gkDNGkod22EsYl04sMf0qLb8luNKTOmgF/eDEDP5BFNwoBKH441w==", "cpu": [ "x64" ], @@ -2084,9 +2084,9 @@ } }, "node_modules/@esbuild/win32-arm64": { - "version": "0.25.11", - "resolved": "https://registry.npmjs.org/@esbuild/win32-arm64/-/win32-arm64-0.25.11.tgz", - "integrity": "sha512-3XxECOWJq1qMZ3MN8srCJ/QfoLpL+VaxD/WfNRm1O3B4+AZ/BnLVgFbUV3eiRYDMXetciH16dwPbbHqwe1uU0Q==", + "version": "0.25.12", + "resolved": "https://registry.npmjs.org/@esbuild/win32-arm64/-/win32-arm64-0.25.12.tgz", + "integrity": "sha512-rMmLrur64A7+DKlnSuwqUdRKyd3UE7oPJZmnljqEptesKM8wx9J8gx5u0+9Pq0fQQW8vqeKebwNXdfOyP+8Bsg==", "cpu": [ "arm64" ], @@ -2101,9 +2101,9 @@ } }, "node_modules/@esbuild/win32-ia32": { - "version": "0.25.11", - "resolved": "https://registry.npmjs.org/@esbuild/win32-ia32/-/win32-ia32-0.25.11.tgz", - "integrity": "sha512-3ukss6gb9XZ8TlRyJlgLn17ecsK4NSQTmdIXRASVsiS2sQ6zPPZklNJT5GR5tE/MUarymmy8kCEf5xPCNCqVOA==", + "version": "0.25.12", + "resolved": "https://registry.npmjs.org/@esbuild/win32-ia32/-/win32-ia32-0.25.12.tgz", + "integrity": "sha512-HkqnmmBoCbCwxUKKNPBixiWDGCpQGVsrQfJoVGYLPT41XWF8lHuE5N6WhVia2n4o5QK5M4tYr21827fNhi4byQ==", "cpu": [ "ia32" ], @@ -2118,9 +2118,9 @@ } }, "node_modules/@esbuild/win32-x64": { - "version": "0.25.11", - "resolved": "https://registry.npmjs.org/@esbuild/win32-x64/-/win32-x64-0.25.11.tgz", - "integrity": "sha512-D7Hpz6A2L4hzsRpPaCYkQnGOotdUpDzSGRIv9I+1ITdHROSFUWW95ZPZWQmGka1Fg7W3zFJowyn9WGwMJ0+KPA==", + "version": "0.25.12", + "resolved": "https://registry.npmjs.org/@esbuild/win32-x64/-/win32-x64-0.25.12.tgz", + "integrity": "sha512-alJC0uCZpTFrSL0CCDjcgleBXPnCrEAhTBILpeAp7M/OFgoqtAetfBzX0xM00MUsVVPpVjlPuMbREqnZCXaTnA==", "cpu": [ "x64" ], @@ -5899,9 +5899,9 @@ } }, "node_modules/esbuild": { - "version": "0.25.11", - "resolved": "https://registry.npmjs.org/esbuild/-/esbuild-0.25.11.tgz", - "integrity": "sha512-KohQwyzrKTQmhXDW1PjCv3Tyspn9n5GcY2RTDqeORIdIJY8yKIF7sTSopFmn/wpMPW4rdPXI0UE5LJLuq3bx0Q==", + "version": "0.25.12", + "resolved": "https://registry.npmjs.org/esbuild/-/esbuild-0.25.12.tgz", + "integrity": "sha512-bbPBYYrtZbkt6Os6FiTLCTFxvq4tt3JKall1vRwshA3fdVztsLAatFaZobhkBC8/BrPetoa0oksYoKXoG4ryJg==", "dev": true, "hasInstallScript": true, "license": "MIT", @@ -5912,32 +5912,32 @@ "node": ">=18" }, "optionalDependencies": { - "@esbuild/aix-ppc64": "0.25.11", - "@esbuild/android-arm": "0.25.11", - "@esbuild/android-arm64": "0.25.11", - "@esbuild/android-x64": "0.25.11", - "@esbuild/darwin-arm64": "0.25.11", - "@esbuild/darwin-x64": "0.25.11", - "@esbuild/freebsd-arm64": "0.25.11", - "@esbuild/freebsd-x64": "0.25.11", - "@esbuild/linux-arm": "0.25.11", - "@esbuild/linux-arm64": "0.25.11", - "@esbuild/linux-ia32": "0.25.11", - "@esbuild/linux-loong64": "0.25.11", - "@esbuild/linux-mips64el": "0.25.11", - "@esbuild/linux-ppc64": "0.25.11", - "@esbuild/linux-riscv64": "0.25.11", - "@esbuild/linux-s390x": "0.25.11", - "@esbuild/linux-x64": "0.25.11", - "@esbuild/netbsd-arm64": "0.25.11", - "@esbuild/netbsd-x64": "0.25.11", - "@esbuild/openbsd-arm64": "0.25.11", - "@esbuild/openbsd-x64": "0.25.11", - "@esbuild/openharmony-arm64": "0.25.11", - "@esbuild/sunos-x64": "0.25.11", - "@esbuild/win32-arm64": "0.25.11", - "@esbuild/win32-ia32": "0.25.11", - "@esbuild/win32-x64": "0.25.11" + "@esbuild/aix-ppc64": "0.25.12", + "@esbuild/android-arm": "0.25.12", + "@esbuild/android-arm64": "0.25.12", + "@esbuild/android-x64": "0.25.12", + "@esbuild/darwin-arm64": "0.25.12", + "@esbuild/darwin-x64": "0.25.12", + "@esbuild/freebsd-arm64": "0.25.12", + "@esbuild/freebsd-x64": "0.25.12", + "@esbuild/linux-arm": "0.25.12", + "@esbuild/linux-arm64": "0.25.12", + "@esbuild/linux-ia32": "0.25.12", + "@esbuild/linux-loong64": "0.25.12", + "@esbuild/linux-mips64el": "0.25.12", + "@esbuild/linux-ppc64": "0.25.12", + "@esbuild/linux-riscv64": "0.25.12", + "@esbuild/linux-s390x": "0.25.12", + "@esbuild/linux-x64": "0.25.12", + "@esbuild/netbsd-arm64": "0.25.12", + "@esbuild/netbsd-x64": "0.25.12", + "@esbuild/openbsd-arm64": "0.25.12", + "@esbuild/openbsd-x64": "0.25.12", + "@esbuild/openharmony-arm64": "0.25.12", + "@esbuild/sunos-x64": "0.25.12", + "@esbuild/win32-arm64": "0.25.12", + "@esbuild/win32-ia32": "0.25.12", + "@esbuild/win32-x64": "0.25.12" } }, "node_modules/escalade": { From a57cf4e9be4fb67321f0d2c13222961d0163ac48 Mon Sep 17 00:00:00 2001 From: James Cole Date: Sun, 2 Nov 2025 14:00:55 +0100 Subject: [PATCH 04/29] Clean up some classes, extend API validation. --- .../Autocomplete/TransactionController.php | 3 +- .../Models/Account/ListController.php | 14 +-- app/Api/V1/Requests/AggregateFormRequest.php | 2 + .../Autocomplete/AutocompleteApiRequest.php | 3 +- .../AutocompleteTransactionApiRequest.php | 47 ++++++++++ .../Requests/Generic/ObjectTypeApiRequest.php | 90 +++++++++++++++++++ .../Requests/Models/Account/ShowRequest.php | 2 + app/Factory/BillFactory.php | 7 +- app/Factory/CategoryFactory.php | 8 +- app/Factory/PiggyBankFactory.php | 5 +- app/Factory/TagFactory.php | 9 +- app/Factory/TransactionFactory.php | 19 ++-- app/Factory/TransactionGroupFactory.php | 5 +- app/Factory/TransactionJournalMetaFactory.php | 17 ++-- .../Report/Account/MonthReportGenerator.php | 5 +- .../Report/Audit/MonthReportGenerator.php | 4 +- .../Report/Budget/MonthReportGenerator.php | 7 +- .../Report/Category/MonthReportGenerator.php | 7 +- .../Report/Standard/MonthReportGenerator.php | 5 +- .../Standard/MultiYearReportGenerator.php | 5 +- .../Report/Standard/YearReportGenerator.php | 5 +- .../Report/Tag/MonthReportGenerator.php | 5 +- app/Rules/IsAllowedGroupAction.php | 14 ++- .../IsValidTransactionTypeList.php | 56 ++++++++++++ app/Support/Http/Api/TransactionFilter.php | 55 +++++++----- .../Http/Api/ValidatesUserGroupTrait.php | 1 + app/TransactionRules/Actions/LinkToBill.php | 32 ++----- resources/lang/en_US/validation.php | 1 + 28 files changed, 324 insertions(+), 109 deletions(-) create mode 100644 app/Api/V1/Requests/Autocomplete/AutocompleteTransactionApiRequest.php create mode 100644 app/Api/V1/Requests/Generic/ObjectTypeApiRequest.php create mode 100644 app/Rules/TransactionType/IsValidTransactionTypeList.php diff --git a/app/Api/V1/Controllers/Autocomplete/TransactionController.php b/app/Api/V1/Controllers/Autocomplete/TransactionController.php index 2bc5c8314b..cf8302fdf2 100644 --- a/app/Api/V1/Controllers/Autocomplete/TransactionController.php +++ b/app/Api/V1/Controllers/Autocomplete/TransactionController.php @@ -26,6 +26,7 @@ namespace FireflyIII\Api\V1\Controllers\Autocomplete; use FireflyIII\Api\V1\Controllers\Controller; use FireflyIII\Api\V1\Requests\Autocomplete\AutocompleteApiRequest; +use FireflyIII\Api\V1\Requests\Autocomplete\AutocompleteTransactionApiRequest; use FireflyIII\Enums\UserRoleEnum; use FireflyIII\Models\TransactionGroup; use FireflyIII\Models\TransactionJournal; @@ -64,7 +65,7 @@ class TransactionController extends Controller ); } - public function transactions(AutocompleteApiRequest $request): JsonResponse + public function transactions(AutocompleteTransactionApiRequest $request): JsonResponse { $result = $this->repository->searchJournalDescriptions($request->attributes->get('query'), $request->attributes->get('limit')); diff --git a/app/Api/V1/Controllers/Models/Account/ListController.php b/app/Api/V1/Controllers/Models/Account/ListController.php index f830be0844..e5ea31a8b7 100644 --- a/app/Api/V1/Controllers/Models/Account/ListController.php +++ b/app/Api/V1/Controllers/Models/Account/ListController.php @@ -136,12 +136,16 @@ class ListController extends Controller /** * Show all transaction groups related to the account. */ - public function transactions(Request $request, Account $account): JsonResponse + public function transactions(PaginationRequest $request, Account $account): JsonResponse { - $pageSize = $this->parameters->get('limit'); + [ + 'limit' => $limit, + 'offset' => $offset, + 'page' => $page, + ] = $request->attributes->all(); + $type = $request->get('type') ?? 'default'; - $this->parameters->set('type', $type); - $types = $this->mapTransactionTypes($this->parameters->get('type')); + $types = $this->mapTransactionTypes($type); $manager = $this->getManager(); /** @var User $admin */ @@ -151,7 +155,7 @@ class ListController extends Controller /** @var GroupCollectorInterface $collector */ $collector = app(GroupCollectorInterface::class); $collector->setUser($admin)->setAccounts(new Collection()->push($account)) - ->withAPIInformation()->setLimit($pageSize)->setPage($this->parameters->get('page'))->setTypes($types) + ->withAPIInformation()->setLimit($limit)->setPage($page)->setTypes($types) ; if (null !== $this->parameters->get('start')) { diff --git a/app/Api/V1/Requests/AggregateFormRequest.php b/app/Api/V1/Requests/AggregateFormRequest.php index 001c902fda..eda707b798 100644 --- a/app/Api/V1/Requests/AggregateFormRequest.php +++ b/app/Api/V1/Requests/AggregateFormRequest.php @@ -23,6 +23,7 @@ declare(strict_types=1); namespace FireflyIII\Api\V1\Requests; +use FireflyIII\Exceptions\FireflyException; use Illuminate\Foundation\Http\FormRequest; use Illuminate\Http\Request; use Illuminate\Support\Facades\Log; @@ -45,6 +46,7 @@ abstract class AggregateFormRequest extends ApiRequest // instantiate all subrequests and share current requests' bags with them Log::debug('Initializing AggregateFormRequest.'); + foreach ($this->getRequests() as $config) { $requestClass = is_array($config) ? array_shift($config) : $config; diff --git a/app/Api/V1/Requests/Autocomplete/AutocompleteApiRequest.php b/app/Api/V1/Requests/Autocomplete/AutocompleteApiRequest.php index 751f9f580b..7c0c3f40ac 100644 --- a/app/Api/V1/Requests/Autocomplete/AutocompleteApiRequest.php +++ b/app/Api/V1/Requests/Autocomplete/AutocompleteApiRequest.php @@ -25,6 +25,7 @@ namespace FireflyIII\Api\V1\Requests\Autocomplete; use FireflyIII\Api\V1\Requests\AggregateFormRequest; use FireflyIII\Api\V1\Requests\DateRequest; +use FireflyIII\Api\V1\Requests\Generic\ObjectTypeApiRequest; use FireflyIII\Api\V1\Requests\Generic\QueryRequest; use FireflyIII\Api\V1\Requests\Models\Account\AccountTypesApiRequest; use FireflyIII\Api\V1\Requests\PaginationRequest; @@ -39,7 +40,7 @@ class AutocompleteApiRequest extends AggregateFormRequest return [ DateRequest::class, [PaginationRequest::class, 'sort_class' => Account::class], - AccountTypesApiRequest::class, + [ObjectTypeApiRequest::class, 'object_type' => Account::class], QueryRequest::class, ]; } diff --git a/app/Api/V1/Requests/Autocomplete/AutocompleteTransactionApiRequest.php b/app/Api/V1/Requests/Autocomplete/AutocompleteTransactionApiRequest.php new file mode 100644 index 0000000000..a6255a4595 --- /dev/null +++ b/app/Api/V1/Requests/Autocomplete/AutocompleteTransactionApiRequest.php @@ -0,0 +1,47 @@ +. + */ + +namespace FireflyIII\Api\V1\Requests\Autocomplete; + +use FireflyIII\Api\V1\Requests\AggregateFormRequest; +use FireflyIII\Api\V1\Requests\DateRequest; +use FireflyIII\Api\V1\Requests\Generic\ObjectTypeApiRequest; +use FireflyIII\Api\V1\Requests\Generic\QueryRequest; +use FireflyIII\Api\V1\Requests\PaginationRequest; +use FireflyIII\Models\Account; +use FireflyIII\Models\Transaction; +use Override; + +class AutocompleteTransactionApiRequest extends AggregateFormRequest +{ + #[Override] + protected function getRequests(): array + { + return [ + DateRequest::class, + [PaginationRequest::class, 'sort_class' => Account::class], + [ObjectTypeApiRequest::class, 'object_type' => Transaction::class], + QueryRequest::class, + ]; + } +} diff --git a/app/Api/V1/Requests/Generic/ObjectTypeApiRequest.php b/app/Api/V1/Requests/Generic/ObjectTypeApiRequest.php new file mode 100644 index 0000000000..bf9b3a496f --- /dev/null +++ b/app/Api/V1/Requests/Generic/ObjectTypeApiRequest.php @@ -0,0 +1,90 @@ +. + */ + +namespace FireflyIII\Api\V1\Requests\Generic; + +use FireflyIII\Api\V1\Requests\ApiRequest; +use FireflyIII\Models\Account; +use FireflyIII\Models\Transaction; +use FireflyIII\Rules\Account\IsValidAccountTypeList; +use FireflyIII\Rules\TransactionType\IsValidTransactionTypeList; +use FireflyIII\Support\Http\Api\AccountFilter; +use FireflyIII\Support\Http\Api\TransactionFilter; +use Illuminate\Validation\Validator; +use RuntimeException; + +class ObjectTypeApiRequest extends ApiRequest +{ + use AccountFilter; + use TransactionFilter; + + private ?string $objectType = null; + + public function handleConfig(array $config): void + { + parent::handleConfig($config); + + $this->objectType = $config['object_type'] ?? null; + + if (!$this->objectType) { + throw new RuntimeException('ObjectTypeApiRequest requires a object_type config'); + } + } + + public function rules(): array + { + $rule = null; + if (Account::class === $this->objectType) { + $rule = new IsValidAccountTypeList(); + } + if (Transaction::class === $this->objectType) { + $rule = new IsValidTransactionTypeList(); + } + return [ + 'types' => $rule, + ]; + } + + public function withValidator(Validator $validator): void + { + $validator->after( + function (Validator $validator): void { + if ($validator->failed()) { + return; + } + $type = $this->convertString('types', 'all'); + $this->attributes->set('type', $type); + switch ($this->objectType) { + default: + $this->attributes->set('types', []); + case Account::class: + $this->attributes->set('types', $this->mapAccountTypes($type)); + break; + case Transaction::class: + $this->attributes->set('types', $this->mapTransactionTypes($type)); + break; + } + } + ); + } +} diff --git a/app/Api/V1/Requests/Models/Account/ShowRequest.php b/app/Api/V1/Requests/Models/Account/ShowRequest.php index ed0a7dafe1..0d7b5f3d1e 100644 --- a/app/Api/V1/Requests/Models/Account/ShowRequest.php +++ b/app/Api/V1/Requests/Models/Account/ShowRequest.php @@ -26,6 +26,7 @@ namespace FireflyIII\Api\V1\Requests\Models\Account; use FireflyIII\Api\V1\Requests\AggregateFormRequest; use FireflyIII\Api\V1\Requests\DateRangeRequest; use FireflyIII\Api\V1\Requests\DateRequest; +use FireflyIII\Api\V1\Requests\Generic\ObjectTypeApiRequest; use FireflyIII\Api\V1\Requests\PaginationRequest; use FireflyIII\Models\Account; @@ -38,6 +39,7 @@ class ShowRequest extends AggregateFormRequest DateRangeRequest::class, DateRequest::class, AccountTypeApiRequest::class, + [ObjectTypeApiRequest::class, 'object_type' => Account::class], ]; } } diff --git a/app/Factory/BillFactory.php b/app/Factory/BillFactory.php index fb284ae921..e7fe5cfa59 100644 --- a/app/Factory/BillFactory.php +++ b/app/Factory/BillFactory.php @@ -31,6 +31,7 @@ use FireflyIII\Repositories\ObjectGroup\CreatesObjectGroups; use FireflyIII\Services\Internal\Support\BillServiceTrait; use FireflyIII\User; use Illuminate\Database\QueryException; +use Illuminate\Support\Facades\Log; /** * Class BillFactory @@ -47,7 +48,7 @@ class BillFactory */ public function create(array $data): ?Bill { - app('log')->debug(sprintf('Now in %s', __METHOD__), $data); + 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')->getPrimaryCurrencyByUserGroup($this->user->userGroup); @@ -82,8 +83,8 @@ class BillFactory ] ); } catch (QueryException $e) { - app('log')->error($e->getMessage()); - app('log')->error($e->getTraceAsString()); + Log::error($e->getMessage()); + Log::error($e->getTraceAsString()); throw new FireflyException('400000: Could not store bill.', 0, $e); } diff --git a/app/Factory/CategoryFactory.php b/app/Factory/CategoryFactory.php index 754dba7644..6313198f97 100644 --- a/app/Factory/CategoryFactory.php +++ b/app/Factory/CategoryFactory.php @@ -27,7 +27,7 @@ use FireflyIII\Exceptions\FireflyException; use FireflyIII\Models\Category; use FireflyIII\User; use Illuminate\Database\QueryException; - +use Illuminate\Support\Facades\Log; /** * Class CategoryFactory */ @@ -43,7 +43,7 @@ class CategoryFactory $categoryId = (int) $categoryId; $categoryName = (string) $categoryName; - app('log')->debug(sprintf('Going to find category with ID %d and name "%s"', $categoryId, $categoryName)); + Log::debug(sprintf('Going to find category with ID %d and name "%s"', $categoryId, $categoryName)); if ('' === $categoryName && 0 === $categoryId) { return null; @@ -72,8 +72,8 @@ class CategoryFactory ] ); } catch (QueryException $e) { - app('log')->error($e->getMessage()); - app('log')->error($e->getTraceAsString()); + Log::error($e->getMessage()); + Log::error($e->getTraceAsString()); throw new FireflyException('400003: Could not store new category.', 0, $e); } diff --git a/app/Factory/PiggyBankFactory.php b/app/Factory/PiggyBankFactory.php index dc6b401311..9631ba8756 100644 --- a/app/Factory/PiggyBankFactory.php +++ b/app/Factory/PiggyBankFactory.php @@ -38,7 +38,6 @@ use Illuminate\Database\QueryException; use Illuminate\Support\Facades\Log; use function Safe\json_encode; - /** * Class PiggyBankFactory */ @@ -92,7 +91,7 @@ class PiggyBankFactory /** @var PiggyBank $piggyBank */ $piggyBank = PiggyBank::createQuietly($piggyBankData); } catch (QueryException $e) { - app('log')->error(sprintf('Could not store piggy bank: %s', $e->getMessage()), $piggyBankData); + Log::error(sprintf('Could not store piggy bank: %s', $e->getMessage()), $piggyBankData); throw new FireflyException('400005: Could not store new piggy bank.', 0, $e); } @@ -211,7 +210,7 @@ class PiggyBankFactory $current = 1; foreach ($set as $piggyBank) { 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)); + 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(); } diff --git a/app/Factory/TagFactory.php b/app/Factory/TagFactory.php index e0bb78254c..8c49cf53d4 100644 --- a/app/Factory/TagFactory.php +++ b/app/Factory/TagFactory.php @@ -28,6 +28,7 @@ use FireflyIII\Models\Location; use FireflyIII\Models\Tag; use FireflyIII\Models\UserGroup; use FireflyIII\User; +use Illuminate\Support\Facades\Log; /** * Class TagFactory @@ -40,12 +41,12 @@ class TagFactory public function findOrCreate(string $tag): ?Tag { $tag = trim($tag); - app('log')->debug(sprintf('Now in TagFactory::findOrCreate("%s")', $tag)); + Log::debug(sprintf('Now in TagFactory::findOrCreate("%s")', $tag)); /** @var null|Tag $dbTag */ $dbTag = $this->user->tags()->where('tag', $tag)->first(); if (null !== $dbTag) { - app('log')->debug(sprintf('Tag exists (#%d), return it.', $dbTag->id)); + Log::debug(sprintf('Tag exists (#%d), return it.', $dbTag->id)); return $dbTag; } @@ -60,11 +61,11 @@ class TagFactory ] ); if (!$newTag instanceof Tag) { - app('log')->error(sprintf('TagFactory::findOrCreate("%s") but tag is unexpectedly NULL!', $tag)); + Log::error(sprintf('TagFactory::findOrCreate("%s") but tag is unexpectedly NULL!', $tag)); return null; } - app('log')->debug(sprintf('Created new tag #%d ("%s")', $newTag->id, $newTag->tag)); + Log::debug(sprintf('Created new tag #%d ("%s")', $newTag->id, $newTag->tag)); return $newTag; } diff --git a/app/Factory/TransactionFactory.php b/app/Factory/TransactionFactory.php index 9a1b590bf7..1f53d562f7 100644 --- a/app/Factory/TransactionFactory.php +++ b/app/Factory/TransactionFactory.php @@ -33,6 +33,7 @@ use FireflyIII\Rules\UniqueIban; use FireflyIII\Services\Internal\Update\AccountUpdateService; use Illuminate\Database\QueryException; use Illuminate\Support\Facades\Validator; +use Illuminate\Support\Facades\Log; /** * Class TransactionFactory @@ -96,9 +97,9 @@ class TransactionFactory /** @var null|Transaction $result */ $result = Transaction::create($data); } catch (QueryException $e) { - app('log')->error(sprintf('Could not create transaction: %s', $e->getMessage()), $data); - app('log')->error($e->getMessage()); - app('log')->error($e->getTraceAsString()); + Log::error(sprintf('Could not create transaction: %s', $e->getMessage()), $data); + Log::error($e->getMessage()); + Log::error($e->getTraceAsString()); throw new FireflyException(sprintf('Query exception when creating transaction: %s', $e->getMessage()), 0, $e); } @@ -106,7 +107,7 @@ class TransactionFactory throw new FireflyException('Transaction is NULL.'); } - app('log')->debug( + Log::debug( sprintf( 'Created transaction #%d (%s %s, account %s), part of journal #%d', $result->id, @@ -138,17 +139,17 @@ class TransactionFactory private function updateAccountInformation(): void { if (!array_key_exists('iban', $this->accountInformation)) { - app('log')->debug('No IBAN information in array, will not update.'); + Log::debug('No IBAN information in array, will not update.'); return; } if ('' !== (string) $this->account->iban) { - app('log')->debug('Account already has IBAN information, will not update.'); + Log::debug('Account already has IBAN information, will not update.'); return; } if ($this->account->iban === $this->accountInformation['iban']) { - app('log')->debug('Account already has this IBAN, will not update.'); + Log::debug('Account already has this IBAN, will not update.'); return; } @@ -157,12 +158,12 @@ class TransactionFactory 'iban' => ['required', new UniqueIban($this->account, $this->account->accountType->type)], ]); if ($validator->fails()) { - app('log')->debug('Invalid or non-unique IBAN, will not update.'); + Log::debug('Invalid or non-unique IBAN, will not update.'); return; } - app('log')->debug('Will update account with IBAN information.'); + Log::debug('Will update account with IBAN information.'); $service = app(AccountUpdateService::class); $service->update($this->account, ['iban' => $this->accountInformation['iban']]); } diff --git a/app/Factory/TransactionGroupFactory.php b/app/Factory/TransactionGroupFactory.php index 10ecf31b52..11bde5fade 100644 --- a/app/Factory/TransactionGroupFactory.php +++ b/app/Factory/TransactionGroupFactory.php @@ -29,6 +29,7 @@ use FireflyIII\Exceptions\FireflyException; use FireflyIII\Models\TransactionGroup; use FireflyIII\Models\UserGroup; use FireflyIII\User; +use Illuminate\Support\Facades\Log; /** * Class TransactionGroupFactory @@ -55,7 +56,7 @@ class TransactionGroupFactory */ public function create(array $data): TransactionGroup { - app('log')->debug('Now in TransactionGroupFactory::create()'); + Log::debug('Now in TransactionGroupFactory::create()'); $this->journalFactory->setUser($data['user']); $this->journalFactory->setUserGroup($data['user_group']); $this->journalFactory->setErrorOnHash($data['error_if_duplicate_hash'] ?? false); @@ -63,7 +64,7 @@ class TransactionGroupFactory try { $collection = $this->journalFactory->create($data); } catch (DuplicateTransactionException $e) { - app('log')->warning('GroupFactory::create() caught journalFactory::create() with a duplicate!'); + Log::warning('GroupFactory::create() caught journalFactory::create() with a duplicate!'); throw new DuplicateTransactionException($e->getMessage(), 0, $e); } diff --git a/app/Factory/TransactionJournalMetaFactory.php b/app/Factory/TransactionJournalMetaFactory.php index 56dd79d1e0..31e9fe4888 100644 --- a/app/Factory/TransactionJournalMetaFactory.php +++ b/app/Factory/TransactionJournalMetaFactory.php @@ -26,6 +26,7 @@ namespace FireflyIII\Factory; use Carbon\Carbon; use FireflyIII\Models\TransactionJournalMeta; +use Illuminate\Support\Facades\Log; /** * Class TransactionJournalMetaFactory @@ -34,27 +35,27 @@ class TransactionJournalMetaFactory { public function updateOrCreate(array $data): ?TransactionJournalMeta { - // app('log')->debug('In updateOrCreate()'); + // 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) { - // app('log')->debug('Value is empty, delete meta value.'); + // Log::debug('Value is empty, delete meta value.'); $entry->delete(); return null; } if ($data['data'] instanceof Carbon) { - app('log')->debug('Is a carbon object.'); + Log::debug('Is a carbon object.'); $value = $data['data']->toW3cString(); } if ('' === (string) $value) { - // app('log')->debug('Is an empty string.'); + // Log::debug('Is an empty string.'); // don't store blank strings. if (null !== $entry) { - app('log')->debug('Will not store empty strings, delete meta value'); + Log::debug('Will not store empty strings, delete meta value'); $entry->delete(); } @@ -62,13 +63,13 @@ class TransactionJournalMetaFactory } if (null === $entry) { - // app('log')->debug('Will create new object.'); - app('log')->debug(sprintf('Going to create new meta-data entry to store "%s".', $data['name'])); + // Log::debug('Will create new object.'); + 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']; } - app('log')->debug('Will update value and return.'); + Log::debug('Will update value and return.'); $entry->data = $value; $entry->save(); diff --git a/app/Generator/Report/Account/MonthReportGenerator.php b/app/Generator/Report/Account/MonthReportGenerator.php index f711be2185..bb9e5c8246 100644 --- a/app/Generator/Report/Account/MonthReportGenerator.php +++ b/app/Generator/Report/Account/MonthReportGenerator.php @@ -28,6 +28,7 @@ use FireflyIII\Exceptions\FireflyException; use FireflyIII\Generator\Report\ReportGeneratorInterface; use Illuminate\Support\Collection; use Throwable; +use Illuminate\Support\Facades\Log; /** * Class MonthReportGenerator. @@ -58,8 +59,8 @@ class MonthReportGenerator implements ReportGeneratorInterface ->render() ; } catch (Throwable $e) { - app('log')->error(sprintf('Cannot render reports.double.report: %s', $e->getMessage())); - app('log')->error($e->getTraceAsString()); + Log::error(sprintf('Cannot render reports.double.report: %s', $e->getMessage())); + Log::error($e->getTraceAsString()); $result = sprintf('Could not render report view: %s', $e->getMessage()); throw new FireflyException($result, 0, $e); diff --git a/app/Generator/Report/Audit/MonthReportGenerator.php b/app/Generator/Report/Audit/MonthReportGenerator.php index b920ab172e..e62d609d9d 100644 --- a/app/Generator/Report/Audit/MonthReportGenerator.php +++ b/app/Generator/Report/Audit/MonthReportGenerator.php @@ -105,8 +105,8 @@ class MonthReportGenerator implements ReportGeneratorInterface ->render() ; } catch (Throwable $e) { - app('log')->error(sprintf('Cannot render reports.audit.report: %s', $e->getMessage())); - app('log')->error($e->getTraceAsString()); + Log::error(sprintf('Cannot render reports.audit.report: %s', $e->getMessage())); + Log::error($e->getTraceAsString()); $result = sprintf('Could not render report view: %s', $e->getMessage()); throw new FireflyException($result, 0, $e); diff --git a/app/Generator/Report/Budget/MonthReportGenerator.php b/app/Generator/Report/Budget/MonthReportGenerator.php index 7c19c19e54..5ed587a6df 100644 --- a/app/Generator/Report/Budget/MonthReportGenerator.php +++ b/app/Generator/Report/Budget/MonthReportGenerator.php @@ -30,6 +30,7 @@ use FireflyIII\Generator\Report\ReportGeneratorInterface; use FireflyIII\Helpers\Collector\GroupCollectorInterface; use Illuminate\Support\Collection; use Throwable; +use Illuminate\Support\Facades\Log; /** * Class MonthReportGenerator. @@ -72,8 +73,8 @@ class MonthReportGenerator implements ReportGeneratorInterface ->render() ; } catch (Throwable $e) { - app('log')->error(sprintf('Cannot render reports.account.report: %s', $e->getMessage())); - app('log')->error($e->getTraceAsString()); + Log::error(sprintf('Cannot render reports.account.report: %s', $e->getMessage())); + Log::error($e->getTraceAsString()); $result = sprintf('Could not render report view: %s', $e->getMessage()); throw new FireflyException($result, 0, $e); @@ -132,7 +133,7 @@ class MonthReportGenerator implements ReportGeneratorInterface protected function getExpenses(): array { if (0 !== count($this->expenses)) { - app('log')->debug('Return previous set of expenses.'); + Log::debug('Return previous set of expenses.'); return $this->expenses; } diff --git a/app/Generator/Report/Category/MonthReportGenerator.php b/app/Generator/Report/Category/MonthReportGenerator.php index 61dd7f5cac..8511c426d8 100644 --- a/app/Generator/Report/Category/MonthReportGenerator.php +++ b/app/Generator/Report/Category/MonthReportGenerator.php @@ -30,6 +30,7 @@ use FireflyIII\Generator\Report\ReportGeneratorInterface; use FireflyIII\Helpers\Collector\GroupCollectorInterface; use Illuminate\Support\Collection; use Throwable; +use Illuminate\Support\Facades\Log; /** * Class MonthReportGenerator. @@ -73,8 +74,8 @@ class MonthReportGenerator implements ReportGeneratorInterface ->render() ; } catch (Throwable $e) { - app('log')->error(sprintf('Cannot render reports.category.month: %s', $e->getMessage())); - app('log')->error($e->getTraceAsString()); + Log::error(sprintf('Cannot render reports.category.month: %s', $e->getMessage())); + Log::error($e->getTraceAsString()); $result = sprintf('Could not render report view: %s', $e->getMessage()); throw new FireflyException($result, 0, $e); @@ -131,7 +132,7 @@ class MonthReportGenerator implements ReportGeneratorInterface protected function getExpenses(): array { if (0 !== count($this->expenses)) { - app('log')->debug('Return previous set of expenses.'); + Log::debug('Return previous set of expenses.'); return $this->expenses; } diff --git a/app/Generator/Report/Standard/MonthReportGenerator.php b/app/Generator/Report/Standard/MonthReportGenerator.php index edbe7910b6..e7cd581f61 100644 --- a/app/Generator/Report/Standard/MonthReportGenerator.php +++ b/app/Generator/Report/Standard/MonthReportGenerator.php @@ -28,6 +28,7 @@ use FireflyIII\Exceptions\FireflyException; use FireflyIII\Generator\Report\ReportGeneratorInterface; use Illuminate\Support\Collection; use Throwable; +use Illuminate\Support\Facades\Log; /** * Class MonthReportGenerator. @@ -56,8 +57,8 @@ 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) { - app('log')->error(sprintf('Cannot render reports.default.month: %s', $e->getMessage())); - app('log')->error($e->getTraceAsString()); + Log::error(sprintf('Cannot render reports.default.month: %s', $e->getMessage())); + Log::error($e->getTraceAsString()); $result = 'Could not render report view.'; throw new FireflyException($result, 0, $e); diff --git a/app/Generator/Report/Standard/MultiYearReportGenerator.php b/app/Generator/Report/Standard/MultiYearReportGenerator.php index d5e42a4dcb..7802931a2d 100644 --- a/app/Generator/Report/Standard/MultiYearReportGenerator.php +++ b/app/Generator/Report/Standard/MultiYearReportGenerator.php @@ -28,6 +28,7 @@ use FireflyIII\Exceptions\FireflyException; use FireflyIII\Generator\Report\ReportGeneratorInterface; use Illuminate\Support\Collection; use Throwable; +use Illuminate\Support\Facades\Log; /** * Class MonthReportGenerator. @@ -60,8 +61,8 @@ class MultiYearReportGenerator implements ReportGeneratorInterface compact('accountIds', 'reportType') )->with('start', $this->start)->with('end', $this->end)->render(); } catch (Throwable $e) { - app('log')->error(sprintf('Cannot render reports.default.multi-year: %s', $e->getMessage())); - app('log')->error($e->getTraceAsString()); + Log::error(sprintf('Cannot render reports.default.multi-year: %s', $e->getMessage())); + Log::error($e->getTraceAsString()); $result = sprintf('Could not render report view: %s', $e->getMessage()); throw new FireflyException($result, 0, $e); diff --git a/app/Generator/Report/Standard/YearReportGenerator.php b/app/Generator/Report/Standard/YearReportGenerator.php index 6ac88700c2..b705cdda61 100644 --- a/app/Generator/Report/Standard/YearReportGenerator.php +++ b/app/Generator/Report/Standard/YearReportGenerator.php @@ -28,6 +28,7 @@ use FireflyIII\Exceptions\FireflyException; use FireflyIII\Generator\Report\ReportGeneratorInterface; use Illuminate\Support\Collection; use Throwable; +use Illuminate\Support\Facades\Log; /** * Class MonthReportGenerator. @@ -60,8 +61,8 @@ class YearReportGenerator implements ReportGeneratorInterface compact('accountIds', 'reportType') )->with('start', $this->start)->with('end', $this->end)->render(); } catch (Throwable $e) { - app('log')->error(sprintf('Cannot render reports.account.report: %s', $e->getMessage())); - app('log')->error($e->getTraceAsString()); + Log::error(sprintf('Cannot render reports.account.report: %s', $e->getMessage())); + Log::error($e->getTraceAsString()); $result = 'Could not render report view.'; throw new FireflyException($result, 0, $e); diff --git a/app/Generator/Report/Tag/MonthReportGenerator.php b/app/Generator/Report/Tag/MonthReportGenerator.php index 82d1c0c247..26d454e336 100644 --- a/app/Generator/Report/Tag/MonthReportGenerator.php +++ b/app/Generator/Report/Tag/MonthReportGenerator.php @@ -29,6 +29,7 @@ use FireflyIII\Exceptions\FireflyException; use FireflyIII\Generator\Report\ReportGeneratorInterface; use Illuminate\Support\Collection; use Throwable; +use Illuminate\Support\Facades\Log; /** * Class MonthReportGenerator. @@ -67,8 +68,8 @@ class MonthReportGenerator implements ReportGeneratorInterface compact('accountIds', 'reportType', 'tagIds') )->with('start', $this->start)->with('end', $this->end)->with('tags', $this->tags)->with('accounts', $this->accounts)->render(); } catch (Throwable $e) { - app('log')->error(sprintf('Cannot render reports.tag.month: %s', $e->getMessage())); - app('log')->error($e->getTraceAsString()); + Log::error(sprintf('Cannot render reports.tag.month: %s', $e->getMessage())); + Log::error($e->getTraceAsString()); $result = sprintf('Could not render report view: %s', $e->getMessage()); throw new FireflyException($result, 0, $e); diff --git a/app/Rules/IsAllowedGroupAction.php b/app/Rules/IsAllowedGroupAction.php index 7e30cd30ec..d8e8c4f08a 100644 --- a/app/Rules/IsAllowedGroupAction.php +++ b/app/Rules/IsAllowedGroupAction.php @@ -26,6 +26,7 @@ namespace FireflyIII\Rules; use Closure; use FireflyIII\Enums\UserRoleEnum; +use FireflyIII\Exceptions\FireflyException; use FireflyIII\Models\Account; use FireflyIII\Repositories\UserGroup\UserGroupRepositoryInterface; use FireflyIII\User; @@ -68,11 +69,18 @@ class IsAllowedGroupAction implements ValidationRule break; } } - $this->validateUserGroup((int) $value, $fail); + $this->validateUserGroup((int)$value, $fail); } + private function validateUserGroup(int $userGroupId, Closure $fail): void { + try { + throw new FireflyException('Here we are'); + } catch (FireflyException $e) { + Log::error($e->getTraceAsString()); + } + die('here we are'); Log::debug(sprintf('validateUserGroup: %s', static::class)); if (!auth()->check()) { Log::debug('validateUserGroup: user is not logged in, return NULL.'); @@ -82,7 +90,7 @@ class IsAllowedGroupAction implements ValidationRule } /** @var User $user */ - $user = auth()->user(); + $user = auth()->user(); if (0 !== $userGroupId) { Log::debug(sprintf('validateUserGroup: user group submitted, search for memberships in group #%d.', $userGroupId)); } @@ -102,7 +110,7 @@ class IsAllowedGroupAction implements ValidationRule } // need to get the group from the membership: - $userGroup = $this->repository->getById($userGroupId); + $userGroup = $this->repository->getById($userGroupId); if (null === $userGroup) { Log::debug(sprintf('validateUserGroup: group #%d does not exist.', $userGroupId)); $fail('validation.belongs_user_or_user_group')->translate(); diff --git a/app/Rules/TransactionType/IsValidTransactionTypeList.php b/app/Rules/TransactionType/IsValidTransactionTypeList.php new file mode 100644 index 0000000000..4f27b57f00 --- /dev/null +++ b/app/Rules/TransactionType/IsValidTransactionTypeList.php @@ -0,0 +1,56 @@ +translate(); + } + $keys = array_keys($this->transactionTypes); + foreach ($values as $entry) { + $entry = (string)$entry; + if (!in_array($entry, $keys, true)) { + $fail('validation.invalid_transaction_type_list')->translate(); + } + } + } +} diff --git a/app/Support/Http/Api/TransactionFilter.php b/app/Support/Http/Api/TransactionFilter.php index f6f13d77a7..74b8090468 100644 --- a/app/Support/Http/Api/TransactionFilter.php +++ b/app/Support/Http/Api/TransactionFilter.php @@ -31,39 +31,48 @@ use FireflyIII\Enums\TransactionTypeEnum; */ trait TransactionFilter { - /** - * All the types you can request. - */ - protected function mapTransactionTypes(string $type): array - { - $types = [ - 'all' => [ + protected $transactionTypes + = [ + 'all' => [ TransactionTypeEnum::WITHDRAWAL->value, TransactionTypeEnum::DEPOSIT->value, TransactionTypeEnum::TRANSFER->value, TransactionTypeEnum::OPENING_BALANCE->value, TransactionTypeEnum::RECONCILIATION->value, ], - 'withdrawal' => [TransactionTypeEnum::WITHDRAWAL->value], - 'withdrawals' => [TransactionTypeEnum::WITHDRAWAL->value], - 'expense' => [TransactionTypeEnum::WITHDRAWAL->value], - 'expenses' => [TransactionTypeEnum::WITHDRAWAL->value], - 'income' => [TransactionTypeEnum::DEPOSIT->value], - 'deposit' => [TransactionTypeEnum::DEPOSIT->value], - 'deposits' => [TransactionTypeEnum::DEPOSIT->value], - 'transfer' => [TransactionTypeEnum::TRANSFER->value], - 'transfers' => [TransactionTypeEnum::TRANSFER->value], - 'opening_balance' => [TransactionTypeEnum::OPENING_BALANCE->value], - 'reconciliation' => [TransactionTypeEnum::RECONCILIATION->value], - 'reconciliations' => [TransactionTypeEnum::RECONCILIATION->value], - 'special' => [TransactionTypeEnum::OPENING_BALANCE->value, TransactionTypeEnum::RECONCILIATION->value], - 'specials' => [TransactionTypeEnum::OPENING_BALANCE->value, TransactionTypeEnum::RECONCILIATION->value], - 'default' => [TransactionTypeEnum::WITHDRAWAL->value, TransactionTypeEnum::DEPOSIT->value, TransactionTypeEnum::TRANSFER->value], + TransactionTypeEnum::WITHDRAWAL->value => [TransactionTypeEnum::WITHDRAWAL->value], + 'withdrawal' => [TransactionTypeEnum::WITHDRAWAL->value], + 'withdrawals' => [TransactionTypeEnum::WITHDRAWAL->value], + 'expense' => [TransactionTypeEnum::WITHDRAWAL->value], + 'expenses' => [TransactionTypeEnum::WITHDRAWAL->value], + TransactionTypeEnum::DEPOSIT->value => [TransactionTypeEnum::DEPOSIT->value], + 'income' => [TransactionTypeEnum::DEPOSIT->value], + 'deposit' => [TransactionTypeEnum::DEPOSIT->value], + 'deposits' => [TransactionTypeEnum::DEPOSIT->value], + TransactionTypeEnum::TRANSFER->value => [TransactionTypeEnum::TRANSFER->value], + 'transfer' => [TransactionTypeEnum::TRANSFER->value], + 'transfers' => [TransactionTypeEnum::TRANSFER->value], + TransactionTypeEnum::OPENING_BALANCE->value => [TransactionTypeEnum::OPENING_BALANCE->value], + 'opening_balance' => [TransactionTypeEnum::OPENING_BALANCE->value], + TransactionTypeEnum::RECONCILIATION->value => [TransactionTypeEnum::RECONCILIATION->value], + 'reconciliation' => [TransactionTypeEnum::RECONCILIATION->value], + 'reconciliations' => [TransactionTypeEnum::RECONCILIATION->value], + 'special' => [TransactionTypeEnum::OPENING_BALANCE->value, TransactionTypeEnum::RECONCILIATION->value], + 'specials' => [TransactionTypeEnum::OPENING_BALANCE->value, TransactionTypeEnum::RECONCILIATION->value], + 'default' => [TransactionTypeEnum::WITHDRAWAL->value, TransactionTypeEnum::DEPOSIT->value, TransactionTypeEnum::TRANSFER->value], ]; + + /** + * All the types you can request. + */ + protected function mapTransactionTypes(string $type): array + { $return = []; $parts = explode(',', $type); foreach ($parts as $part) { - $return = array_merge($return, $types[$part] ?? $types['default']); + if(array_key_exists($part, $this->transactionTypes)) { + $return = array_merge($return, $this->transactionTypes[$part]); + } } return array_unique($return); diff --git a/app/Support/Http/Api/ValidatesUserGroupTrait.php b/app/Support/Http/Api/ValidatesUserGroupTrait.php index 3d17a7b42c..2c9db16cb3 100644 --- a/app/Support/Http/Api/ValidatesUserGroupTrait.php +++ b/app/Support/Http/Api/ValidatesUserGroupTrait.php @@ -25,6 +25,7 @@ declare(strict_types=1); namespace FireflyIII\Support\Http\Api; use FireflyIII\Enums\UserRoleEnum; +use FireflyIII\Exceptions\FireflyException; use FireflyIII\Models\UserGroup; use FireflyIII\Repositories\UserGroup\UserGroupRepositoryInterface; use FireflyIII\User; diff --git a/app/TransactionRules/Actions/LinkToBill.php b/app/TransactionRules/Actions/LinkToBill.php index b52f278442..4b118f763b 100644 --- a/app/TransactionRules/Actions/LinkToBill.php +++ b/app/TransactionRules/Actions/LinkToBill.php @@ -31,6 +31,7 @@ use FireflyIII\Models\TransactionJournal; use FireflyIII\Repositories\Bill\BillRepositoryInterface; use FireflyIII\User; use Illuminate\Support\Facades\DB; +use Illuminate\Support\Facades\Log; /** * Class LinkToBill. @@ -54,29 +55,16 @@ class LinkToBill implements ActionInterface $bill = $repository->findByName($billName); if (null !== $bill && TransactionTypeEnum::WITHDRAWAL->value === $journal['transaction_type_type']) { - $count = DB::table('transaction_journals')->where('id', '=', $journal['transaction_journal_id']) - ->where('bill_id', $bill->id)->count() - ; + $count = DB::table('transaction_journals')->where('id', '=', $journal['transaction_journal_id'])->where('bill_id', $bill->id)->count(); if (0 !== $count) { - app('log')->error( - sprintf( - 'RuleAction LinkToBill could not set the bill of journal #%d to bill "%s": already set.', - $journal['transaction_journal_id'], - $billName - ) - ); - event(new RuleActionFailedOnArray($this->action, $journal, trans('rules.already_linked_to_subscription', ['name' => $billName]))); + Log::error(sprintf('RuleAction LinkToBill could not set the bill of journal #%d to bill "%s": already set.', $journal['transaction_journal_id'], $billName)); + // event(new RuleActionFailedOnArray($this->action, $journal, trans('rules.already_linked_to_subscription', ['name' => $billName]))); return false; } - DB::table('transaction_journals') - ->where('id', '=', $journal['transaction_journal_id']) - ->update(['bill_id' => $bill->id]) - ; - app('log')->debug( - sprintf('RuleAction LinkToBill set the bill of journal #%d to bill #%d ("%s").', $journal['transaction_journal_id'], $bill->id, $bill->name) - ); + DB::table('transaction_journals')->where('id', '=', $journal['transaction_journal_id'])->update(['bill_id' => $bill->id]); + 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']); @@ -85,13 +73,7 @@ class LinkToBill implements ActionInterface return true; } - 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'], - $billName - ) - ); + 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'], $billName)); event(new RuleActionFailedOnArray($this->action, $journal, trans('rules.cannot_find_subscription', ['name' => $billName]))); return false; diff --git a/resources/lang/en_US/validation.php b/resources/lang/en_US/validation.php index 008eee28b2..833154b1e1 100644 --- a/resources/lang/en_US/validation.php +++ b/resources/lang/en_US/validation.php @@ -25,6 +25,7 @@ declare(strict_types=1); return [ 'invalid_account_list' => 'Invalid account type list', + 'invalid_transaction_type_list' => 'Invalid transaction type list', 'limit_exists' => 'There is already a budget limit (amount) for this budget and currency in the given period.', 'invalid_sort_instruction' => 'The sort instruction is invalid for an object of type ":object".', 'invalid_sort_instruction_index' => 'The sort instruction at index #:index is invalid for an object of type ":object".', From e9cf5111c9d100fdb403e6a90ade897e4bcc18ac Mon Sep 17 00:00:00 2001 From: James Cole Date: Sun, 2 Nov 2025 14:03:59 +0100 Subject: [PATCH 05/29] Add required parameter. --- app/Api/V1/Controllers/Models/Account/ListController.php | 1 - app/Api/V1/Requests/Generic/ObjectTypeApiRequest.php | 8 ++++++-- 2 files changed, 6 insertions(+), 3 deletions(-) diff --git a/app/Api/V1/Controllers/Models/Account/ListController.php b/app/Api/V1/Controllers/Models/Account/ListController.php index e5ea31a8b7..919a48dada 100644 --- a/app/Api/V1/Controllers/Models/Account/ListController.php +++ b/app/Api/V1/Controllers/Models/Account/ListController.php @@ -175,7 +175,6 @@ class ListController extends Controller /** @var TransactionGroupTransformer $transformer */ $transformer = app(TransactionGroupTransformer::class); - $transformer->setParameters($this->parameters); $resource = new FractalCollection($transactions, $transformer, 'transactions'); $resource->setPaginator(new IlluminatePaginatorAdapter($paginator)); diff --git a/app/Api/V1/Requests/Generic/ObjectTypeApiRequest.php b/app/Api/V1/Requests/Generic/ObjectTypeApiRequest.php index bf9b3a496f..cdc1837438 100644 --- a/app/Api/V1/Requests/Generic/ObjectTypeApiRequest.php +++ b/app/Api/V1/Requests/Generic/ObjectTypeApiRequest.php @@ -60,9 +60,13 @@ class ObjectTypeApiRequest extends ApiRequest if (Transaction::class === $this->objectType) { $rule = new IsValidTransactionTypeList(); } - return [ - 'types' => $rule, + $rules = [ + 'types' => [$rule], ]; + if ('' !== $this->required) { + $rules['types'][] = $this->required; + } + return $rules; } public function withValidator(Validator $validator): void From 69b816d95798cc716a462d0581dd69e7b727c001 Mon Sep 17 00:00:00 2001 From: James Cole Date: Sun, 2 Nov 2025 14:39:34 +0100 Subject: [PATCH 06/29] Clean up a variety of requests. --- .../Models/Account/ListController.php | 25 ++++---- .../Models/Account/StoreController.php | 1 - .../Models/Account/UpdateController.php | 1 - .../Models/Attachment/ShowController.php | 18 +++--- .../Models/Attachment/StoreController.php | 1 - .../Models/Attachment/UpdateController.php | 1 - .../Models/AvailableBudget/ShowController.php | 23 ++++---- .../Models/Bill/ListController.php | 59 +++++++++++-------- .../Models/Bill/ShowController.php | 35 +++++++---- .../Generic/PaginationDateRangeRequest.php | 43 ++++++++++++++ app/Models/BudgetLimit.php | 2 +- 11 files changed, 133 insertions(+), 76 deletions(-) create mode 100644 app/Api/V1/Requests/Generic/PaginationDateRangeRequest.php diff --git a/app/Api/V1/Controllers/Models/Account/ListController.php b/app/Api/V1/Controllers/Models/Account/ListController.php index 919a48dada..3acdfbc6cf 100644 --- a/app/Api/V1/Controllers/Models/Account/ListController.php +++ b/app/Api/V1/Controllers/Models/Account/ListController.php @@ -25,6 +25,7 @@ declare(strict_types=1); namespace FireflyIII\Api\V1\Controllers\Models\Account; use FireflyIII\Api\V1\Controllers\Controller; +use FireflyIII\Api\V1\Requests\Generic\PaginationDateRangeRequest; use FireflyIII\Api\V1\Requests\PaginationRequest; use FireflyIII\Helpers\Collector\GroupCollectorInterface; use FireflyIII\Models\Account; @@ -110,7 +111,7 @@ class ListController extends Controller // get list of piggy banks. Count it and split it. $collection = $this->repository->getPiggyBanks($account); $count = $collection->count(); - $piggyBanks = $collection->slice(($page - 1) * $limit, $limit); + $piggyBanks = $collection->slice($offset, $limit); // enrich /** @var User $admin */ @@ -136,16 +137,15 @@ class ListController extends Controller /** * Show all transaction groups related to the account. */ - public function transactions(PaginationRequest $request, Account $account): JsonResponse + public function transactions(PaginationDateRangeRequest $request, Account $account): JsonResponse { [ 'limit' => $limit, - 'offset' => $offset, 'page' => $page, + 'start' => $start, + 'end' => $end, + 'types' => $types, ] = $request->attributes->all(); - - $type = $request->get('type') ?? 'default'; - $types = $this->mapTransactionTypes($type); $manager = $this->getManager(); /** @var User $admin */ @@ -154,15 +154,12 @@ class ListController extends Controller // use new group collector: /** @var GroupCollectorInterface $collector */ $collector = app(GroupCollectorInterface::class); - $collector->setUser($admin)->setAccounts(new Collection()->push($account)) - ->withAPIInformation()->setLimit($limit)->setPage($page)->setTypes($types) - ; - - if (null !== $this->parameters->get('start')) { - $collector->setStart($this->parameters->get('start')); + $collector->setUser($admin)->setAccounts(new Collection()->push($account))->withAPIInformation()->setLimit($limit)->setPage($page)->setTypes($types); + if (null !== $start) { + $collector->setStart($start); } - if (null !== $this->parameters->get('end')) { - $collector->setEnd($this->parameters->get('end')); + if (null !== $end) { + $collector->setEnd($end); } $paginator = $collector->getPaginatedGroups(); diff --git a/app/Api/V1/Controllers/Models/Account/StoreController.php b/app/Api/V1/Controllers/Models/Account/StoreController.php index bbda9b50ef..3d9addc3c5 100644 --- a/app/Api/V1/Controllers/Models/Account/StoreController.php +++ b/app/Api/V1/Controllers/Models/Account/StoreController.php @@ -81,7 +81,6 @@ class StoreController extends Controller /** @var AccountTransformer $transformer */ $transformer = app(AccountTransformer::class); - $transformer->setParameters($this->parameters); $resource = new Item($account, $transformer, self::RESOURCE_KEY); diff --git a/app/Api/V1/Controllers/Models/Account/UpdateController.php b/app/Api/V1/Controllers/Models/Account/UpdateController.php index 5ae8f5b45d..71cf69152f 100644 --- a/app/Api/V1/Controllers/Models/Account/UpdateController.php +++ b/app/Api/V1/Controllers/Models/Account/UpdateController.php @@ -87,7 +87,6 @@ class UpdateController extends Controller /** @var AccountTransformer $transformer */ $transformer = app(AccountTransformer::class); - $transformer->setParameters($this->parameters); $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/ShowController.php b/app/Api/V1/Controllers/Models/Attachment/ShowController.php index 273c8dc986..8b5099946b 100644 --- a/app/Api/V1/Controllers/Models/Attachment/ShowController.php +++ b/app/Api/V1/Controllers/Models/Attachment/ShowController.php @@ -26,6 +26,7 @@ namespace FireflyIII\Api\V1\Controllers\Models\Attachment; use FireflyIII\Api\V1\Controllers\Controller; use FireflyIII\Api\V1\Middleware\ApiDemoUser; +use FireflyIII\Api\V1\Requests\PaginationRequest; use FireflyIII\Exceptions\FireflyException; use FireflyIII\Models\Attachment; use FireflyIII\Repositories\Attachment\AttachmentRepositoryInterface; @@ -120,8 +121,14 @@ class ShowController extends Controller * * Display a listing of the resource. */ - public function index(): JsonResponse + public function index(PaginationRequest $request): JsonResponse { + [ + 'limit' => $limit, + 'offset' => $offset, + 'page' => $page, + ] = $request->attributes->all(); + if (true === auth()->user()->hasRole('demo')) { Log::channel('audit')->warning(sprintf('Demo user tries to access attachment API in %s', __METHOD__)); @@ -130,21 +137,17 @@ class ShowController extends Controller $manager = $this->getManager(); - // types to get, page size: - $pageSize = $this->parameters->get('limit'); - // get list of attachments. Count it and split it. $collection = $this->repository->get(); $count = $collection->count(); - $attachments = $collection->slice(($this->parameters->get('page') - 1) * $pageSize, $pageSize); + $attachments = $collection->slice($offset, $limit); // make paginator: - $paginator = new LengthAwarePaginator($attachments, $count, $pageSize, $this->parameters->get('page')); + $paginator = new LengthAwarePaginator($attachments, $count, $limit, $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->setPaginator(new IlluminatePaginatorAdapter($paginator)); @@ -169,7 +172,6 @@ class ShowController extends Controller /** @var AttachmentTransformer $transformer */ $transformer = app(AttachmentTransformer::class); - $transformer->setParameters($this->parameters); $resource = new Item($attachment, $transformer, 'attachments'); diff --git a/app/Api/V1/Controllers/Models/Attachment/StoreController.php b/app/Api/V1/Controllers/Models/Attachment/StoreController.php index a070ff8c5d..77e2060c36 100644 --- a/app/Api/V1/Controllers/Models/Attachment/StoreController.php +++ b/app/Api/V1/Controllers/Models/Attachment/StoreController.php @@ -87,7 +87,6 @@ class StoreController extends Controller /** @var AttachmentTransformer $transformer */ $transformer = app(AttachmentTransformer::class); - $transformer->setParameters($this->parameters); $resource = new Item($attachment, $transformer, 'attachments'); diff --git a/app/Api/V1/Controllers/Models/Attachment/UpdateController.php b/app/Api/V1/Controllers/Models/Attachment/UpdateController.php index c5e2fd2a9c..9945b61697 100644 --- a/app/Api/V1/Controllers/Models/Attachment/UpdateController.php +++ b/app/Api/V1/Controllers/Models/Attachment/UpdateController.php @@ -81,7 +81,6 @@ class UpdateController extends Controller /** @var AttachmentTransformer $transformer */ $transformer = app(AttachmentTransformer::class); - $transformer->setParameters($this->parameters); $resource = new Item($attachment, $transformer, 'attachments'); diff --git a/app/Api/V1/Controllers/Models/AvailableBudget/ShowController.php b/app/Api/V1/Controllers/Models/AvailableBudget/ShowController.php index ee0c01610f..624199c9fa 100644 --- a/app/Api/V1/Controllers/Models/AvailableBudget/ShowController.php +++ b/app/Api/V1/Controllers/Models/AvailableBudget/ShowController.php @@ -25,6 +25,7 @@ declare(strict_types=1); namespace FireflyIII\Api\V1\Controllers\Models\AvailableBudget; use FireflyIII\Api\V1\Controllers\Controller; +use FireflyIII\Api\V1\Requests\Generic\PaginationDateRangeRequest; use FireflyIII\Models\AvailableBudget; use FireflyIII\Repositories\Budget\AvailableBudgetRepositoryInterface; use FireflyIII\Support\JsonApi\Enrichments\AvailableBudgetEnrichment; @@ -67,19 +68,21 @@ class ShowController extends Controller * * Display a listing of the resource. */ - public function index(): JsonResponse + public function index(PaginationDateRangeRequest $request): JsonResponse { $manager = $this->getManager(); - - // types to get, page size: - $pageSize = $this->parameters->get('limit'); - $start = $this->parameters->get('start'); - $end = $this->parameters->get('end'); + [ + 'limit' => $limit, + 'offset' => $offset, + 'page' => $page, + 'start' => $start, + 'end' => $end, + ] = $request->attributes->all(); // get list of available budgets. Count it and split it. $collection = $this->abRepository->getAvailableBudgetsByDate($start, $end); $count = $collection->count(); - $availableBudgets = $collection->slice(($this->parameters->get('page') - 1) * $pageSize, $pageSize); + $availableBudgets = $collection->slice($offset, $limit); // enrich /** @var User $admin */ @@ -89,12 +92,11 @@ class ShowController extends Controller $availableBudgets = $enrichment->enrich($availableBudgets); // make paginator: - $paginator = new LengthAwarePaginator($availableBudgets, $count, $pageSize, $this->parameters->get('page')); + $paginator = new LengthAwarePaginator($availableBudgets, $count, $limit, $page); $paginator->setPath(route('api.v1.available-budgets.index').$this->buildParams()); /** @var AvailableBudgetTransformer $transformer */ $transformer = app(AvailableBudgetTransformer::class); - $transformer->setParameters($this->parameters); $resource = new FractalCollection($availableBudgets, $transformer, 'available_budgets'); $resource->setPaginator(new IlluminatePaginatorAdapter($paginator)); @@ -116,15 +118,12 @@ class ShowController extends Controller /** @var AvailableBudgetTransformer $transformer */ $transformer = app(AvailableBudgetTransformer::class); - $transformer->setParameters($this->parameters); // enrich /** @var User $admin */ $admin = auth()->user(); $enrichment = new AvailableBudgetEnrichment(); $enrichment->setUser($admin); - // $enrichment->setStart($start); - // $enrichment->setEnd($end); $availableBudget = $enrichment->enrichSingle($availableBudget); diff --git a/app/Api/V1/Controllers/Models/Bill/ListController.php b/app/Api/V1/Controllers/Models/Bill/ListController.php index e33c6f5804..f3867841fc 100644 --- a/app/Api/V1/Controllers/Models/Bill/ListController.php +++ b/app/Api/V1/Controllers/Models/Bill/ListController.php @@ -25,6 +25,8 @@ declare(strict_types=1); namespace FireflyIII\Api\V1\Controllers\Models\Bill; use FireflyIII\Api\V1\Controllers\Controller; +use FireflyIII\Api\V1\Requests\Generic\PaginationDateRangeRequest; +use FireflyIII\Api\V1\Requests\PaginationRequest; use FireflyIII\Helpers\Collector\GroupCollectorInterface; use FireflyIII\Models\Bill; use FireflyIII\Repositories\Bill\BillRepositoryInterface; @@ -71,22 +73,25 @@ class ListController extends Controller * * Display a listing of the resource. */ - public function attachments(Bill $bill): JsonResponse + public function attachments(PaginationRequest $request, Bill $bill): JsonResponse { + [ + 'limit' => $limit, + 'offset' => $offset, + 'page' => $page, + ] = $request->attributes->all(); $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); + $attachments = $collection->slice($offset, $limit); // make paginator: - $paginator = new LengthAwarePaginator($attachments, $count, $pageSize, $this->parameters->get('page')); + $paginator = new LengthAwarePaginator($attachments, $count, $limit, $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->setPaginator(new IlluminatePaginatorAdapter($paginator)); @@ -100,25 +105,25 @@ class ListController extends Controller * * List all of them. */ - public function rules(Bill $bill): JsonResponse + public function rules(PaginationRequest $request, Bill $bill): JsonResponse { + [ + 'limit' => $limit, + 'offset' => $offset, + 'page' => $page, + ] = $request->attributes->all(); + $manager = $this->getManager(); - - // types to get, page size: - $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); + $rules = $collection->slice($offset, $limit); // make paginator: - $paginator = new LengthAwarePaginator($rules, $count, $pageSize, $this->parameters->get('page')); + $paginator = new LengthAwarePaginator($rules, $count, $limit, $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->setPaginator(new IlluminatePaginatorAdapter($paginator)); @@ -131,13 +136,16 @@ class ListController extends Controller * * Show all transactions. */ - public function transactions(Request $request, Bill $bill): JsonResponse + public function transactions(PaginationDateRangeRequest $request, Bill $bill): JsonResponse { - $pageSize = $this->parameters->get('limit'); - $type = $request->get('type') ?? 'default'; - $this->parameters->set('type', $type); + [ + 'limit' => $limit, + 'page' => $page, + 'types' => $types, + 'start' => $start, + 'end' => $end, + ] = $request->attributes->all(); - $types = $this->mapTransactionTypes($this->parameters->get('type')); $manager = $this->getManager(); /** @var User $admin */ @@ -153,18 +161,18 @@ class ListController extends Controller // all info needed for the API: ->withAPIInformation() // set page size: - ->setLimit($pageSize) + ->setLimit($limit) // set page to retrieve - ->setPage($this->parameters->get('page')) + ->setPage($page) // set types of transactions to return. ->setTypes($types) ; - if (null !== $this->parameters->get('start')) { - $collector->setStart($this->parameters->get('start')); + if (null !== $start) { + $collector->setStart($start); } - if (null !== $this->parameters->get('end')) { - $collector->setEnd($this->parameters->get('end')); + if (null !== $end) { + $collector->setEnd($end); } // get paginator. @@ -178,7 +186,6 @@ class ListController extends Controller /** @var TransactionGroupTransformer $transformer */ $transformer = app(TransactionGroupTransformer::class); - $transformer->setParameters($this->parameters); $resource = new FractalCollection($transactions, $transformer, 'transactions'); $resource->setPaginator(new IlluminatePaginatorAdapter($paginator)); diff --git a/app/Api/V1/Controllers/Models/Bill/ShowController.php b/app/Api/V1/Controllers/Models/Bill/ShowController.php index 396c6e4db8..cdcb67cf9a 100644 --- a/app/Api/V1/Controllers/Models/Bill/ShowController.php +++ b/app/Api/V1/Controllers/Models/Bill/ShowController.php @@ -25,6 +25,9 @@ declare(strict_types=1); namespace FireflyIII\Api\V1\Controllers\Models\Bill; use FireflyIII\Api\V1\Controllers\Controller; +use FireflyIII\Api\V1\Requests\DateRangeRequest; +use FireflyIII\Api\V1\Requests\Generic\PaginationDateRangeRequest; +use FireflyIII\Api\V1\Requests\PaginationRequest; use FireflyIII\Models\Bill; use FireflyIII\Repositories\Bill\BillRepositoryInterface; use FireflyIII\Support\JsonApi\Enrichments\SubscriptionEnrichment; @@ -65,28 +68,34 @@ class ShowController extends Controller * * Display a listing of the resource. */ - public function index(): JsonResponse + public function index(PaginationDateRangeRequest $request): JsonResponse { + [ + 'limit' => $limit, + 'offset' => $offset, + 'start' => $start, + 'end' => $end, + 'page' => $page, + ] = $request->attributes->all(); + $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 = $bills->slice($offset, $limit); + $paginator = new LengthAwarePaginator($bills, $count, $limit, $page); // enrich /** @var User $admin */ $admin = auth()->user(); $enrichment = new SubscriptionEnrichment(); $enrichment->setUser($admin); - $enrichment->setStart($this->parameters->get('start')); - $enrichment->setEnd($this->parameters->get('end')); + $enrichment->setStart($start); + $enrichment->setEnd($end); $bills = $enrichment->enrich($bills); /** @var BillTransformer $transformer */ $transformer = app(BillTransformer::class); - $transformer->setParameters($this->parameters); $resource = new FractalCollection($bills, $transformer, 'bills'); $resource->setPaginator(new IlluminatePaginatorAdapter($paginator)); @@ -100,8 +109,13 @@ class ShowController extends Controller * * Show the specified bill. */ - public function show(Bill $bill): JsonResponse + public function show(DateRangeRequest $request, Bill $bill): JsonResponse { + [ + 'start' => $start, + 'end' => $end, + ] = $request->attributes->all(); + $manager = $this->getManager(); // enrich @@ -109,13 +123,12 @@ class ShowController extends Controller $admin = auth()->user(); $enrichment = new SubscriptionEnrichment(); $enrichment->setUser($admin); - $enrichment->setStart($this->parameters->get('start')); - $enrichment->setEnd($this->parameters->get('end')); + $enrichment->setStart($start); + $enrichment->setEnd($end); $bill = $enrichment->enrichSingle($bill); /** @var BillTransformer $transformer */ $transformer = app(BillTransformer::class); - $transformer->setParameters($this->parameters); $resource = new Item($bill, $transformer, 'bills'); diff --git a/app/Api/V1/Requests/Generic/PaginationDateRangeRequest.php b/app/Api/V1/Requests/Generic/PaginationDateRangeRequest.php new file mode 100644 index 0000000000..ed7e2cdd94 --- /dev/null +++ b/app/Api/V1/Requests/Generic/PaginationDateRangeRequest.php @@ -0,0 +1,43 @@ +. + */ + +namespace FireflyIII\Api\V1\Requests\Generic; + +use FireflyIII\Api\V1\Requests\AggregateFormRequest; +use FireflyIII\Api\V1\Requests\DateRangeRequest; +use FireflyIII\Api\V1\Requests\PaginationRequest; +use FireflyIII\Models\Transaction; + +/** + * TODO this class includes an object type filter which should be moved to its own thing. + */ +class PaginationDateRangeRequest extends AggregateFormRequest +{ + #[Override] + protected function getRequests(): array + { + return [ + DateRangeRequest::class, + [ObjectTypeApiRequest::class, 'object_type' => Transaction::class], + [PaginationRequest::class, 'sort_class' => Transaction::class], + ]; + } +} diff --git a/app/Models/BudgetLimit.php b/app/Models/BudgetLimit.php index 6ac0d049f3..bd4c602dd5 100644 --- a/app/Models/BudgetLimit.php +++ b/app/Models/BudgetLimit.php @@ -39,7 +39,7 @@ use Symfony\Component\HttpKernel\Exception\NotFoundHttpException; * * @property TransactionCurrency $transactionCurrency * @property Carbon $start_date - * @property Carbon $end_date + * @property Carbon|null $end_date */ #[ObservedBy([BudgetLimitObserver::class])] class BudgetLimit extends Model From b49575db8b51631e0a8ee6ee1585b45bbe130192 Mon Sep 17 00:00:00 2001 From: James Cole Date: Sun, 2 Nov 2025 14:42:34 +0100 Subject: [PATCH 07/29] Replace reference. --- .../Events/Model/PiggyBankEventHandler.php | 3 +- app/Handlers/Events/Model/RuleHandler.php | 4 +- app/Handlers/Events/Security/MFAHandler.php | 71 ++++++++++--------- 3 files changed, 40 insertions(+), 38 deletions(-) diff --git a/app/Handlers/Events/Model/PiggyBankEventHandler.php b/app/Handlers/Events/Model/PiggyBankEventHandler.php index b44c9e4741..764ad00711 100644 --- a/app/Handlers/Events/Model/PiggyBankEventHandler.php +++ b/app/Handlers/Events/Model/PiggyBankEventHandler.php @@ -31,6 +31,7 @@ use FireflyIII\Models\PiggyBankEvent; use FireflyIII\Models\Rule; use FireflyIII\Models\RuleAction; use FireflyIII\Models\TransactionGroup; +use Illuminate\Support\Facades\Log; /** * Class PiggyBankEventHandler @@ -70,7 +71,7 @@ class PiggyBankEventHandler ->exists() ; if ($exists) { - app('log')->warning('Already have event for this journal and piggy, will not create another.'); + 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 9655368b52..0703488e2c 100644 --- a/app/Handlers/Events/Model/RuleHandler.php +++ b/app/Handlers/Events/Model/RuleHandler.php @@ -47,7 +47,7 @@ class RuleHandler if (false === $preference) { return; } - app('log')->debug('Now in ruleActionFailedOnArray'); + Log::debug('Now in ruleActionFailedOnArray'); $journal = $event->journal; $error = $event->error; $user = $ruleAction->rule->user; @@ -76,7 +76,7 @@ class RuleHandler if (false === $preference) { return; } - app('log')->debug('Now in ruleActionFailedOnObject'); + Log::debug('Now in ruleActionFailedOnObject'); $journal = $event->journal; $error = $event->error; $user = $ruleAction->rule->user; diff --git a/app/Handlers/Events/Security/MFAHandler.php b/app/Handlers/Events/Security/MFAHandler.php index f3b6dab533..63f9ec31b9 100644 --- a/app/Handlers/Events/Security/MFAHandler.php +++ b/app/Handlers/Events/Security/MFAHandler.php @@ -40,12 +40,13 @@ use FireflyIII\Notifications\Security\MFAManyFailedAttemptsNotification; use FireflyIII\Notifications\Security\MFAUsedBackupCodeNotification; use FireflyIII\Notifications\Security\NewBackupCodesNotification; use Illuminate\Support\Facades\Notification; +use Illuminate\Support\Facades\Log; class MFAHandler { public function sendBackupFewLeftMail(MFABackupFewLeft $event): void { - app('log')->debug(sprintf('Now in %s', __METHOD__)); + Log::debug(sprintf('Now in %s', __METHOD__)); $user = $event->user; $count = $event->count; @@ -55,23 +56,23 @@ class MFAHandler } catch (Exception $e) { $message = $e->getMessage(); if (str_contains($message, 'Bcc')) { - app('log')->warning('[Bcc] Could not send notification. Please validate your email settings, use the .env.example file as a guide.'); + 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')) { - app('log')->warning('[RFC] Could not send notification. Please validate your email settings, use the .env.example file as a guide.'); + Log::warning('[RFC] Could not send notification. Please validate your email settings, use the .env.example file as a guide.'); return; } - app('log')->error($e->getMessage()); - app('log')->error($e->getTraceAsString()); + Log::error($e->getMessage()); + Log::error($e->getTraceAsString()); } } public function sendBackupNoLeftMail(MFABackupNoLeft $event): void { - app('log')->debug(sprintf('Now in %s', __METHOD__)); + Log::debug(sprintf('Now in %s', __METHOD__)); $user = $event->user; @@ -80,23 +81,23 @@ class MFAHandler } catch (Exception $e) { $message = $e->getMessage(); if (str_contains($message, 'Bcc')) { - app('log')->warning('[Bcc] Could not send notification. Please validate your email settings, use the .env.example file as a guide.'); + 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')) { - app('log')->warning('[RFC] Could not send notification. Please validate your email settings, use the .env.example file as a guide.'); + Log::warning('[RFC] Could not send notification. Please validate your email settings, use the .env.example file as a guide.'); return; } - app('log')->error($e->getMessage()); - app('log')->error($e->getTraceAsString()); + Log::error($e->getMessage()); + Log::error($e->getTraceAsString()); } } public function sendMFADisabledMail(DisabledMFA $event): void { - app('log')->debug(sprintf('Now in %s', __METHOD__)); + Log::debug(sprintf('Now in %s', __METHOD__)); $user = $event->user; @@ -105,23 +106,23 @@ class MFAHandler } catch (Exception $e) { $message = $e->getMessage(); if (str_contains($message, 'Bcc')) { - app('log')->warning('[Bcc] Could not send notification. Please validate your email settings, use the .env.example file as a guide.'); + 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')) { - app('log')->warning('[RFC] Could not send notification. Please validate your email settings, use the .env.example file as a guide.'); + Log::warning('[RFC] Could not send notification. Please validate your email settings, use the .env.example file as a guide.'); return; } - app('log')->error($e->getMessage()); - app('log')->error($e->getTraceAsString()); + Log::error($e->getMessage()); + Log::error($e->getTraceAsString()); } } public function sendMFAEnabledMail(EnabledMFA $event): void { - app('log')->debug(sprintf('Now in %s', __METHOD__)); + Log::debug(sprintf('Now in %s', __METHOD__)); $user = $event->user; @@ -130,23 +131,23 @@ class MFAHandler } catch (Exception $e) { $message = $e->getMessage(); if (str_contains($message, 'Bcc')) { - app('log')->warning('[Bcc] Could not send notification. Please validate your email settings, use the .env.example file as a guide.'); + 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')) { - app('log')->warning('[RFC] Could not send notification. Please validate your email settings, use the .env.example file as a guide.'); + Log::warning('[RFC] Could not send notification. Please validate your email settings, use the .env.example file as a guide.'); return; } - app('log')->error($e->getMessage()); - app('log')->error($e->getTraceAsString()); + Log::error($e->getMessage()); + Log::error($e->getTraceAsString()); } } public function sendMFAFailedAttemptsMail(MFAManyFailedAttempts $event): void { - app('log')->debug(sprintf('Now in %s', __METHOD__)); + Log::debug(sprintf('Now in %s', __METHOD__)); $user = $event->user; $count = $event->count; @@ -156,23 +157,23 @@ class MFAHandler } catch (Exception $e) { $message = $e->getMessage(); if (str_contains($message, 'Bcc')) { - app('log')->warning('[Bcc] Could not send notification. Please validate your email settings, use the .env.example file as a guide.'); + 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')) { - app('log')->warning('[RFC] Could not send notification. Please validate your email settings, use the .env.example file as a guide.'); + Log::warning('[RFC] Could not send notification. Please validate your email settings, use the .env.example file as a guide.'); return; } - app('log')->error($e->getMessage()); - app('log')->error($e->getTraceAsString()); + Log::error($e->getMessage()); + Log::error($e->getTraceAsString()); } } public function sendNewMFABackupCodesMail(MFANewBackupCodes $event): void { - app('log')->debug(sprintf('Now in %s', __METHOD__)); + Log::debug(sprintf('Now in %s', __METHOD__)); $user = $event->user; @@ -181,23 +182,23 @@ class MFAHandler } catch (Exception $e) { $message = $e->getMessage(); if (str_contains($message, 'Bcc')) { - app('log')->warning('[Bcc] Could not send notification. Please validate your email settings, use the .env.example file as a guide.'); + 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')) { - app('log')->warning('[RFC] Could not send notification. Please validate your email settings, use the .env.example file as a guide.'); + Log::warning('[RFC] Could not send notification. Please validate your email settings, use the .env.example file as a guide.'); return; } - app('log')->error($e->getMessage()); - app('log')->error($e->getTraceAsString()); + Log::error($e->getMessage()); + Log::error($e->getTraceAsString()); } } public function sendUsedBackupCodeMail(MFAUsedBackupCode $event): void { - app('log')->debug(sprintf('Now in %s', __METHOD__)); + Log::debug(sprintf('Now in %s', __METHOD__)); $user = $event->user; @@ -206,17 +207,17 @@ class MFAHandler } catch (Exception $e) { $message = $e->getMessage(); if (str_contains($message, 'Bcc')) { - app('log')->warning('[Bcc] Could not send notification. Please validate your email settings, use the .env.example file as a guide.'); + 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')) { - app('log')->warning('[RFC] Could not send notification. Please validate your email settings, use the .env.example file as a guide.'); + Log::warning('[RFC] Could not send notification. Please validate your email settings, use the .env.example file as a guide.'); return; } - app('log')->error($e->getMessage()); - app('log')->error($e->getTraceAsString()); + Log::error($e->getMessage()); + Log::error($e->getTraceAsString()); } } } From ae767fc90dccba37c51684157bb179462b5ce2ab Mon Sep 17 00:00:00 2001 From: James Cole Date: Sun, 2 Nov 2025 14:45:39 +0100 Subject: [PATCH 08/29] Replace references to log service. --- app/Handlers/Events/APIEventHandler.php | 11 +-- app/Handlers/Events/AdminEventHandler.php | 35 ++++---- app/Handlers/Events/AuditEventHandler.php | 9 ++- app/Handlers/Events/AutomationHandler.php | 19 ++--- .../Events/DestroyedGroupEventHandler.php | 2 +- app/Handlers/Events/UserEventHandler.php | 81 ++++++++++--------- 6 files changed, 81 insertions(+), 76 deletions(-) diff --git a/app/Handlers/Events/APIEventHandler.php b/app/Handlers/Events/APIEventHandler.php index de67afd8e8..f9b17ab3f2 100644 --- a/app/Handlers/Events/APIEventHandler.php +++ b/app/Handlers/Events/APIEventHandler.php @@ -29,6 +29,7 @@ use FireflyIII\Notifications\User\NewAccessToken; use FireflyIII\Repositories\User\UserRepositoryInterface; use Illuminate\Support\Facades\Notification; use Laravel\Passport\Events\AccessTokenCreated; +use Illuminate\Support\Facades\Log; /** * Class APIEventHandler @@ -40,7 +41,7 @@ class APIEventHandler */ public function accessTokenCreated(AccessTokenCreated $event): void { - app('log')->debug(__METHOD__); + Log::debug(__METHOD__); /** @var UserRepositoryInterface $repository */ $repository = app(UserRepositoryInterface::class); @@ -52,17 +53,17 @@ class APIEventHandler } catch (Exception $e) { $message = $e->getMessage(); if (str_contains($message, 'Bcc')) { - app('log')->warning('[Bcc] Could not send notification. Please validate your email settings, use the .env.example file as a guide.'); + 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')) { - app('log')->warning('[RFC] Could not send notification. Please validate your email settings, use the .env.example file as a guide.'); + Log::warning('[RFC] Could not send notification. Please validate your email settings, use the .env.example file as a guide.'); return; } - app('log')->error($e->getMessage()); - app('log')->error($e->getTraceAsString()); + Log::error($e->getMessage()); + Log::error($e->getTraceAsString()); } } } diff --git a/app/Handlers/Events/AdminEventHandler.php b/app/Handlers/Events/AdminEventHandler.php index d3a9a1e73e..5dbcb37226 100644 --- a/app/Handlers/Events/AdminEventHandler.php +++ b/app/Handlers/Events/AdminEventHandler.php @@ -38,6 +38,7 @@ use FireflyIII\Notifications\Test\OwnerTestNotificationSlack; use Illuminate\Support\Facades\Log; use Illuminate\Support\Facades\Notification; + /** * Class AdminEventHandler. */ @@ -55,17 +56,17 @@ class AdminEventHandler } catch (Exception $e) { $message = $e->getMessage(); if (str_contains($message, 'Bcc')) { - app('log')->warning('[Bcc] Could not send notification. Please validate your email settings, use the .env.example file as a guide.'); + 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')) { - app('log')->warning('[RFC] Could not send notification. Please validate your email settings, use the .env.example file as a guide.'); + Log::warning('[RFC] Could not send notification. Please validate your email settings, use the .env.example file as a guide.'); return; } - app('log')->error($e->getMessage()); - app('log')->error($e->getTraceAsString()); + Log::error($e->getMessage()); + Log::error($e->getTraceAsString()); } } @@ -77,17 +78,17 @@ class AdminEventHandler } catch (Exception $e) { $message = $e->getMessage(); if (str_contains($message, 'Bcc')) { - app('log')->warning('[Bcc] Could not send notification. Please validate your email settings, use the .env.example file as a guide.'); + 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')) { - app('log')->warning('[RFC] Could not send notification. Please validate your email settings, use the .env.example file as a guide.'); + Log::warning('[RFC] Could not send notification. Please validate your email settings, use the .env.example file as a guide.'); return; } - app('log')->error($e->getMessage()); - app('log')->error($e->getTraceAsString()); + Log::error($e->getMessage()); + Log::error($e->getTraceAsString()); } } @@ -107,17 +108,17 @@ class AdminEventHandler } catch (Exception $e) { $message = $e->getMessage(); if (str_contains($message, 'Bcc')) { - app('log')->warning('[Bcc] Could not send notification. Please validate your email settings, use the .env.example file as a guide.'); + 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')) { - app('log')->warning('[RFC] Could not send notification. Please validate your email settings, use the .env.example file as a guide.'); + Log::warning('[RFC] Could not send notification. Please validate your email settings, use the .env.example file as a guide.'); return; } - app('log')->error($e->getMessage()); - app('log')->error($e->getTraceAsString()); + Log::error($e->getMessage()); + Log::error($e->getTraceAsString()); } } @@ -150,7 +151,7 @@ class AdminEventHandler break; default: - app('log')->error(sprintf('Unknown channel "%s" in sendTestNotification method.', $event->channel)); + Log::error(sprintf('Unknown channel "%s" in sendTestNotification method.', $event->channel)); return; } @@ -161,17 +162,17 @@ class AdminEventHandler } catch (Exception $e) { $message = $e->getMessage(); if (str_contains($message, 'Bcc')) { - app('log')->warning('[Bcc] Could not send notification. Please validate your email settings, use the .env.example file as a guide.'); + 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')) { - app('log')->warning('[RFC] Could not send notification. Please validate your email settings, use the .env.example file as a guide.'); + Log::warning('[RFC] Could not send notification. Please validate your email settings, use the .env.example file as a guide.'); return; } - app('log')->error($e->getMessage()); - app('log')->error($e->getTraceAsString()); + Log::error($e->getMessage()); + Log::error($e->getTraceAsString()); } Log::debug(sprintf('If you see no errors above this line, test notification was sent over channel "%s"', $event->channel)); } diff --git a/app/Handlers/Events/AuditEventHandler.php b/app/Handlers/Events/AuditEventHandler.php index d881b19ed4..21e8ac56ed 100644 --- a/app/Handlers/Events/AuditEventHandler.php +++ b/app/Handlers/Events/AuditEventHandler.php @@ -27,6 +27,7 @@ namespace FireflyIII\Handlers\Events; use Carbon\Carbon; use FireflyIII\Events\TriggeredAuditLog; use FireflyIII\Repositories\AuditLogEntry\ALERepositoryInterface; +use Illuminate\Support\Facades\Log; /** * Class AuditEventHandler @@ -44,20 +45,20 @@ class AuditEventHandler ]; if ($event->before === $event->after) { - app('log')->debug('Will not store event log because before and after are the same.'); + Log::debug('Will not store event log because before and after are the same.'); return; } if ($event->before instanceof Carbon && $event->after instanceof Carbon && $event->before->eq($event->after)) { - app('log')->debug('Will not store event log because before and after Carbon values are the same.'); + Log::debug('Will not store event log because before and after Carbon values are the same.'); return; } if ($event->before instanceof Carbon && $event->after instanceof Carbon) { $array['before'] = $event->before->toIso8601String(); $array['after'] = $event->after->toIso8601String(); - app('log')->debug(sprintf('Converted "before" to "%s".', $event->before)); - app('log')->debug(sprintf('Converted "after" to "%s".', $event->after)); + Log::debug(sprintf('Converted "before" to "%s".', $event->before)); + Log::debug(sprintf('Converted "after" to "%s".', $event->after)); } /** @var ALERepositoryInterface $repository */ diff --git a/app/Handlers/Events/AutomationHandler.php b/app/Handlers/Events/AutomationHandler.php index 9d60e4dc5b..8d2b97c38c 100644 --- a/app/Handlers/Events/AutomationHandler.php +++ b/app/Handlers/Events/AutomationHandler.php @@ -33,6 +33,7 @@ use FireflyIII\Repositories\User\UserRepositoryInterface; use FireflyIII\Support\Facades\Preferences; use FireflyIII\Transformers\TransactionGroupTransformer; use Illuminate\Support\Facades\Notification; +use Illuminate\Support\Facades\Log; /** * Class AutomationHandler @@ -46,7 +47,7 @@ class AutomationHandler */ public function reportJournals(RequestedReportOnJournals $event): void { - app('log')->debug('In reportJournals.'); + Log::debug('In reportJournals.'); /** @var UserRepositoryInterface $repository */ $repository = app(UserRepositoryInterface::class); @@ -56,17 +57,17 @@ class AutomationHandler $sendReport = Preferences::getForUser($user, 'notification_transaction_creation', false)->data; if (false === $sendReport) { - app('log')->debug('Not sending report, because config says so.'); + Log::debug('Not sending report, because config says so.'); return; } if (null === $user || 0 === $event->groups->count()) { - app('log')->debug('No transaction groups in event, nothing to email about.'); + Log::debug('No transaction groups in event, nothing to email about.'); return; } - app('log')->debug('Continue with message!'); + Log::debug('Continue with message!'); // transform groups into array: /** @var TransactionGroupTransformer $transformer */ @@ -83,18 +84,18 @@ class AutomationHandler } catch (Exception $e) { $message = $e->getMessage(); if (str_contains($message, 'Bcc')) { - app('log')->warning('[Bcc] Could not send notification. Please validate your email settings, use the .env.example file as a guide.'); + 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')) { - app('log')->warning('[RFC] Could not send notification. Please validate your email settings, use the .env.example file as a guide.'); + Log::warning('[RFC] Could not send notification. Please validate your email settings, use the .env.example file as a guide.'); return; } - app('log')->error($e->getMessage()); - app('log')->error($e->getTraceAsString()); + Log::error($e->getMessage()); + Log::error($e->getTraceAsString()); } - app('log')->debug('If there is no error above this line, message was sent.'); + Log::debug('If there is no error above this line, message was sent.'); } } diff --git a/app/Handlers/Events/DestroyedGroupEventHandler.php b/app/Handlers/Events/DestroyedGroupEventHandler.php index 638cbc8e76..1498dd326f 100644 --- a/app/Handlers/Events/DestroyedGroupEventHandler.php +++ b/app/Handlers/Events/DestroyedGroupEventHandler.php @@ -45,7 +45,7 @@ class DestroyedGroupEventHandler private function triggerWebhooks(DestroyedTransactionGroup $destroyedGroupEvent): void { - app('log')->debug('DestroyedTransactionGroup:triggerWebhooks'); + Log::debug('DestroyedTransactionGroup:triggerWebhooks'); $group = $destroyedGroupEvent->transactionGroup; $user = $group->user; diff --git a/app/Handlers/Events/UserEventHandler.php b/app/Handlers/Events/UserEventHandler.php index 9e9f0d25cf..3c1b164ed5 100644 --- a/app/Handlers/Events/UserEventHandler.php +++ b/app/Handlers/Events/UserEventHandler.php @@ -58,6 +58,7 @@ use Illuminate\Support\Facades\Log; use Illuminate\Support\Facades\Mail; use Illuminate\Support\Facades\Notification; + /** * Class UserEventHandler. * @@ -77,7 +78,7 @@ class UserEventHandler // first user ever? if (1 === $repository->count()) { - app('log')->debug('User count is one, attach role.'); + Log::debug('User count is one, attach role.'); $repository->attachRole($event->user, 'owner'); } } @@ -101,10 +102,10 @@ 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'); - app('log')->error('Could not find role "owner". This is weird.'); + Log::error('Could not find role "owner". This is weird.'); } - app('log')->info(sprintf('Gave user #%d role #%d ("%s")', $user->id, $role->id, $role->name)); + Log::info(sprintf('Gave user #%d role #%d ("%s")', $user->id, $role->id, $role->name)); // give user the role $repository->attachRole($user, 'owner'); } @@ -203,17 +204,17 @@ class UserEventHandler } catch (Exception $e) { $message = $e->getMessage(); if (str_contains($message, 'Bcc')) { - app('log')->warning('[Bcc] Could not send notification. Please validate your email settings, use the .env.example file as a guide.'); + 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')) { - app('log')->warning('[RFC] Could not send notification. Please validate your email settings, use the .env.example file as a guide.'); + Log::warning('[RFC] Could not send notification. Please validate your email settings, use the .env.example file as a guide.'); return; } - app('log')->error($e->getMessage()); - app('log')->error($e->getTraceAsString()); + Log::error($e->getMessage()); + Log::error($e->getTraceAsString()); } } $list[$index]['notified'] = true; @@ -233,17 +234,17 @@ class UserEventHandler } catch (Exception $e) { $message = $e->getMessage(); if (str_contains($message, 'Bcc')) { - app('log')->warning('[Bcc] Could not send notification. Please validate your email settings, use the .env.example file as a guide.'); + 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')) { - app('log')->warning('[RFC] Could not send notification. Please validate your email settings, use the .env.example file as a guide.'); + Log::warning('[RFC] Could not send notification. Please validate your email settings, use the .env.example file as a guide.'); return; } - app('log')->error($e->getMessage()); - app('log')->error($e->getTraceAsString()); + Log::error($e->getMessage()); + Log::error($e->getTraceAsString()); } } } @@ -265,8 +266,8 @@ class UserEventHandler try { Mail::to($newEmail)->send(new ConfirmEmailChangeMail($newEmail, $oldEmail, $url)); } catch (Exception $e) { - app('log')->error($e->getMessage()); - app('log')->error($e->getTraceAsString()); + Log::error($e->getMessage()); + Log::error($e->getTraceAsString()); throw new FireflyException($e->getMessage(), 0, $e); } @@ -290,8 +291,8 @@ class UserEventHandler try { Mail::to($oldEmail)->send(new UndoEmailChangeMail($newEmail, $oldEmail, $url)); } catch (Exception $e) { - app('log')->error($e->getMessage()); - app('log')->error($e->getTraceAsString()); + Log::error($e->getMessage()); + Log::error($e->getTraceAsString()); throw new FireflyException($e->getMessage(), 0, $e); } @@ -304,17 +305,17 @@ class UserEventHandler } catch (Exception $e) { $message = $e->getMessage(); if (str_contains($message, 'Bcc')) { - app('log')->warning('[Bcc] Could not send notification. Please validate your email settings, use the .env.example file as a guide.'); + 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')) { - app('log')->warning('[RFC] Could not send notification. Please validate your email settings, use the .env.example file as a guide.'); + Log::warning('[RFC] Could not send notification. Please validate your email settings, use the .env.example file as a guide.'); return; } - app('log')->error($e->getMessage()); - app('log')->error($e->getTraceAsString()); + Log::error($e->getMessage()); + Log::error($e->getTraceAsString()); } } @@ -328,17 +329,17 @@ class UserEventHandler } catch (Exception $e) { $message = $e->getMessage(); if (str_contains($message, 'Bcc')) { - app('log')->warning('[Bcc] Could not send notification. Please validate your email settings, use the .env.example file as a guide.'); + 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')) { - app('log')->warning('[RFC] Could not send notification. Please validate your email settings, use the .env.example file as a guide.'); + Log::warning('[RFC] Could not send notification. Please validate your email settings, use the .env.example file as a guide.'); return; } - app('log')->error($e->getMessage()); - app('log')->error($e->getTraceAsString()); + Log::error($e->getMessage()); + Log::error($e->getTraceAsString()); } } @@ -354,8 +355,8 @@ class UserEventHandler try { Mail::to($invitee)->send(new InvitationMail($invitee, $admin, $url)); } catch (Exception $e) { - app('log')->error($e->getMessage()); - app('log')->error($e->getTraceAsString()); + Log::error($e->getMessage()); + Log::error($e->getTraceAsString()); throw new FireflyException($e->getMessage(), 0, $e); } @@ -374,17 +375,17 @@ class UserEventHandler } catch (Exception $e) { $message = $e->getMessage(); if (str_contains($message, 'Bcc')) { - app('log')->warning('[Bcc] Could not send notification. Please validate your email settings, use the .env.example file as a guide.'); + 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')) { - app('log')->warning('[RFC] Could not send notification. Please validate your email settings, use the .env.example file as a guide.'); + Log::warning('[RFC] Could not send notification. Please validate your email settings, use the .env.example file as a guide.'); return; } - app('log')->error($e->getMessage()); - app('log')->error($e->getTraceAsString()); + Log::error($e->getMessage()); + Log::error($e->getTraceAsString()); } } } @@ -418,7 +419,7 @@ class UserEventHandler break; default: - app('log')->error(sprintf('Unknown channel "%s" in (user) sendTestNotification method.', $event->channel)); + Log::error(sprintf('Unknown channel "%s" in (user) sendTestNotification method.', $event->channel)); return; } @@ -429,28 +430,28 @@ class UserEventHandler } catch (Exception $e) { $message = $e->getMessage(); if (str_contains($message, 'Bcc')) { - app('log')->warning('[Bcc] Could not send notification. Please validate your email settings, use the .env.example file as a guide.'); + 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')) { - app('log')->warning('[RFC] Could not send notification. Please validate your email settings, use the .env.example file as a guide.'); + Log::warning('[RFC] Could not send notification. Please validate your email settings, use the .env.example file as a guide.'); return; } - app('log')->error($e->getMessage()); - app('log')->error($e->getTraceAsString()); + Log::error($e->getMessage()); + Log::error($e->getTraceAsString()); } Log::debug(sprintf('If you see no errors above this line, test notification was sent over channel "%s"', $event->channel)); } public function storeUserIPAddress(ActuallyLoggedIn $event): void { - app('log')->debug('Now in storeUserIPAddress'); + Log::debug('Now in storeUserIPAddress'); $user = $event->user; if ($user->hasRole('demo')) { - app('log')->debug('Do not log demo user logins'); + Log::debug('Do not log demo user logins'); return; } @@ -460,25 +461,25 @@ class UserEventHandler $preference = Preferences::getForUser($user, 'login_ip_history', [])->data; } catch (FireflyException $e) { // don't care. - app('log')->error($e->getMessage()); + Log::error($e->getMessage()); return; } $inArray = false; $ip = request()->ip(); - app('log')->debug(sprintf('User logging in from IP address %s', $ip)); + 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) { - app('log')->debug('Found IP in array, refresh time.'); + 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 instanceof Carbon && $carbon->diffInMonths(today(), true) > 6) { - app('log')->debug(sprintf('Entry for %s is very old, remove it.', $row['ip'])); + Log::debug(sprintf('Entry for %s is very old, remove it.', $row['ip'])); unset($preference[$index]); } } From 7743d16ea1ce2272457720efbc199aac22d201cc Mon Sep 17 00:00:00 2001 From: James Cole Date: Sun, 2 Nov 2025 14:48:36 +0100 Subject: [PATCH 09/29] Replace references to log service. --- app/Handlers/Observer/AccountObserver.php | 3 ++- app/Handlers/Observer/AttachmentObserver.php | 3 ++- app/Handlers/Observer/BillObserver.php | 3 ++- app/Handlers/Observer/CategoryObserver.php | 3 ++- app/Handlers/Observer/PiggyBankObserver.php | 3 ++- app/Handlers/Observer/RecurrenceObserver.php | 3 ++- .../RecurrenceTransactionObserver.php | 3 ++- app/Handlers/Observer/RuleGroupObserver.php | 3 ++- app/Handlers/Observer/RuleObserver.php | 3 ++- app/Handlers/Observer/TagObserver.php | 3 ++- app/Handlers/Observer/TransactionObserver.php | 2 +- .../Observer/WebhookMessageObserver.php | 4 ++-- app/Handlers/Observer/WebhookObserver.php | 4 ++-- .../Extensions/AccountCollection.php | 18 +++++++------- .../Extensions/AttachmentCollection.php | 6 ++--- app/Helpers/Collector/GroupCollector.php | 24 +++++++++---------- app/Helpers/Fiscal/FiscalHelper.php | 7 +++--- app/Helpers/Update/UpdateTrait.php | 3 ++- .../Webhook/Sha3SignatureGenerator.php | 9 +++---- 19 files changed, 60 insertions(+), 47 deletions(-) diff --git a/app/Handlers/Observer/AccountObserver.php b/app/Handlers/Observer/AccountObserver.php index b29983ada5..a780c8a97d 100644 --- a/app/Handlers/Observer/AccountObserver.php +++ b/app/Handlers/Observer/AccountObserver.php @@ -36,6 +36,7 @@ use FireflyIII\Support\Http\Api\ExchangeRateConverter; use Illuminate\Support\Facades\DB; use Illuminate\Support\Facades\Log; + /** * Class AccountObserver */ @@ -75,7 +76,7 @@ class AccountObserver */ public function deleting(Account $account): void { - app('log')->debug('Observe "deleting" of an account.'); + Log::debug('Observe "deleting" of an account.'); $repository = app(AttachmentRepositoryInterface::class); $repository->setUser($account->user); diff --git a/app/Handlers/Observer/AttachmentObserver.php b/app/Handlers/Observer/AttachmentObserver.php index 0ec7040701..e88b3d9fca 100644 --- a/app/Handlers/Observer/AttachmentObserver.php +++ b/app/Handlers/Observer/AttachmentObserver.php @@ -24,6 +24,7 @@ declare(strict_types=1); namespace FireflyIII\Handlers\Observer; use FireflyIII\Models\Attachment; +use Illuminate\Support\Facades\Log; /** * Class AttachmentObserver @@ -32,7 +33,7 @@ class AttachmentObserver { public function deleting(Attachment $attachment): void { - app('log')->debug('Observe "deleting" of an attachment.'); + Log::debug('Observe "deleting" of an attachment.'); $attachment->notes()->delete(); } } diff --git a/app/Handlers/Observer/BillObserver.php b/app/Handlers/Observer/BillObserver.php index 9d7d5f9672..21e3ba63a0 100644 --- a/app/Handlers/Observer/BillObserver.php +++ b/app/Handlers/Observer/BillObserver.php @@ -30,6 +30,7 @@ use FireflyIII\Support\Facades\Amount; use FireflyIII\Support\Http\Api\ExchangeRateConverter; use Illuminate\Support\Facades\Log; + /** * Class BillObserver */ @@ -65,7 +66,7 @@ class BillObserver $repository = app(AttachmentRepositoryInterface::class); $repository->setUser($bill->user); - // app('log')->debug('Observe "deleting" of a bill.'); + // Log::debug('Observe "deleting" of a bill.'); /** @var Attachment $attachment */ foreach ($bill->attachments()->get() as $attachment) { $repository->destroy($attachment); diff --git a/app/Handlers/Observer/CategoryObserver.php b/app/Handlers/Observer/CategoryObserver.php index 24f7edf792..4a9664a39a 100644 --- a/app/Handlers/Observer/CategoryObserver.php +++ b/app/Handlers/Observer/CategoryObserver.php @@ -26,6 +26,7 @@ namespace FireflyIII\Handlers\Observer; use FireflyIII\Models\Attachment; use FireflyIII\Models\Category; use FireflyIII\Repositories\Attachment\AttachmentRepositoryInterface; +use Illuminate\Support\Facades\Log; /** * Class CategoryObserver @@ -34,7 +35,7 @@ class CategoryObserver { public function deleting(Category $category): void { - app('log')->debug('Observe "deleting" of a category.'); + Log::debug('Observe "deleting" of a category.'); $repository = app(AttachmentRepositoryInterface::class); $repository->setUser($category->user); diff --git a/app/Handlers/Observer/PiggyBankObserver.php b/app/Handlers/Observer/PiggyBankObserver.php index 8c8364f01f..fa862abd49 100644 --- a/app/Handlers/Observer/PiggyBankObserver.php +++ b/app/Handlers/Observer/PiggyBankObserver.php @@ -30,6 +30,7 @@ use FireflyIII\Repositories\Attachment\AttachmentRepositoryInterface; use FireflyIII\Support\Http\Api\ExchangeRateConverter; use Illuminate\Support\Facades\Log; + /** * Class PiggyBankObserver */ @@ -66,7 +67,7 @@ class PiggyBankObserver */ public function deleting(PiggyBank $piggyBank): void { - app('log')->debug('Observe "deleting" of a piggy bank.'); + Log::debug('Observe "deleting" of a piggy bank.'); $repository = app(AttachmentRepositoryInterface::class); $repository->setUser($piggyBank->accounts()->first()->user); diff --git a/app/Handlers/Observer/RecurrenceObserver.php b/app/Handlers/Observer/RecurrenceObserver.php index ff2e4218f8..a2dc023e49 100644 --- a/app/Handlers/Observer/RecurrenceObserver.php +++ b/app/Handlers/Observer/RecurrenceObserver.php @@ -26,6 +26,7 @@ namespace FireflyIII\Handlers\Observer; use FireflyIII\Models\Attachment; use FireflyIII\Models\Recurrence; use FireflyIII\Repositories\Attachment\AttachmentRepositoryInterface; +use Illuminate\Support\Facades\Log; /** * Class RecurrenceObserver @@ -34,7 +35,7 @@ class RecurrenceObserver { public function deleting(Recurrence $recurrence): void { - app('log')->debug('Observe "deleting" of a recurrence.'); + Log::debug('Observe "deleting" of a recurrence.'); $repository = app(AttachmentRepositoryInterface::class); $repository->setUser($recurrence->user); diff --git a/app/Handlers/Observer/RecurrenceTransactionObserver.php b/app/Handlers/Observer/RecurrenceTransactionObserver.php index f88cb38b5d..956faec6f6 100644 --- a/app/Handlers/Observer/RecurrenceTransactionObserver.php +++ b/app/Handlers/Observer/RecurrenceTransactionObserver.php @@ -24,6 +24,7 @@ declare(strict_types=1); namespace FireflyIII\Handlers\Observer; use FireflyIII\Models\RecurrenceTransaction; +use Illuminate\Support\Facades\Log; /** * Class RecurrenceTransactionObserver @@ -32,7 +33,7 @@ class RecurrenceTransactionObserver { public function deleting(RecurrenceTransaction $transaction): void { - app('log')->debug('Observe "deleting" of a recurrence transaction.'); + 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 c7e1c223bf..88118998c4 100644 --- a/app/Handlers/Observer/RuleGroupObserver.php +++ b/app/Handlers/Observer/RuleGroupObserver.php @@ -24,6 +24,7 @@ declare(strict_types=1); namespace FireflyIII\Handlers\Observer; use FireflyIII\Models\RuleGroup; +use Illuminate\Support\Facades\Log; /** * Class RuleGroupObserver @@ -32,7 +33,7 @@ class RuleGroupObserver { public function deleting(RuleGroup $ruleGroup): void { - app('log')->debug('Observe "deleting" of a rule group.'); + 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 3121a6b62e..9e1795ebb6 100644 --- a/app/Handlers/Observer/RuleObserver.php +++ b/app/Handlers/Observer/RuleObserver.php @@ -24,6 +24,7 @@ declare(strict_types=1); namespace FireflyIII\Handlers\Observer; use FireflyIII\Models\Rule; +use Illuminate\Support\Facades\Log; /** * Class RuleObserver @@ -32,7 +33,7 @@ class RuleObserver { public function deleting(Rule $rule): void { - app('log')->debug('Observe "deleting" of a rule.'); + 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 71090e6ef3..85f56ed7f7 100644 --- a/app/Handlers/Observer/TagObserver.php +++ b/app/Handlers/Observer/TagObserver.php @@ -26,6 +26,7 @@ namespace FireflyIII\Handlers\Observer; use FireflyIII\Models\Attachment; use FireflyIII\Models\Tag; use FireflyIII\Repositories\Attachment\AttachmentRepositoryInterface; +use Illuminate\Support\Facades\Log; /** * Class TagObserver @@ -34,7 +35,7 @@ class TagObserver { public function deleting(Tag $tag): void { - app('log')->debug('Observe "deleting" of a tag.'); + Log::debug('Observe "deleting" of a tag.'); $repository = app(AttachmentRepositoryInterface::class); $repository->setUser($tag->user); diff --git a/app/Handlers/Observer/TransactionObserver.php b/app/Handlers/Observer/TransactionObserver.php index 6c720f6f3f..e040fae67a 100644 --- a/app/Handlers/Observer/TransactionObserver.php +++ b/app/Handlers/Observer/TransactionObserver.php @@ -77,7 +77,7 @@ class TransactionObserver public function deleting(?Transaction $transaction): void { - app('log')->debug('Observe "deleting" of a transaction.'); + 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 6248dc4d3c..8c059f356a 100644 --- a/app/Handlers/Observer/WebhookMessageObserver.php +++ b/app/Handlers/Observer/WebhookMessageObserver.php @@ -24,7 +24,7 @@ declare(strict_types=1); namespace FireflyIII\Handlers\Observer; use FireflyIII\Models\WebhookMessage; - +use Illuminate\Support\Facades\Log; /** * Class WebhookMessageObserver */ @@ -32,7 +32,7 @@ class WebhookMessageObserver { public function deleting(WebhookMessage $webhookMessage): void { - app('log')->debug('Observe "deleting" of a webhook message.'); + Log::debug('Observe "deleting" of a webhook message.'); $webhookMessage->webhookAttempts()->delete(); } } diff --git a/app/Handlers/Observer/WebhookObserver.php b/app/Handlers/Observer/WebhookObserver.php index 6a0799db99..d817e92bc3 100644 --- a/app/Handlers/Observer/WebhookObserver.php +++ b/app/Handlers/Observer/WebhookObserver.php @@ -24,7 +24,7 @@ declare(strict_types=1); namespace FireflyIII\Handlers\Observer; use FireflyIII\Models\Webhook; - +use Illuminate\Support\Facades\Log; /** * Class WebhookObserver */ @@ -32,7 +32,7 @@ class WebhookObserver { public function deleting(Webhook $webhook): void { - app('log')->debug('Observe "deleting" of a webhook.'); + Log::debug('Observe "deleting" of a webhook.'); foreach ($webhook->webhookMessages()->get() as $message) { $message->delete(); } diff --git a/app/Helpers/Collector/Extensions/AccountCollection.php b/app/Helpers/Collector/Extensions/AccountCollection.php index 203cad80ab..ba51cd07f4 100644 --- a/app/Helpers/Collector/Extensions/AccountCollection.php +++ b/app/Helpers/Collector/Extensions/AccountCollection.php @@ -130,7 +130,7 @@ trait AccountCollection $this->query->whereNotIn('source.account_id', $accountIds); $this->query->whereNotIn('destination.account_id', $accountIds); - app('log')->debug(sprintf('GroupCollector: excludeAccounts: %s', implode(', ', $accountIds))); + Log::debug(sprintf('GroupCollector: excludeAccounts: %s', implode(', ', $accountIds))); } return $this; @@ -145,7 +145,7 @@ trait AccountCollection $accountIds = $accounts->pluck('id')->toArray(); $this->query->whereNotIn('destination.account_id', $accountIds); - app('log')->debug(sprintf('GroupCollector: excludeDestinationAccounts: %s', implode(', ', $accountIds))); + Log::debug(sprintf('GroupCollector: excludeDestinationAccounts: %s', implode(', ', $accountIds))); } return $this; @@ -160,7 +160,7 @@ trait AccountCollection $accountIds = $accounts->pluck('id')->toArray(); $this->query->whereNotIn('source.account_id', $accountIds); - app('log')->debug(sprintf('GroupCollector: excludeSourceAccounts: %s', implode(', ', $accountIds))); + Log::debug(sprintf('GroupCollector: excludeSourceAccounts: %s', implode(', ', $accountIds))); } return $this; @@ -179,7 +179,7 @@ trait AccountCollection $query->orWhereIn('destination.account_id', $accountIds); } ); - // app('log')->debug(sprintf('GroupCollector: setAccounts: %s', implode(', ', $accountIds))); + // Log::debug(sprintf('GroupCollector: setAccounts: %s', implode(', ', $accountIds))); } return $this; @@ -198,7 +198,7 @@ trait AccountCollection $query->whereIn('destination.account_id', $accountIds); } ); - app('log')->debug(sprintf('GroupCollector: setBothAccounts: %s', implode(', ', $accountIds))); + Log::debug(sprintf('GroupCollector: setBothAccounts: %s', implode(', ', $accountIds))); } return $this; @@ -213,7 +213,7 @@ trait AccountCollection $accountIds = $accounts->pluck('id')->toArray(); $this->query->whereIn('destination.account_id', $accountIds); - app('log')->debug(sprintf('GroupCollector: setDestinationAccounts: %s', implode(', ', $accountIds))); + Log::debug(sprintf('GroupCollector: setDestinationAccounts: %s', implode(', ', $accountIds))); } return $this; @@ -232,7 +232,7 @@ trait AccountCollection $query->whereNotIn('destination.account_id', $accountIds); } ); - // app('log')->debug(sprintf('GroupCollector: setAccounts: %s', implode(', ', $accountIds))); + // Log::debug(sprintf('GroupCollector: setAccounts: %s', implode(', ', $accountIds))); } return $this; @@ -247,7 +247,7 @@ trait AccountCollection $accountIds = $accounts->pluck('id')->toArray(); $this->query->whereIn('source.account_id', $accountIds); - app('log')->debug(sprintf('GroupCollector: setSourceAccounts: %s', implode(', ', $accountIds))); + Log::debug(sprintf('GroupCollector: setSourceAccounts: %s', implode(', ', $accountIds))); } return $this; @@ -280,7 +280,7 @@ trait AccountCollection } ); - app('log')->debug(sprintf('GroupCollector: setXorAccounts: %s', implode(', ', $accountIds))); + Log::debug(sprintf('GroupCollector: setXorAccounts: %s', implode(', ', $accountIds))); } return $this; diff --git a/app/Helpers/Collector/Extensions/AttachmentCollection.php b/app/Helpers/Collector/Extensions/AttachmentCollection.php index b2b3ed0103..3e19d10a28 100644 --- a/app/Helpers/Collector/Extensions/AttachmentCollection.php +++ b/app/Helpers/Collector/Extensions/AttachmentCollection.php @@ -29,7 +29,7 @@ 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 */ @@ -72,7 +72,7 @@ trait AttachmentCollection */ public function hasAttachments(): GroupCollectorInterface { - app('log')->debug('Add filter on attachment ID.'); + Log::debug('Add filter on attachment ID.'); $this->joinAttachmentTables(); $this->query->whereNotNull('attachments.attachable_id'); $this->query->whereNull('attachments.deleted_at'); @@ -510,7 +510,7 @@ trait AttachmentCollection */ public function hasNoAttachments(): GroupCollectorInterface { - app('log')->debug('Add filter on no attachments.'); + Log::debug('Add filter on no attachments.'); $this->joinAttachmentTables(); $this->query->where(static function (Builder $q1): void { // @phpstan-ignore-line diff --git a/app/Helpers/Collector/GroupCollector.php b/app/Helpers/Collector/GroupCollector.php index 7a44ba5737..5c265da4b5 100644 --- a/app/Helpers/Collector/GroupCollector.php +++ b/app/Helpers/Collector/GroupCollector.php @@ -320,8 +320,8 @@ class GroupCollector implements GroupCollectorInterface public function dumpQueryInLogs(): void { - app('log')->debug($this->query->select($this->fields)->toSql()); - app('log')->debug('Bindings', $this->query->getBindings()); + Log::debug($this->query->select($this->fields)->toSql()); + Log::debug('Bindings', $this->query->getBindings()); } /** @@ -590,7 +590,7 @@ class GroupCollector implements GroupCollectorInterface $result['created_at']->setTimezone(config('app.timezone')); $result['updated_at']->setTimezone(config('app.timezone')); } catch (Exception $e) { // intentional generic exception - app('log')->error($e->getMessage()); + Log::error($e->getMessage()); throw new FireflyException($e->getMessage(), 0, $e); } @@ -621,7 +621,7 @@ class GroupCollector implements GroupCollectorInterface try { $tagDate = Carbon::parse($augumentedJournal['tag_date']); } catch (InvalidFormatException $e) { - app('log')->debug(sprintf('Could not parse date: %s', $e->getMessage())); + Log::debug(sprintf('Could not parse date: %s', $e->getMessage())); } $result['tags'][$tagId] = [ @@ -697,7 +697,7 @@ class GroupCollector implements GroupCollectorInterface try { $tagDate = Carbon::parse($newArray['tag_date']); } catch (InvalidFormatException $e) { - app('log')->debug(sprintf('Could not parse date: %s', $e->getMessage())); + Log::debug(sprintf('Could not parse date: %s', $e->getMessage())); } $existingJournal['tags'][$tagId] = [ @@ -783,13 +783,13 @@ class GroupCollector implements GroupCollectorInterface if (0 === $countFilters) { return $currentCollection; } - app('log')->debug(sprintf('GroupCollector: postFilterCollection has %d filter(s) and %d transaction(s).', count($this->postFilters), count($currentCollection))); + Log::debug(sprintf('GroupCollector: postFilterCollection has %d filter(s) and %d transaction(s).', count($this->postFilters), count($currentCollection))); /** * @var Closure $function */ foreach ($this->postFilters as $function) { - app('log')->debug('Applying filter...'); + Log::debug('Applying filter...'); $nextCollection = new Collection(); // loop everything in the current collection @@ -814,7 +814,7 @@ class GroupCollector implements GroupCollectorInterface } } $currentCollection = $nextCollection; - app('log')->debug(sprintf('GroupCollector: postFilterCollection has %d transaction(s) left.', count($currentCollection))); + Log::debug(sprintf('GroupCollector: postFilterCollection has %d transaction(s) left.', count($currentCollection))); } return $currentCollection; @@ -875,7 +875,7 @@ class GroupCollector implements GroupCollectorInterface public function setLimit(int $limit): GroupCollectorInterface { $this->limit = $limit; - // app('log')->debug(sprintf('GroupCollector: The limit is now %d', $limit)); + // Log::debug(sprintf('GroupCollector: The limit is now %d', $limit)); return $this; } @@ -973,7 +973,7 @@ class GroupCollector implements GroupCollectorInterface { $page = 0 === $page ? 1 : $page; $this->page = $page; - // app('log')->debug(sprintf('GroupCollector: page is now %d', $page)); + // Log::debug(sprintf('GroupCollector: page is now %d', $page)); return $this; } @@ -1066,7 +1066,7 @@ class GroupCollector implements GroupCollectorInterface */ private function startQuery(): void { - // app('log')->debug('GroupCollector::startQuery'); + // Log::debug('GroupCollector::startQuery'); $this->query = $this->user // ->transactionGroups() // ->leftJoin('transaction_journals', 'transaction_journals.transaction_group_id', 'transaction_groups.id') @@ -1126,7 +1126,7 @@ class GroupCollector implements GroupCollectorInterface */ private function startQueryForGroup(): void { - // app('log')->debug('GroupCollector::startQuery'); + // Log::debug('GroupCollector::startQuery'); $this->query = $this->userGroup ->transactionJournals() ->leftJoin('transaction_groups', 'transaction_journals.transaction_group_id', 'transaction_groups.id') diff --git a/app/Helpers/Fiscal/FiscalHelper.php b/app/Helpers/Fiscal/FiscalHelper.php index c9450d597e..1503e4e437 100644 --- a/app/Helpers/Fiscal/FiscalHelper.php +++ b/app/Helpers/Fiscal/FiscalHelper.php @@ -27,6 +27,7 @@ use Carbon\Carbon; use FireflyIII\Support\Facades\Preferences; use Psr\Container\ContainerExceptionInterface; use Psr\Container\NotFoundExceptionInterface; +use Illuminate\Support\Facades\Log; /** * Class FiscalHelper. @@ -49,7 +50,7 @@ class FiscalHelper implements FiscalHelperInterface */ public function endOfFiscalYear(Carbon $date): Carbon { - // app('log')->debug(sprintf('Now in endOfFiscalYear(%s).', $date->format('Y-m-d'))); + // 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 @@ -59,7 +60,7 @@ class FiscalHelper implements FiscalHelperInterface if (false === $this->useCustomFiscalYear) { $endDate->endOfYear(); } - // app('log')->debug(sprintf('Result of endOfFiscalYear(%s) = %s', $date->format('Y-m-d'), $endDate->format('Y-m-d'))); + // Log::debug(sprintf('Result of endOfFiscalYear(%s) = %s', $date->format('Y-m-d'), $endDate->format('Y-m-d'))); return $endDate; } @@ -92,7 +93,7 @@ class FiscalHelper implements FiscalHelperInterface $startDate->startOfYear(); } - // app('log')->debug(sprintf('Result of startOfFiscalYear(%s) = %s', $date->format('Y-m-d'), $startDate->format('Y-m-d'))); + // 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/Update/UpdateTrait.php b/app/Helpers/Update/UpdateTrait.php index 8a779cdfc2..20b65fb024 100644 --- a/app/Helpers/Update/UpdateTrait.php +++ b/app/Helpers/Update/UpdateTrait.php @@ -25,6 +25,7 @@ declare(strict_types=1); namespace FireflyIII\Helpers\Update; use FireflyIII\Services\FireflyIIIOrg\Update\UpdateRequestInterface; +use Illuminate\Support\Facades\Log; /** * Trait UpdateTrait @@ -38,7 +39,7 @@ trait UpdateTrait */ public function getLatestRelease(): array { - app('log')->debug('Now in getLatestRelease()'); + Log::debug('Now in getLatestRelease()'); /** @var UpdateRequestInterface $checker */ $checker = app(UpdateRequestInterface::class); diff --git a/app/Helpers/Webhook/Sha3SignatureGenerator.php b/app/Helpers/Webhook/Sha3SignatureGenerator.php index 06967cff04..2a95435461 100644 --- a/app/Helpers/Webhook/Sha3SignatureGenerator.php +++ b/app/Helpers/Webhook/Sha3SignatureGenerator.php @@ -30,6 +30,7 @@ use FireflyIII\Models\WebhookMessage; use JsonException; use function Safe\json_encode; +use Illuminate\Support\Facades\Log; /** * Class Sha3SignatureGenerator @@ -52,10 +53,10 @@ class Sha3SignatureGenerator implements SignatureGeneratorInterface try { $json = json_encode($message->message, JSON_THROW_ON_ERROR); } 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()); + Log::error('Could not generate hash.'); + Log::error(sprintf('JSON value: %s', $json)); + Log::error($e->getMessage()); + Log::error($e->getTraceAsString()); throw new FireflyException('Could not generate JSON for SHA3 hash.', 0, $e); } From 2852a36712a0dee600f770f395b75f8855b83b00 Mon Sep 17 00:00:00 2001 From: JC5 Date: Mon, 3 Nov 2025 04:30:12 +0100 Subject: [PATCH 10/29] =?UTF-8?q?=F0=9F=A4=96=20Auto=20commit=20for=20rele?= =?UTF-8?q?ase=20'develop'=20on=202025-11-03?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../Models/Account/ListController.php | 5 ++--- .../Models/AvailableBudget/ShowController.php | 6 +++--- .../Controllers/Models/Bill/ListController.php | 5 ++--- .../Controllers/Models/Bill/ShowController.php | 1 - app/Api/V1/Requests/AggregateFormRequest.php | 1 - .../Autocomplete/AutocompleteApiRequest.php | 1 - .../Requests/Generic/ObjectTypeApiRequest.php | 9 ++++++++- .../Generic/PaginationDateRangeRequest.php | 2 ++ app/Factory/CategoryFactory.php | 1 + app/Factory/PiggyBankFactory.php | 1 + app/Handlers/Events/AdminEventHandler.php | 1 - app/Handlers/Events/UserEventHandler.php | 1 - app/Handlers/Observer/AccountObserver.php | 1 - app/Handlers/Observer/BillObserver.php | 1 - app/Handlers/Observer/PiggyBankObserver.php | 1 - .../Observer/WebhookMessageObserver.php | 1 + app/Handlers/Observer/WebhookObserver.php | 1 + .../Extensions/AttachmentCollection.php | 1 + app/Helpers/Webhook/Sha3SignatureGenerator.php | 2 +- app/Models/BudgetLimit.php | 2 +- app/Rules/IsAllowedGroupAction.php | 8 ++++---- .../IsValidTransactionTypeList.php | 2 +- app/Support/Http/Api/TransactionFilter.php | 2 +- .../Http/Api/ValidatesUserGroupTrait.php | 1 - config/firefly.php | 4 ++-- package-lock.json | 18 +++++++++--------- 26 files changed, 41 insertions(+), 38 deletions(-) diff --git a/app/Api/V1/Controllers/Models/Account/ListController.php b/app/Api/V1/Controllers/Models/Account/ListController.php index 3acdfbc6cf..5cf90ff2e6 100644 --- a/app/Api/V1/Controllers/Models/Account/ListController.php +++ b/app/Api/V1/Controllers/Models/Account/ListController.php @@ -38,7 +38,6 @@ use FireflyIII\Transformers\PiggyBankTransformer; use FireflyIII\Transformers\TransactionGroupTransformer; use FireflyIII\User; use Illuminate\Http\JsonResponse; -use Illuminate\Http\Request; use Illuminate\Pagination\LengthAwarePaginator; use Illuminate\Support\Collection; use League\Fractal\Pagination\IlluminatePaginatorAdapter; @@ -144,8 +143,8 @@ class ListController extends Controller 'page' => $page, 'start' => $start, 'end' => $end, - 'types' => $types, - ] = $request->attributes->all(); + 'types' => $types, + ] = $request->attributes->all(); $manager = $this->getManager(); /** @var User $admin */ diff --git a/app/Api/V1/Controllers/Models/AvailableBudget/ShowController.php b/app/Api/V1/Controllers/Models/AvailableBudget/ShowController.php index 624199c9fa..c621d3fbab 100644 --- a/app/Api/V1/Controllers/Models/AvailableBudget/ShowController.php +++ b/app/Api/V1/Controllers/Models/AvailableBudget/ShowController.php @@ -75,9 +75,9 @@ class ShowController extends Controller 'limit' => $limit, 'offset' => $offset, 'page' => $page, - 'start' => $start, - 'end' => $end, - ] = $request->attributes->all(); + 'start' => $start, + 'end' => $end, + ] = $request->attributes->all(); // get list of available budgets. Count it and split it. $collection = $this->abRepository->getAvailableBudgetsByDate($start, $end); diff --git a/app/Api/V1/Controllers/Models/Bill/ListController.php b/app/Api/V1/Controllers/Models/Bill/ListController.php index f3867841fc..7face940cf 100644 --- a/app/Api/V1/Controllers/Models/Bill/ListController.php +++ b/app/Api/V1/Controllers/Models/Bill/ListController.php @@ -37,7 +37,6 @@ use FireflyIII\Transformers\RuleTransformer; use FireflyIII\Transformers\TransactionGroupTransformer; 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; @@ -141,10 +140,10 @@ class ListController extends Controller [ 'limit' => $limit, 'page' => $page, - 'types' => $types, + 'types' => $types, 'start' => $start, 'end' => $end, - ] = $request->attributes->all(); + ] = $request->attributes->all(); $manager = $this->getManager(); diff --git a/app/Api/V1/Controllers/Models/Bill/ShowController.php b/app/Api/V1/Controllers/Models/Bill/ShowController.php index cdcb67cf9a..873c8c8d4e 100644 --- a/app/Api/V1/Controllers/Models/Bill/ShowController.php +++ b/app/Api/V1/Controllers/Models/Bill/ShowController.php @@ -27,7 +27,6 @@ namespace FireflyIII\Api\V1\Controllers\Models\Bill; use FireflyIII\Api\V1\Controllers\Controller; use FireflyIII\Api\V1\Requests\DateRangeRequest; use FireflyIII\Api\V1\Requests\Generic\PaginationDateRangeRequest; -use FireflyIII\Api\V1\Requests\PaginationRequest; use FireflyIII\Models\Bill; use FireflyIII\Repositories\Bill\BillRepositoryInterface; use FireflyIII\Support\JsonApi\Enrichments\SubscriptionEnrichment; diff --git a/app/Api/V1/Requests/AggregateFormRequest.php b/app/Api/V1/Requests/AggregateFormRequest.php index eda707b798..59d0bf456d 100644 --- a/app/Api/V1/Requests/AggregateFormRequest.php +++ b/app/Api/V1/Requests/AggregateFormRequest.php @@ -23,7 +23,6 @@ declare(strict_types=1); namespace FireflyIII\Api\V1\Requests; -use FireflyIII\Exceptions\FireflyException; use Illuminate\Foundation\Http\FormRequest; use Illuminate\Http\Request; use Illuminate\Support\Facades\Log; diff --git a/app/Api/V1/Requests/Autocomplete/AutocompleteApiRequest.php b/app/Api/V1/Requests/Autocomplete/AutocompleteApiRequest.php index 7c0c3f40ac..448d4eb895 100644 --- a/app/Api/V1/Requests/Autocomplete/AutocompleteApiRequest.php +++ b/app/Api/V1/Requests/Autocomplete/AutocompleteApiRequest.php @@ -27,7 +27,6 @@ use FireflyIII\Api\V1\Requests\AggregateFormRequest; use FireflyIII\Api\V1\Requests\DateRequest; use FireflyIII\Api\V1\Requests\Generic\ObjectTypeApiRequest; use FireflyIII\Api\V1\Requests\Generic\QueryRequest; -use FireflyIII\Api\V1\Requests\Models\Account\AccountTypesApiRequest; use FireflyIII\Api\V1\Requests\PaginationRequest; use FireflyIII\Models\Account; use Override; diff --git a/app/Api/V1/Requests/Generic/ObjectTypeApiRequest.php b/app/Api/V1/Requests/Generic/ObjectTypeApiRequest.php index cdc1837438..7fb642d72d 100644 --- a/app/Api/V1/Requests/Generic/ObjectTypeApiRequest.php +++ b/app/Api/V1/Requests/Generic/ObjectTypeApiRequest.php @@ -53,7 +53,7 @@ class ObjectTypeApiRequest extends ApiRequest public function rules(): array { - $rule = null; + $rule = null; if (Account::class === $this->objectType) { $rule = new IsValidAccountTypeList(); } @@ -66,6 +66,7 @@ class ObjectTypeApiRequest extends ApiRequest if ('' !== $this->required) { $rules['types'][] = $this->required; } + return $rules; } @@ -78,14 +79,20 @@ class ObjectTypeApiRequest extends ApiRequest } $type = $this->convertString('types', 'all'); $this->attributes->set('type', $type); + switch ($this->objectType) { default: $this->attributes->set('types', []); + + // no break case Account::class: $this->attributes->set('types', $this->mapAccountTypes($type)); + break; + case Transaction::class: $this->attributes->set('types', $this->mapTransactionTypes($type)); + break; } } diff --git a/app/Api/V1/Requests/Generic/PaginationDateRangeRequest.php b/app/Api/V1/Requests/Generic/PaginationDateRangeRequest.php index ed7e2cdd94..21a50f15fb 100644 --- a/app/Api/V1/Requests/Generic/PaginationDateRangeRequest.php +++ b/app/Api/V1/Requests/Generic/PaginationDateRangeRequest.php @@ -1,4 +1,6 @@ validateUserGroup((int)$value, $fail); } - private function validateUserGroup(int $userGroupId, Closure $fail): void { try { @@ -80,7 +79,8 @@ class IsAllowedGroupAction implements ValidationRule } catch (FireflyException $e) { Log::error($e->getTraceAsString()); } - die('here we are'); + + exit('here we are'); Log::debug(sprintf('validateUserGroup: %s', static::class)); if (!auth()->check()) { Log::debug('validateUserGroup: user is not logged in, return NULL.'); @@ -90,7 +90,7 @@ class IsAllowedGroupAction implements ValidationRule } /** @var User $user */ - $user = auth()->user(); + $user = auth()->user(); if (0 !== $userGroupId) { Log::debug(sprintf('validateUserGroup: user group submitted, search for memberships in group #%d.', $userGroupId)); } @@ -110,7 +110,7 @@ class IsAllowedGroupAction implements ValidationRule } // need to get the group from the membership: - $userGroup = $this->repository->getById($userGroupId); + $userGroup = $this->repository->getById($userGroupId); if (null === $userGroup) { Log::debug(sprintf('validateUserGroup: group #%d does not exist.', $userGroupId)); $fail('validation.belongs_user_or_user_group')->translate(); diff --git a/app/Rules/TransactionType/IsValidTransactionTypeList.php b/app/Rules/TransactionType/IsValidTransactionTypeList.php index 4f27b57f00..f0c68e2af5 100644 --- a/app/Rules/TransactionType/IsValidTransactionTypeList.php +++ b/app/Rules/TransactionType/IsValidTransactionTypeList.php @@ -45,7 +45,7 @@ class IsValidTransactionTypeList implements ValidationRule if (!is_array($values)) { $fail('validation.invalid_transaction_type_list')->translate(); } - $keys = array_keys($this->transactionTypes); + $keys = array_keys($this->transactionTypes); foreach ($values as $entry) { $entry = (string)$entry; if (!in_array($entry, $keys, true)) { diff --git a/app/Support/Http/Api/TransactionFilter.php b/app/Support/Http/Api/TransactionFilter.php index 74b8090468..45734abf75 100644 --- a/app/Support/Http/Api/TransactionFilter.php +++ b/app/Support/Http/Api/TransactionFilter.php @@ -70,7 +70,7 @@ trait TransactionFilter $return = []; $parts = explode(',', $type); foreach ($parts as $part) { - if(array_key_exists($part, $this->transactionTypes)) { + if (array_key_exists($part, $this->transactionTypes)) { $return = array_merge($return, $this->transactionTypes[$part]); } } diff --git a/app/Support/Http/Api/ValidatesUserGroupTrait.php b/app/Support/Http/Api/ValidatesUserGroupTrait.php index 2c9db16cb3..3d17a7b42c 100644 --- a/app/Support/Http/Api/ValidatesUserGroupTrait.php +++ b/app/Support/Http/Api/ValidatesUserGroupTrait.php @@ -25,7 +25,6 @@ declare(strict_types=1); namespace FireflyIII\Support\Http\Api; use FireflyIII\Enums\UserRoleEnum; -use FireflyIII\Exceptions\FireflyException; use FireflyIII\Models\UserGroup; use FireflyIII\Repositories\UserGroup\UserGroupRepositoryInterface; use FireflyIII\User; diff --git a/config/firefly.php b/config/firefly.php index 634cf70045..68a8862a38 100644 --- a/config/firefly.php +++ b/config/firefly.php @@ -78,8 +78,8 @@ return [ 'running_balance_column' => env('USE_RUNNING_BALANCE', false), // see cer.php for exchange rates feature flag. ], - 'version' => 'develop/2025-11-02', - 'build_time' => 1762056298, + 'version' => 'develop/2025-11-03', + 'build_time' => 1762140500, 'api_version' => '2.1.0', // field is no longer used. 'db_version' => 28, // field is no longer used. diff --git a/package-lock.json b/package-lock.json index e7e72c82ed..d93e5609f9 100644 --- a/package-lock.json +++ b/package-lock.json @@ -3173,9 +3173,9 @@ "license": "MIT" }, "node_modules/@types/node": { - "version": "24.9.2", - "resolved": "https://registry.npmjs.org/@types/node/-/node-24.9.2.tgz", - "integrity": "sha512-uWN8YqxXxqFMX2RqGOrumsKeti4LlmIMIyV0lgut4jx7KQBcBiW6vkDtIBvHnHIquwNfJhk8v2OtmO8zXWHfPA==", + "version": "24.10.0", + "resolved": "https://registry.npmjs.org/@types/node/-/node-24.10.0.tgz", + "integrity": "sha512-qzQZRBqkFsYyaSWXuEHc2WR9c0a0CXwiE5FWUvn7ZM+vdy1uZLfCunD38UzhuB7YN/J11ndbDBcTmOdxJo9Q7A==", "dev": true, "license": "MIT", "dependencies": { @@ -4521,9 +4521,9 @@ } }, "node_modules/caniuse-lite": { - "version": "1.0.30001752", - "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001752.tgz", - "integrity": "sha512-vKUk7beoukxE47P5gcVNKkDRzXdVofotshHwfR9vmpeFKxmI5PBpgOMC18LUJUA/DvJ70Y7RveasIBraqsyO/g==", + "version": "1.0.30001753", + "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001753.tgz", + "integrity": "sha512-Bj5H35MD/ebaOV4iDLqPEtiliTN29qkGtEHCwawWn4cYm+bPJM2NsaP30vtZcnERClMzp52J4+aw2UNbK4o+zw==", "dev": true, "funding": [ { @@ -5820,9 +5820,9 @@ } }, "node_modules/envinfo": { - "version": "7.19.0", - "resolved": "https://registry.npmjs.org/envinfo/-/envinfo-7.19.0.tgz", - "integrity": "sha512-DoSM9VyG6O3vqBf+p3Gjgr/Q52HYBBtO3v+4koAxt1MnWr+zEnxE+nke/yXS4lt2P4SYCHQ4V3f1i88LQVOpAw==", + "version": "7.20.0", + "resolved": "https://registry.npmjs.org/envinfo/-/envinfo-7.20.0.tgz", + "integrity": "sha512-+zUomDcLXsVkQ37vUqWBvQwLaLlj8eZPSi61llaEFAVBY5mhcXdaSw1pSJVl4yTYD5g/gEfpNl28YYk4IPvrrg==", "dev": true, "license": "MIT", "bin": { From d66f03d538e3f1c38cd04cbf60ccbb5ab404600a Mon Sep 17 00:00:00 2001 From: James Cole Date: Mon, 3 Nov 2025 20:08:31 +0100 Subject: [PATCH 11/29] Add support for sentry. --- .env.example | 8 + app/Api/V1/Requests/AggregateFormRequest.php | 3 +- app/Exceptions/Handler.php | 39 +-- composer.json | 1 + composer.lock | 239 ++++++++++++++++++- config/firefly.php | 63 ++--- config/sentry.php | 126 ++++++++++ 7 files changed, 430 insertions(+), 49 deletions(-) create mode 100644 config/sentry.php diff --git a/.env.example b/.env.example index e6737be1e7..6810317fdf 100644 --- a/.env.example +++ b/.env.example @@ -275,6 +275,14 @@ DISABLE_CSP_HEADER=false TRACKER_SITE_ID= TRACKER_URL= +# +# You can automatically submit errors to the Firefly III developer using sentry.io +# +# This is entirely optional of course. If you run into errors, I will gladly accept GitHub +# issues or a forwared email message. +# +TRACK_ERRORS=false + # # Firefly III supports webhooks. These are security sensitive and must be enabled manually first. # diff --git a/app/Api/V1/Requests/AggregateFormRequest.php b/app/Api/V1/Requests/AggregateFormRequest.php index eda707b798..8ac9d0949b 100644 --- a/app/Api/V1/Requests/AggregateFormRequest.php +++ b/app/Api/V1/Requests/AggregateFormRequest.php @@ -37,7 +37,7 @@ abstract class AggregateFormRequest extends ApiRequest */ protected array $requests = []; - /** @return class-string[] */ + /** @return array */ abstract protected function getRequests(): array; public function initialize(array $query = [], array $request = [], array $attributes = [], array $cookies = [], array $files = [], array $server = [], $content = null): void @@ -47,6 +47,7 @@ abstract class AggregateFormRequest extends ApiRequest // instantiate all subrequests and share current requests' bags with them Log::debug('Initializing AggregateFormRequest.'); + /** @var array|string $config */ foreach ($this->getRequests() as $config) { $requestClass = is_array($config) ? array_shift($config) : $config; diff --git a/app/Exceptions/Handler.php b/app/Exceptions/Handler.php index bc010ba8fa..3b4eb49151 100644 --- a/app/Exceptions/Handler.php +++ b/app/Exceptions/Handler.php @@ -42,6 +42,7 @@ use Illuminate\Validation\ValidationException as LaravelValidationException; use Laravel\Passport\Exceptions\OAuthServerException as LaravelOAuthException; use League\OAuth2\Server\Exception\OAuthServerException; use Override; +use Sentry\Laravel\Integration; use Symfony\Component\HttpFoundation\Exception\SuspiciousOperationException; use Symfony\Component\HttpFoundation\Response; use Symfony\Component\HttpKernel\Exception\BadRequestHttpException; @@ -49,11 +50,11 @@ use Symfony\Component\HttpKernel\Exception\HttpException; use Symfony\Component\HttpKernel\Exception\MethodNotAllowedHttpException; use Symfony\Component\HttpKernel\Exception\NotFoundHttpException; use Throwable; - use function Safe\json_encode; use function Safe\parse_url; // temp + /** * Class Handler */ @@ -65,7 +66,7 @@ class Handler extends ExceptionHandler * @var array> */ protected $dontReport - = [ + = [ AuthenticationException::class, LaravelValidationException::class, NotFoundHttpException::class, @@ -81,7 +82,14 @@ class Handler extends ExceptionHandler * Register the exception handling callbacks for the application. */ #[Override] - public function register(): void {} + public function register(): void + { + if (true === config('firefly.track_errors')) { + $this->reportable(function (Throwable $e) { + Integration::captureUnhandledException($e); + }); + } + } /** * Render an exception into an HTTP response. It's complex but lucky for us, we never use it because @@ -160,7 +168,7 @@ class Handler extends ExceptionHandler $errorCode = 500; $errorCode = $e instanceof MethodNotAllowedHttpException ? 405 : $errorCode; - $isDebug = (bool) config('app.debug', false); + $isDebug = (bool)config('app.debug', false); if ($isDebug) { Log::debug(sprintf('Return JSON %s with debug.', $e::class)); @@ -219,13 +227,13 @@ class Handler extends ExceptionHandler public function report(Throwable $e): void { self::$lastError = $e; - $doMailError = (bool) 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', ]; @@ -234,9 +242,9 @@ class Handler extends ExceptionHandler $userData['email'] = auth()->user()->email; } - $headers = request()->headers->all(); + $headers = request()->headers->all(); - $data = [ + $data = [ 'class' => $e::class, 'errorMessage' => $e->getMessage(), 'time' => Carbon::now()->format('r'), @@ -254,8 +262,8 @@ class Handler extends ExceptionHandler ]; // 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); @@ -264,9 +272,9 @@ class Handler extends ExceptionHandler private function shouldntReportLocal(Throwable $e): bool { return null !== Arr::first( - $this->dontReport, - static fn ($type) => $e instanceof $type - ); + $this->dontReport, + static fn($type) => $e instanceof $type + ); } /** @@ -275,7 +283,7 @@ class Handler extends ExceptionHandler * @param Request $request */ #[Override] - protected function invalid($request, LaravelValidationException $exception): \Illuminate\Http\Response|JsonResponse|RedirectResponse + protected function invalid($request, LaravelValidationException $exception): \Illuminate\Http\Response | JsonResponse | RedirectResponse { // protect against open redirect when submitting invalid forms. $previous = app('steam')->getSafePreviousUrl(); @@ -283,8 +291,7 @@ 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)); } /** diff --git a/composer.json b/composer.json index 037c109753..38f19e3e14 100644 --- a/composer.json +++ b/composer.json @@ -103,6 +103,7 @@ "psr/log": "<4", "ramsey/uuid": "^4.7", "rcrowe/twigbridge": "^0.14", + "sentry/sentry-laravel": "^4.18", "spatie/laravel-html": "^3.2", "spatie/laravel-ignition": "^2", "spatie/period": "^2.4", diff --git a/composer.lock b/composer.lock index 6bb9b491ee..ba0c780fe9 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": "5c65637d2a997c3503e4922eb7647e2a", + "content-hash": "946638fa99da77780e75953c338d9a55", "packages": [ { "name": "bacon/bacon-qr-code", @@ -1808,6 +1808,66 @@ }, "time": "2022-03-31T05:55:34+00:00" }, + { + "name": "jean85/pretty-package-versions", + "version": "2.1.1", + "source": { + "type": "git", + "url": "https://github.com/Jean85/pretty-package-versions.git", + "reference": "4d7aa5dab42e2a76d99559706022885de0e18e1a" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/Jean85/pretty-package-versions/zipball/4d7aa5dab42e2a76d99559706022885de0e18e1a", + "reference": "4d7aa5dab42e2a76d99559706022885de0e18e1a", + "shasum": "" + }, + "require": { + "composer-runtime-api": "^2.1.0", + "php": "^7.4|^8.0" + }, + "require-dev": { + "friendsofphp/php-cs-fixer": "^3.2", + "jean85/composer-provided-replaced-stub-package": "^1.0", + "phpstan/phpstan": "^2.0", + "phpunit/phpunit": "^7.5|^8.5|^9.6", + "rector/rector": "^2.0", + "vimeo/psalm": "^4.3 || ^5.0" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "1.x-dev" + } + }, + "autoload": { + "psr-4": { + "Jean85\\": "src/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Alessandro Lai", + "email": "alessandro.lai85@gmail.com" + } + ], + "description": "A library to get pretty versions strings of installed dependencies", + "keywords": [ + "composer", + "package", + "release", + "versions" + ], + "support": { + "issues": "https://github.com/Jean85/pretty-package-versions/issues", + "source": "https://github.com/Jean85/pretty-package-versions/tree/2.1.1" + }, + "time": "2025-03-19T14:43:43+00:00" + }, { "name": "laravel-notification-channels/pushover", "version": "4.1.2", @@ -5903,6 +5963,183 @@ }, "time": "2025-08-20T11:25:49+00:00" }, + { + "name": "sentry/sentry", + "version": "4.17.1", + "source": { + "type": "git", + "url": "https://github.com/getsentry/sentry-php.git", + "reference": "5c696b8de57e841a2bf3b6f6eecfd99acfdda80c" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/getsentry/sentry-php/zipball/5c696b8de57e841a2bf3b6f6eecfd99acfdda80c", + "reference": "5c696b8de57e841a2bf3b6f6eecfd99acfdda80c", + "shasum": "" + }, + "require": { + "ext-curl": "*", + "ext-json": "*", + "ext-mbstring": "*", + "guzzlehttp/psr7": "^1.8.4|^2.1.1", + "jean85/pretty-package-versions": "^1.5|^2.0.4", + "php": "^7.2|^8.0", + "psr/log": "^1.0|^2.0|^3.0", + "symfony/options-resolver": "^4.4.30|^5.0.11|^6.0|^7.0" + }, + "conflict": { + "raven/raven": "*" + }, + "require-dev": { + "friendsofphp/php-cs-fixer": "^3.4", + "guzzlehttp/promises": "^2.0.3", + "guzzlehttp/psr7": "^1.8.4|^2.1.1", + "monolog/monolog": "^1.6|^2.0|^3.0", + "phpbench/phpbench": "^1.0", + "phpstan/phpstan": "^1.3", + "phpunit/phpunit": "^8.5|^9.6", + "vimeo/psalm": "^4.17" + }, + "suggest": { + "monolog/monolog": "Allow sending log messages to Sentry by using the included Monolog handler." + }, + "type": "library", + "autoload": { + "files": [ + "src/functions.php" + ], + "psr-4": { + "Sentry\\": "src/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Sentry", + "email": "accounts@sentry.io" + } + ], + "description": "PHP SDK for Sentry (http://sentry.io)", + "homepage": "http://sentry.io", + "keywords": [ + "crash-reporting", + "crash-reports", + "error-handler", + "error-monitoring", + "log", + "logging", + "profiling", + "sentry", + "tracing" + ], + "support": { + "issues": "https://github.com/getsentry/sentry-php/issues", + "source": "https://github.com/getsentry/sentry-php/tree/4.17.1" + }, + "funding": [ + { + "url": "https://sentry.io/", + "type": "custom" + }, + { + "url": "https://sentry.io/pricing/", + "type": "custom" + } + ], + "time": "2025-10-23T15:19:24+00:00" + }, + { + "name": "sentry/sentry-laravel", + "version": "4.18.0", + "source": { + "type": "git", + "url": "https://github.com/getsentry/sentry-laravel.git", + "reference": "b9a647f93f9a040eaf6f21d0684f2351310d3360" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/getsentry/sentry-laravel/zipball/b9a647f93f9a040eaf6f21d0684f2351310d3360", + "reference": "b9a647f93f9a040eaf6f21d0684f2351310d3360", + "shasum": "" + }, + "require": { + "illuminate/support": "^6.0 | ^7.0 | ^8.0 | ^9.0 | ^10.0 | ^11.0 | ^12.0", + "nyholm/psr7": "^1.0", + "php": "^7.2 | ^8.0", + "sentry/sentry": "^4.16.0", + "symfony/psr-http-message-bridge": "^1.0 | ^2.0 | ^6.0 | ^7.0" + }, + "require-dev": { + "friendsofphp/php-cs-fixer": "^3.11", + "guzzlehttp/guzzle": "^7.2", + "laravel/folio": "^1.1", + "laravel/framework": "^6.0 | ^7.0 | ^8.0 | ^9.0 | ^10.0 | ^11.0 | ^12.0", + "livewire/livewire": "^2.0 | ^3.0", + "mockery/mockery": "^1.3", + "orchestra/testbench": "^4.7 | ^5.1 | ^6.0 | ^7.0 | ^8.0 | ^9.0 | ^10.0", + "phpstan/phpstan": "^1.10", + "phpunit/phpunit": "^8.4 | ^9.3 | ^10.4 | ^11.5" + }, + "type": "library", + "extra": { + "laravel": { + "aliases": { + "Sentry": "Sentry\\Laravel\\Facade" + }, + "providers": [ + "Sentry\\Laravel\\ServiceProvider", + "Sentry\\Laravel\\Tracing\\ServiceProvider" + ] + } + }, + "autoload": { + "psr-0": { + "Sentry\\Laravel\\": "src/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Sentry", + "email": "accounts@sentry.io" + } + ], + "description": "Laravel SDK for Sentry (https://sentry.io)", + "homepage": "https://sentry.io", + "keywords": [ + "crash-reporting", + "crash-reports", + "error-handler", + "error-monitoring", + "laravel", + "log", + "logging", + "profiling", + "sentry", + "tracing" + ], + "support": { + "issues": "https://github.com/getsentry/sentry-laravel/issues", + "source": "https://github.com/getsentry/sentry-laravel/tree/4.18.0" + }, + "funding": [ + { + "url": "https://sentry.io/", + "type": "custom" + }, + { + "url": "https://sentry.io/pricing/", + "type": "custom" + } + ], + "time": "2025-10-20T12:57:51+00:00" + }, { "name": "spatie/backtrace", "version": "1.8.1", diff --git a/config/firefly.php b/config/firefly.php index 634cf70045..37c9d78e30 100644 --- a/config/firefly.php +++ b/config/firefly.php @@ -107,6 +107,7 @@ return [ 'demo_password' => env('DEMO_PASSWORD', ''), 'tracker_site_id' => env('TRACKER_SITE_ID', ''), 'tracker_url' => env('TRACKER_URL', ''), + 'track_errors' => env('TRACK_ERRORS', false), // authentication settings 'authentication_guard' => envNonEmpty('AUTHENTICATION_GUARD', 'web'), @@ -410,7 +411,7 @@ return [ ], - 'rule-actions' => [ + 'rule-actions' => [ 'set_category' => SetCategory::class, 'clear_category' => ClearCategory::class, 'set_budget' => SetBudget::class, @@ -444,7 +445,7 @@ return [ // 'set_foreign_amount' => SetForeignAmount::class, // 'set_foreign_currency' => SetForeignCurrency::class, ], - 'context-rule-actions' => [ + 'context-rule-actions' => [ 'set_category', 'set_budget', 'add_tag', @@ -463,13 +464,13 @@ return [ 'convert_transfer', ], - 'test-triggers' => [ + 'test-triggers' => [ 'limit' => 10, 'range' => 200, ], // expected source types for each transaction type, in order of preference. - 'expected_source_types' => [ + 'expected_source_types' => [ 'source' => [ TransactionTypeEnum::WITHDRAWAL->value => [AccountTypeEnum::ASSET->value, AccountTypeEnum::LOAN->value, AccountTypeEnum::DEBT->value, AccountTypeEnum::MORTGAGE->value], TransactionTypeEnum::DEPOSIT->value => [AccountTypeEnum::LOAN->value, AccountTypeEnum::DEBT->value, AccountTypeEnum::MORTGAGE->value, AccountTypeEnum::REVENUE->value, AccountTypeEnum::CASH->value], @@ -514,7 +515,7 @@ return [ TransactionTypeEnum::LIABILITY_CREDIT->value => [AccountTypeEnum::LIABILITY_CREDIT->value, AccountTypeEnum::LOAN->value, AccountTypeEnum::DEBT->value, AccountTypeEnum::MORTGAGE->value], ], ], - 'allowed_opposing_types' => [ + 'allowed_opposing_types' => [ 'source' => [ AccountTypeEnum::ASSET->value => [ AccountTypeEnum::ASSET->value, @@ -604,7 +605,7 @@ return [ ], ], // depending on the account type, return the allowed transaction types: - 'allowed_transaction_types' => [ + 'allowed_transaction_types' => [ 'source' => [ AccountTypeEnum::ASSET->value => [ TransactionTypeEnum::WITHDRAWAL->value, @@ -673,7 +674,7 @@ return [ ], // having the source + dest will tell you the transaction type. - 'account_to_transaction' => [ + 'account_to_transaction' => [ AccountTypeEnum::ASSET->value => [ AccountTypeEnum::ASSET->value => TransactionTypeEnum::TRANSFER->value, AccountTypeEnum::CASH->value => TransactionTypeEnum::WITHDRAWAL->value, @@ -738,7 +739,7 @@ return [ ], // allowed source -> destination accounts. - 'source_dests' => [ + 'source_dests' => [ TransactionTypeEnum::WITHDRAWAL->value => [ AccountTypeEnum::ASSET->value => [AccountTypeEnum::EXPENSE->value, AccountTypeEnum::LOAN->value, AccountTypeEnum::DEBT->value, AccountTypeEnum::MORTGAGE->value, AccountTypeEnum::CASH->value], AccountTypeEnum::LOAN->value => [AccountTypeEnum::EXPENSE->value, AccountTypeEnum::CASH->value], @@ -777,7 +778,7 @@ return [ ], ], // if you add fields to this array, don't forget to update the export routine (ExportDataGenerator). - 'journal_meta_fields' => [ + 'journal_meta_fields' => [ // sepa 'sepa_cc', 'sepa_ct_op', @@ -811,47 +812,47 @@ return [ 'recurrence_count', 'recurrence_date', ], - 'webhooks' => [ + 'webhooks' => [ 'max_attempts' => env('WEBHOOK_MAX_ATTEMPTS', 3), ], - 'can_have_virtual_amounts' => [AccountTypeEnum::ASSET->value], - 'can_have_opening_balance' => [AccountTypeEnum::ASSET->value, AccountTypeEnum::LOAN->value, AccountTypeEnum::DEBT->value, AccountTypeEnum::MORTGAGE->value], - 'dynamic_creation_allowed' => [ + 'can_have_virtual_amounts' => [AccountTypeEnum::ASSET->value], + 'can_have_opening_balance' => [AccountTypeEnum::ASSET->value, AccountTypeEnum::LOAN->value, AccountTypeEnum::DEBT->value, AccountTypeEnum::MORTGAGE->value], + 'dynamic_creation_allowed' => [ AccountTypeEnum::EXPENSE->value, AccountTypeEnum::REVENUE->value, AccountTypeEnum::INITIAL_BALANCE->value, AccountTypeEnum::RECONCILIATION->value, AccountTypeEnum::LIABILITY_CREDIT->value, ], - 'valid_asset_fields' => ['account_role', 'account_number', 'currency_id', 'BIC', 'include_net_worth'], - 'valid_cc_fields' => ['account_role', 'cc_monthly_payment_date', 'cc_type', 'account_number', 'currency_id', 'BIC', 'include_net_worth'], - 'valid_account_fields' => ['account_number', 'currency_id', 'BIC', 'interest', 'interest_period', 'include_net_worth', 'liability_direction'], + 'valid_asset_fields' => ['account_role', 'account_number', 'currency_id', 'BIC', 'include_net_worth'], + 'valid_cc_fields' => ['account_role', 'cc_monthly_payment_date', 'cc_type', 'account_number', 'currency_id', 'BIC', 'include_net_worth'], + 'valid_account_fields' => ['account_number', 'currency_id', 'BIC', 'interest', 'interest_period', 'include_net_worth', 'liability_direction'], // dynamic date ranges are as follows: - 'dynamic_date_ranges' => ['last7', 'last30', 'last90', 'last365', 'MTD', 'QTD', 'YTD'], + 'dynamic_date_ranges' => ['last7', 'last30', 'last90', 'last365', 'MTD', 'QTD', 'YTD'], - 'allowed_sort_parameters' => [ + 'allowed_sort_parameters' => [ 'Account' => ['id', 'order', 'name', 'iban', 'active', 'account_type_id', - 'current_balance', - 'pc_current_balance', - 'opening_balance', - 'pc_opening_balance', - 'virtual_balance', - 'pc_virtual_balance', - 'debt_amount', - 'pc_debt_amount', - 'balance_difference', - 'pc_balance_difference', + 'current_balance', + 'pc_current_balance', + 'opening_balance', + 'pc_opening_balance', + 'virtual_balance', + 'pc_virtual_balance', + 'debt_amount', + 'pc_debt_amount', + 'balance_difference', + 'pc_balance_difference', ], ], - 'allowed_db_sort_parameters' => [ + 'allowed_db_sort_parameters' => [ 'Account' => ['id', 'order', 'name', 'iban', 'active', 'account_type_id'], ], // preselected account lists possibilities: - 'preselected_accounts' => ['all', 'assets', 'liabilities'], + 'preselected_accounts' => ['all', 'assets', 'liabilities'], // allowed to store a piggy bank in: - 'piggy_bank_account_types' => [AccountTypeEnum::ASSET->value, AccountTypeEnum::LOAN->value, AccountTypeEnum::DEBT->value, AccountTypeEnum::MORTGAGE->value], + 'piggy_bank_account_types' => [AccountTypeEnum::ASSET->value, AccountTypeEnum::LOAN->value, AccountTypeEnum::DEBT->value, AccountTypeEnum::MORTGAGE->value], ]; diff --git a/config/sentry.php b/config/sentry.php new file mode 100644 index 0000000000..b4256e1524 --- /dev/null +++ b/config/sentry.php @@ -0,0 +1,126 @@ + 'SENTRY_LARAVEL_DSN=https://cf9d7aea92537db1e97e3e758b88b0a3@o4510302583848960.ingest.de.sentry.io/4510302585290832', + 'release' => env('SENTRY_RELEASE'), + + // When left empty or `null` the Laravel environment will be used (usually discovered from `APP_ENV` in your `.env`) + 'environment' => env('SENTRY_ENVIRONMENT'), + + // @see: https://docs.sentry.io/platforms/php/guides/laravel/configuration/options/#sample_rate + 'sample_rate' => env('SENTRY_SAMPLE_RATE') === null ? 1.0 : (float)env('SENTRY_SAMPLE_RATE'), + + // @see: https://docs.sentry.io/platforms/php/guides/laravel/configuration/options/#traces_sample_rate + 'traces_sample_rate' => env('SENTRY_TRACES_SAMPLE_RATE') === null ? null : (float)env('SENTRY_TRACES_SAMPLE_RATE'), + + // @see: https://docs.sentry.io/platforms/php/guides/laravel/configuration/options/#profiles-sample-rate + 'profiles_sample_rate' => env('SENTRY_PROFILES_SAMPLE_RATE') === null ? null : (float)env('SENTRY_PROFILES_SAMPLE_RATE'), + + // @see: https://docs.sentry.io/platforms/php/guides/laravel/configuration/options/#enable_logs + 'enable_logs' => env('SENTRY_ENABLE_LOGS', false), + + // The minimum log level that will be sent to Sentry as logs using the `sentry_logs` logging channel + 'logs_channel_level' => env('SENTRY_LOG_LEVEL', env('SENTRY_LOGS_LEVEL', env('LOG_LEVEL', 'debug'))), + + // @see: https://docs.sentry.io/platforms/php/guides/laravel/configuration/options/#send_default_pii + 'send_default_pii' => env('SENTRY_SEND_DEFAULT_PII', false), + + // @see: https://docs.sentry.io/platforms/php/guides/laravel/configuration/options/#ignore_exceptions + 'ignore_exceptions' => [ + \Illuminate\Auth\AuthenticationException::class, + ], + + // @see: https://docs.sentry.io/platforms/php/guides/laravel/configuration/options/#ignore_transactions + 'ignore_transactions' => [ + // Ignore Laravel's default health URL + '/up', + ], + + // Breadcrumb specific configuration + 'breadcrumbs' => [ + // Capture Laravel logs as breadcrumbs + 'logs' => env('SENTRY_BREADCRUMBS_LOGS_ENABLED', true), + + // Capture Laravel cache events (hits, writes etc.) as breadcrumbs + 'cache' => env('SENTRY_BREADCRUMBS_CACHE_ENABLED', true), + + // Capture Livewire components like routes as breadcrumbs + 'livewire' => env('SENTRY_BREADCRUMBS_LIVEWIRE_ENABLED', true), + + // Capture SQL queries as breadcrumbs + 'sql_queries' => env('SENTRY_BREADCRUMBS_SQL_QUERIES_ENABLED', true), + + // Capture SQL query bindings (parameters) in SQL query breadcrumbs + 'sql_bindings' => env('SENTRY_BREADCRUMBS_SQL_BINDINGS_ENABLED', false), + + // Capture queue job information as breadcrumbs + 'queue_info' => env('SENTRY_BREADCRUMBS_QUEUE_INFO_ENABLED', true), + + // Capture command information as breadcrumbs + 'command_info' => env('SENTRY_BREADCRUMBS_COMMAND_JOBS_ENABLED', true), + + // Capture HTTP client request information as breadcrumbs + 'http_client_requests' => env('SENTRY_BREADCRUMBS_HTTP_CLIENT_REQUESTS_ENABLED', true), + + // Capture send notifications as breadcrumbs + 'notifications' => env('SENTRY_BREADCRUMBS_NOTIFICATIONS_ENABLED', true), + ], + + // Performance monitoring specific configuration + 'tracing' => [ + // Trace queue jobs as their own transactions (this enables tracing for queue jobs) + 'queue_job_transactions' => env('SENTRY_TRACE_QUEUE_ENABLED', true), + + // Capture queue jobs as spans when executed on the sync driver + 'queue_jobs' => env('SENTRY_TRACE_QUEUE_JOBS_ENABLED', true), + + // Capture SQL queries as spans + 'sql_queries' => env('SENTRY_TRACE_SQL_QUERIES_ENABLED', true), + + // Capture SQL query bindings (parameters) in SQL query spans + 'sql_bindings' => env('SENTRY_TRACE_SQL_BINDINGS_ENABLED', false), + + // Capture where the SQL query originated from on the SQL query spans + 'sql_origin' => env('SENTRY_TRACE_SQL_ORIGIN_ENABLED', true), + + // Define a threshold in milliseconds for SQL queries to resolve their origin + 'sql_origin_threshold_ms' => env('SENTRY_TRACE_SQL_ORIGIN_THRESHOLD_MS', 100), + + // Capture views rendered as spans + 'views' => env('SENTRY_TRACE_VIEWS_ENABLED', true), + + // Capture Livewire components as spans + 'livewire' => env('SENTRY_TRACE_LIVEWIRE_ENABLED', true), + + // Capture HTTP client requests as spans + 'http_client_requests' => env('SENTRY_TRACE_HTTP_CLIENT_REQUESTS_ENABLED', true), + + // Capture Laravel cache events (hits, writes etc.) as spans + 'cache' => env('SENTRY_TRACE_CACHE_ENABLED', true), + + // Capture Redis operations as spans (this enables Redis events in Laravel) + 'redis_commands' => env('SENTRY_TRACE_REDIS_COMMANDS', false), + + // Capture where the Redis command originated from on the Redis command spans + 'redis_origin' => env('SENTRY_TRACE_REDIS_ORIGIN_ENABLED', true), + + // Capture send notifications as spans + 'notifications' => env('SENTRY_TRACE_NOTIFICATIONS_ENABLED', true), + + // Enable tracing for requests without a matching route (404's) + 'missing_routes' => env('SENTRY_TRACE_MISSING_ROUTES_ENABLED', false), + + // Configures if the performance trace should continue after the response has been sent to the user until the application terminates + // This is required to capture any spans that are created after the response has been sent like queue jobs dispatched using `dispatch(...)->afterResponse()` for example + 'continue_after_response' => env('SENTRY_TRACE_CONTINUE_AFTER_RESPONSE', true), + + // Enable the tracing integrations supplied by Sentry (recommended) + 'default_integrations' => env('SENTRY_TRACE_DEFAULT_INTEGRATIONS_ENABLED', true), + ], + +]; From 774e02017718110c94bafe5f4f84b8c0f431c3df Mon Sep 17 00:00:00 2001 From: JC5 Date: Mon, 3 Nov 2025 20:13:41 +0100 Subject: [PATCH 12/29] =?UTF-8?q?=F0=9F=A4=96=20Auto=20commit=20for=20rele?= =?UTF-8?q?ase=20'develop'=20on=202025-11-03?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- app/Api/V1/Requests/AggregateFormRequest.php | 2 +- app/Exceptions/Handler.php | 28 +++++---- composer.lock | 17 +++--- config/firefly.php | 64 ++++++++++---------- config/sentry.php | 12 ++-- 5 files changed, 65 insertions(+), 58 deletions(-) diff --git a/app/Api/V1/Requests/AggregateFormRequest.php b/app/Api/V1/Requests/AggregateFormRequest.php index 069d4fab29..8aa3cecffb 100644 --- a/app/Api/V1/Requests/AggregateFormRequest.php +++ b/app/Api/V1/Requests/AggregateFormRequest.php @@ -36,7 +36,7 @@ abstract class AggregateFormRequest extends ApiRequest */ protected array $requests = []; - /** @return array */ + /** @return array */ abstract protected function getRequests(): array; public function initialize(array $query = [], array $request = [], array $attributes = [], array $cookies = [], array $files = [], array $server = [], $content = null): void diff --git a/app/Exceptions/Handler.php b/app/Exceptions/Handler.php index 3b4eb49151..12801ca009 100644 --- a/app/Exceptions/Handler.php +++ b/app/Exceptions/Handler.php @@ -50,6 +50,7 @@ use Symfony\Component\HttpKernel\Exception\HttpException; use Symfony\Component\HttpKernel\Exception\MethodNotAllowedHttpException; use Symfony\Component\HttpKernel\Exception\NotFoundHttpException; use Throwable; + use function Safe\json_encode; use function Safe\parse_url; @@ -66,7 +67,7 @@ class Handler extends ExceptionHandler * @var array> */ protected $dontReport - = [ + = [ AuthenticationException::class, LaravelValidationException::class, NotFoundHttpException::class, @@ -85,7 +86,7 @@ class Handler extends ExceptionHandler public function register(): void { if (true === config('firefly.track_errors')) { - $this->reportable(function (Throwable $e) { + $this->reportable(function (Throwable $e): void { Integration::captureUnhandledException($e); }); } @@ -168,7 +169,7 @@ class Handler extends ExceptionHandler $errorCode = 500; $errorCode = $e instanceof MethodNotAllowedHttpException ? 405 : $errorCode; - $isDebug = (bool)config('app.debug', false); + $isDebug = (bool)config('app.debug', false); if ($isDebug) { Log::debug(sprintf('Return JSON %s with debug.', $e::class)); @@ -233,7 +234,7 @@ class Handler extends ExceptionHandler return; } - $userData = [ + $userData = [ 'id' => 0, 'email' => 'unknown@example.com', ]; @@ -242,9 +243,9 @@ class Handler extends ExceptionHandler $userData['email'] = auth()->user()->email; } - $headers = request()->headers->all(); + $headers = request()->headers->all(); - $data = [ + $data = [ 'class' => $e::class, 'errorMessage' => $e->getMessage(), 'time' => Carbon::now()->format('r'), @@ -262,8 +263,8 @@ class Handler extends ExceptionHandler ]; // 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); @@ -272,9 +273,9 @@ class Handler extends ExceptionHandler private function shouldntReportLocal(Throwable $e): bool { return null !== Arr::first( - $this->dontReport, - static fn($type) => $e instanceof $type - ); + $this->dontReport, + static fn ($type) => $e instanceof $type + ); } /** @@ -283,7 +284,7 @@ class Handler extends ExceptionHandler * @param Request $request */ #[Override] - protected function invalid($request, LaravelValidationException $exception): \Illuminate\Http\Response | JsonResponse | RedirectResponse + protected function invalid($request, LaravelValidationException $exception): \Illuminate\Http\Response|JsonResponse|RedirectResponse { // protect against open redirect when submitting invalid forms. $previous = app('steam')->getSafePreviousUrl(); @@ -291,7 +292,8 @@ 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)) + ; } /** diff --git a/composer.lock b/composer.lock index ba0c780fe9..790f7a9f12 100644 --- a/composer.lock +++ b/composer.lock @@ -10920,16 +10920,16 @@ }, { "name": "larastan/larastan", - "version": "v3.7.2", + "version": "v3.8.0", "source": { "type": "git", "url": "https://github.com/larastan/larastan.git", - "reference": "a761859a7487bd7d0cb8b662a7538a234d5bb5ae" + "reference": "d13ef96d652d1b2a8f34f1760ba6bf5b9c98112e" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/larastan/larastan/zipball/a761859a7487bd7d0cb8b662a7538a234d5bb5ae", - "reference": "a761859a7487bd7d0cb8b662a7538a234d5bb5ae", + "url": "https://api.github.com/repos/larastan/larastan/zipball/d13ef96d652d1b2a8f34f1760ba6bf5b9c98112e", + "reference": "d13ef96d652d1b2a8f34f1760ba6bf5b9c98112e", "shasum": "" }, "require": { @@ -10943,7 +10943,7 @@ "illuminate/pipeline": "^11.44.2 || ^12.4.1", "illuminate/support": "^11.44.2 || ^12.4.1", "php": "^8.2", - "phpstan/phpstan": "^2.1.28" + "phpstan/phpstan": "^2.1.29" }, "require-dev": { "doctrine/coding-standard": "^13", @@ -10956,7 +10956,8 @@ "phpunit/phpunit": "^10.5.35 || ^11.5.15" }, "suggest": { - "orchestra/testbench": "Using Larastan for analysing a package needs Testbench" + "orchestra/testbench": "Using Larastan for analysing a package needs Testbench", + "phpmyadmin/sql-parser": "Install to enable Larastan's optional phpMyAdmin-based SQL parser automatically" }, "type": "phpstan-extension", "extra": { @@ -10997,7 +10998,7 @@ ], "support": { "issues": "https://github.com/larastan/larastan/issues", - "source": "https://github.com/larastan/larastan/tree/v3.7.2" + "source": "https://github.com/larastan/larastan/tree/v3.8.0" }, "funding": [ { @@ -11005,7 +11006,7 @@ "type": "github" } ], - "time": "2025-09-19T09:03:05+00:00" + "time": "2025-10-27T23:09:14+00:00" }, { "name": "laravel-json-api/testing", diff --git a/config/firefly.php b/config/firefly.php index 9b753b555d..0df50fce02 100644 --- a/config/firefly.php +++ b/config/firefly.php @@ -79,7 +79,7 @@ return [ // see cer.php for exchange rates feature flag. ], 'version' => 'develop/2025-11-03', - 'build_time' => 1762140500, + 'build_time' => 1762197101, 'api_version' => '2.1.0', // field is no longer used. 'db_version' => 28, // field is no longer used. @@ -411,7 +411,7 @@ return [ ], - 'rule-actions' => [ + 'rule-actions' => [ 'set_category' => SetCategory::class, 'clear_category' => ClearCategory::class, 'set_budget' => SetBudget::class, @@ -445,7 +445,7 @@ return [ // 'set_foreign_amount' => SetForeignAmount::class, // 'set_foreign_currency' => SetForeignCurrency::class, ], - 'context-rule-actions' => [ + 'context-rule-actions' => [ 'set_category', 'set_budget', 'add_tag', @@ -464,13 +464,13 @@ return [ 'convert_transfer', ], - 'test-triggers' => [ + 'test-triggers' => [ 'limit' => 10, 'range' => 200, ], // expected source types for each transaction type, in order of preference. - 'expected_source_types' => [ + 'expected_source_types' => [ 'source' => [ TransactionTypeEnum::WITHDRAWAL->value => [AccountTypeEnum::ASSET->value, AccountTypeEnum::LOAN->value, AccountTypeEnum::DEBT->value, AccountTypeEnum::MORTGAGE->value], TransactionTypeEnum::DEPOSIT->value => [AccountTypeEnum::LOAN->value, AccountTypeEnum::DEBT->value, AccountTypeEnum::MORTGAGE->value, AccountTypeEnum::REVENUE->value, AccountTypeEnum::CASH->value], @@ -515,7 +515,7 @@ return [ TransactionTypeEnum::LIABILITY_CREDIT->value => [AccountTypeEnum::LIABILITY_CREDIT->value, AccountTypeEnum::LOAN->value, AccountTypeEnum::DEBT->value, AccountTypeEnum::MORTGAGE->value], ], ], - 'allowed_opposing_types' => [ + 'allowed_opposing_types' => [ 'source' => [ AccountTypeEnum::ASSET->value => [ AccountTypeEnum::ASSET->value, @@ -605,7 +605,7 @@ return [ ], ], // depending on the account type, return the allowed transaction types: - 'allowed_transaction_types' => [ + 'allowed_transaction_types' => [ 'source' => [ AccountTypeEnum::ASSET->value => [ TransactionTypeEnum::WITHDRAWAL->value, @@ -674,7 +674,7 @@ return [ ], // having the source + dest will tell you the transaction type. - 'account_to_transaction' => [ + 'account_to_transaction' => [ AccountTypeEnum::ASSET->value => [ AccountTypeEnum::ASSET->value => TransactionTypeEnum::TRANSFER->value, AccountTypeEnum::CASH->value => TransactionTypeEnum::WITHDRAWAL->value, @@ -739,7 +739,7 @@ return [ ], // allowed source -> destination accounts. - 'source_dests' => [ + 'source_dests' => [ TransactionTypeEnum::WITHDRAWAL->value => [ AccountTypeEnum::ASSET->value => [AccountTypeEnum::EXPENSE->value, AccountTypeEnum::LOAN->value, AccountTypeEnum::DEBT->value, AccountTypeEnum::MORTGAGE->value, AccountTypeEnum::CASH->value], AccountTypeEnum::LOAN->value => [AccountTypeEnum::EXPENSE->value, AccountTypeEnum::CASH->value], @@ -778,7 +778,7 @@ return [ ], ], // if you add fields to this array, don't forget to update the export routine (ExportDataGenerator). - 'journal_meta_fields' => [ + 'journal_meta_fields' => [ // sepa 'sepa_cc', 'sepa_ct_op', @@ -812,47 +812,47 @@ return [ 'recurrence_count', 'recurrence_date', ], - 'webhooks' => [ + 'webhooks' => [ 'max_attempts' => env('WEBHOOK_MAX_ATTEMPTS', 3), ], - 'can_have_virtual_amounts' => [AccountTypeEnum::ASSET->value], - 'can_have_opening_balance' => [AccountTypeEnum::ASSET->value, AccountTypeEnum::LOAN->value, AccountTypeEnum::DEBT->value, AccountTypeEnum::MORTGAGE->value], - 'dynamic_creation_allowed' => [ + 'can_have_virtual_amounts' => [AccountTypeEnum::ASSET->value], + 'can_have_opening_balance' => [AccountTypeEnum::ASSET->value, AccountTypeEnum::LOAN->value, AccountTypeEnum::DEBT->value, AccountTypeEnum::MORTGAGE->value], + 'dynamic_creation_allowed' => [ AccountTypeEnum::EXPENSE->value, AccountTypeEnum::REVENUE->value, AccountTypeEnum::INITIAL_BALANCE->value, AccountTypeEnum::RECONCILIATION->value, AccountTypeEnum::LIABILITY_CREDIT->value, ], - 'valid_asset_fields' => ['account_role', 'account_number', 'currency_id', 'BIC', 'include_net_worth'], - 'valid_cc_fields' => ['account_role', 'cc_monthly_payment_date', 'cc_type', 'account_number', 'currency_id', 'BIC', 'include_net_worth'], - 'valid_account_fields' => ['account_number', 'currency_id', 'BIC', 'interest', 'interest_period', 'include_net_worth', 'liability_direction'], + 'valid_asset_fields' => ['account_role', 'account_number', 'currency_id', 'BIC', 'include_net_worth'], + 'valid_cc_fields' => ['account_role', 'cc_monthly_payment_date', 'cc_type', 'account_number', 'currency_id', 'BIC', 'include_net_worth'], + 'valid_account_fields' => ['account_number', 'currency_id', 'BIC', 'interest', 'interest_period', 'include_net_worth', 'liability_direction'], // dynamic date ranges are as follows: - 'dynamic_date_ranges' => ['last7', 'last30', 'last90', 'last365', 'MTD', 'QTD', 'YTD'], + 'dynamic_date_ranges' => ['last7', 'last30', 'last90', 'last365', 'MTD', 'QTD', 'YTD'], - 'allowed_sort_parameters' => [ + 'allowed_sort_parameters' => [ 'Account' => ['id', 'order', 'name', 'iban', 'active', 'account_type_id', - 'current_balance', - 'pc_current_balance', - 'opening_balance', - 'pc_opening_balance', - 'virtual_balance', - 'pc_virtual_balance', - 'debt_amount', - 'pc_debt_amount', - 'balance_difference', - 'pc_balance_difference', + 'current_balance', + 'pc_current_balance', + 'opening_balance', + 'pc_opening_balance', + 'virtual_balance', + 'pc_virtual_balance', + 'debt_amount', + 'pc_debt_amount', + 'balance_difference', + 'pc_balance_difference', ], ], - 'allowed_db_sort_parameters' => [ + 'allowed_db_sort_parameters' => [ 'Account' => ['id', 'order', 'name', 'iban', 'active', 'account_type_id'], ], // preselected account lists possibilities: - 'preselected_accounts' => ['all', 'assets', 'liabilities'], + 'preselected_accounts' => ['all', 'assets', 'liabilities'], // allowed to store a piggy bank in: - 'piggy_bank_account_types' => [AccountTypeEnum::ASSET->value, AccountTypeEnum::LOAN->value, AccountTypeEnum::DEBT->value, AccountTypeEnum::MORTGAGE->value], + 'piggy_bank_account_types' => [AccountTypeEnum::ASSET->value, AccountTypeEnum::LOAN->value, AccountTypeEnum::DEBT->value, AccountTypeEnum::MORTGAGE->value], ]; diff --git a/config/sentry.php b/config/sentry.php index b4256e1524..30b362d7d6 100644 --- a/config/sentry.php +++ b/config/sentry.php @@ -1,5 +1,9 @@ env('SENTRY_ENVIRONMENT'), // @see: https://docs.sentry.io/platforms/php/guides/laravel/configuration/options/#sample_rate - 'sample_rate' => env('SENTRY_SAMPLE_RATE') === null ? 1.0 : (float)env('SENTRY_SAMPLE_RATE'), + 'sample_rate' => null === env('SENTRY_SAMPLE_RATE') ? 1.0 : (float)env('SENTRY_SAMPLE_RATE'), // @see: https://docs.sentry.io/platforms/php/guides/laravel/configuration/options/#traces_sample_rate - 'traces_sample_rate' => env('SENTRY_TRACES_SAMPLE_RATE') === null ? null : (float)env('SENTRY_TRACES_SAMPLE_RATE'), + 'traces_sample_rate' => null === env('SENTRY_TRACES_SAMPLE_RATE') ? null : (float)env('SENTRY_TRACES_SAMPLE_RATE'), // @see: https://docs.sentry.io/platforms/php/guides/laravel/configuration/options/#profiles-sample-rate - 'profiles_sample_rate' => env('SENTRY_PROFILES_SAMPLE_RATE') === null ? null : (float)env('SENTRY_PROFILES_SAMPLE_RATE'), + 'profiles_sample_rate' => null === env('SENTRY_PROFILES_SAMPLE_RATE') ? null : (float)env('SENTRY_PROFILES_SAMPLE_RATE'), // @see: https://docs.sentry.io/platforms/php/guides/laravel/configuration/options/#enable_logs 'enable_logs' => env('SENTRY_ENABLE_LOGS', false), @@ -32,7 +36,7 @@ return [ // @see: https://docs.sentry.io/platforms/php/guides/laravel/configuration/options/#ignore_exceptions 'ignore_exceptions' => [ - \Illuminate\Auth\AuthenticationException::class, + AuthenticationException::class, ], // @see: https://docs.sentry.io/platforms/php/guides/laravel/configuration/options/#ignore_transactions From 9bd294257b660f2a77efbf9feab2584e332f6734 Mon Sep 17 00:00:00 2001 From: James Cole Date: Mon, 3 Nov 2025 20:49:42 +0100 Subject: [PATCH 13/29] Whoops. --- config/sentry.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/config/sentry.php b/config/sentry.php index 30b362d7d6..d91723d47d 100644 --- a/config/sentry.php +++ b/config/sentry.php @@ -10,7 +10,7 @@ use Illuminate\Auth\AuthenticationException; * @see https://docs.sentry.io/platforms/php/guides/laravel/configuration/options/ */ return [ - 'dsn' => 'SENTRY_LARAVEL_DSN=https://cf9d7aea92537db1e97e3e758b88b0a3@o4510302583848960.ingest.de.sentry.io/4510302585290832', + 'dsn' => 'https://cf9d7aea92537db1e97e3e758b88b0a3@o4510302583848960.ingest.de.sentry.io/4510302585290832', 'release' => env('SENTRY_RELEASE'), // When left empty or `null` the Laravel environment will be used (usually discovered from `APP_ENV` in your `.env`) From f000f96b00eaa1768313f66d05795183c7f5f82f Mon Sep 17 00:00:00 2001 From: JC5 Date: Mon, 3 Nov 2025 20:54:02 +0100 Subject: [PATCH 14/29] =?UTF-8?q?=F0=9F=A4=96=20Auto=20commit=20for=20rele?= =?UTF-8?q?ase=20'develop'=20on=202025-11-03?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- config/firefly.php | 2 +- config/sentry.php | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/config/firefly.php b/config/firefly.php index 0df50fce02..7a7d022a7b 100644 --- a/config/firefly.php +++ b/config/firefly.php @@ -79,7 +79,7 @@ return [ // see cer.php for exchange rates feature flag. ], 'version' => 'develop/2025-11-03', - 'build_time' => 1762197101, + 'build_time' => 1762199520, 'api_version' => '2.1.0', // field is no longer used. 'db_version' => 28, // field is no longer used. diff --git a/config/sentry.php b/config/sentry.php index d91723d47d..fbda6afc06 100644 --- a/config/sentry.php +++ b/config/sentry.php @@ -4,7 +4,7 @@ declare(strict_types=1); use Illuminate\Auth\AuthenticationException; -/** +/* * Sentry Laravel SDK configuration file. * * @see https://docs.sentry.io/platforms/php/guides/laravel/configuration/options/ From b3421faf2533e355efdf6465704cc57d33dad1da Mon Sep 17 00:00:00 2001 From: James Cole Date: Mon, 3 Nov 2025 20:58:04 +0100 Subject: [PATCH 15/29] Fix #11168 --- app/Api/V1/Requests/Generic/QueryRequest.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/Api/V1/Requests/Generic/QueryRequest.php b/app/Api/V1/Requests/Generic/QueryRequest.php index 6414cbbc64..10051fc0a8 100644 --- a/app/Api/V1/Requests/Generic/QueryRequest.php +++ b/app/Api/V1/Requests/Generic/QueryRequest.php @@ -36,7 +36,7 @@ class QueryRequest extends ApiRequest public function rules(): array { return [ - 'query' => sprintf('min:1|max:50|%s', $this->required), + 'query' => sprintf('min:0|max:50|%s', $this->required), ]; } From 35e4ece20581e9867a945822c7ffb6e2613d2d86 Mon Sep 17 00:00:00 2001 From: JC5 Date: Mon, 3 Nov 2025 21:03:36 +0100 Subject: [PATCH 16/29] =?UTF-8?q?=F0=9F=A4=96=20Auto=20commit=20for=20rele?= =?UTF-8?q?ase=20'develop'=20on=202025-11-03?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- config/firefly.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/config/firefly.php b/config/firefly.php index 7a7d022a7b..3628bc960a 100644 --- a/config/firefly.php +++ b/config/firefly.php @@ -79,7 +79,7 @@ return [ // see cer.php for exchange rates feature flag. ], 'version' => 'develop/2025-11-03', - 'build_time' => 1762199520, + 'build_time' => 1762200103, 'api_version' => '2.1.0', // field is no longer used. 'db_version' => 28, // field is no longer used. From 917b9195038ce6ba57a65ae49816e35fcb7a7c02 Mon Sep 17 00:00:00 2001 From: JC5 Date: Tue, 4 Nov 2025 05:17:07 +0100 Subject: [PATCH 17/29] =?UTF-8?q?=F0=9F=A4=96=20Auto=20commit=20for=20rele?= =?UTF-8?q?ase=20'develop'=20on=202025-11-04?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- config/firefly.php | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/config/firefly.php b/config/firefly.php index 3628bc960a..98774cc377 100644 --- a/config/firefly.php +++ b/config/firefly.php @@ -78,8 +78,8 @@ return [ 'running_balance_column' => env('USE_RUNNING_BALANCE', false), // see cer.php for exchange rates feature flag. ], - 'version' => 'develop/2025-11-03', - 'build_time' => 1762200103, + 'version' => 'develop/2025-11-04', + 'build_time' => 1762229717, 'api_version' => '2.1.0', // field is no longer used. 'db_version' => 28, // field is no longer used. From eda81ef7b54b7ac518f5a357723cf40eccd6a821 Mon Sep 17 00:00:00 2001 From: James Cole Date: Tue, 4 Nov 2025 05:50:06 +0100 Subject: [PATCH 18/29] Rename the variable so there is no doubt what it does. --- .env.example | 4 +++- app/Exceptions/Handler.php | 2 +- config/firefly.php | 2 +- 3 files changed, 5 insertions(+), 3 deletions(-) diff --git a/.env.example b/.env.example index 6810317fdf..af3fc69a18 100644 --- a/.env.example +++ b/.env.example @@ -281,7 +281,9 @@ TRACKER_URL= # This is entirely optional of course. If you run into errors, I will gladly accept GitHub # issues or a forwared email message. # -TRACK_ERRORS=false +# If you set this to true, your installation will try to contact sentry.io when it runs into errors. +# +REPORT_ERRORS_ONLINE=false # # Firefly III supports webhooks. These are security sensitive and must be enabled manually first. diff --git a/app/Exceptions/Handler.php b/app/Exceptions/Handler.php index 12801ca009..8db203a421 100644 --- a/app/Exceptions/Handler.php +++ b/app/Exceptions/Handler.php @@ -85,7 +85,7 @@ class Handler extends ExceptionHandler #[Override] public function register(): void { - if (true === config('firefly.track_errors')) { + if (true === config('firefly.report_errors_online')) { $this->reportable(function (Throwable $e): void { Integration::captureUnhandledException($e); }); diff --git a/config/firefly.php b/config/firefly.php index 98774cc377..92120370f0 100644 --- a/config/firefly.php +++ b/config/firefly.php @@ -107,7 +107,7 @@ return [ 'demo_password' => env('DEMO_PASSWORD', ''), 'tracker_site_id' => env('TRACKER_SITE_ID', ''), 'tracker_url' => env('TRACKER_URL', ''), - 'track_errors' => env('TRACK_ERRORS', false), + 'report_errors_online' => env('REPORT_ERRORS_ONLINE', false), // authentication settings 'authentication_guard' => envNonEmpty('AUTHENTICATION_GUARD', 'web'), From bc5d52435efb158836d383e49feb37b3a0a74fc2 Mon Sep 17 00:00:00 2001 From: JC5 Date: Tue, 4 Nov 2025 05:54:30 +0100 Subject: [PATCH 19/29] =?UTF-8?q?=F0=9F=A4=96=20Auto=20commit=20for=20rele?= =?UTF-8?q?ase=20'develop'=20on=202025-11-04?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- config/firefly.php | 158 ++++++++++++++++++++++----------------------- 1 file changed, 79 insertions(+), 79 deletions(-) diff --git a/config/firefly.php b/config/firefly.php index 92120370f0..b6551e9b17 100644 --- a/config/firefly.php +++ b/config/firefly.php @@ -64,12 +64,12 @@ use FireflyIII\TransactionRules\Actions\UpdatePiggyBank; return [ // default values for certain things: - 'configuration' => [ + 'configuration' => [ 'single_user_mode' => true, 'is_demo_site' => false, ], // some feature flags: - 'feature_flags' => [ + 'feature_flags' => [ 'export' => true, 'telemetry' => false, 'webhooks' => true, @@ -78,48 +78,48 @@ return [ 'running_balance_column' => env('USE_RUNNING_BALANCE', false), // see cer.php for exchange rates feature flag. ], - 'version' => 'develop/2025-11-04', - 'build_time' => 1762229717, - 'api_version' => '2.1.0', // field is no longer used. - 'db_version' => 28, // field is no longer used. + 'version' => 'develop/2025-11-04', + 'build_time' => 1762231951, + 'api_version' => '2.1.0', // field is no longer used. + 'db_version' => 28, // field is no longer used. // generic settings - 'maxUploadSize' => 1073741824, // 1 GB - 'send_error_message' => env('SEND_ERROR_MESSAGE', true), - 'site_owner' => env('SITE_OWNER', ''), + 'maxUploadSize' => 1073741824, // 1 GB + 'send_error_message' => env('SEND_ERROR_MESSAGE', true), + 'site_owner' => env('SITE_OWNER', ''), // tokens and keys - 'fixer_api_key' => env('FIXER_API_KEY', ''), - 'ipinfo_token' => env('IPINFO_TOKEN', ''), - 'static_cron_token' => envNonEmpty('STATIC_CRON_TOKEN'), + 'fixer_api_key' => env('FIXER_API_KEY', ''), + 'ipinfo_token' => env('IPINFO_TOKEN', ''), + 'static_cron_token' => envNonEmpty('STATIC_CRON_TOKEN'), // flags - 'enable_external_map' => env('ENABLE_EXTERNAL_MAP', false), - 'disable_frame_header' => env('DISABLE_FRAME_HEADER', false), - 'disable_csp_header' => env('DISABLE_CSP_HEADER', false), - 'allow_webhooks' => env('ALLOW_WEBHOOKS', false), + 'enable_external_map' => env('ENABLE_EXTERNAL_MAP', false), + 'disable_frame_header' => env('DISABLE_FRAME_HEADER', false), + 'disable_csp_header' => env('DISABLE_CSP_HEADER', false), + 'allow_webhooks' => env('ALLOW_WEBHOOKS', false), // flags - 'send_report_journals' => envNonEmpty('SEND_REPORT_JOURNALS', true), + 'send_report_journals' => envNonEmpty('SEND_REPORT_JOURNALS', true), // info for demo site - 'demo_username' => env('DEMO_USERNAME', ''), - 'demo_password' => env('DEMO_PASSWORD', ''), - 'tracker_site_id' => env('TRACKER_SITE_ID', ''), - 'tracker_url' => env('TRACKER_URL', ''), + 'demo_username' => env('DEMO_USERNAME', ''), + 'demo_password' => env('DEMO_PASSWORD', ''), + 'tracker_site_id' => env('TRACKER_SITE_ID', ''), + 'tracker_url' => env('TRACKER_URL', ''), 'report_errors_online' => env('REPORT_ERRORS_ONLINE', false), // authentication settings - 'authentication_guard' => envNonEmpty('AUTHENTICATION_GUARD', 'web'), - 'custom_logout_url' => envNonEmpty('CUSTOM_LOGOUT_URL', ''), + 'authentication_guard' => envNonEmpty('AUTHENTICATION_GUARD', 'web'), + 'custom_logout_url' => envNonEmpty('CUSTOM_LOGOUT_URL', ''), // static config (cannot be changed by user) - 'update_endpoint' => 'https://version.firefly-iii.org/index.json', - 'update_minimum_age' => 7, + 'update_endpoint' => 'https://version.firefly-iii.org/index.json', + 'update_minimum_age' => 7, // enabled languages - 'languages' => [ + 'languages' => [ // currently enabled languages // 'af_ZA' => ['name_locale' => 'Afrikaans', 'name_english' => 'Afrikaans'], 'ar_SA' => ['name_locale' => 'العربية', 'name_english' => 'Arabic'], @@ -167,22 +167,22 @@ return [ ], // web configuration: - 'trusted_proxies' => env('TRUSTED_PROXIES', ''), + 'trusted_proxies' => env('TRUSTED_PROXIES', ''), // map configuration - 'default_location' => [ + 'default_location' => [ 'longitude' => env('MAP_DEFAULT_LONG', '5.916667'), 'latitude' => env('MAP_DEFAULT_LAT', '51.983333'), 'zoom_level' => env('MAP_DEFAULT_ZOOM', '6'), ], // administration specific preferences - 'admin_specific_prefs' => [], + 'admin_specific_prefs' => [], // default user-related values - 'darkMode' => 'browser', - 'list_length' => 10, // to be removed if v1 is cancelled. - 'default_preferences' => [ + 'darkMode' => 'browser', + 'list_length' => 10, // to be removed if v1 is cancelled. + 'default_preferences' => [ 'anonymous' => false, 'frontpageAccounts' => [], 'listPageSize' => 50, @@ -191,12 +191,12 @@ return [ 'locale' => 'equal', 'convertToPrimary' => false, ], - 'default_currency' => 'EUR', - 'default_language' => envNonEmpty('DEFAULT_LANGUAGE', 'en_US'), - 'default_locale' => envNonEmpty('DEFAULT_LOCALE', 'equal'), + 'default_currency' => 'EUR', + 'default_language' => envNonEmpty('DEFAULT_LANGUAGE', 'en_US'), + 'default_locale' => envNonEmpty('DEFAULT_LOCALE', 'equal'), // account types that may have or set a currency - 'valid_currency_account_types' => [ + 'valid_currency_account_types' => [ AccountTypeEnum::ASSET->value, AccountTypeEnum::LOAN->value, AccountTypeEnum::DEBT->value, @@ -208,7 +208,7 @@ return [ ], // "value must be in this list" values - 'valid_attachment_models' => [ + 'valid_attachment_models' => [ Account::class, Bill::class, Budget::class, @@ -219,11 +219,11 @@ return [ TransactionJournal::class, Recurrence::class, ], - 'available_dark_modes' => ['light', 'dark', 'browser'], - 'bill_reminder_periods' => [90, 30, 14, 7, 0], - 'valid_view_ranges' => ['1D', '1W', '1M', '3M', '6M', '1Y'], - 'valid_url_protocols' => envNonEmpty('VALID_URL_PROTOCOLS', 'http,https,ftp,ftps,mailto'), - 'allowedMimes' => [ + 'available_dark_modes' => ['light', 'dark', 'browser'], + 'bill_reminder_periods' => [90, 30, 14, 7, 0], + 'valid_view_ranges' => ['1D', '1W', '1M', '3M', '6M', '1Y'], + 'valid_url_protocols' => envNonEmpty('VALID_URL_PROTOCOLS', 'http,https,ftp,ftps,mailto'), + 'allowedMimes' => [ // plain files 'text/plain', 'text/html', @@ -303,17 +303,17 @@ return [ // JSON 'application/json', ], - 'accountRoles' => ['defaultAsset', 'sharedAsset', 'savingAsset', 'ccAsset', 'cashWalletAsset'], - 'valid_liabilities' => [AccountTypeEnum::DEBT->value, AccountTypeEnum::LOAN->value, AccountTypeEnum::MORTGAGE->value], - 'ccTypes' => ['monthlyFull' => 'Full payment every month'], - 'credit_card_types' => ['monthlyFull'], + 'accountRoles' => ['defaultAsset', 'sharedAsset', 'savingAsset', 'ccAsset', 'cashWalletAsset'], + 'valid_liabilities' => [AccountTypeEnum::DEBT->value, AccountTypeEnum::LOAN->value, AccountTypeEnum::MORTGAGE->value], + 'ccTypes' => ['monthlyFull' => 'Full payment every month'], + 'credit_card_types' => ['monthlyFull'], // "period must be in this list" values - 'bill_periods' => ['daily', 'weekly', 'monthly', 'quarterly', 'half-year', 'yearly'], - 'interest_periods' => ['daily', 'weekly', 'monthly', 'quarterly', 'half-year', 'yearly'], + 'bill_periods' => ['daily', 'weekly', 'monthly', 'quarterly', 'half-year', 'yearly'], + 'interest_periods' => ['daily', 'weekly', 'monthly', 'quarterly', 'half-year', 'yearly'], // settings to translate X to Y - 'range_to_repeat_freq' => [ + 'range_to_repeat_freq' => [ '1D' => 'weekly', '1W' => 'weekly', '1M' => 'monthly', @@ -322,7 +322,7 @@ return [ '1Y' => 'yearly', 'custom' => 'custom', ], - 'subTitlesByIdentifier' => [ + 'subTitlesByIdentifier' => [ 'asset' => 'Asset accounts', 'expense' => 'Expense accounts', 'revenue' => 'Revenue accounts', @@ -330,7 +330,7 @@ return [ 'liabilities' => 'Liabilities', 'liability' => 'Liabilities', ], - 'subIconsByIdentifier' => [ + 'subIconsByIdentifier' => [ 'asset' => 'fa-money', AccountTypeEnum::ASSET->value => 'fa-money', AccountTypeEnum::DEFAULT->value => 'fa-money', @@ -344,14 +344,14 @@ return [ AccountTypeEnum::IMPORT->value => 'fa-download', 'liabilities' => 'fa-ticket', ], - 'accountTypesByIdentifier' => [ + 'accountTypesByIdentifier' => [ 'asset' => [AccountTypeEnum::DEFAULT->value, AccountTypeEnum::ASSET->value], 'expense' => [AccountTypeEnum::EXPENSE->value, AccountTypeEnum::BENEFICIARY->value], 'revenue' => [AccountTypeEnum::REVENUE->value], 'import' => [AccountTypeEnum::IMPORT->value], 'liabilities' => [AccountTypeEnum::LOAN->value, AccountTypeEnum::DEBT->value, AccountTypeEnum::CREDITCARD->value, AccountTypeEnum::MORTGAGE->value], ], - 'accountTypeByIdentifier' => [ + 'accountTypeByIdentifier' => [ 'asset' => [AccountTypeEnum::ASSET->value], 'expense' => [AccountTypeEnum::EXPENSE->value], 'revenue' => [AccountTypeEnum::REVENUE->value], @@ -365,7 +365,7 @@ return [ 'liabilities' => [AccountTypeEnum::LOAN->value, AccountTypeEnum::DEBT->value, AccountTypeEnum::MORTGAGE->value, AccountTypeEnum::CREDITCARD->value], 'liability' => [AccountTypeEnum::LOAN->value, AccountTypeEnum::DEBT->value, AccountTypeEnum::MORTGAGE->value, AccountTypeEnum::CREDITCARD->value], ], - 'shortNamesByFullName' => [ + 'shortNamesByFullName' => [ AccountTypeEnum::DEFAULT->value => 'asset', AccountTypeEnum::ASSET->value => 'asset', AccountTypeEnum::IMPORT->value => 'import', @@ -380,13 +380,13 @@ return [ AccountTypeEnum::DEBT->value => 'liabilities', AccountTypeEnum::MORTGAGE->value => 'liabilities', ], - 'shortLiabilityNameByFullName' => [ + 'shortLiabilityNameByFullName' => [ AccountTypeEnum::CREDITCARD->value => 'creditcard', AccountTypeEnum::LOAN->value => AccountTypeEnum::LOAN->value, AccountTypeEnum::DEBT->value => AccountTypeEnum::DEBT->value, AccountTypeEnum::MORTGAGE->value => AccountTypeEnum::MORTGAGE->value, ], - 'transactionTypesByType' => [ + 'transactionTypesByType' => [ 'expenses' => ['Withdrawal'], 'withdrawal' => ['Withdrawal'], 'revenue' => ['Deposit'], @@ -394,14 +394,14 @@ return [ 'transfer' => ['Transfer'], 'transfers' => ['Transfer'], ], - 'transactionTypesToShort' => [ + 'transactionTypesToShort' => [ 'Withdrawal' => 'withdrawal', 'Deposit' => 'deposit', 'Transfer' => 'transfer', 'Opening balance' => 'opening-balance', 'Reconciliation' => 'reconciliation', ], - 'transactionIconsByType' => [ + 'transactionIconsByType' => [ 'expenses' => 'fa-long-arrow-left', 'withdrawal' => 'fa-long-arrow-left', 'revenue' => 'fa-long-arrow-right', @@ -411,7 +411,7 @@ return [ ], - 'rule-actions' => [ + 'rule-actions' => [ 'set_category' => SetCategory::class, 'clear_category' => ClearCategory::class, 'set_budget' => SetBudget::class, @@ -445,7 +445,7 @@ return [ // 'set_foreign_amount' => SetForeignAmount::class, // 'set_foreign_currency' => SetForeignCurrency::class, ], - 'context-rule-actions' => [ + 'context-rule-actions' => [ 'set_category', 'set_budget', 'add_tag', @@ -464,13 +464,13 @@ return [ 'convert_transfer', ], - 'test-triggers' => [ + 'test-triggers' => [ 'limit' => 10, 'range' => 200, ], // expected source types for each transaction type, in order of preference. - 'expected_source_types' => [ + 'expected_source_types' => [ 'source' => [ TransactionTypeEnum::WITHDRAWAL->value => [AccountTypeEnum::ASSET->value, AccountTypeEnum::LOAN->value, AccountTypeEnum::DEBT->value, AccountTypeEnum::MORTGAGE->value], TransactionTypeEnum::DEPOSIT->value => [AccountTypeEnum::LOAN->value, AccountTypeEnum::DEBT->value, AccountTypeEnum::MORTGAGE->value, AccountTypeEnum::REVENUE->value, AccountTypeEnum::CASH->value], @@ -515,7 +515,7 @@ return [ TransactionTypeEnum::LIABILITY_CREDIT->value => [AccountTypeEnum::LIABILITY_CREDIT->value, AccountTypeEnum::LOAN->value, AccountTypeEnum::DEBT->value, AccountTypeEnum::MORTGAGE->value], ], ], - 'allowed_opposing_types' => [ + 'allowed_opposing_types' => [ 'source' => [ AccountTypeEnum::ASSET->value => [ AccountTypeEnum::ASSET->value, @@ -605,7 +605,7 @@ return [ ], ], // depending on the account type, return the allowed transaction types: - 'allowed_transaction_types' => [ + 'allowed_transaction_types' => [ 'source' => [ AccountTypeEnum::ASSET->value => [ TransactionTypeEnum::WITHDRAWAL->value, @@ -674,7 +674,7 @@ return [ ], // having the source + dest will tell you the transaction type. - 'account_to_transaction' => [ + 'account_to_transaction' => [ AccountTypeEnum::ASSET->value => [ AccountTypeEnum::ASSET->value => TransactionTypeEnum::TRANSFER->value, AccountTypeEnum::CASH->value => TransactionTypeEnum::WITHDRAWAL->value, @@ -739,7 +739,7 @@ return [ ], // allowed source -> destination accounts. - 'source_dests' => [ + 'source_dests' => [ TransactionTypeEnum::WITHDRAWAL->value => [ AccountTypeEnum::ASSET->value => [AccountTypeEnum::EXPENSE->value, AccountTypeEnum::LOAN->value, AccountTypeEnum::DEBT->value, AccountTypeEnum::MORTGAGE->value, AccountTypeEnum::CASH->value], AccountTypeEnum::LOAN->value => [AccountTypeEnum::EXPENSE->value, AccountTypeEnum::CASH->value], @@ -778,7 +778,7 @@ return [ ], ], // if you add fields to this array, don't forget to update the export routine (ExportDataGenerator). - 'journal_meta_fields' => [ + 'journal_meta_fields' => [ // sepa 'sepa_cc', 'sepa_ct_op', @@ -812,26 +812,26 @@ return [ 'recurrence_count', 'recurrence_date', ], - 'webhooks' => [ + 'webhooks' => [ 'max_attempts' => env('WEBHOOK_MAX_ATTEMPTS', 3), ], - 'can_have_virtual_amounts' => [AccountTypeEnum::ASSET->value], - 'can_have_opening_balance' => [AccountTypeEnum::ASSET->value, AccountTypeEnum::LOAN->value, AccountTypeEnum::DEBT->value, AccountTypeEnum::MORTGAGE->value], - 'dynamic_creation_allowed' => [ + 'can_have_virtual_amounts' => [AccountTypeEnum::ASSET->value], + 'can_have_opening_balance' => [AccountTypeEnum::ASSET->value, AccountTypeEnum::LOAN->value, AccountTypeEnum::DEBT->value, AccountTypeEnum::MORTGAGE->value], + 'dynamic_creation_allowed' => [ AccountTypeEnum::EXPENSE->value, AccountTypeEnum::REVENUE->value, AccountTypeEnum::INITIAL_BALANCE->value, AccountTypeEnum::RECONCILIATION->value, AccountTypeEnum::LIABILITY_CREDIT->value, ], - 'valid_asset_fields' => ['account_role', 'account_number', 'currency_id', 'BIC', 'include_net_worth'], - 'valid_cc_fields' => ['account_role', 'cc_monthly_payment_date', 'cc_type', 'account_number', 'currency_id', 'BIC', 'include_net_worth'], - 'valid_account_fields' => ['account_number', 'currency_id', 'BIC', 'interest', 'interest_period', 'include_net_worth', 'liability_direction'], + 'valid_asset_fields' => ['account_role', 'account_number', 'currency_id', 'BIC', 'include_net_worth'], + 'valid_cc_fields' => ['account_role', 'cc_monthly_payment_date', 'cc_type', 'account_number', 'currency_id', 'BIC', 'include_net_worth'], + 'valid_account_fields' => ['account_number', 'currency_id', 'BIC', 'interest', 'interest_period', 'include_net_worth', 'liability_direction'], // dynamic date ranges are as follows: - 'dynamic_date_ranges' => ['last7', 'last30', 'last90', 'last365', 'MTD', 'QTD', 'YTD'], + 'dynamic_date_ranges' => ['last7', 'last30', 'last90', 'last365', 'MTD', 'QTD', 'YTD'], - 'allowed_sort_parameters' => [ + 'allowed_sort_parameters' => [ 'Account' => ['id', 'order', 'name', 'iban', 'active', 'account_type_id', 'current_balance', 'pc_current_balance', @@ -845,14 +845,14 @@ return [ 'pc_balance_difference', ], ], - 'allowed_db_sort_parameters' => [ + 'allowed_db_sort_parameters' => [ 'Account' => ['id', 'order', 'name', 'iban', 'active', 'account_type_id'], ], // preselected account lists possibilities: - 'preselected_accounts' => ['all', 'assets', 'liabilities'], + 'preselected_accounts' => ['all', 'assets', 'liabilities'], // allowed to store a piggy bank in: - 'piggy_bank_account_types' => [AccountTypeEnum::ASSET->value, AccountTypeEnum::LOAN->value, AccountTypeEnum::DEBT->value, AccountTypeEnum::MORTGAGE->value], + 'piggy_bank_account_types' => [AccountTypeEnum::ASSET->value, AccountTypeEnum::LOAN->value, AccountTypeEnum::DEBT->value, AccountTypeEnum::MORTGAGE->value], ]; From 0bc2d40d9b011266e5b6a9597759b54b6439b3db Mon Sep 17 00:00:00 2001 From: James Cole Date: Tue, 4 Nov 2025 20:48:58 +0100 Subject: [PATCH 20/29] Don't throw error, report it. --- app/Http/Controllers/AttachmentController.php | 11 ++--- .../Auth/ForgotPasswordController.php | 4 +- .../Controllers/Auth/RegisterController.php | 6 +-- .../Auth/ResetPasswordController.php | 4 +- app/Http/Controllers/ReportController.php | 12 +++--- .../views/{error.twig => error-old.twig} | 0 resources/views/errors/error.blade.php | 42 +++++++++++++++++++ 7 files changed, 61 insertions(+), 18 deletions(-) rename resources/views/{error.twig => error-old.twig} (100%) create mode 100644 resources/views/errors/error.blade.php diff --git a/app/Http/Controllers/AttachmentController.php b/app/Http/Controllers/AttachmentController.php index 2741d94812..6e7e573e98 100644 --- a/app/Http/Controllers/AttachmentController.php +++ b/app/Http/Controllers/AttachmentController.php @@ -95,7 +95,7 @@ class AttachmentController extends Controller /** * Download attachment to PC. * - * @return LaravelResponse + * @return LaravelResponse|View * * @throws FireflyException */ @@ -121,8 +121,8 @@ class AttachmentController extends Controller return $response; } - - throw new FireflyException('Could not find the indicated attachment. The file is no longer there.'); + $message = 'Could not find the indicated attachment. The file is no longer there.'; + return view('errors.error', compact('message')); } /** @@ -194,7 +194,7 @@ class AttachmentController extends Controller * * @throws FireflyException */ - public function view(Attachment $attachment): LaravelResponse + public function view(Attachment $attachment): LaravelResponse|View { if ($this->repository->exists($attachment)) { $content = $this->repository->getContent($attachment); @@ -223,6 +223,7 @@ class AttachmentController extends Controller ); } - throw new FireflyException('Could not find the indicated attachment. The file is no longer there.'); + $message = 'Could not find the indicated attachment. The file is no longer there.'; + return view('errors.error', compact('message')); } } diff --git a/app/Http/Controllers/Auth/ForgotPasswordController.php b/app/Http/Controllers/Auth/ForgotPasswordController.php index a945fc7879..d3f996c6f4 100644 --- a/app/Http/Controllers/Auth/ForgotPasswordController.php +++ b/app/Http/Controllers/Auth/ForgotPasswordController.php @@ -73,7 +73,7 @@ class ForgotPasswordController extends Controller $message = sprintf('Cannot reset password when authenticating over "%s".', config('firefly.authentication_guard')); Log::error($message); - return view('error', compact('message')); + return view('errors.error', compact('message')); } // validate host header. @@ -138,7 +138,7 @@ class ForgotPasswordController extends Controller if ('web' !== config('firefly.authentication_guard')) { $message = sprintf('Cannot reset password when authenticating over "%s".', config('firefly.authentication_guard')); - return view('error', compact('message')); + return view('errors.error', compact('message')); } // is allowed to? diff --git a/app/Http/Controllers/Auth/RegisterController.php b/app/Http/Controllers/Auth/RegisterController.php index a36e65e8bc..ea1e8619f1 100644 --- a/app/Http/Controllers/Auth/RegisterController.php +++ b/app/Http/Controllers/Auth/RegisterController.php @@ -158,12 +158,12 @@ class RegisterController extends Controller if (true === $allowRegistration) { $message = 'You do not need an invite code on this installation.'; - return view('error', compact('message')); + return view('errors.error', compact('message')); } if (false === $validCode) { $message = 'Invalid code.'; - return view('error', compact('message')); + return view('errors.error', compact('message')); } $email = $request->old('email'); @@ -189,7 +189,7 @@ class RegisterController extends Controller if (false === $allowRegistration) { $message = 'Registration is currently not available. If you are the administrator, you can enable this in the administration.'; - return view('error', compact('message')); + return view('errors.error', compact('message')); } $email = $request?->old('email'); diff --git a/app/Http/Controllers/Auth/ResetPasswordController.php b/app/Http/Controllers/Auth/ResetPasswordController.php index 714d98bf32..b52ae8e0e7 100644 --- a/app/Http/Controllers/Auth/ResetPasswordController.php +++ b/app/Http/Controllers/Auth/ResetPasswordController.php @@ -80,7 +80,7 @@ class ResetPasswordController extends Controller if ('web' !== config('firefly.authentication_guard')) { $message = sprintf('Cannot reset password when authenticating over "%s".', config('firefly.authentication_guard')); - return view('error', compact('message')); + return view('errors.error', compact('message')); } $rules = [ @@ -127,7 +127,7 @@ class ResetPasswordController extends Controller if ('web' !== config('firefly.authentication_guard')) { $message = sprintf('Cannot reset password when authenticating over "%s".', config('firefly.authentication_guard')); - return view('error', compact('message')); + return view('errors.error', compact('message')); } // is allowed to register? diff --git a/app/Http/Controllers/ReportController.php b/app/Http/Controllers/ReportController.php index eb82e859d9..46506681d6 100644 --- a/app/Http/Controllers/ReportController.php +++ b/app/Http/Controllers/ReportController.php @@ -82,7 +82,7 @@ class ReportController extends Controller public function auditReport(Collection $accounts, Carbon $start, Carbon $end) { if ($end < $start) { - return view('error')->with('message', (string) trans('firefly.end_after_start_date')); + return view('errors.error')->with('message', (string) trans('firefly.end_after_start_date')); } $this->repository->cleanupBudgets(); $start->endOfDay(); // end of day so the final balance is at the end of that day. @@ -115,7 +115,7 @@ class ReportController extends Controller public function budgetReport(Collection $accounts, Collection $budgets, Carbon $start, Carbon $end) { if ($end < $start) { - return view('error')->with('message', (string) trans('firefly.end_after_start_date')); + return view('errors.error')->with('message', (string) trans('firefly.end_after_start_date')); } $this->repository->cleanupBudgets(); $start->endOfDay(); // end of day so the final balance is at the end of that day. @@ -149,7 +149,7 @@ class ReportController extends Controller public function categoryReport(Collection $accounts, Collection $categories, Carbon $start, Carbon $end) { if ($end < $start) { - return view('error')->with('message', (string) trans('firefly.end_after_start_date')); + return view('errors.error')->with('message', (string) trans('firefly.end_after_start_date')); } $this->repository->cleanupBudgets(); $start->endOfDay(); // end of day so the final balance is at the end of that day. @@ -183,7 +183,7 @@ class ReportController extends Controller public function defaultReport(Collection $accounts, Carbon $start, Carbon $end) { if ($end < $start) { - return view('error')->with('message', (string) trans('firefly.end_after_start_date')); + return view('errors.error')->with('message', (string) trans('firefly.end_after_start_date')); } $this->repository->cleanupBudgets(); @@ -336,7 +336,7 @@ class ReportController extends Controller } if ($request->getEndDate() < $request->getStartDate()) { - return view('error')->with('message', (string) trans('firefly.end_after_start_date')); + return view('errors.error')->with('message', (string) trans('firefly.end_after_start_date')); } $url = match ($reportType) { @@ -361,7 +361,7 @@ class ReportController extends Controller public function tagReport(Collection $accounts, Collection $tags, Carbon $start, Carbon $end) { if ($end < $start) { - return view('error')->with('message', (string) trans('firefly.end_after_start_date')); + return view('errors.error')->with('message', (string) trans('firefly.end_after_start_date')); } $this->repository->cleanupBudgets(); $start->endOfDay(); // end of day so the final balance is at the end of that day. diff --git a/resources/views/error.twig b/resources/views/error-old.twig similarity index 100% rename from resources/views/error.twig rename to resources/views/error-old.twig diff --git a/resources/views/errors/error.blade.php b/resources/views/errors/error.blade.php new file mode 100644 index 0000000000..12a061bfce --- /dev/null +++ b/resources/views/errors/error.blade.php @@ -0,0 +1,42 @@ +@extends('layout.v2.error') +@section('status_code','') +@section('status','Error message') +@section('sub_title', trans('errors.error_occurred')) +@section('content') +
+
+

+ {{ trans('errors.error_not_recoverable') }} +

+

+ {{ $message }} +

+
+
+
+
+

+ {{ trans('errors.more_info') }} +

+

+ {!! trans('errors.collect_info') !!} + {!! trans('errors.collect_info_more') !!} +

+

+ {{ trans('errors.github_help') }} +

+

+ {!! trans('errors.github_instructions') !!} +

+
    +
  1. {{ trans('errors.use_search') }}
  2. +
  3. {!! trans('errors.include_info', ['link' => route('debug') ]) !!}
  4. +
  5. {{ trans('errors.tell_more') }}
  6. +
  7. {{ trans('errors.include_logs') }}
  8. +
  9. {{ trans('errors.what_did_you_do') }}
  10. +
+
+
+@endsection + + From e0153dd33f105d61e06412c9760c15d703d755aa Mon Sep 17 00:00:00 2001 From: James Cole Date: Thu, 6 Nov 2025 06:17:59 +0100 Subject: [PATCH 21/29] Fix https://github.com/firefly-iii/firefly-iii/issues/11177 --- app/Models/RuleGroup.php | 2 ++ app/Repositories/RuleGroup/RuleGroupRepository.php | 2 +- 2 files changed, 3 insertions(+), 1 deletion(-) diff --git a/app/Models/RuleGroup.php b/app/Models/RuleGroup.php index 514d4d222e..1f0deafb58 100644 --- a/app/Models/RuleGroup.php +++ b/app/Models/RuleGroup.php @@ -33,10 +33,12 @@ 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\Collection; use Symfony\Component\HttpKernel\Exception\NotFoundHttpException; /** * @property User $user + * @property Collection $rules */ #[ObservedBy([RuleGroupObserver::class])] class RuleGroup extends Model diff --git a/app/Repositories/RuleGroup/RuleGroupRepository.php b/app/Repositories/RuleGroup/RuleGroupRepository.php index 8ef670d2b2..45557e6a2b 100644 --- a/app/Repositories/RuleGroup/RuleGroupRepository.php +++ b/app/Repositories/RuleGroup/RuleGroupRepository.php @@ -263,7 +263,7 @@ class RuleGroupRepository implements RuleGroupRepositoryInterface, UserGroupInte [ // @phpstan-ignore-line 'rules' => static function (HasMany $query): void { $query->orderBy('order', 'ASC'); - $query->where('rules.active', true); + // $query->where('rules.active', true); }, 'rules.ruleTriggers' => static function (HasMany $query): void { $query->orderBy('order', 'ASC'); From d2b15734cc1eca73c772c1289cb95f9343a78387 Mon Sep 17 00:00:00 2001 From: James Cole Date: Thu, 6 Nov 2025 06:18:07 +0100 Subject: [PATCH 22/29] Fix account list filter. --- app/Api/V1/Controllers/Models/Account/ShowController.php | 1 - app/Api/V1/Requests/Models/Account/ShowRequest.php | 2 +- 2 files changed, 1 insertion(+), 2 deletions(-) diff --git a/app/Api/V1/Controllers/Models/Account/ShowController.php b/app/Api/V1/Controllers/Models/Account/ShowController.php index 5616869a8d..4e979c84ba 100644 --- a/app/Api/V1/Controllers/Models/Account/ShowController.php +++ b/app/Api/V1/Controllers/Models/Account/ShowController.php @@ -82,7 +82,6 @@ class ShowController extends Controller 'date' => $date, ] = $request->attributes->all(); - // get list of accounts. Count it and split it. $this->repository->resetAccountOrder(); $collection = $this->repository->getAccountsByType($types, $sort); diff --git a/app/Api/V1/Requests/Models/Account/ShowRequest.php b/app/Api/V1/Requests/Models/Account/ShowRequest.php index 0d7b5f3d1e..cdbbeae60b 100644 --- a/app/Api/V1/Requests/Models/Account/ShowRequest.php +++ b/app/Api/V1/Requests/Models/Account/ShowRequest.php @@ -39,7 +39,7 @@ class ShowRequest extends AggregateFormRequest DateRangeRequest::class, DateRequest::class, AccountTypeApiRequest::class, - [ObjectTypeApiRequest::class, 'object_type' => Account::class], + //[ObjectTypeApiRequest::class, 'object_type' => Account::class], ]; } } From cf1c7262cd1377b8a9eed30c8f7d325ef573e011 Mon Sep 17 00:00:00 2001 From: JC5 Date: Thu, 6 Nov 2025 06:23:01 +0100 Subject: [PATCH 23/29] =?UTF-8?q?=F0=9F=A4=96=20Auto=20commit=20for=20rele?= =?UTF-8?q?ase=20'develop'=20on=202025-11-06?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../Requests/Models/Account/ShowRequest.php | 2 +- app/Http/Controllers/AttachmentController.php | 2 + app/Models/RuleGroup.php | 2 +- composer.lock | 97 +++++++++++++++---- config/firefly.php | 4 +- package-lock.json | 84 ++++++++-------- 6 files changed, 126 insertions(+), 65 deletions(-) diff --git a/app/Api/V1/Requests/Models/Account/ShowRequest.php b/app/Api/V1/Requests/Models/Account/ShowRequest.php index cdbbeae60b..b9abe7957b 100644 --- a/app/Api/V1/Requests/Models/Account/ShowRequest.php +++ b/app/Api/V1/Requests/Models/Account/ShowRequest.php @@ -39,7 +39,7 @@ class ShowRequest extends AggregateFormRequest DateRangeRequest::class, DateRequest::class, AccountTypeApiRequest::class, - //[ObjectTypeApiRequest::class, 'object_type' => Account::class], + // [ObjectTypeApiRequest::class, 'object_type' => Account::class], ]; } } diff --git a/app/Http/Controllers/AttachmentController.php b/app/Http/Controllers/AttachmentController.php index 6e7e573e98..d1cdfa9a58 100644 --- a/app/Http/Controllers/AttachmentController.php +++ b/app/Http/Controllers/AttachmentController.php @@ -122,6 +122,7 @@ class AttachmentController extends Controller return $response; } $message = 'Could not find the indicated attachment. The file is no longer there.'; + return view('errors.error', compact('message')); } @@ -224,6 +225,7 @@ class AttachmentController extends Controller } $message = 'Could not find the indicated attachment. The file is no longer there.'; + return view('errors.error', compact('message')); } } diff --git a/app/Models/RuleGroup.php b/app/Models/RuleGroup.php index 1f0deafb58..16c87815bd 100644 --- a/app/Models/RuleGroup.php +++ b/app/Models/RuleGroup.php @@ -37,7 +37,7 @@ use Illuminate\Support\Collection; use Symfony\Component\HttpKernel\Exception\NotFoundHttpException; /** - * @property User $user + * @property User $user * @property Collection $rules */ #[ObservedBy([RuleGroupObserver::class])] diff --git a/composer.lock b/composer.lock index 790f7a9f12..757e217764 100644 --- a/composer.lock +++ b/composer.lock @@ -1937,16 +1937,16 @@ }, { "name": "laravel/framework", - "version": "v12.36.1", + "version": "v12.37.0", "source": { "type": "git", "url": "https://github.com/laravel/framework.git", - "reference": "cad110d7685fbab990a6bb8184d0cfd847d7c4d8" + "reference": "3c3c4ad30f5b528b164a7c09aa4ad03118c4c125" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/laravel/framework/zipball/cad110d7685fbab990a6bb8184d0cfd847d7c4d8", - "reference": "cad110d7685fbab990a6bb8184d0cfd847d7c4d8", + "url": "https://api.github.com/repos/laravel/framework/zipball/3c3c4ad30f5b528b164a7c09aa4ad03118c4c125", + "reference": "3c3c4ad30f5b528b164a7c09aa4ad03118c4c125", "shasum": "" }, "require": { @@ -2152,7 +2152,7 @@ "issues": "https://github.com/laravel/framework/issues", "source": "https://github.com/laravel/framework" }, - "time": "2025-10-29T14:20:57+00:00" + "time": "2025-11-04T15:39:33+00:00" }, { "name": "laravel/passport", @@ -5965,16 +5965,16 @@ }, { "name": "sentry/sentry", - "version": "4.17.1", + "version": "4.18.0", "source": { "type": "git", "url": "https://github.com/getsentry/sentry-php.git", - "reference": "5c696b8de57e841a2bf3b6f6eecfd99acfdda80c" + "reference": "75f7efb7d435d24767c93d0081b8edf228be5772" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/getsentry/sentry-php/zipball/5c696b8de57e841a2bf3b6f6eecfd99acfdda80c", - "reference": "5c696b8de57e841a2bf3b6f6eecfd99acfdda80c", + "url": "https://api.github.com/repos/getsentry/sentry-php/zipball/75f7efb7d435d24767c93d0081b8edf228be5772", + "reference": "75f7efb7d435d24767c93d0081b8edf228be5772", "shasum": "" }, "require": { @@ -5985,7 +5985,7 @@ "jean85/pretty-package-versions": "^1.5|^2.0.4", "php": "^7.2|^8.0", "psr/log": "^1.0|^2.0|^3.0", - "symfony/options-resolver": "^4.4.30|^5.0.11|^6.0|^7.0" + "symfony/options-resolver": "^4.4.30|^5.0.11|^6.0|^7.0|^8.0" }, "conflict": { "raven/raven": "*" @@ -6037,7 +6037,7 @@ ], "support": { "issues": "https://github.com/getsentry/sentry-php/issues", - "source": "https://github.com/getsentry/sentry-php/tree/4.17.1" + "source": "https://github.com/getsentry/sentry-php/tree/4.18.0" }, "funding": [ { @@ -6049,7 +6049,7 @@ "type": "custom" } ], - "time": "2025-10-23T15:19:24+00:00" + "time": "2025-11-05T14:37:07+00:00" }, { "name": "sentry/sentry-laravel", @@ -10730,21 +10730,22 @@ }, { "name": "driftingly/rector-laravel", - "version": "2.1.2", + "version": "2.1.3", "source": { "type": "git", "url": "https://github.com/driftingly/rector-laravel.git", - "reference": "d7cd932cff9e398a43393f1a1a63b27d574e35ef" + "reference": "2f1e9c3997bf45592d58916f0cedd775e844b9c6" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/driftingly/rector-laravel/zipball/d7cd932cff9e398a43393f1a1a63b27d574e35ef", - "reference": "d7cd932cff9e398a43393f1a1a63b27d574e35ef", + "url": "https://api.github.com/repos/driftingly/rector-laravel/zipball/2f1e9c3997bf45592d58916f0cedd775e844b9c6", + "reference": "2f1e9c3997bf45592d58916f0cedd775e844b9c6", "shasum": "" }, "require": { "php": "^7.4 || ^8.0", - "rector/rector": "^2.2.7" + "rector/rector": "^2.2.7", + "webmozart/assert": "^1.11" }, "type": "rector-extension", "autoload": { @@ -10759,9 +10760,9 @@ "description": "Rector upgrades rules for Laravel Framework", "support": { "issues": "https://github.com/driftingly/rector-laravel/issues", - "source": "https://github.com/driftingly/rector-laravel/tree/2.1.2" + "source": "https://github.com/driftingly/rector-laravel/tree/2.1.3" }, - "time": "2025-10-31T21:56:58+00:00" + "time": "2025-11-04T18:32:57+00:00" }, { "name": "fakerphp/faker", @@ -13216,6 +13217,64 @@ } ], "time": "2024-03-03T12:36:25+00:00" + }, + { + "name": "webmozart/assert", + "version": "1.12.1", + "source": { + "type": "git", + "url": "https://github.com/webmozarts/assert.git", + "reference": "9be6926d8b485f55b9229203f962b51ed377ba68" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/webmozarts/assert/zipball/9be6926d8b485f55b9229203f962b51ed377ba68", + "reference": "9be6926d8b485f55b9229203f962b51ed377ba68", + "shasum": "" + }, + "require": { + "ext-ctype": "*", + "ext-date": "*", + "ext-filter": "*", + "php": "^7.2 || ^8.0" + }, + "suggest": { + "ext-intl": "", + "ext-simplexml": "", + "ext-spl": "" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "1.10-dev" + } + }, + "autoload": { + "psr-4": { + "Webmozart\\Assert\\": "src/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Bernhard Schussek", + "email": "bschussek@gmail.com" + } + ], + "description": "Assertions to validate method input/output with nice error messages.", + "keywords": [ + "assert", + "check", + "validate" + ], + "support": { + "issues": "https://github.com/webmozarts/assert/issues", + "source": "https://github.com/webmozarts/assert/tree/1.12.1" + }, + "time": "2025-10-29T15:56:20+00:00" } ], "aliases": [], diff --git a/config/firefly.php b/config/firefly.php index b6551e9b17..9c548983ce 100644 --- a/config/firefly.php +++ b/config/firefly.php @@ -78,8 +78,8 @@ return [ 'running_balance_column' => env('USE_RUNNING_BALANCE', false), // see cer.php for exchange rates feature flag. ], - 'version' => 'develop/2025-11-04', - 'build_time' => 1762231951, + 'version' => 'develop/2025-11-06', + 'build_time' => 1762406472, 'api_version' => '2.1.0', // field is no longer used. 'db_version' => 28, // field is no longer used. diff --git a/package-lock.json b/package-lock.json index d93e5609f9..b0d8029ba1 100644 --- a/package-lock.json +++ b/package-lock.json @@ -3291,57 +3291,57 @@ } }, "node_modules/@vue/compiler-core": { - "version": "3.5.22", - "resolved": "https://registry.npmjs.org/@vue/compiler-core/-/compiler-core-3.5.22.tgz", - "integrity": "sha512-jQ0pFPmZwTEiRNSb+i9Ow/I/cHv2tXYqsnHKKyCQ08irI2kdF5qmYedmF8si8mA7zepUFmJ2hqzS8CQmNOWOkQ==", + "version": "3.5.23", + "resolved": "https://registry.npmjs.org/@vue/compiler-core/-/compiler-core-3.5.23.tgz", + "integrity": "sha512-nW7THWj5HOp085ROk65LwaoxuzDsjIxr485F4iu63BoxsXoSqKqmsUUoP4A7Gl67DgIgi0zJ8JFgHfvny/74MA==", "dev": true, "license": "MIT", "dependencies": { - "@babel/parser": "^7.28.4", - "@vue/shared": "3.5.22", + "@babel/parser": "^7.28.5", + "@vue/shared": "3.5.23", "entities": "^4.5.0", "estree-walker": "^2.0.2", "source-map-js": "^1.2.1" } }, "node_modules/@vue/compiler-dom": { - "version": "3.5.22", - "resolved": "https://registry.npmjs.org/@vue/compiler-dom/-/compiler-dom-3.5.22.tgz", - "integrity": "sha512-W8RknzUM1BLkypvdz10OVsGxnMAuSIZs9Wdx1vzA3mL5fNMN15rhrSCLiTm6blWeACwUwizzPVqGJgOGBEN/hA==", + "version": "3.5.23", + "resolved": "https://registry.npmjs.org/@vue/compiler-dom/-/compiler-dom-3.5.23.tgz", + "integrity": "sha512-AT8RMw0vEzzzO0JU5gY0F6iCzaWUIh/aaRVordzMBKXRpoTllTT4kocHDssByPsvodNCfump/Lkdow2mT/O5KQ==", "dev": true, "license": "MIT", "dependencies": { - "@vue/compiler-core": "3.5.22", - "@vue/shared": "3.5.22" + "@vue/compiler-core": "3.5.23", + "@vue/shared": "3.5.23" } }, "node_modules/@vue/compiler-sfc": { - "version": "3.5.22", - "resolved": "https://registry.npmjs.org/@vue/compiler-sfc/-/compiler-sfc-3.5.22.tgz", - "integrity": "sha512-tbTR1zKGce4Lj+JLzFXDq36K4vcSZbJ1RBu8FxcDv1IGRz//Dh2EBqksyGVypz3kXpshIfWKGOCcqpSbyGWRJQ==", + "version": "3.5.23", + "resolved": "https://registry.npmjs.org/@vue/compiler-sfc/-/compiler-sfc-3.5.23.tgz", + "integrity": "sha512-3QTEUo4qg7FtQwaDJa8ou1CUikx5WTtZlY61rRRDu3lK2ZKrGoAGG8mvDgOpDsQ4A1bez9s+WtBB6DS2KuFCPw==", "dev": true, "license": "MIT", "dependencies": { - "@babel/parser": "^7.28.4", - "@vue/compiler-core": "3.5.22", - "@vue/compiler-dom": "3.5.22", - "@vue/compiler-ssr": "3.5.22", - "@vue/shared": "3.5.22", + "@babel/parser": "^7.28.5", + "@vue/compiler-core": "3.5.23", + "@vue/compiler-dom": "3.5.23", + "@vue/compiler-ssr": "3.5.23", + "@vue/shared": "3.5.23", "estree-walker": "^2.0.2", - "magic-string": "^0.30.19", + "magic-string": "^0.30.21", "postcss": "^8.5.6", "source-map-js": "^1.2.1" } }, "node_modules/@vue/compiler-ssr": { - "version": "3.5.22", - "resolved": "https://registry.npmjs.org/@vue/compiler-ssr/-/compiler-ssr-3.5.22.tgz", - "integrity": "sha512-GdgyLvg4R+7T8Nk2Mlighx7XGxq/fJf9jaVofc3IL0EPesTE86cP/8DD1lT3h1JeZr2ySBvyqKQJgbS54IX1Ww==", + "version": "3.5.23", + "resolved": "https://registry.npmjs.org/@vue/compiler-ssr/-/compiler-ssr-3.5.23.tgz", + "integrity": "sha512-Hld2xphbMjXs9Q9WKxPf2EqmE+Rq/FEDnK/wUBtmYq74HCV4XDdSCheAaB823OQXIIFGq9ig/RbAZkF9s4U0Ow==", "dev": true, "license": "MIT", "dependencies": { - "@vue/compiler-dom": "3.5.22", - "@vue/shared": "3.5.22" + "@vue/compiler-dom": "3.5.23", + "@vue/shared": "3.5.23" } }, "node_modules/@vue/component-compiler-utils": { @@ -3423,9 +3423,9 @@ "license": "MIT" }, "node_modules/@vue/shared": { - "version": "3.5.22", - "resolved": "https://registry.npmjs.org/@vue/shared/-/shared-3.5.22.tgz", - "integrity": "sha512-F4yc6palwq3TT0u+FYf0Ns4Tfl9GRFURDN2gWG7L1ecIaS/4fCIuFOjMTnCyjsu/OK6vaDKLCrGAa+KvvH+h4w==", + "version": "3.5.23", + "resolved": "https://registry.npmjs.org/@vue/shared/-/shared-3.5.23.tgz", + "integrity": "sha512-0YZ1DYuC5o/YJPf6pFdt2KYxVGDxkDbH/1NYJnVJWUkzr8ituBEmFVQRNX2gCaAsFEjEDnLkWpgqlZA7htgS/g==", "dev": true, "license": "MIT" }, @@ -3963,9 +3963,9 @@ } }, "node_modules/axios": { - "version": "1.13.1", - "resolved": "https://registry.npmjs.org/axios/-/axios-1.13.1.tgz", - "integrity": "sha512-hU4EGxxt+j7TQijx1oYdAjw4xuIp1wRQSsbMFwSthCWeBQur1eF+qJ5iQ5sN3Tw8YRzQNKb8jszgBdMDVqwJcw==", + "version": "1.13.2", + "resolved": "https://registry.npmjs.org/axios/-/axios-1.13.2.tgz", + "integrity": "sha512-VPk9ebNqPcy5lRGuSlKx752IlDatOjT9paPlm8A7yOuW2Fbvp4X3JznJtT4f0GzGLLiWE9W8onz51SqLYwzGaA==", "dev": true, "license": "MIT", "dependencies": { @@ -4075,9 +4075,9 @@ "license": "MIT" }, "node_modules/baseline-browser-mapping": { - "version": "2.8.23", - "resolved": "https://registry.npmjs.org/baseline-browser-mapping/-/baseline-browser-mapping-2.8.23.tgz", - "integrity": "sha512-616V5YX4bepJFzNyOfce5Fa8fDJMfoxzOIzDCZwaGL8MKVpFrXqfNUoIpRn9YMI5pXf/VKgzjB4htFMsFKKdiQ==", + "version": "2.8.25", + "resolved": "https://registry.npmjs.org/baseline-browser-mapping/-/baseline-browser-mapping-2.8.25.tgz", + "integrity": "sha512-2NovHVesVF5TXefsGX1yzx1xgr7+m9JQenvz6FQY3qd+YXkKkYiv+vTCc7OriP9mcDZpTC5mAOYN4ocd29+erA==", "dev": true, "license": "Apache-2.0", "bin": { @@ -5736,9 +5736,9 @@ "license": "MIT" }, "node_modules/electron-to-chromium": { - "version": "1.5.244", - "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.5.244.tgz", - "integrity": "sha512-OszpBN7xZX4vWMPJwB9illkN/znA8M36GQqQxi6MNy9axWxhOfJyZZJtSLQCpEFLHP2xK33BiWx9aIuIEXVCcw==", + "version": "1.5.245", + "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.5.245.tgz", + "integrity": "sha512-rdmGfW47ZhL/oWEJAY4qxRtdly2B98ooTJ0pdEI4jhVLZ6tNf8fPtov2wS1IRKwFJT92le3x4Knxiwzl7cPPpQ==", "dev": true, "license": "ISC" }, @@ -11008,9 +11008,9 @@ } }, "node_modules/terser": { - "version": "5.44.0", - "resolved": "https://registry.npmjs.org/terser/-/terser-5.44.0.tgz", - "integrity": "sha512-nIVck8DK+GM/0Frwd+nIhZ84pR/BX7rmXMfYwyg+Sri5oGVE99/E3KvXqpC2xHFxyqXyGHTKBSioxxplrO4I4w==", + "version": "5.44.1", + "resolved": "https://registry.npmjs.org/terser/-/terser-5.44.1.tgz", + "integrity": "sha512-t/R3R/n0MSwnnazuPpPNVO60LX0SKL45pyl9YlvxIdkH0Of7D5qM2EVe+yASRIlY5pZ73nclYJfNANGWPwFDZw==", "dev": true, "license": "BSD-2-Clause", "dependencies": { @@ -11517,9 +11517,9 @@ } }, "node_modules/vite": { - "version": "7.1.12", - "resolved": "https://registry.npmjs.org/vite/-/vite-7.1.12.tgz", - "integrity": "sha512-ZWyE8YXEXqJrrSLvYgrRP7p62OziLW7xI5HYGWFzOvupfAlrLvURSzv/FyGyy0eidogEM3ujU+kUG1zuHgb6Ug==", + "version": "7.2.1", + "resolved": "https://registry.npmjs.org/vite/-/vite-7.2.1.tgz", + "integrity": "sha512-qTl3VF7BvOupTR85Zc561sPEgxyUSNSvTQ9fit7DEMP7yPgvvIGm5Zfa1dOM+kOwWGNviK9uFM9ra77+OjK7lQ==", "dev": true, "license": "MIT", "dependencies": { From 49d3b11f86ba73e55f246e44d29821cf571b0253 Mon Sep 17 00:00:00 2001 From: James Cole Date: Fri, 7 Nov 2025 19:50:10 +0100 Subject: [PATCH 24/29] Update changelog. --- changelog.md | 1 + 1 file changed, 1 insertion(+) diff --git a/changelog.md b/changelog.md index f3edb0b596..edd3a6e4dd 100644 --- a/changelog.md +++ b/changelog.md @@ -8,6 +8,7 @@ This project adheres to [Semantic Versioning](http://semver.org/). ### Fixed - [Issue 11157](https://github.com/firefly-iii/firefly-iii/issues/11157) (Redacted amounts misbehave with Reports) reported by @barreeeiroo +- #11185 ## 6.4.4 - 2025-11-02 From 33e6a44d6f77ef9c9bee404a31ecb1593fe8c26f Mon Sep 17 00:00:00 2001 From: James Cole Date: Fri, 7 Nov 2025 20:37:48 +0100 Subject: [PATCH 25/29] Add some debug to find rules that stop. --- app/Repositories/RuleGroup/RuleGroupRepository.php | 8 ++++---- app/TransactionRules/Engine/SearchRuleEngine.php | 2 +- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/app/Repositories/RuleGroup/RuleGroupRepository.php b/app/Repositories/RuleGroup/RuleGroupRepository.php index 45557e6a2b..37b6066a64 100644 --- a/app/Repositories/RuleGroup/RuleGroupRepository.php +++ b/app/Repositories/RuleGroup/RuleGroupRepository.php @@ -284,11 +284,11 @@ class RuleGroupRepository implements RuleGroupRepositoryInterface, UserGroupInte Log::debug(sprintf('Now filtering group #%d', $group->id)); // filter the rules in the rule group: $group->rules = $group->rules->filter( - static function (Rule $rule) use ($filter) { + static function (Rule $rule) use ($filter, $group) { 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)); + Log::debug(sprintf('Rule #%d triggers on %s, include it in rule group #%d.', $rule->id, $filter, $group->id)); return true; } @@ -341,11 +341,11 @@ class RuleGroupRepository implements RuleGroupRepositoryInterface, UserGroupInte Log::debug(sprintf('Now filtering group #%d', $group->id)); // filter the rules in the rule group: $group->rules = $group->rules->filter( - static function (Rule $rule) use ($filter) { + static function (Rule $rule) use ($filter, $group) { 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)); + Log::debug(sprintf('Rule #%d triggers on %s, include it in rule group #%d.', $rule->id, $filter, $group->id)); return true; } diff --git a/app/TransactionRules/Engine/SearchRuleEngine.php b/app/TransactionRules/Engine/SearchRuleEngine.php index 72f7228f20..5861cf888f 100644 --- a/app/TransactionRules/Engine/SearchRuleEngine.php +++ b/app/TransactionRules/Engine/SearchRuleEngine.php @@ -278,7 +278,7 @@ class SearchRuleEngine implements RuleEngineInterface ++$count; // if trigger says stop processing, do so. if (true === $ruleTrigger->stop_processing && $result->count() > 0) { - Log::debug('The trigger says to stop processing, so stop processing other triggers.'); + Log::debug('The trigger in this rule trigger says to stop processing, so stop processing other triggers.'); break; } From 7266a2315d664686719b5a685805ef0f29f85e17 Mon Sep 17 00:00:00 2001 From: JC5 Date: Fri, 7 Nov 2025 21:07:01 +0100 Subject: [PATCH 26/29] =?UTF-8?q?=F0=9F=A4=96=20Auto=20commit=20for=20rele?= =?UTF-8?q?ase=20'develop'=20on=202025-11-07?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .ci/php-cs-fixer/composer.lock | 54 +++---- changelog.md | 2 +- composer.lock | 132 +++++++++-------- config/firefly.php | 4 +- package-lock.json | 255 +++++++++++++++++---------------- 5 files changed, 232 insertions(+), 215 deletions(-) diff --git a/.ci/php-cs-fixer/composer.lock b/.ci/php-cs-fixer/composer.lock index 4f9ef616a0..ae089b21e6 100644 --- a/.ci/php-cs-fixer/composer.lock +++ b/.ci/php-cs-fixer/composer.lock @@ -402,16 +402,16 @@ }, { "name": "friendsofphp/php-cs-fixer", - "version": "v3.89.1", + "version": "v3.89.2", "source": { "type": "git", "url": "https://github.com/PHP-CS-Fixer/PHP-CS-Fixer.git", - "reference": "f34967da2866ace090a2b447de1f357356474573" + "reference": "7569658f91e475ec93b99bd5964b059ad1336dcf" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/PHP-CS-Fixer/PHP-CS-Fixer/zipball/f34967da2866ace090a2b447de1f357356474573", - "reference": "f34967da2866ace090a2b447de1f357356474573", + "url": "https://api.github.com/repos/PHP-CS-Fixer/PHP-CS-Fixer/zipball/7569658f91e475ec93b99bd5964b059ad1336dcf", + "reference": "7569658f91e475ec93b99bd5964b059ad1336dcf", "shasum": "" }, "require": { @@ -447,7 +447,7 @@ "justinrainbow/json-schema": "^6.5", "keradus/cli-executor": "^2.2", "mikey179/vfsstream": "^1.6.12", - "php-coveralls/php-coveralls": "^2.8", + "php-coveralls/php-coveralls": "^2.9", "php-cs-fixer/phpunit-constraint-isidenticalstring": "^1.6", "php-cs-fixer/phpunit-constraint-xmlmatchesxsd": "^1.6", "phpunit/phpunit": "^9.6.25 || ^10.5.53 || ^11.5.34", @@ -493,7 +493,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.89.1" + "source": "https://github.com/PHP-CS-Fixer/PHP-CS-Fixer/tree/v3.89.2" }, "funding": [ { @@ -501,7 +501,7 @@ "type": "github" } ], - "time": "2025-10-24T12:05:10+00:00" + "time": "2025-11-06T21:12:50+00:00" }, { "name": "psr/container", @@ -1251,16 +1251,16 @@ }, { "name": "symfony/console", - "version": "v7.3.5", + "version": "v7.3.6", "source": { "type": "git", "url": "https://github.com/symfony/console.git", - "reference": "cdb80fa5869653c83cfe1a9084a673b6daf57ea7" + "reference": "c28ad91448f86c5f6d9d2c70f0cf68bf135f252a" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/console/zipball/cdb80fa5869653c83cfe1a9084a673b6daf57ea7", - "reference": "cdb80fa5869653c83cfe1a9084a673b6daf57ea7", + "url": "https://api.github.com/repos/symfony/console/zipball/c28ad91448f86c5f6d9d2c70f0cf68bf135f252a", + "reference": "c28ad91448f86c5f6d9d2c70f0cf68bf135f252a", "shasum": "" }, "require": { @@ -1325,7 +1325,7 @@ "terminal" ], "support": { - "source": "https://github.com/symfony/console/tree/v7.3.5" + "source": "https://github.com/symfony/console/tree/v7.3.6" }, "funding": [ { @@ -1345,7 +1345,7 @@ "type": "tidelift" } ], - "time": "2025-10-14T15:46:26+00:00" + "time": "2025-11-04T01:21:42+00:00" }, { "name": "symfony/deprecation-contracts", @@ -1576,16 +1576,16 @@ }, { "name": "symfony/filesystem", - "version": "v7.3.2", + "version": "v7.3.6", "source": { "type": "git", "url": "https://github.com/symfony/filesystem.git", - "reference": "edcbb768a186b5c3f25d0643159a787d3e63b7fd" + "reference": "e9bcfd7837928ab656276fe00464092cc9e1826a" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/filesystem/zipball/edcbb768a186b5c3f25d0643159a787d3e63b7fd", - "reference": "edcbb768a186b5c3f25d0643159a787d3e63b7fd", + "url": "https://api.github.com/repos/symfony/filesystem/zipball/e9bcfd7837928ab656276fe00464092cc9e1826a", + "reference": "e9bcfd7837928ab656276fe00464092cc9e1826a", "shasum": "" }, "require": { @@ -1622,7 +1622,7 @@ "description": "Provides basic utilities for the filesystem", "homepage": "https://symfony.com", "support": { - "source": "https://github.com/symfony/filesystem/tree/v7.3.2" + "source": "https://github.com/symfony/filesystem/tree/v7.3.6" }, "funding": [ { @@ -1642,7 +1642,7 @@ "type": "tidelift" } ], - "time": "2025-07-07T08:17:47+00:00" + "time": "2025-11-05T09:52:27+00:00" }, { "name": "symfony/finder", @@ -2429,16 +2429,16 @@ }, { "name": "symfony/service-contracts", - "version": "v3.6.0", + "version": "v3.6.1", "source": { "type": "git", "url": "https://github.com/symfony/service-contracts.git", - "reference": "f021b05a130d35510bd6b25fe9053c2a8a15d5d4" + "reference": "45112560a3ba2d715666a509a0bc9521d10b6c43" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/service-contracts/zipball/f021b05a130d35510bd6b25fe9053c2a8a15d5d4", - "reference": "f021b05a130d35510bd6b25fe9053c2a8a15d5d4", + "url": "https://api.github.com/repos/symfony/service-contracts/zipball/45112560a3ba2d715666a509a0bc9521d10b6c43", + "reference": "45112560a3ba2d715666a509a0bc9521d10b6c43", "shasum": "" }, "require": { @@ -2492,7 +2492,7 @@ "standards" ], "support": { - "source": "https://github.com/symfony/service-contracts/tree/v3.6.0" + "source": "https://github.com/symfony/service-contracts/tree/v3.6.1" }, "funding": [ { @@ -2503,12 +2503,16 @@ "url": "https://github.com/fabpot", "type": "github" }, + { + "url": "https://github.com/nicolas-grekas", + "type": "github" + }, { "url": "https://tidelift.com/funding/github/packagist/symfony/symfony", "type": "tidelift" } ], - "time": "2025-04-25T09:37:31+00:00" + "time": "2025-07-15T11:30:57+00:00" }, { "name": "symfony/stopwatch", diff --git a/changelog.md b/changelog.md index edd3a6e4dd..ca0d798b23 100644 --- a/changelog.md +++ b/changelog.md @@ -8,7 +8,7 @@ This project adheres to [Semantic Versioning](http://semver.org/). ### Fixed - [Issue 11157](https://github.com/firefly-iii/firefly-iii/issues/11157) (Redacted amounts misbehave with Reports) reported by @barreeeiroo -- #11185 +- [Issue 11185](https://github.com/firefly-iii/firefly-iii/issues/11185) (Internal server error after apply rule) reported by @Citroene ## 6.4.4 - 2025-11-02 diff --git a/composer.lock b/composer.lock index 757e217764..6a4493981b 100644 --- a/composer.lock +++ b/composer.lock @@ -6655,16 +6655,16 @@ }, { "name": "symfony/cache", - "version": "v7.3.5", + "version": "v7.3.6", "source": { "type": "git", "url": "https://github.com/symfony/cache.git", - "reference": "4a55feb59664f49042a0824c0f955e2f4c1412ad" + "reference": "1277a1ec61c8d93ea61b2a59738f1deb9bfb6701" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/cache/zipball/4a55feb59664f49042a0824c0f955e2f4c1412ad", - "reference": "4a55feb59664f49042a0824c0f955e2f4c1412ad", + "url": "https://api.github.com/repos/symfony/cache/zipball/1277a1ec61c8d93ea61b2a59738f1deb9bfb6701", + "reference": "1277a1ec61c8d93ea61b2a59738f1deb9bfb6701", "shasum": "" }, "require": { @@ -6733,7 +6733,7 @@ "psr6" ], "support": { - "source": "https://github.com/symfony/cache/tree/v7.3.5" + "source": "https://github.com/symfony/cache/tree/v7.3.6" }, "funding": [ { @@ -6753,7 +6753,7 @@ "type": "tidelift" } ], - "time": "2025-10-16T13:55:38+00:00" + "time": "2025-10-30T13:22:58+00:00" }, { "name": "symfony/cache-contracts", @@ -6907,16 +6907,16 @@ }, { "name": "symfony/console", - "version": "v7.3.5", + "version": "v7.3.6", "source": { "type": "git", "url": "https://github.com/symfony/console.git", - "reference": "cdb80fa5869653c83cfe1a9084a673b6daf57ea7" + "reference": "c28ad91448f86c5f6d9d2c70f0cf68bf135f252a" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/console/zipball/cdb80fa5869653c83cfe1a9084a673b6daf57ea7", - "reference": "cdb80fa5869653c83cfe1a9084a673b6daf57ea7", + "url": "https://api.github.com/repos/symfony/console/zipball/c28ad91448f86c5f6d9d2c70f0cf68bf135f252a", + "reference": "c28ad91448f86c5f6d9d2c70f0cf68bf135f252a", "shasum": "" }, "require": { @@ -6981,7 +6981,7 @@ "terminal" ], "support": { - "source": "https://github.com/symfony/console/tree/v7.3.5" + "source": "https://github.com/symfony/console/tree/v7.3.6" }, "funding": [ { @@ -7001,20 +7001,20 @@ "type": "tidelift" } ], - "time": "2025-10-14T15:46:26+00:00" + "time": "2025-11-04T01:21:42+00:00" }, { "name": "symfony/css-selector", - "version": "v7.3.0", + "version": "v7.3.6", "source": { "type": "git", "url": "https://github.com/symfony/css-selector.git", - "reference": "601a5ce9aaad7bf10797e3663faefce9e26c24e2" + "reference": "84321188c4754e64273b46b406081ad9b18e8614" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/css-selector/zipball/601a5ce9aaad7bf10797e3663faefce9e26c24e2", - "reference": "601a5ce9aaad7bf10797e3663faefce9e26c24e2", + "url": "https://api.github.com/repos/symfony/css-selector/zipball/84321188c4754e64273b46b406081ad9b18e8614", + "reference": "84321188c4754e64273b46b406081ad9b18e8614", "shasum": "" }, "require": { @@ -7050,7 +7050,7 @@ "description": "Converts CSS selectors to XPath expressions", "homepage": "https://symfony.com", "support": { - "source": "https://github.com/symfony/css-selector/tree/v7.3.0" + "source": "https://github.com/symfony/css-selector/tree/v7.3.6" }, "funding": [ { @@ -7061,12 +7061,16 @@ "url": "https://github.com/fabpot", "type": "github" }, + { + "url": "https://github.com/nicolas-grekas", + "type": "github" + }, { "url": "https://tidelift.com/funding/github/packagist/symfony/symfony", "type": "tidelift" } ], - "time": "2024-09-25T14:21:43+00:00" + "time": "2025-10-29T17:24:25+00:00" }, { "name": "symfony/deprecation-contracts", @@ -7137,16 +7141,16 @@ }, { "name": "symfony/error-handler", - "version": "v7.3.4", + "version": "v7.3.6", "source": { "type": "git", "url": "https://github.com/symfony/error-handler.git", - "reference": "99f81bc944ab8e5dae4f21b4ca9972698bbad0e4" + "reference": "bbe40bfab84323d99dab491b716ff142410a92a8" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/error-handler/zipball/99f81bc944ab8e5dae4f21b4ca9972698bbad0e4", - "reference": "99f81bc944ab8e5dae4f21b4ca9972698bbad0e4", + "url": "https://api.github.com/repos/symfony/error-handler/zipball/bbe40bfab84323d99dab491b716ff142410a92a8", + "reference": "bbe40bfab84323d99dab491b716ff142410a92a8", "shasum": "" }, "require": { @@ -7194,7 +7198,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/v7.3.4" + "source": "https://github.com/symfony/error-handler/tree/v7.3.6" }, "funding": [ { @@ -7214,7 +7218,7 @@ "type": "tidelift" } ], - "time": "2025-09-11T10:12:26+00:00" + "time": "2025-10-31T19:12:50+00:00" }, { "name": "symfony/event-dispatcher", @@ -7514,16 +7518,16 @@ }, { "name": "symfony/http-client", - "version": "v7.3.4", + "version": "v7.3.6", "source": { "type": "git", "url": "https://github.com/symfony/http-client.git", - "reference": "4b62871a01c49457cf2a8e560af7ee8a94b87a62" + "reference": "3c0a55a2c8e21e30a37022801c11c7ab5a6cb2de" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/http-client/zipball/4b62871a01c49457cf2a8e560af7ee8a94b87a62", - "reference": "4b62871a01c49457cf2a8e560af7ee8a94b87a62", + "url": "https://api.github.com/repos/symfony/http-client/zipball/3c0a55a2c8e21e30a37022801c11c7ab5a6cb2de", + "reference": "3c0a55a2c8e21e30a37022801c11c7ab5a6cb2de", "shasum": "" }, "require": { @@ -7590,7 +7594,7 @@ "http" ], "support": { - "source": "https://github.com/symfony/http-client/tree/v7.3.4" + "source": "https://github.com/symfony/http-client/tree/v7.3.6" }, "funding": [ { @@ -7610,7 +7614,7 @@ "type": "tidelift" } ], - "time": "2025-09-11T10:12:26+00:00" + "time": "2025-11-05T17:41:46+00:00" }, { "name": "symfony/http-client-contracts", @@ -7692,16 +7696,16 @@ }, { "name": "symfony/http-foundation", - "version": "v7.3.5", + "version": "v7.3.6", "source": { "type": "git", "url": "https://github.com/symfony/http-foundation.git", - "reference": "ce31218c7cac92eab280762c4375fb70a6f4f897" + "reference": "6379e490d6ecfc5c4224ff3a754b90495ecd135c" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/http-foundation/zipball/ce31218c7cac92eab280762c4375fb70a6f4f897", - "reference": "ce31218c7cac92eab280762c4375fb70a6f4f897", + "url": "https://api.github.com/repos/symfony/http-foundation/zipball/6379e490d6ecfc5c4224ff3a754b90495ecd135c", + "reference": "6379e490d6ecfc5c4224ff3a754b90495ecd135c", "shasum": "" }, "require": { @@ -7751,7 +7755,7 @@ "description": "Defines an object-oriented layer for the HTTP specification", "homepage": "https://symfony.com", "support": { - "source": "https://github.com/symfony/http-foundation/tree/v7.3.5" + "source": "https://github.com/symfony/http-foundation/tree/v7.3.6" }, "funding": [ { @@ -7771,20 +7775,20 @@ "type": "tidelift" } ], - "time": "2025-10-24T21:42:11+00:00" + "time": "2025-11-06T11:05:57+00:00" }, { "name": "symfony/http-kernel", - "version": "v7.3.5", + "version": "v7.3.6", "source": { "type": "git", "url": "https://github.com/symfony/http-kernel.git", - "reference": "24fd3f123532e26025f49f1abefcc01a69ef15ab" + "reference": "f9a34dc0196677250e3609c2fac9de9e1551a262" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/http-kernel/zipball/24fd3f123532e26025f49f1abefcc01a69ef15ab", - "reference": "24fd3f123532e26025f49f1abefcc01a69ef15ab", + "url": "https://api.github.com/repos/symfony/http-kernel/zipball/f9a34dc0196677250e3609c2fac9de9e1551a262", + "reference": "f9a34dc0196677250e3609c2fac9de9e1551a262", "shasum": "" }, "require": { @@ -7869,7 +7873,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/v7.3.5" + "source": "https://github.com/symfony/http-kernel/tree/v7.3.6" }, "funding": [ { @@ -7889,7 +7893,7 @@ "type": "tidelift" } ], - "time": "2025-10-28T10:19:01+00:00" + "time": "2025-11-06T20:58:12+00:00" }, { "name": "symfony/mailer", @@ -9182,16 +9186,16 @@ }, { "name": "symfony/routing", - "version": "v7.3.4", + "version": "v7.3.6", "source": { "type": "git", "url": "https://github.com/symfony/routing.git", - "reference": "8dc648e159e9bac02b703b9fbd937f19ba13d07c" + "reference": "c97abe725f2a1a858deca629a6488c8fc20c3091" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/routing/zipball/8dc648e159e9bac02b703b9fbd937f19ba13d07c", - "reference": "8dc648e159e9bac02b703b9fbd937f19ba13d07c", + "url": "https://api.github.com/repos/symfony/routing/zipball/c97abe725f2a1a858deca629a6488c8fc20c3091", + "reference": "c97abe725f2a1a858deca629a6488c8fc20c3091", "shasum": "" }, "require": { @@ -9243,7 +9247,7 @@ "url" ], "support": { - "source": "https://github.com/symfony/routing/tree/v7.3.4" + "source": "https://github.com/symfony/routing/tree/v7.3.6" }, "funding": [ { @@ -9263,20 +9267,20 @@ "type": "tidelift" } ], - "time": "2025-09-11T10:12:26+00:00" + "time": "2025-11-05T07:57:47+00:00" }, { "name": "symfony/service-contracts", - "version": "v3.6.0", + "version": "v3.6.1", "source": { "type": "git", "url": "https://github.com/symfony/service-contracts.git", - "reference": "f021b05a130d35510bd6b25fe9053c2a8a15d5d4" + "reference": "45112560a3ba2d715666a509a0bc9521d10b6c43" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/service-contracts/zipball/f021b05a130d35510bd6b25fe9053c2a8a15d5d4", - "reference": "f021b05a130d35510bd6b25fe9053c2a8a15d5d4", + "url": "https://api.github.com/repos/symfony/service-contracts/zipball/45112560a3ba2d715666a509a0bc9521d10b6c43", + "reference": "45112560a3ba2d715666a509a0bc9521d10b6c43", "shasum": "" }, "require": { @@ -9330,7 +9334,7 @@ "standards" ], "support": { - "source": "https://github.com/symfony/service-contracts/tree/v3.6.0" + "source": "https://github.com/symfony/service-contracts/tree/v3.6.1" }, "funding": [ { @@ -9341,12 +9345,16 @@ "url": "https://github.com/fabpot", "type": "github" }, + { + "url": "https://github.com/nicolas-grekas", + "type": "github" + }, { "url": "https://tidelift.com/funding/github/packagist/symfony/symfony", "type": "tidelift" } ], - "time": "2025-04-25T09:37:31+00:00" + "time": "2025-07-15T11:30:57+00:00" }, { "name": "symfony/string", @@ -9540,16 +9548,16 @@ }, { "name": "symfony/translation-contracts", - "version": "v3.6.0", + "version": "v3.6.1", "source": { "type": "git", "url": "https://github.com/symfony/translation-contracts.git", - "reference": "df210c7a2573f1913b2d17cc95f90f53a73d8f7d" + "reference": "65a8bc82080447fae78373aa10f8d13b38338977" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/translation-contracts/zipball/df210c7a2573f1913b2d17cc95f90f53a73d8f7d", - "reference": "df210c7a2573f1913b2d17cc95f90f53a73d8f7d", + "url": "https://api.github.com/repos/symfony/translation-contracts/zipball/65a8bc82080447fae78373aa10f8d13b38338977", + "reference": "65a8bc82080447fae78373aa10f8d13b38338977", "shasum": "" }, "require": { @@ -9598,7 +9606,7 @@ "standards" ], "support": { - "source": "https://github.com/symfony/translation-contracts/tree/v3.6.0" + "source": "https://github.com/symfony/translation-contracts/tree/v3.6.1" }, "funding": [ { @@ -9609,12 +9617,16 @@ "url": "https://github.com/fabpot", "type": "github" }, + { + "url": "https://github.com/nicolas-grekas", + "type": "github" + }, { "url": "https://tidelift.com/funding/github/packagist/symfony/symfony", "type": "tidelift" } ], - "time": "2024-09-27T08:32:26+00:00" + "time": "2025-07-15T13:41:35+00:00" }, { "name": "symfony/uid", diff --git a/config/firefly.php b/config/firefly.php index 9c548983ce..3a1b91c84e 100644 --- a/config/firefly.php +++ b/config/firefly.php @@ -78,8 +78,8 @@ return [ 'running_balance_column' => env('USE_RUNNING_BALANCE', false), // see cer.php for exchange rates feature flag. ], - 'version' => 'develop/2025-11-06', - 'build_time' => 1762406472, + 'version' => 'develop/2025-11-07', + 'build_time' => 1762545905, 'api_version' => '2.1.0', // field is no longer used. 'db_version' => 28, // field is no longer used. diff --git a/package-lock.json b/package-lock.json index b0d8029ba1..bfb2e959b0 100644 --- a/package-lock.json +++ b/package-lock.json @@ -2589,9 +2589,9 @@ } }, "node_modules/@rollup/rollup-android-arm-eabi": { - "version": "4.52.5", - "resolved": "https://registry.npmjs.org/@rollup/rollup-android-arm-eabi/-/rollup-android-arm-eabi-4.52.5.tgz", - "integrity": "sha512-8c1vW4ocv3UOMp9K+gToY5zL2XiiVw3k7f1ksf4yO1FlDFQ1C2u72iACFnSOceJFsWskc2WZNqeRhFRPzv+wtQ==", + "version": "4.53.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-android-arm-eabi/-/rollup-android-arm-eabi-4.53.0.tgz", + "integrity": "sha512-MX3DD/o2W36nlgQb8KA5QtUw/bK5aR9YDzNmX1PRHZAa6LF/MQCWMN477CgBMg8gH1vEiEZsjWRIZeL/7ttUVA==", "cpu": [ "arm" ], @@ -2603,9 +2603,9 @@ ] }, "node_modules/@rollup/rollup-android-arm64": { - "version": "4.52.5", - "resolved": "https://registry.npmjs.org/@rollup/rollup-android-arm64/-/rollup-android-arm64-4.52.5.tgz", - "integrity": "sha512-mQGfsIEFcu21mvqkEKKu2dYmtuSZOBMmAl5CFlPGLY94Vlcm+zWApK7F/eocsNzp8tKmbeBP8yXyAbx0XHsFNA==", + "version": "4.53.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-android-arm64/-/rollup-android-arm64-4.53.0.tgz", + "integrity": "sha512-U4/R8ZvikDYLkl+hyAGP23SRHp3LwYSRy9SvJqsnva7TYLhVMy39RTVCYn1DdRNxXl1CyCQgE/mXKm9jaQT4ig==", "cpu": [ "arm64" ], @@ -2617,9 +2617,9 @@ ] }, "node_modules/@rollup/rollup-darwin-arm64": { - "version": "4.52.5", - "resolved": "https://registry.npmjs.org/@rollup/rollup-darwin-arm64/-/rollup-darwin-arm64-4.52.5.tgz", - "integrity": "sha512-takF3CR71mCAGA+v794QUZ0b6ZSrgJkArC+gUiG6LB6TQty9T0Mqh3m2ImRBOxS2IeYBo4lKWIieSvnEk2OQWA==", + "version": "4.53.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-darwin-arm64/-/rollup-darwin-arm64-4.53.0.tgz", + "integrity": "sha512-nBG2BXRU3ifdK0HdqBKaT5VI6ScoIpABYZ+dWwQkIOYd8Suo4iykgPikjhsTd7NeHgJJ3OqlKYCcNkZtB1iLVQ==", "cpu": [ "arm64" ], @@ -2631,9 +2631,9 @@ ] }, "node_modules/@rollup/rollup-darwin-x64": { - "version": "4.52.5", - "resolved": "https://registry.npmjs.org/@rollup/rollup-darwin-x64/-/rollup-darwin-x64-4.52.5.tgz", - "integrity": "sha512-W901Pla8Ya95WpxDn//VF9K9u2JbocwV/v75TE0YIHNTbhqUTv9w4VuQ9MaWlNOkkEfFwkdNhXgcLqPSmHy0fA==", + "version": "4.53.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-darwin-x64/-/rollup-darwin-x64-4.53.0.tgz", + "integrity": "sha512-QuZ5hYStB/vW7b8zQYtdIPpIfNNlUXtGk8zVTkoTMKzMhE2/6tVvcCWqdWqCVhx6eguJJjKjtZ9lAAG/D3yNeA==", "cpu": [ "x64" ], @@ -2645,9 +2645,9 @@ ] }, "node_modules/@rollup/rollup-freebsd-arm64": { - "version": "4.52.5", - "resolved": "https://registry.npmjs.org/@rollup/rollup-freebsd-arm64/-/rollup-freebsd-arm64-4.52.5.tgz", - "integrity": "sha512-QofO7i7JycsYOWxe0GFqhLmF6l1TqBswJMvICnRUjqCx8b47MTo46W8AoeQwiokAx3zVryVnxtBMcGcnX12LvA==", + "version": "4.53.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-freebsd-arm64/-/rollup-freebsd-arm64-4.53.0.tgz", + "integrity": "sha512-4yYPm1PJwK/HKI4FzElAPj2EAAFaaLUWzXV3S3edKy71JcEVzBCpgaXyEcDh3blBIjLml+aMkj6HEVGSuzpz+g==", "cpu": [ "arm64" ], @@ -2659,9 +2659,9 @@ ] }, "node_modules/@rollup/rollup-freebsd-x64": { - "version": "4.52.5", - "resolved": "https://registry.npmjs.org/@rollup/rollup-freebsd-x64/-/rollup-freebsd-x64-4.52.5.tgz", - "integrity": "sha512-jr21b/99ew8ujZubPo9skbrItHEIE50WdV86cdSoRkKtmWa+DDr6fu2c/xyRT0F/WazZpam6kk7IHBerSL7LDQ==", + "version": "4.53.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-freebsd-x64/-/rollup-freebsd-x64-4.53.0.tgz", + "integrity": "sha512-1SvE5euwWV8JqFc4zEAqHbJbf2yJl00EoHVcnlFqLzjrIExYttLxfZeMDIXY6Yx+bskphrQakpChZKzE2JECEg==", "cpu": [ "x64" ], @@ -2673,9 +2673,9 @@ ] }, "node_modules/@rollup/rollup-linux-arm-gnueabihf": { - "version": "4.52.5", - "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm-gnueabihf/-/rollup-linux-arm-gnueabihf-4.52.5.tgz", - "integrity": "sha512-PsNAbcyv9CcecAUagQefwX8fQn9LQ4nZkpDboBOttmyffnInRy8R8dSg6hxxl2Re5QhHBf6FYIDhIj5v982ATQ==", + "version": "4.53.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm-gnueabihf/-/rollup-linux-arm-gnueabihf-4.53.0.tgz", + "integrity": "sha512-9tS4QyfU5NF5CdUugEi7kWbcGD7pbu6Fm8SunuePH6beeQgtcRZ9K9KVwKHEgfBHeeyrr5OvfV1qWs7PMDOf5w==", "cpu": [ "arm" ], @@ -2687,9 +2687,9 @@ ] }, "node_modules/@rollup/rollup-linux-arm-musleabihf": { - "version": "4.52.5", - "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm-musleabihf/-/rollup-linux-arm-musleabihf-4.52.5.tgz", - "integrity": "sha512-Fw4tysRutyQc/wwkmcyoqFtJhh0u31K+Q6jYjeicsGJJ7bbEq8LwPWV/w0cnzOqR2m694/Af6hpFayLJZkG2VQ==", + "version": "4.53.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm-musleabihf/-/rollup-linux-arm-musleabihf-4.53.0.tgz", + "integrity": "sha512-U+0ovxGU9bVJIHfW+oALpHd0ho1YDwhj0yHASDzIj+bOeo+VzEpNtHxcjhFab0YcHUorIMoqyxckC98+81oTJw==", "cpu": [ "arm" ], @@ -2701,9 +2701,9 @@ ] }, "node_modules/@rollup/rollup-linux-arm64-gnu": { - "version": "4.52.5", - "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm64-gnu/-/rollup-linux-arm64-gnu-4.52.5.tgz", - "integrity": "sha512-a+3wVnAYdQClOTlyapKmyI6BLPAFYs0JM8HRpgYZQO02rMR09ZcV9LbQB+NL6sljzG38869YqThrRnfPMCDtZg==", + "version": "4.53.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm64-gnu/-/rollup-linux-arm64-gnu-4.53.0.tgz", + "integrity": "sha512-Cp/TQ+wLjRTqTuiVwLz4XPZMo3ROl7EJYMF8HhMp8Uf+9kOOATB3/p4gGZPpuQ4BP7qEXG29ET24u9+F0ERYkQ==", "cpu": [ "arm64" ], @@ -2715,9 +2715,9 @@ ] }, "node_modules/@rollup/rollup-linux-arm64-musl": { - "version": "4.52.5", - "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm64-musl/-/rollup-linux-arm64-musl-4.52.5.tgz", - "integrity": "sha512-AvttBOMwO9Pcuuf7m9PkC1PUIKsfaAJ4AYhy944qeTJgQOqJYJ9oVl2nYgY7Rk0mkbsuOpCAYSs6wLYB2Xiw0Q==", + "version": "4.53.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm64-musl/-/rollup-linux-arm64-musl-4.53.0.tgz", + "integrity": "sha512-SuGoAwhsSonrSTEZTiQOGC3+XZfq7rc/qAdAOBrYYIp8pu+Wh4EFFXl6+QYYNbNrHL3DnVoWACLwnfwlTa0neA==", "cpu": [ "arm64" ], @@ -2729,9 +2729,9 @@ ] }, "node_modules/@rollup/rollup-linux-loong64-gnu": { - "version": "4.52.5", - "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-loong64-gnu/-/rollup-linux-loong64-gnu-4.52.5.tgz", - "integrity": "sha512-DkDk8pmXQV2wVrF6oq5tONK6UHLz/XcEVow4JTTerdeV1uqPeHxwcg7aFsfnSm9L+OO8WJsWotKM2JJPMWrQtA==", + "version": "4.53.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-loong64-gnu/-/rollup-linux-loong64-gnu-4.53.0.tgz", + "integrity": "sha512-EOKej1x0WoePnJWfg7ZbnUqiuiQunshzsKZSIfTHFDiCY9pnsr3Weit1GjcpGnun7H5HuRREqkT2c9CcKxNwSg==", "cpu": [ "loong64" ], @@ -2743,9 +2743,9 @@ ] }, "node_modules/@rollup/rollup-linux-ppc64-gnu": { - "version": "4.52.5", - "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-ppc64-gnu/-/rollup-linux-ppc64-gnu-4.52.5.tgz", - "integrity": "sha512-W/b9ZN/U9+hPQVvlGwjzi+Wy4xdoH2I8EjaCkMvzpI7wJUs8sWJ03Rq96jRnHkSrcHTpQe8h5Tg3ZzUPGauvAw==", + "version": "4.53.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-ppc64-gnu/-/rollup-linux-ppc64-gnu-4.53.0.tgz", + "integrity": "sha512-YAvv2aMFlfiawJ97lutomuehG2Yowd4YgsAqI85XNiMK9eBA1vEMZHt3BShg8cUvak71BM+VFRHddqc+OrRdVA==", "cpu": [ "ppc64" ], @@ -2757,9 +2757,9 @@ ] }, "node_modules/@rollup/rollup-linux-riscv64-gnu": { - "version": "4.52.5", - "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-riscv64-gnu/-/rollup-linux-riscv64-gnu-4.52.5.tgz", - "integrity": "sha512-sjQLr9BW7R/ZiXnQiWPkErNfLMkkWIoCz7YMn27HldKsADEKa5WYdobaa1hmN6slu9oWQbB6/jFpJ+P2IkVrmw==", + "version": "4.53.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-riscv64-gnu/-/rollup-linux-riscv64-gnu-4.53.0.tgz", + "integrity": "sha512-DxZe/sMVaqN+s5kVk3Iq619Rgyl1JCTob7xOLSNC84mbzg3NYTSheqqrtVllYjLYo4wm9YyqjVS57miuzNyXbQ==", "cpu": [ "riscv64" ], @@ -2771,9 +2771,9 @@ ] }, "node_modules/@rollup/rollup-linux-riscv64-musl": { - "version": "4.52.5", - "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-riscv64-musl/-/rollup-linux-riscv64-musl-4.52.5.tgz", - "integrity": "sha512-hq3jU/kGyjXWTvAh2awn8oHroCbrPm8JqM7RUpKjalIRWWXE01CQOf/tUNWNHjmbMHg/hmNCwc/Pz3k1T/j/Lg==", + "version": "4.53.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-riscv64-musl/-/rollup-linux-riscv64-musl-4.53.0.tgz", + "integrity": "sha512-N7+iZ0jEhwLY1FEsjbCR9lAxIZP0k+3Cghx9vSQWn+rcW8SgN8VcCmwJDoPDaGKTzWWB791U1s79BSLnEhUa0Q==", "cpu": [ "riscv64" ], @@ -2785,9 +2785,9 @@ ] }, "node_modules/@rollup/rollup-linux-s390x-gnu": { - "version": "4.52.5", - "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-s390x-gnu/-/rollup-linux-s390x-gnu-4.52.5.tgz", - "integrity": "sha512-gn8kHOrku8D4NGHMK1Y7NA7INQTRdVOntt1OCYypZPRt6skGbddska44K8iocdpxHTMMNui5oH4elPH4QOLrFQ==", + "version": "4.53.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-s390x-gnu/-/rollup-linux-s390x-gnu-4.53.0.tgz", + "integrity": "sha512-MA/NVneZyIskjvXdh2NR9YcPi7eHWBlQOWP2X8OymzyeUEB0JfUpmbKQZngHmOlyleV2IoR5nHIgMSRjLskOnA==", "cpu": [ "s390x" ], @@ -2799,9 +2799,9 @@ ] }, "node_modules/@rollup/rollup-linux-x64-gnu": { - "version": "4.52.5", - "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-x64-gnu/-/rollup-linux-x64-gnu-4.52.5.tgz", - "integrity": "sha512-hXGLYpdhiNElzN770+H2nlx+jRog8TyynpTVzdlc6bndktjKWyZyiCsuDAlpd+j+W+WNqfcyAWz9HxxIGfZm1Q==", + "version": "4.53.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-x64-gnu/-/rollup-linux-x64-gnu-4.53.0.tgz", + "integrity": "sha512-iYEYzYpfaSCkunVD0LOYrD9OMc357be7+rBuCxW1qvsjCGl+95iWnYAFfyEoxAm6koasNN3tFxFYze5MKl5S3A==", "cpu": [ "x64" ], @@ -2813,9 +2813,9 @@ ] }, "node_modules/@rollup/rollup-linux-x64-musl": { - "version": "4.52.5", - "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-x64-musl/-/rollup-linux-x64-musl-4.52.5.tgz", - "integrity": "sha512-arCGIcuNKjBoKAXD+y7XomR9gY6Mw7HnFBv5Rw7wQRvwYLR7gBAgV7Mb2QTyjXfTveBNFAtPt46/36vV9STLNg==", + "version": "4.53.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-x64-musl/-/rollup-linux-x64-musl-4.53.0.tgz", + "integrity": "sha512-FoRekOqhRUKbJMsB5LvhQchDeFeNlS6UGUwi0p3860sxE4zE+lp07FnkuR+yQH0rSn6iLXsnr44jnorgl8mGlQ==", "cpu": [ "x64" ], @@ -2827,9 +2827,9 @@ ] }, "node_modules/@rollup/rollup-openharmony-arm64": { - "version": "4.52.5", - "resolved": "https://registry.npmjs.org/@rollup/rollup-openharmony-arm64/-/rollup-openharmony-arm64-4.52.5.tgz", - "integrity": "sha512-QoFqB6+/9Rly/RiPjaomPLmR/13cgkIGfA40LHly9zcH1S0bN2HVFYk3a1eAyHQyjs3ZJYlXvIGtcCs5tko9Cw==", + "version": "4.53.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-openharmony-arm64/-/rollup-openharmony-arm64-4.53.0.tgz", + "integrity": "sha512-mEN2k1zKO5PUzW8W15hKpLh+zZI2by1onX2GfI93OekGbKN5aTjWGo7yAjwRZLjhAgs2UQcXmEWbIw0R5B4RnQ==", "cpu": [ "arm64" ], @@ -2841,9 +2841,9 @@ ] }, "node_modules/@rollup/rollup-win32-arm64-msvc": { - "version": "4.52.5", - "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-arm64-msvc/-/rollup-win32-arm64-msvc-4.52.5.tgz", - "integrity": "sha512-w0cDWVR6MlTstla1cIfOGyl8+qb93FlAVutcor14Gf5Md5ap5ySfQ7R9S/NjNaMLSFdUnKGEasmVnu3lCMqB7w==", + "version": "4.53.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-arm64-msvc/-/rollup-win32-arm64-msvc-4.53.0.tgz", + "integrity": "sha512-V1dEKUXqevG0wxo6ysGrL7g2T6tndmo6Uqw5vzOqCXv+DHc8m0RRgcCm+96iigDniwpvV6o4HZtkRUnuTz9XiA==", "cpu": [ "arm64" ], @@ -2855,9 +2855,9 @@ ] }, "node_modules/@rollup/rollup-win32-ia32-msvc": { - "version": "4.52.5", - "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-ia32-msvc/-/rollup-win32-ia32-msvc-4.52.5.tgz", - "integrity": "sha512-Aufdpzp7DpOTULJCuvzqcItSGDH73pF3ko/f+ckJhxQyHtp67rHw3HMNxoIdDMUITJESNE6a8uh4Lo4SLouOUg==", + "version": "4.53.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-ia32-msvc/-/rollup-win32-ia32-msvc-4.53.0.tgz", + "integrity": "sha512-93mJ8Hm9+vbhtu+A1VtmwptSqCYojtMQkBGDjLytCWC8muxmZLGo/MA/4CMAWf6+QpKlxTTMDAHdTC+kxn9ZcQ==", "cpu": [ "ia32" ], @@ -2869,9 +2869,9 @@ ] }, "node_modules/@rollup/rollup-win32-x64-gnu": { - "version": "4.52.5", - "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-x64-gnu/-/rollup-win32-x64-gnu-4.52.5.tgz", - "integrity": "sha512-UGBUGPFp1vkj6p8wCRraqNhqwX/4kNQPS57BCFc8wYh0g94iVIW33wJtQAx3G7vrjjNtRaxiMUylM0ktp/TRSQ==", + "version": "4.53.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-x64-gnu/-/rollup-win32-x64-gnu-4.53.0.tgz", + "integrity": "sha512-1OrYs0p/deXEFLUW1gvyjIabmsJKY3I/9fCUA1K6demaNc4iEhXDW6RnyPv/BWqb7NRmQ9+i+SKoi1HgJxWcwg==", "cpu": [ "x64" ], @@ -2883,9 +2883,9 @@ ] }, "node_modules/@rollup/rollup-win32-x64-msvc": { - "version": "4.52.5", - "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-x64-msvc/-/rollup-win32-x64-msvc-4.52.5.tgz", - "integrity": "sha512-TAcgQh2sSkykPRWLrdyy2AiceMckNf5loITqXxFI5VuQjS5tSuw3WlwdN8qv8vzjLAUTvYaH/mVjSFpbkFbpTg==", + "version": "4.53.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-x64-msvc/-/rollup-win32-x64-msvc-4.53.0.tgz", + "integrity": "sha512-xtSei8paPcLy3GzeeOjoRrllJn6EN8PB+/bXnhZ4R0AaviJsRwtKxFZRVnfFXNZTTp0nLeDo+BcEuIfdZS14/A==", "cpu": [ "x64" ], @@ -3291,42 +3291,42 @@ } }, "node_modules/@vue/compiler-core": { - "version": "3.5.23", - "resolved": "https://registry.npmjs.org/@vue/compiler-core/-/compiler-core-3.5.23.tgz", - "integrity": "sha512-nW7THWj5HOp085ROk65LwaoxuzDsjIxr485F4iu63BoxsXoSqKqmsUUoP4A7Gl67DgIgi0zJ8JFgHfvny/74MA==", + "version": "3.5.24", + "resolved": "https://registry.npmjs.org/@vue/compiler-core/-/compiler-core-3.5.24.tgz", + "integrity": "sha512-eDl5H57AOpNakGNAkFDH+y7kTqrQpJkZFXhWZQGyx/5Wh7B1uQYvcWkvZi11BDhscPgj8N7XV3oRwiPnx1Vrig==", "dev": true, "license": "MIT", "dependencies": { "@babel/parser": "^7.28.5", - "@vue/shared": "3.5.23", + "@vue/shared": "3.5.24", "entities": "^4.5.0", "estree-walker": "^2.0.2", "source-map-js": "^1.2.1" } }, "node_modules/@vue/compiler-dom": { - "version": "3.5.23", - "resolved": "https://registry.npmjs.org/@vue/compiler-dom/-/compiler-dom-3.5.23.tgz", - "integrity": "sha512-AT8RMw0vEzzzO0JU5gY0F6iCzaWUIh/aaRVordzMBKXRpoTllTT4kocHDssByPsvodNCfump/Lkdow2mT/O5KQ==", + "version": "3.5.24", + "resolved": "https://registry.npmjs.org/@vue/compiler-dom/-/compiler-dom-3.5.24.tgz", + "integrity": "sha512-1QHGAvs53gXkWdd3ZMGYuvQFXHW4ksKWPG8HP8/2BscrbZ0brw183q2oNWjMrSWImYLHxHrx1ItBQr50I/q2zw==", "dev": true, "license": "MIT", "dependencies": { - "@vue/compiler-core": "3.5.23", - "@vue/shared": "3.5.23" + "@vue/compiler-core": "3.5.24", + "@vue/shared": "3.5.24" } }, "node_modules/@vue/compiler-sfc": { - "version": "3.5.23", - "resolved": "https://registry.npmjs.org/@vue/compiler-sfc/-/compiler-sfc-3.5.23.tgz", - "integrity": "sha512-3QTEUo4qg7FtQwaDJa8ou1CUikx5WTtZlY61rRRDu3lK2ZKrGoAGG8mvDgOpDsQ4A1bez9s+WtBB6DS2KuFCPw==", + "version": "3.5.24", + "resolved": "https://registry.npmjs.org/@vue/compiler-sfc/-/compiler-sfc-3.5.24.tgz", + "integrity": "sha512-8EG5YPRgmTB+YxYBM3VXy8zHD9SWHUJLIGPhDovo3Z8VOgvP+O7UP5vl0J4BBPWYD9vxtBabzW1EuEZ+Cqs14g==", "dev": true, "license": "MIT", "dependencies": { "@babel/parser": "^7.28.5", - "@vue/compiler-core": "3.5.23", - "@vue/compiler-dom": "3.5.23", - "@vue/compiler-ssr": "3.5.23", - "@vue/shared": "3.5.23", + "@vue/compiler-core": "3.5.24", + "@vue/compiler-dom": "3.5.24", + "@vue/compiler-ssr": "3.5.24", + "@vue/shared": "3.5.24", "estree-walker": "^2.0.2", "magic-string": "^0.30.21", "postcss": "^8.5.6", @@ -3334,14 +3334,14 @@ } }, "node_modules/@vue/compiler-ssr": { - "version": "3.5.23", - "resolved": "https://registry.npmjs.org/@vue/compiler-ssr/-/compiler-ssr-3.5.23.tgz", - "integrity": "sha512-Hld2xphbMjXs9Q9WKxPf2EqmE+Rq/FEDnK/wUBtmYq74HCV4XDdSCheAaB823OQXIIFGq9ig/RbAZkF9s4U0Ow==", + "version": "3.5.24", + "resolved": "https://registry.npmjs.org/@vue/compiler-ssr/-/compiler-ssr-3.5.24.tgz", + "integrity": "sha512-trOvMWNBMQ/odMRHW7Ae1CdfYx+7MuiQu62Jtu36gMLXcaoqKvAyh+P73sYG9ll+6jLB6QPovqoKGGZROzkFFg==", "dev": true, "license": "MIT", "dependencies": { - "@vue/compiler-dom": "3.5.23", - "@vue/shared": "3.5.23" + "@vue/compiler-dom": "3.5.24", + "@vue/shared": "3.5.24" } }, "node_modules/@vue/component-compiler-utils": { @@ -3423,9 +3423,9 @@ "license": "MIT" }, "node_modules/@vue/shared": { - "version": "3.5.23", - "resolved": "https://registry.npmjs.org/@vue/shared/-/shared-3.5.23.tgz", - "integrity": "sha512-0YZ1DYuC5o/YJPf6pFdt2KYxVGDxkDbH/1NYJnVJWUkzr8ituBEmFVQRNX2gCaAsFEjEDnLkWpgqlZA7htgS/g==", + "version": "3.5.24", + "resolved": "https://registry.npmjs.org/@vue/shared/-/shared-3.5.24.tgz", + "integrity": "sha512-9cwHL2EsJBdi8NY22pngYYWzkTDhld6fAD6jlaeloNGciNSJL6bLpbxVgXl96X00Jtc6YWQv96YA/0sxex/k1A==", "dev": true, "license": "MIT" }, @@ -4521,9 +4521,9 @@ } }, "node_modules/caniuse-lite": { - "version": "1.0.30001753", - "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001753.tgz", - "integrity": "sha512-Bj5H35MD/ebaOV4iDLqPEtiliTN29qkGtEHCwawWn4cYm+bPJM2NsaP30vtZcnERClMzp52J4+aw2UNbK4o+zw==", + "version": "1.0.30001754", + "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001754.tgz", + "integrity": "sha512-x6OeBXueoAceOmotzx3PO4Zpt4rzpeIFsSr6AAePTZxSkXiYDUmpypEl7e2+8NCd9bD7bXjqyef8CJYPC1jfxg==", "dev": true, "funding": [ { @@ -5736,9 +5736,9 @@ "license": "MIT" }, "node_modules/electron-to-chromium": { - "version": "1.5.245", - "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.5.245.tgz", - "integrity": "sha512-rdmGfW47ZhL/oWEJAY4qxRtdly2B98ooTJ0pdEI4jhVLZ6tNf8fPtov2wS1IRKwFJT92le3x4Knxiwzl7cPPpQ==", + "version": "1.5.248", + "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.5.248.tgz", + "integrity": "sha512-zsur2yunphlyAO4gIubdJEXCK6KOVvtpiuDfCIqbM9FjcnMYiyn0ICa3hWfPr0nc41zcLWobgy1iL7VvoOyA2Q==", "dev": true, "license": "ISC" }, @@ -7088,9 +7088,9 @@ } }, "node_modules/i18next": { - "version": "25.6.0", - "resolved": "https://registry.npmjs.org/i18next/-/i18next-25.6.0.tgz", - "integrity": "sha512-tTn8fLrwBYtnclpL5aPXK/tAYBLWVvoHM1zdfXoRNLcI+RvtMsoZRV98ePlaW3khHYKuNh/Q65W/+NVFUeIwVw==", + "version": "25.6.1", + "resolved": "https://registry.npmjs.org/i18next/-/i18next-25.6.1.tgz", + "integrity": "sha512-yUWvdXtalZztmKrKw3yz/AvSP3yKyqIkVPx/wyvoYy9lkLmwzItLxp0iHZLG5hfVQ539Jor4XLO+U+NHIXg7pw==", "funding": [ { "type": "individual", @@ -10110,10 +10110,11 @@ } }, "node_modules/rollup": { - "version": "4.52.5", - "resolved": "https://registry.npmjs.org/rollup/-/rollup-4.52.5.tgz", - "integrity": "sha512-3GuObel8h7Kqdjt0gxkEzaifHTqLVW56Y/bjN7PSQtkKr0w3V/QYSdt6QWYtd7A1xUtYQigtdUfgj1RvWVtorw==", + "version": "4.53.0", + "resolved": "https://registry.npmjs.org/rollup/-/rollup-4.53.0.tgz", + "integrity": "sha512-43Z5T+4YTdfYkkA6CStU2DUYh7Ha9dLtvK+K3n0yEE/QS+4i28vSxrQsM59KqpvmT4tbOwJsFnRGMj/tvmQwWw==", "dev": true, + "hasInstallScript": true, "license": "MIT", "dependencies": { "@types/estree": "1.0.8" @@ -10126,28 +10127,28 @@ "npm": ">=8.0.0" }, "optionalDependencies": { - "@rollup/rollup-android-arm-eabi": "4.52.5", - "@rollup/rollup-android-arm64": "4.52.5", - "@rollup/rollup-darwin-arm64": "4.52.5", - "@rollup/rollup-darwin-x64": "4.52.5", - "@rollup/rollup-freebsd-arm64": "4.52.5", - "@rollup/rollup-freebsd-x64": "4.52.5", - "@rollup/rollup-linux-arm-gnueabihf": "4.52.5", - "@rollup/rollup-linux-arm-musleabihf": "4.52.5", - "@rollup/rollup-linux-arm64-gnu": "4.52.5", - "@rollup/rollup-linux-arm64-musl": "4.52.5", - "@rollup/rollup-linux-loong64-gnu": "4.52.5", - "@rollup/rollup-linux-ppc64-gnu": "4.52.5", - "@rollup/rollup-linux-riscv64-gnu": "4.52.5", - "@rollup/rollup-linux-riscv64-musl": "4.52.5", - "@rollup/rollup-linux-s390x-gnu": "4.52.5", - "@rollup/rollup-linux-x64-gnu": "4.52.5", - "@rollup/rollup-linux-x64-musl": "4.52.5", - "@rollup/rollup-openharmony-arm64": "4.52.5", - "@rollup/rollup-win32-arm64-msvc": "4.52.5", - "@rollup/rollup-win32-ia32-msvc": "4.52.5", - "@rollup/rollup-win32-x64-gnu": "4.52.5", - "@rollup/rollup-win32-x64-msvc": "4.52.5", + "@rollup/rollup-android-arm-eabi": "4.53.0", + "@rollup/rollup-android-arm64": "4.53.0", + "@rollup/rollup-darwin-arm64": "4.53.0", + "@rollup/rollup-darwin-x64": "4.53.0", + "@rollup/rollup-freebsd-arm64": "4.53.0", + "@rollup/rollup-freebsd-x64": "4.53.0", + "@rollup/rollup-linux-arm-gnueabihf": "4.53.0", + "@rollup/rollup-linux-arm-musleabihf": "4.53.0", + "@rollup/rollup-linux-arm64-gnu": "4.53.0", + "@rollup/rollup-linux-arm64-musl": "4.53.0", + "@rollup/rollup-linux-loong64-gnu": "4.53.0", + "@rollup/rollup-linux-ppc64-gnu": "4.53.0", + "@rollup/rollup-linux-riscv64-gnu": "4.53.0", + "@rollup/rollup-linux-riscv64-musl": "4.53.0", + "@rollup/rollup-linux-s390x-gnu": "4.53.0", + "@rollup/rollup-linux-x64-gnu": "4.53.0", + "@rollup/rollup-linux-x64-musl": "4.53.0", + "@rollup/rollup-openharmony-arm64": "4.53.0", + "@rollup/rollup-win32-arm64-msvc": "4.53.0", + "@rollup/rollup-win32-ia32-msvc": "4.53.0", + "@rollup/rollup-win32-x64-gnu": "4.53.0", + "@rollup/rollup-win32-x64-msvc": "4.53.0", "fsevents": "~2.3.2" } }, @@ -11517,9 +11518,9 @@ } }, "node_modules/vite": { - "version": "7.2.1", - "resolved": "https://registry.npmjs.org/vite/-/vite-7.2.1.tgz", - "integrity": "sha512-qTl3VF7BvOupTR85Zc561sPEgxyUSNSvTQ9fit7DEMP7yPgvvIGm5Zfa1dOM+kOwWGNviK9uFM9ra77+OjK7lQ==", + "version": "7.2.2", + "resolved": "https://registry.npmjs.org/vite/-/vite-7.2.2.tgz", + "integrity": "sha512-BxAKBWmIbrDgrokdGZH1IgkIk/5mMHDreLDmCJ0qpyJaAteP8NvMhkwr/ZCQNqNH97bw/dANTE9PDzqwJghfMQ==", "dev": true, "license": "MIT", "dependencies": { From 075b0690264a87f104356f6a514b88e35a9dd972 Mon Sep 17 00:00:00 2001 From: James Cole Date: Sat, 8 Nov 2025 08:12:20 +0100 Subject: [PATCH 27/29] Expand changelog, add some debug. --- app/Http/Controllers/Recurring/EditController.php | 5 ++++- app/Http/Controllers/ReportController.php | 11 +---------- app/TransactionRules/Engine/SearchRuleEngine.php | 8 ++++---- changelog.md | 3 +++ 4 files changed, 12 insertions(+), 15 deletions(-) diff --git a/app/Http/Controllers/Recurring/EditController.php b/app/Http/Controllers/Recurring/EditController.php index 15d3e1d5b1..d32f789295 100644 --- a/app/Http/Controllers/Recurring/EditController.php +++ b/app/Http/Controllers/Recurring/EditController.php @@ -106,7 +106,6 @@ class EditController extends Controller /** @var RecurrenceTransformer $transformer */ $transformer = app(RecurrenceTransformer::class); - $transformer->setParameters(new ParameterBag()); $array = $transformer->transform($recurrence); $budgets = ExpandedForm::makeSelectListWithEmpty($this->budgetRepos->getActiveBudgets()); $bills = ExpandedForm::makeSelectListWithEmpty($this->billRepository->getActiveBills()); @@ -155,6 +154,10 @@ class EditController extends Controller $array['first_date'] = substr((string) $array['first_date'], 0, 10); $array['repeat_until'] = substr((string) $array['repeat_until'], 0, 10); $array['transactions'][0]['tags'] = implode(',', $array['transactions'][0]['tags'] ?? []); + $array['transactions'][0]['amount'] = round((float) $array['transactions'][0]['amount'], $array['transactions'][0]['currency_decimal_places']); + if(null !== $array['transactions'][0]['foreign_amount']) { + $array['transactions'][0]['foreign_amount'] = round((float) $array['transactions'][0]['foreign_amount'], $array['transactions'][0]['foreign_currency_decimal_places']); + } return view( 'recurring.edit', diff --git a/app/Http/Controllers/ReportController.php b/app/Http/Controllers/ReportController.php index 46506681d6..faf704fa10 100644 --- a/app/Http/Controllers/ReportController.php +++ b/app/Http/Controllers/ReportController.php @@ -155,16 +155,7 @@ class ReportController extends Controller $start->endOfDay(); // end of day so the final balance is at the end of that day. $end->endOfDay(); - app('view')->share( - 'subTitle', - trans( - 'firefly.report_category', - [ - 'start' => $start->isoFormat($this->monthAndDayFormat), - 'end' => $end->isoFormat($this->monthAndDayFormat), - ] - ) - ); + app('view')->share('subTitle', trans('firefly.report_category', ['start' => $start->isoFormat($this->monthAndDayFormat), 'end' => $end->isoFormat($this->monthAndDayFormat),])); $generator = ReportGeneratorFactory::reportGenerator('Category', $start, $end); $generator->setAccounts($accounts); diff --git a/app/TransactionRules/Engine/SearchRuleEngine.php b/app/TransactionRules/Engine/SearchRuleEngine.php index 5861cf888f..70f55f4d24 100644 --- a/app/TransactionRules/Engine/SearchRuleEngine.php +++ b/app/TransactionRules/Engine/SearchRuleEngine.php @@ -376,15 +376,14 @@ class SearchRuleEngine implements RuleEngineInterface $collection = $this->findStrictRule($rule); $this->processResults($rule, $collection); - Log::debug(sprintf('SearchRuleEngine:: done processing strict rule #%d', $rule->id)); $result = $collection->count() > 0; if (true === $result) { - Log::debug(sprintf('SearchRuleEngine:: rule #%d was triggered (on %d transaction(s)).', $rule->id, $collection->count())); + Log::debug(sprintf('SearchRuleEngine:: Done. 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())); + Log::debug(sprintf('SearchRuleEngine:: Done. Rule #%d was not triggered (on %d transaction(s)).', $rule->id, $collection->count())); return false; } @@ -496,7 +495,7 @@ class SearchRuleEngine implements RuleEngineInterface $collection = $this->findNonStrictRule($rule); $this->processResults($rule, $collection); - Log::debug(sprintf('SearchRuleEngine:: done processing non-strict rule #%d', $rule->id)); + Log::debug(sprintf('SearchRuleEngine:: Done processing non-strict rule #%d', $rule->id)); return $collection->count() > 0; } @@ -534,6 +533,7 @@ class SearchRuleEngine implements RuleEngineInterface return; } } + Log::debug(sprintf('Done with rule group #%d.', $group->id)); } /** diff --git a/changelog.md b/changelog.md index edd3a6e4dd..7f0edb50a2 100644 --- a/changelog.md +++ b/changelog.md @@ -8,8 +8,11 @@ This project adheres to [Semantic Versioning](http://semver.org/). ### Fixed - [Issue 11157](https://github.com/firefly-iii/firefly-iii/issues/11157) (Redacted amounts misbehave with Reports) reported by @barreeeiroo +- #11166 - #11185 + + ## 6.4.4 - 2025-11-02 ### Added From 1a81ae466bc0bab34fe66f157da5b4f732a959b8 Mon Sep 17 00:00:00 2001 From: JC5 Date: Sat, 8 Nov 2025 08:17:33 +0100 Subject: [PATCH 28/29] =?UTF-8?q?=F0=9F=A4=96=20Auto=20commit=20for=20rele?= =?UTF-8?q?ase=20'develop'=20on=202025-11-08?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../Controllers/Recurring/EditController.php | 39 ++-- app/Http/Controllers/ReportController.php | 2 +- changelog.md | 2 +- config/firefly.php | 4 +- package-lock.json | 189 +++++++++--------- 5 files changed, 117 insertions(+), 119 deletions(-) diff --git a/app/Http/Controllers/Recurring/EditController.php b/app/Http/Controllers/Recurring/EditController.php index d32f789295..45ada44542 100644 --- a/app/Http/Controllers/Recurring/EditController.php +++ b/app/Http/Controllers/Recurring/EditController.php @@ -44,7 +44,6 @@ use Illuminate\Http\Request; use Illuminate\Routing\Redirector; use Illuminate\Support\Facades\Log; use Illuminate\View\View; -use Symfony\Component\HttpFoundation\ParameterBag; /** * Class EditController @@ -90,29 +89,29 @@ class EditController extends Controller 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!'); } // enrich /** @var User $admin */ - $admin = auth()->user(); - $enrichment = new RecurringEnrichment(); + $admin = auth()->user(); + $enrichment = new RecurringEnrichment(); $enrichment->setUser($admin); /** @var Recurrence $recurrence */ - $recurrence = $enrichment->enrichSingle($recurrence); + $recurrence = $enrichment->enrichSingle($recurrence); /** @var RecurrenceTransformer $transformer */ - $transformer = app(RecurrenceTransformer::class); - $array = $transformer->transform($recurrence); - $budgets = ExpandedForm::makeSelectListWithEmpty($this->budgetRepos->getActiveBudgets()); - $bills = ExpandedForm::makeSelectListWithEmpty($this->billRepository->getActiveBills()); + $transformer = app(RecurrenceTransformer::class); + $array = $transformer->transform($recurrence); + $budgets = ExpandedForm::makeSelectListWithEmpty($this->budgetRepos->getActiveBudgets()); + $bills = 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 = sprintf('%s,%s', $currentRepType, $repetition->repetition_moment); } @@ -123,8 +122,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'), @@ -136,26 +135,26 @@ class EditController extends Controller $repetitionEnd = 'times'; } - $weekendResponses = [ + $weekendResponses = [ RecurrenceRepetitionWeekend::WEEKEND_DO_NOTHING->value => (string) trans('firefly.do_nothing'), RecurrenceRepetitionWeekend::WEEKEND_SKIP_CREATION->value => (string) trans('firefly.skip_transaction'), RecurrenceRepetitionWeekend::WEEKEND_TO_FRIDAY->value => (string) trans('firefly.jump_to_friday'), RecurrenceRepetitionWeekend::WEEKEND_TO_MONDAY->value => (string) trans('firefly.jump_to_monday'), ]; - $hasOldInput = null !== $request->old('_token'); - $preFilled = [ + $hasOldInput = null !== $request->old('_token'); + $preFilled = [ 'transaction_type' => strtolower((string) $recurrence->transactionType->type), 'active' => $hasOldInput ? (bool) $request->old('active') : $recurrence->active, 'apply_rules' => $hasOldInput ? (bool) $request->old('apply_rules') : $recurrence->apply_rules, 'deposit_source_id' => $array['transactions'][0]['source_id'], 'withdrawal_destination_id' => $array['transactions'][0]['destination_id'], ]; - $array['first_date'] = substr((string) $array['first_date'], 0, 10); - $array['repeat_until'] = substr((string) $array['repeat_until'], 0, 10); - $array['transactions'][0]['tags'] = implode(',', $array['transactions'][0]['tags'] ?? []); + $array['first_date'] = substr((string) $array['first_date'], 0, 10); + $array['repeat_until'] = substr((string) $array['repeat_until'], 0, 10); + $array['transactions'][0]['tags'] = implode(',', $array['transactions'][0]['tags'] ?? []); $array['transactions'][0]['amount'] = round((float) $array['transactions'][0]['amount'], $array['transactions'][0]['currency_decimal_places']); - if(null !== $array['transactions'][0]['foreign_amount']) { + if (null !== $array['transactions'][0]['foreign_amount']) { $array['transactions'][0]['foreign_amount'] = round((float) $array['transactions'][0]['foreign_amount'], $array['transactions'][0]['foreign_currency_decimal_places']); } diff --git a/app/Http/Controllers/ReportController.php b/app/Http/Controllers/ReportController.php index faf704fa10..48b37d70ba 100644 --- a/app/Http/Controllers/ReportController.php +++ b/app/Http/Controllers/ReportController.php @@ -155,7 +155,7 @@ class ReportController extends Controller $start->endOfDay(); // end of day so the final balance is at the end of that day. $end->endOfDay(); - app('view')->share('subTitle', trans('firefly.report_category', ['start' => $start->isoFormat($this->monthAndDayFormat), 'end' => $end->isoFormat($this->monthAndDayFormat),])); + app('view')->share('subTitle', trans('firefly.report_category', ['start' => $start->isoFormat($this->monthAndDayFormat), 'end' => $end->isoFormat($this->monthAndDayFormat)])); $generator = ReportGeneratorFactory::reportGenerator('Category', $start, $end); $generator->setAccounts($accounts); diff --git a/changelog.md b/changelog.md index 4d8c7206fa..5683dbc248 100644 --- a/changelog.md +++ b/changelog.md @@ -8,7 +8,7 @@ This project adheres to [Semantic Versioning](http://semver.org/). ### Fixed - [Issue 11157](https://github.com/firefly-iii/firefly-iii/issues/11157) (Redacted amounts misbehave with Reports) reported by @barreeeiroo -- #11166 +- [Issue 11166](https://github.com/firefly-iii/firefly-iii/issues/11166) (Optional transaction information field not saved when updating a recuring transaction) reported by @Old-Veeh - [Issue 11185](https://github.com/firefly-iii/firefly-iii/issues/11185) (Internal server error after apply rule) reported by @Citroene ## 6.4.4 - 2025-11-02 diff --git a/config/firefly.php b/config/firefly.php index 3a1b91c84e..bcd9cc0992 100644 --- a/config/firefly.php +++ b/config/firefly.php @@ -78,8 +78,8 @@ return [ 'running_balance_column' => env('USE_RUNNING_BALANCE', false), // see cer.php for exchange rates feature flag. ], - 'version' => 'develop/2025-11-07', - 'build_time' => 1762545905, + 'version' => 'develop/2025-11-08', + 'build_time' => 1762586129, 'api_version' => '2.1.0', // field is no longer used. 'db_version' => 28, // field is no longer used. diff --git a/package-lock.json b/package-lock.json index bfb2e959b0..83896a722d 100644 --- a/package-lock.json +++ b/package-lock.json @@ -2589,9 +2589,9 @@ } }, "node_modules/@rollup/rollup-android-arm-eabi": { - "version": "4.53.0", - "resolved": "https://registry.npmjs.org/@rollup/rollup-android-arm-eabi/-/rollup-android-arm-eabi-4.53.0.tgz", - "integrity": "sha512-MX3DD/o2W36nlgQb8KA5QtUw/bK5aR9YDzNmX1PRHZAa6LF/MQCWMN477CgBMg8gH1vEiEZsjWRIZeL/7ttUVA==", + "version": "4.53.1", + "resolved": "https://registry.npmjs.org/@rollup/rollup-android-arm-eabi/-/rollup-android-arm-eabi-4.53.1.tgz", + "integrity": "sha512-bxZtughE4VNVJlL1RdoSE545kc4JxL7op57KKoi59/gwuU5rV6jLWFXXc8jwgFoT6vtj+ZjO+Z2C5nrY0Cl6wA==", "cpu": [ "arm" ], @@ -2603,9 +2603,9 @@ ] }, "node_modules/@rollup/rollup-android-arm64": { - "version": "4.53.0", - "resolved": "https://registry.npmjs.org/@rollup/rollup-android-arm64/-/rollup-android-arm64-4.53.0.tgz", - "integrity": "sha512-U4/R8ZvikDYLkl+hyAGP23SRHp3LwYSRy9SvJqsnva7TYLhVMy39RTVCYn1DdRNxXl1CyCQgE/mXKm9jaQT4ig==", + "version": "4.53.1", + "resolved": "https://registry.npmjs.org/@rollup/rollup-android-arm64/-/rollup-android-arm64-4.53.1.tgz", + "integrity": "sha512-44a1hreb02cAAfAKmZfXVercPFaDjqXCK+iKeVOlJ9ltvnO6QqsBHgKVPTu+MJHSLLeMEUbeG2qiDYgbFPU48g==", "cpu": [ "arm64" ], @@ -2617,9 +2617,9 @@ ] }, "node_modules/@rollup/rollup-darwin-arm64": { - "version": "4.53.0", - "resolved": "https://registry.npmjs.org/@rollup/rollup-darwin-arm64/-/rollup-darwin-arm64-4.53.0.tgz", - "integrity": "sha512-nBG2BXRU3ifdK0HdqBKaT5VI6ScoIpABYZ+dWwQkIOYd8Suo4iykgPikjhsTd7NeHgJJ3OqlKYCcNkZtB1iLVQ==", + "version": "4.53.1", + "resolved": "https://registry.npmjs.org/@rollup/rollup-darwin-arm64/-/rollup-darwin-arm64-4.53.1.tgz", + "integrity": "sha512-usmzIgD0rf1syoOZ2WZvy8YpXK5G1V3btm3QZddoGSa6mOgfXWkkv+642bfUUldomgrbiLQGrPryb7DXLovPWQ==", "cpu": [ "arm64" ], @@ -2631,9 +2631,9 @@ ] }, "node_modules/@rollup/rollup-darwin-x64": { - "version": "4.53.0", - "resolved": "https://registry.npmjs.org/@rollup/rollup-darwin-x64/-/rollup-darwin-x64-4.53.0.tgz", - "integrity": "sha512-QuZ5hYStB/vW7b8zQYtdIPpIfNNlUXtGk8zVTkoTMKzMhE2/6tVvcCWqdWqCVhx6eguJJjKjtZ9lAAG/D3yNeA==", + "version": "4.53.1", + "resolved": "https://registry.npmjs.org/@rollup/rollup-darwin-x64/-/rollup-darwin-x64-4.53.1.tgz", + "integrity": "sha512-is3r/k4vig2Gt8mKtTlzzyaSQ+hd87kDxiN3uDSDwggJLUV56Umli6OoL+/YZa/KvtdrdyNfMKHzL/P4siOOmg==", "cpu": [ "x64" ], @@ -2645,9 +2645,9 @@ ] }, "node_modules/@rollup/rollup-freebsd-arm64": { - "version": "4.53.0", - "resolved": "https://registry.npmjs.org/@rollup/rollup-freebsd-arm64/-/rollup-freebsd-arm64-4.53.0.tgz", - "integrity": "sha512-4yYPm1PJwK/HKI4FzElAPj2EAAFaaLUWzXV3S3edKy71JcEVzBCpgaXyEcDh3blBIjLml+aMkj6HEVGSuzpz+g==", + "version": "4.53.1", + "resolved": "https://registry.npmjs.org/@rollup/rollup-freebsd-arm64/-/rollup-freebsd-arm64-4.53.1.tgz", + "integrity": "sha512-QJ1ksgp/bDJkZB4daldVmHaEQkG4r8PUXitCOC2WRmRaSaHx5RwPoI3DHVfXKwDkB+Sk6auFI/+JHacTekPRSw==", "cpu": [ "arm64" ], @@ -2659,9 +2659,9 @@ ] }, "node_modules/@rollup/rollup-freebsd-x64": { - "version": "4.53.0", - "resolved": "https://registry.npmjs.org/@rollup/rollup-freebsd-x64/-/rollup-freebsd-x64-4.53.0.tgz", - "integrity": "sha512-1SvE5euwWV8JqFc4zEAqHbJbf2yJl00EoHVcnlFqLzjrIExYttLxfZeMDIXY6Yx+bskphrQakpChZKzE2JECEg==", + "version": "4.53.1", + "resolved": "https://registry.npmjs.org/@rollup/rollup-freebsd-x64/-/rollup-freebsd-x64-4.53.1.tgz", + "integrity": "sha512-J6ma5xgAzvqsnU6a0+jgGX/gvoGokqpkx6zY4cWizRrm0ffhHDpJKQgC8dtDb3+MqfZDIqs64REbfHDMzxLMqQ==", "cpu": [ "x64" ], @@ -2673,9 +2673,9 @@ ] }, "node_modules/@rollup/rollup-linux-arm-gnueabihf": { - "version": "4.53.0", - "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm-gnueabihf/-/rollup-linux-arm-gnueabihf-4.53.0.tgz", - "integrity": "sha512-9tS4QyfU5NF5CdUugEi7kWbcGD7pbu6Fm8SunuePH6beeQgtcRZ9K9KVwKHEgfBHeeyrr5OvfV1qWs7PMDOf5w==", + "version": "4.53.1", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm-gnueabihf/-/rollup-linux-arm-gnueabihf-4.53.1.tgz", + "integrity": "sha512-JzWRR41o2U3/KMNKRuZNsDUAcAVUYhsPuMlx5RUldw0E4lvSIXFUwejtYz1HJXohUmqs/M6BBJAUBzKXZVddbg==", "cpu": [ "arm" ], @@ -2687,9 +2687,9 @@ ] }, "node_modules/@rollup/rollup-linux-arm-musleabihf": { - "version": "4.53.0", - "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm-musleabihf/-/rollup-linux-arm-musleabihf-4.53.0.tgz", - "integrity": "sha512-U+0ovxGU9bVJIHfW+oALpHd0ho1YDwhj0yHASDzIj+bOeo+VzEpNtHxcjhFab0YcHUorIMoqyxckC98+81oTJw==", + "version": "4.53.1", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm-musleabihf/-/rollup-linux-arm-musleabihf-4.53.1.tgz", + "integrity": "sha512-L8kRIrnfMrEoHLHtHn+4uYA52fiLDEDyezgxZtGUTiII/yb04Krq+vk3P2Try+Vya9LeCE9ZHU8CXD6J9EhzHQ==", "cpu": [ "arm" ], @@ -2701,9 +2701,9 @@ ] }, "node_modules/@rollup/rollup-linux-arm64-gnu": { - "version": "4.53.0", - "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm64-gnu/-/rollup-linux-arm64-gnu-4.53.0.tgz", - "integrity": "sha512-Cp/TQ+wLjRTqTuiVwLz4XPZMo3ROl7EJYMF8HhMp8Uf+9kOOATB3/p4gGZPpuQ4BP7qEXG29ET24u9+F0ERYkQ==", + "version": "4.53.1", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm64-gnu/-/rollup-linux-arm64-gnu-4.53.1.tgz", + "integrity": "sha512-ysAc0MFRV+WtQ8li8hi3EoFi7us6d1UzaS/+Dp7FYZfg3NdDljGMoVyiIp6Ucz7uhlYDBZ/zt6XI0YEZbUO11Q==", "cpu": [ "arm64" ], @@ -2715,9 +2715,9 @@ ] }, "node_modules/@rollup/rollup-linux-arm64-musl": { - "version": "4.53.0", - "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm64-musl/-/rollup-linux-arm64-musl-4.53.0.tgz", - "integrity": "sha512-SuGoAwhsSonrSTEZTiQOGC3+XZfq7rc/qAdAOBrYYIp8pu+Wh4EFFXl6+QYYNbNrHL3DnVoWACLwnfwlTa0neA==", + "version": "4.53.1", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm64-musl/-/rollup-linux-arm64-musl-4.53.1.tgz", + "integrity": "sha512-UV6l9MJpDbDZZ/fJvqNcvO1PcivGEf1AvKuTcHoLjVZVFeAMygnamCTDikCVMRnA+qJe+B3pSbgX2+lBMqgBhA==", "cpu": [ "arm64" ], @@ -2729,9 +2729,9 @@ ] }, "node_modules/@rollup/rollup-linux-loong64-gnu": { - "version": "4.53.0", - "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-loong64-gnu/-/rollup-linux-loong64-gnu-4.53.0.tgz", - "integrity": "sha512-EOKej1x0WoePnJWfg7ZbnUqiuiQunshzsKZSIfTHFDiCY9pnsr3Weit1GjcpGnun7H5HuRREqkT2c9CcKxNwSg==", + "version": "4.53.1", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-loong64-gnu/-/rollup-linux-loong64-gnu-4.53.1.tgz", + "integrity": "sha512-UDUtelEprkA85g95Q+nj3Xf0M4hHa4DiJ+3P3h4BuGliY4NReYYqwlc0Y8ICLjN4+uIgCEvaygYlpf0hUj90Yg==", "cpu": [ "loong64" ], @@ -2743,9 +2743,9 @@ ] }, "node_modules/@rollup/rollup-linux-ppc64-gnu": { - "version": "4.53.0", - "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-ppc64-gnu/-/rollup-linux-ppc64-gnu-4.53.0.tgz", - "integrity": "sha512-YAvv2aMFlfiawJ97lutomuehG2Yowd4YgsAqI85XNiMK9eBA1vEMZHt3BShg8cUvak71BM+VFRHddqc+OrRdVA==", + "version": "4.53.1", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-ppc64-gnu/-/rollup-linux-ppc64-gnu-4.53.1.tgz", + "integrity": "sha512-vrRn+BYhEtNOte/zbc2wAUQReJXxEx2URfTol6OEfY2zFEUK92pkFBSXRylDM7aHi+YqEPJt9/ABYzmcrS4SgQ==", "cpu": [ "ppc64" ], @@ -2757,9 +2757,9 @@ ] }, "node_modules/@rollup/rollup-linux-riscv64-gnu": { - "version": "4.53.0", - "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-riscv64-gnu/-/rollup-linux-riscv64-gnu-4.53.0.tgz", - "integrity": "sha512-DxZe/sMVaqN+s5kVk3Iq619Rgyl1JCTob7xOLSNC84mbzg3NYTSheqqrtVllYjLYo4wm9YyqjVS57miuzNyXbQ==", + "version": "4.53.1", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-riscv64-gnu/-/rollup-linux-riscv64-gnu-4.53.1.tgz", + "integrity": "sha512-gto/1CxHyi4A7YqZZNznQYrVlPSaodOBPKM+6xcDSCMVZN/Fzb4K+AIkNz/1yAYz9h3Ng+e2fY9H6bgawVq17w==", "cpu": [ "riscv64" ], @@ -2771,9 +2771,9 @@ ] }, "node_modules/@rollup/rollup-linux-riscv64-musl": { - "version": "4.53.0", - "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-riscv64-musl/-/rollup-linux-riscv64-musl-4.53.0.tgz", - "integrity": "sha512-N7+iZ0jEhwLY1FEsjbCR9lAxIZP0k+3Cghx9vSQWn+rcW8SgN8VcCmwJDoPDaGKTzWWB791U1s79BSLnEhUa0Q==", + "version": "4.53.1", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-riscv64-musl/-/rollup-linux-riscv64-musl-4.53.1.tgz", + "integrity": "sha512-KZ6Vx7jAw3aLNjFR8eYVcQVdFa/cvBzDNRFM3z7XhNNunWjA03eUrEwJYPk0G8V7Gs08IThFKcAPS4WY/ybIrQ==", "cpu": [ "riscv64" ], @@ -2785,9 +2785,9 @@ ] }, "node_modules/@rollup/rollup-linux-s390x-gnu": { - "version": "4.53.0", - "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-s390x-gnu/-/rollup-linux-s390x-gnu-4.53.0.tgz", - "integrity": "sha512-MA/NVneZyIskjvXdh2NR9YcPi7eHWBlQOWP2X8OymzyeUEB0JfUpmbKQZngHmOlyleV2IoR5nHIgMSRjLskOnA==", + "version": "4.53.1", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-s390x-gnu/-/rollup-linux-s390x-gnu-4.53.1.tgz", + "integrity": "sha512-HvEixy2s/rWNgpwyKpXJcHmE7om1M89hxBTBi9Fs6zVuLU4gOrEMQNbNsN/tBVIMbLyysz/iwNiGtMOpLAOlvA==", "cpu": [ "s390x" ], @@ -2799,9 +2799,9 @@ ] }, "node_modules/@rollup/rollup-linux-x64-gnu": { - "version": "4.53.0", - "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-x64-gnu/-/rollup-linux-x64-gnu-4.53.0.tgz", - "integrity": "sha512-iYEYzYpfaSCkunVD0LOYrD9OMc357be7+rBuCxW1qvsjCGl+95iWnYAFfyEoxAm6koasNN3tFxFYze5MKl5S3A==", + "version": "4.53.1", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-x64-gnu/-/rollup-linux-x64-gnu-4.53.1.tgz", + "integrity": "sha512-E/n8x2MSjAQgjj9IixO4UeEUeqXLtiA7pyoXCFYLuXpBA/t2hnbIdxHfA7kK9BFsYAoNU4st1rHYdldl8dTqGA==", "cpu": [ "x64" ], @@ -2813,9 +2813,9 @@ ] }, "node_modules/@rollup/rollup-linux-x64-musl": { - "version": "4.53.0", - "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-x64-musl/-/rollup-linux-x64-musl-4.53.0.tgz", - "integrity": "sha512-FoRekOqhRUKbJMsB5LvhQchDeFeNlS6UGUwi0p3860sxE4zE+lp07FnkuR+yQH0rSn6iLXsnr44jnorgl8mGlQ==", + "version": "4.53.1", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-x64-musl/-/rollup-linux-x64-musl-4.53.1.tgz", + "integrity": "sha512-IhJ087PbLOQXCN6Ui/3FUkI9pWNZe/Z7rEIVOzMsOs1/HSAECCvSZ7PkIbkNqL/AZn6WbZvnoVZw/qwqYMo4/w==", "cpu": [ "x64" ], @@ -2827,9 +2827,9 @@ ] }, "node_modules/@rollup/rollup-openharmony-arm64": { - "version": "4.53.0", - "resolved": "https://registry.npmjs.org/@rollup/rollup-openharmony-arm64/-/rollup-openharmony-arm64-4.53.0.tgz", - "integrity": "sha512-mEN2k1zKO5PUzW8W15hKpLh+zZI2by1onX2GfI93OekGbKN5aTjWGo7yAjwRZLjhAgs2UQcXmEWbIw0R5B4RnQ==", + "version": "4.53.1", + "resolved": "https://registry.npmjs.org/@rollup/rollup-openharmony-arm64/-/rollup-openharmony-arm64-4.53.1.tgz", + "integrity": "sha512-0++oPNgLJHBblreu0SFM7b3mAsBJBTY0Ksrmu9N6ZVrPiTkRgda52mWR7TKhHAsUb9noCjFvAw9l6ZO1yzaVbA==", "cpu": [ "arm64" ], @@ -2841,9 +2841,9 @@ ] }, "node_modules/@rollup/rollup-win32-arm64-msvc": { - "version": "4.53.0", - "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-arm64-msvc/-/rollup-win32-arm64-msvc-4.53.0.tgz", - "integrity": "sha512-V1dEKUXqevG0wxo6ysGrL7g2T6tndmo6Uqw5vzOqCXv+DHc8m0RRgcCm+96iigDniwpvV6o4HZtkRUnuTz9XiA==", + "version": "4.53.1", + "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-arm64-msvc/-/rollup-win32-arm64-msvc-4.53.1.tgz", + "integrity": "sha512-VJXivz61c5uVdbmitLkDlbcTk9Or43YC2QVLRkqp86QoeFSqI81bNgjhttqhKNMKnQMWnecOCm7lZz4s+WLGpQ==", "cpu": [ "arm64" ], @@ -2855,9 +2855,9 @@ ] }, "node_modules/@rollup/rollup-win32-ia32-msvc": { - "version": "4.53.0", - "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-ia32-msvc/-/rollup-win32-ia32-msvc-4.53.0.tgz", - "integrity": "sha512-93mJ8Hm9+vbhtu+A1VtmwptSqCYojtMQkBGDjLytCWC8muxmZLGo/MA/4CMAWf6+QpKlxTTMDAHdTC+kxn9ZcQ==", + "version": "4.53.1", + "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-ia32-msvc/-/rollup-win32-ia32-msvc-4.53.1.tgz", + "integrity": "sha512-NmZPVTUOitCXUH6erJDzTQ/jotYw4CnkMDjCYRxNHVD9bNyfrGoIse684F9okwzKCV4AIHRbUkeTBc9F2OOH5Q==", "cpu": [ "ia32" ], @@ -2869,9 +2869,9 @@ ] }, "node_modules/@rollup/rollup-win32-x64-gnu": { - "version": "4.53.0", - "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-x64-gnu/-/rollup-win32-x64-gnu-4.53.0.tgz", - "integrity": "sha512-1OrYs0p/deXEFLUW1gvyjIabmsJKY3I/9fCUA1K6demaNc4iEhXDW6RnyPv/BWqb7NRmQ9+i+SKoi1HgJxWcwg==", + "version": "4.53.1", + "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-x64-gnu/-/rollup-win32-x64-gnu-4.53.1.tgz", + "integrity": "sha512-2SNj7COIdAf6yliSpLdLG8BEsp5lgzRehgfkP0Av8zKfQFKku6JcvbobvHASPJu4f3BFxej5g+HuQPvqPhHvpQ==", "cpu": [ "x64" ], @@ -2883,9 +2883,9 @@ ] }, "node_modules/@rollup/rollup-win32-x64-msvc": { - "version": "4.53.0", - "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-x64-msvc/-/rollup-win32-x64-msvc-4.53.0.tgz", - "integrity": "sha512-xtSei8paPcLy3GzeeOjoRrllJn6EN8PB+/bXnhZ4R0AaviJsRwtKxFZRVnfFXNZTTp0nLeDo+BcEuIfdZS14/A==", + "version": "4.53.1", + "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-x64-msvc/-/rollup-win32-x64-msvc-4.53.1.tgz", + "integrity": "sha512-rLarc1Ofcs3DHtgSzFO31pZsCh8g05R2azN1q3fF+H423Co87My0R+tazOEvYVKXSLh8C4LerMK41/K7wlklcg==", "cpu": [ "x64" ], @@ -5736,9 +5736,9 @@ "license": "MIT" }, "node_modules/electron-to-chromium": { - "version": "1.5.248", - "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.5.248.tgz", - "integrity": "sha512-zsur2yunphlyAO4gIubdJEXCK6KOVvtpiuDfCIqbM9FjcnMYiyn0ICa3hWfPr0nc41zcLWobgy1iL7VvoOyA2Q==", + "version": "1.5.249", + "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.5.249.tgz", + "integrity": "sha512-5vcfL3BBe++qZ5kuFhD/p8WOM1N9m3nwvJPULJx+4xf2usSlZFJ0qoNYO2fOX4hi3ocuDcmDobtA+5SFr4OmBg==", "dev": true, "license": "ISC" }, @@ -10110,11 +10110,10 @@ } }, "node_modules/rollup": { - "version": "4.53.0", - "resolved": "https://registry.npmjs.org/rollup/-/rollup-4.53.0.tgz", - "integrity": "sha512-43Z5T+4YTdfYkkA6CStU2DUYh7Ha9dLtvK+K3n0yEE/QS+4i28vSxrQsM59KqpvmT4tbOwJsFnRGMj/tvmQwWw==", + "version": "4.53.1", + "resolved": "https://registry.npmjs.org/rollup/-/rollup-4.53.1.tgz", + "integrity": "sha512-n2I0V0lN3E9cxxMqBCT3opWOiQBzRN7UG60z/WDKqdX2zHUS/39lezBcsckZFsV6fUTSnfqI7kHf60jDAPGKug==", "dev": true, - "hasInstallScript": true, "license": "MIT", "dependencies": { "@types/estree": "1.0.8" @@ -10127,28 +10126,28 @@ "npm": ">=8.0.0" }, "optionalDependencies": { - "@rollup/rollup-android-arm-eabi": "4.53.0", - "@rollup/rollup-android-arm64": "4.53.0", - "@rollup/rollup-darwin-arm64": "4.53.0", - "@rollup/rollup-darwin-x64": "4.53.0", - "@rollup/rollup-freebsd-arm64": "4.53.0", - "@rollup/rollup-freebsd-x64": "4.53.0", - "@rollup/rollup-linux-arm-gnueabihf": "4.53.0", - "@rollup/rollup-linux-arm-musleabihf": "4.53.0", - "@rollup/rollup-linux-arm64-gnu": "4.53.0", - "@rollup/rollup-linux-arm64-musl": "4.53.0", - "@rollup/rollup-linux-loong64-gnu": "4.53.0", - "@rollup/rollup-linux-ppc64-gnu": "4.53.0", - "@rollup/rollup-linux-riscv64-gnu": "4.53.0", - "@rollup/rollup-linux-riscv64-musl": "4.53.0", - "@rollup/rollup-linux-s390x-gnu": "4.53.0", - "@rollup/rollup-linux-x64-gnu": "4.53.0", - "@rollup/rollup-linux-x64-musl": "4.53.0", - "@rollup/rollup-openharmony-arm64": "4.53.0", - "@rollup/rollup-win32-arm64-msvc": "4.53.0", - "@rollup/rollup-win32-ia32-msvc": "4.53.0", - "@rollup/rollup-win32-x64-gnu": "4.53.0", - "@rollup/rollup-win32-x64-msvc": "4.53.0", + "@rollup/rollup-android-arm-eabi": "4.53.1", + "@rollup/rollup-android-arm64": "4.53.1", + "@rollup/rollup-darwin-arm64": "4.53.1", + "@rollup/rollup-darwin-x64": "4.53.1", + "@rollup/rollup-freebsd-arm64": "4.53.1", + "@rollup/rollup-freebsd-x64": "4.53.1", + "@rollup/rollup-linux-arm-gnueabihf": "4.53.1", + "@rollup/rollup-linux-arm-musleabihf": "4.53.1", + "@rollup/rollup-linux-arm64-gnu": "4.53.1", + "@rollup/rollup-linux-arm64-musl": "4.53.1", + "@rollup/rollup-linux-loong64-gnu": "4.53.1", + "@rollup/rollup-linux-ppc64-gnu": "4.53.1", + "@rollup/rollup-linux-riscv64-gnu": "4.53.1", + "@rollup/rollup-linux-riscv64-musl": "4.53.1", + "@rollup/rollup-linux-s390x-gnu": "4.53.1", + "@rollup/rollup-linux-x64-gnu": "4.53.1", + "@rollup/rollup-linux-x64-musl": "4.53.1", + "@rollup/rollup-openharmony-arm64": "4.53.1", + "@rollup/rollup-win32-arm64-msvc": "4.53.1", + "@rollup/rollup-win32-ia32-msvc": "4.53.1", + "@rollup/rollup-win32-x64-gnu": "4.53.1", + "@rollup/rollup-win32-x64-msvc": "4.53.1", "fsevents": "~2.3.2" } }, From 732d6c807c504a7fb586429f8a1dc20b912da36f Mon Sep 17 00:00:00 2001 From: JC5 Date: Sat, 8 Nov 2025 11:24:08 +0100 Subject: [PATCH 29/29] =?UTF-8?q?=F0=9F=A4=96=20Auto=20commit=20for=20rele?= =?UTF-8?q?ase=20'v6.4.5'=20on=202025-11-08?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- config/firefly.php | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/config/firefly.php b/config/firefly.php index bcd9cc0992..4aebc936e2 100644 --- a/config/firefly.php +++ b/config/firefly.php @@ -78,8 +78,8 @@ return [ 'running_balance_column' => env('USE_RUNNING_BALANCE', false), // see cer.php for exchange rates feature flag. ], - 'version' => 'develop/2025-11-08', - 'build_time' => 1762586129, + 'version' => '6.4.5', + 'build_time' => 1762597345, 'api_version' => '2.1.0', // field is no longer used. 'db_version' => 28, // field is no longer used.