diff --git a/.ci/php-cs-fixer/composer.lock b/.ci/php-cs-fixer/composer.lock
index 1f30d2db98..2614d5842f 100644
--- a/.ci/php-cs-fixer/composer.lock
+++ b/.ci/php-cs-fixer/composer.lock
@@ -1331,16 +1331,16 @@
},
{
"name": "symfony/console",
- "version": "v8.1.2",
+ "version": "v8.1.4",
"source": {
"type": "git",
"url": "https://github.com/symfony/console.git",
- "reference": "535e18a1b8925f6c01a55b171d157ab66c2ace15"
+ "reference": "68efa2ebfd9a362951eb5a8b09fd177c66ddec24"
},
"dist": {
"type": "zip",
- "url": "https://api.github.com/repos/symfony/console/zipball/535e18a1b8925f6c01a55b171d157ab66c2ace15",
- "reference": "535e18a1b8925f6c01a55b171d157ab66c2ace15",
+ "url": "https://api.github.com/repos/symfony/console/zipball/68efa2ebfd9a362951eb5a8b09fd177c66ddec24",
+ "reference": "68efa2ebfd9a362951eb5a8b09fd177c66ddec24",
"shasum": ""
},
"require": {
@@ -1407,7 +1407,7 @@
"terminal"
],
"support": {
- "source": "https://github.com/symfony/console/tree/v8.1.2"
+ "source": "https://github.com/symfony/console/tree/v8.1.4"
},
"funding": [
{
@@ -1427,7 +1427,7 @@
"type": "tidelift"
}
],
- "time": "2026-07-27T13:58:19+00:00"
+ "time": "2026-07-31T12:43:13+00:00"
},
{
"name": "symfony/deprecation-contracts",
diff --git a/app/Api/V1/Controllers/Insight/Income/TagController.php b/app/Api/V1/Controllers/Insight/Income/TagController.php
index 94be2ae461..df99eef909 100644
--- a/app/Api/V1/Controllers/Insight/Income/TagController.php
+++ b/app/Api/V1/Controllers/Insight/Income/TagController.php
@@ -158,10 +158,7 @@ final class TagController extends Controller
'currency_id' => (string) $foreignCurrencyId,
'currency_code' => $journal['foreign_currency_code'],
];
- $response[$foreignKey]['difference'] = bcadd(
- (string) $response[$foreignKey]['difference'],
- Steam::positive($journal['foreign_amount'])
- );
+ $response[$foreignKey]['difference'] = bcadd((string) $response[$foreignKey]['difference'], Steam::positive($journal['foreign_amount']));
$response[$foreignKey]['difference_float'] = (float) $response[$foreignKey]['difference'];
}
}
diff --git a/app/Api/V1/Controllers/Insight/Transfer/TagController.php b/app/Api/V1/Controllers/Insight/Transfer/TagController.php
index b7b85fd376..f92a7aa9f0 100644
--- a/app/Api/V1/Controllers/Insight/Transfer/TagController.php
+++ b/app/Api/V1/Controllers/Insight/Transfer/TagController.php
@@ -155,10 +155,7 @@ final class TagController extends Controller
'currency_id' => (string) $foreignCurrencyId,
'currency_code' => $journal['foreign_currency_code'],
];
- $response[$foreignKey]['difference'] = bcadd(
- (string) $response[$foreignKey]['difference'],
- Steam::positive($journal['foreign_amount'])
- );
+ $response[$foreignKey]['difference'] = bcadd((string) $response[$foreignKey]['difference'], Steam::positive($journal['foreign_amount']));
$response[$foreignKey]['difference_float'] = (float) $response[$foreignKey]['difference']; // intentional float
}
}
diff --git a/app/Exceptions/GracefulNotFoundHandler.php b/app/Exceptions/GracefulNotFoundHandler.php
index 7339838641..741e900fd4 100644
--- a/app/Exceptions/GracefulNotFoundHandler.php
+++ b/app/Exceptions/GracefulNotFoundHandler.php
@@ -63,6 +63,7 @@ class GracefulNotFoundHandler extends ExceptionHandler
if (!auth()->check()) {
return parent::render($request, $e);
}
+
switch ($name) {
default:
Log::warning(sprintf('GracefulNotFoundHandler cannot handle route with name "%s"', $name));
@@ -261,6 +262,7 @@ class GracefulNotFoundHandler extends ExceptionHandler
if (TransactionTypeEnum::RECONCILIATION->value === $type) {
session()->flash('info', trans('errors.note_not_found_reconciliation', ['description' => $group->title ?? $journal->description]));
+
return redirect(route('accounts.index', ['asset']));
}
session()->flash('info', trans('errors.note_not_found_group', ['description' => $group->title ?? $journal->description]));
diff --git a/app/Http/Controllers/Account/CreateController.php b/app/Http/Controllers/Account/CreateController.php
index bb7a4dd3e9..eac446fe15 100644
--- a/app/Http/Controllers/Account/CreateController.php
+++ b/app/Http/Controllers/Account/CreateController.php
@@ -44,7 +44,7 @@ final class CreateController extends Controller
{
use ModelInformation;
- private AttachmentHelperInterface $attachments;
+ private AttachmentHelperInterface $attachments;
private AccountRepositoryInterface $repository;
/**
@@ -57,7 +57,7 @@ final class CreateController extends Controller
// translations:
$this->middleware(function ($request, $next) {
app('view')->share('mainTitleIcon', 'bi-credit-card');
- app('view')->share('title', (string)trans('firefly.accounts'));
+ app('view')->share('title', (string) trans('firefly.accounts'));
$this->repository = app(AccountRepositoryInterface::class);
$this->attachments = app(AttachmentHelperInterface::class);
@@ -71,12 +71,12 @@ final class CreateController extends Controller
*
* @return Factory|View
*/
- public function create(Request $request, string $objectType): Factory | \Illuminate\Contracts\View\View
+ public function create(Request $request, string $objectType): Factory|\Illuminate\Contracts\View\View
{
$subTitleIcon = config(sprintf('firefly.subIconsByIdentifier.%s', $objectType));
- $subTitle = (string)trans(sprintf('firefly.make_new_%s_account', $objectType));
+ $subTitle = (string) trans(sprintf('firefly.make_new_%s_account', $objectType));
$roles = $this->getRoles();
- $from = $request->input('_from', '');
+ $from = $request->input('_from', '');
$liabilityTypes = $this->getLiabilityTypes();
$hasOldInput = null !== $request->old('_token');
$locations = [
@@ -90,7 +90,7 @@ final class CreateController extends Controller
$liabilityDirections = ['debit' => trans('firefly.liability_direction_debit'), 'credit' => trans('firefly.liability_direction_credit')];
// interest calculation periods:
- $interestPeriods = [];
+ $interestPeriods = [];
foreach (config('firefly.interest_periods') as $period) {
$interestPeriods[$period] = trans(sprintf('firefly.interest_calc_%s', $period));
}
@@ -98,10 +98,10 @@ final class CreateController extends Controller
// prefill some data
$request->session()->flash('preFilled', [
'currency_id' => $this->primaryCurrency->id,
- 'include_net_worth' => !$hasOldInput || (bool)$request->old('include_net_worth'),
+ 'include_net_worth' => !$hasOldInput || (bool) $request->old('include_net_worth'),
]);
// issue #8321
- $showNetWorth = true;
+ $showNetWorth = true;
if ('liabilities' !== $objectType && 'asset' !== $objectType) {
$showNetWorth = false;
}
@@ -129,9 +129,9 @@ final class CreateController extends Controller
public function store(AccountFormRequest $request): RedirectResponse
{
- $data = $request->getAccountData();
- $account = $this->repository->store($data);
- $request->session()->flash('success', (string)trans('firefly.stored_new_account', ['name' => $account->name]));
+ $data = $request->getAccountData();
+ $account = $this->repository->store($data);
+ $request->session()->flash('success', (string) trans('firefly.stored_new_account', ['name' => $account->name]));
Preferences::mark();
Log::channel('audit')->info('Stored new account.', $data);
@@ -148,13 +148,13 @@ final class CreateController extends Controller
// store attachment(s):
/** @var null|array $files */
- $files = $request->hasFile('attachments') ? $request->file('attachments') : null;
+ $files = $request->hasFile('attachments') ? $request->file('attachments') : null;
if (null !== $files && !auth()->user()->hasRole('demo')) {
$this->attachments->saveAttachmentsForModel($account, $files);
}
if (null !== $files && auth()->user()->hasRole('demo')) {
Log::channel('audit')->warning(sprintf('The demo user is trying to upload attachments in %s.', __METHOD__));
- session()->flash('info', (string)trans('firefly.no_att_demo_user'));
+ session()->flash('info', (string) trans('firefly.no_att_demo_user'));
}
if (count($this->attachments->getMessages()->get('attachments')) > 0) {
@@ -162,9 +162,9 @@ final class CreateController extends Controller
}
// redirect to previous URL.
- $from = $request->input('_from', '');
- $redirect = redirect(route('index') . $from);
- if (1 === (int)$request->input('create_another')) {
+ $from = $request->input('_from', '');
+ $redirect = redirect(route('index').$from);
+ if (1 === (int) $request->input('create_another')) {
// set value so create routine will not overwrite URL:
$request->session()->put('accounts.create.fromStore', true);
diff --git a/app/Http/Controllers/Account/EditController.php b/app/Http/Controllers/Account/EditController.php
index 3cb8a3b3bf..e4b95ed447 100644
--- a/app/Http/Controllers/Account/EditController.php
+++ b/app/Http/Controllers/Account/EditController.php
@@ -84,7 +84,7 @@ final class EditController extends Controller
if (!$this->isEditableAccount($account)) {
return $this->redirectAccountToAccount($account);
}
- $from = $request->input('_from', '');
+ $from = $request->input('_from', '');
$objectType = config('firefly.shortNamesByFullName')[$account->accountType->type];
$subTitle = (string) trans(sprintf('firefly.edit_%s_account', $objectType), ['name' => $account->name]);
$subTitleIcon = config(sprintf('firefly.subIconsByIdentifier.%s', $objectType));
@@ -165,7 +165,7 @@ final class EditController extends Controller
$request->session()->flash('preFilled', $preFilled);
return view('accounts.edit', [
- 'from'=>$from,
+ 'from' => $from,
'account' => $account,
'currency' => $currency,
'canEditCurrency' => $canEditCurrency,
@@ -214,8 +214,9 @@ final class EditController extends Controller
}
// redirect
- $from = $request->input('_from', '');
- $redirect = redirect(route('index') . $from);;
+ $from = $request->input('_from', '');
+ $redirect = redirect(route('index').$from);
+
if (1 === (int) $request->input('return_to_edit')) {
// set value so edit routine will not overwrite URL:
$request->session()->put('accounts.edit.fromUpdate', true);
diff --git a/app/Http/Controllers/Budget/BudgetLimitController.php b/app/Http/Controllers/Budget/BudgetLimitController.php
index 04d75cd738..de7337738f 100644
--- a/app/Http/Controllers/Budget/BudgetLimitController.php
+++ b/app/Http/Controllers/Budget/BudgetLimitController.php
@@ -198,13 +198,7 @@ final class BudgetLimitController extends Controller
if ($request->expectsJson()) {
$array = $limit->toArray();
// add some extra metadata:
- $spentArr = $this->opsRepository->sumExpenses(
- $limit->start_date,
- $limit->end_date,
- null,
- new Collection()->push($budget),
- $currency
- );
+ $spentArr = $this->opsRepository->sumExpenses($limit->start_date, $limit->end_date, null, new Collection()->push($budget), $currency);
$array['spent'] = $spentArr[$currency->id]['sum'] ?? '0';
$array['left_formatted'] = Amount::formatAnything($limit->transactionCurrency, bcadd($array['spent'], (string) $array['amount']));
$array['amount_formatted'] = Amount::formatAnything($limit->transactionCurrency, $limit['amount']);
diff --git a/app/Http/Controllers/Budget/IndexController.php b/app/Http/Controllers/Budget/IndexController.php
index d40d4432a3..215ebbd484 100644
--- a/app/Http/Controllers/Budget/IndexController.php
+++ b/app/Http/Controllers/Budget/IndexController.php
@@ -284,10 +284,7 @@ final class IndexController extends Controller
if (array_key_exists($currency->id, $spentArr) && array_key_exists('sum', $spentArr[$currency->id])) {
$array['spent'][$currency->id]['spent'] = $spentArr[$currency->id]['sum'];
- $array['spent'][$currency->id]['spent_outside'] = Steam::negative(bcsub(
- $spentInLimits[$currency->id],
- $spentArr[$currency->id]['sum']
- ));
+ $array['spent'][$currency->id]['spent_outside'] = Steam::negative(bcsub($spentInLimits[$currency->id], $spentArr[$currency->id]['sum']));
$array['spent'][$currency->id]['currency_id'] = $currency->id;
$array['spent'][$currency->id]['currency_symbol'] = $currency->symbol;
$array['spent'][$currency->id]['currency_decimal_places'] = $currency->decimal_places;
diff --git a/app/Http/Controllers/Chart/BudgetController.php b/app/Http/Controllers/Chart/BudgetController.php
index f4b32fe5c5..ad724137dc 100644
--- a/app/Http/Controllers/Chart/BudgetController.php
+++ b/app/Http/Controllers/Chart/BudgetController.php
@@ -539,13 +539,7 @@ final class BudgetController extends Controller
}
// get spent amount in this period for this currency.
- $sum = $this->opsRepository->sumExpenses(
- $currentStart,
- $currentEnd,
- $accounts,
- new Collection()->push($budget),
- $currency
- );
+ $sum = $this->opsRepository->sumExpenses($currentStart, $currentEnd, $accounts, new Collection()->push($budget), $currency);
$amount = Steam::positive($sum[$currency->id]['sum'] ?? '0');
$chartData[0]['entries'][$title] = Steam::bcround($amount, $currency->decimal_places);
diff --git a/app/Http/Controllers/Controller.php b/app/Http/Controllers/Controller.php
index 787f6f5c16..7ba3b2db5d 100644
--- a/app/Http/Controllers/Controller.php
+++ b/app/Http/Controllers/Controller.php
@@ -41,9 +41,10 @@ use Illuminate\Support\Facades\Log;
use Illuminate\Support\Facades\Route;
use Illuminate\Support\Facades\URL;
use Illuminate\Support\Facades\View;
+
use function Safe\ini_get;
-use function Safe\realpath;
use function Safe\parse_url;
+use function Safe\realpath;
/**
* Class Controller.
@@ -60,13 +61,13 @@ abstract class Controller extends BaseController
use ValidatesRequests;
// fails on PHP < 8.4
- public protected(set) string $name;
- protected bool $convertToPrimary = false;
- protected string $dateTimeFormat;
+ public protected(set) string $name;
+ protected bool $convertToPrimary = false;
+ protected string $dateTimeFormat;
protected ?TransactionCurrency $primaryCurrency;
- protected string $monthAndDayFormat;
- protected string $monthFormat;
- protected string $redirectUrl = '/';
+ protected string $monthAndDayFormat;
+ protected string $monthFormat;
+ protected string $redirectUrl = '/';
/**
* Controller constructor.
@@ -82,7 +83,7 @@ abstract class Controller extends BaseController
return;
}
- $isDemoSite = (bool)$isDemoSiteConfig->data;
+ $isDemoSite = (bool) $isDemoSiteConfig->data;
View::share('IS_DEMO_SITE', $isDemoSite);
View::share('DEMO_USERNAME', config('firefly.demo_username'));
View::share('DEMO_PASSWORD', config('firefly.demo_password'));
@@ -90,12 +91,12 @@ abstract class Controller extends BaseController
View::share('FF_BUILD_TIME', config('firefly.build_time'));
View::share('FF3_FROM', $this->getFromUrl());
// this breaks when running < PHP 8.5 and is totally intentional.
- $input = ' James is cool';
- $output = $input
- |> trim(...)
- |> (fn(string $string) => str_replace(' ', '-', $string))
- |> (fn(string $string) => str_replace(['.', '/', '…'], '', $string))
- |> strtolower(...);
+ $input = ' James is cool';
+ $output = $input
+ |> trim(...)
+ |> (fn (string $string) => str_replace(' ', '-', $string))
+ |> (fn (string $string) => str_replace(['.', '/', '…'], '', $string))
+ |> strtolower(...);
// is webhooks enabled?
View::share(
@@ -106,8 +107,8 @@ abstract class Controller extends BaseController
View::share('featuringCer', true === AppConfiguration::get('enable_exchange_rates', config('cer.enabled'))->data);
// share custom auth guard info.
- $authGuard = config('firefly.authentication_guard');
- $logoutUrl = config('firefly.custom_logout_url');
+ $authGuard = config('firefly.authentication_guard');
+ $logoutUrl = config('firefly.custom_logout_url');
// overrule v2 layout back to v1.
@@ -127,17 +128,17 @@ abstract class Controller extends BaseController
View::share('uploadSize', $uploadSize);
// share is alpha, is beta
- $isAlpha = false;
- $isBeta = false;
- $isDevelop = false;
- if (str_contains((string)config('firefly.version'), 'alpha')) {
+ $isAlpha = false;
+ $isBeta = false;
+ $isDevelop = false;
+ if (str_contains((string) config('firefly.version'), 'alpha')) {
$isAlpha = true;
}
- if (str_contains((string)config('firefly.version'), 'develop') || str_contains((string)config('firefly.version'), 'branch')) {
+ if (str_contains((string) config('firefly.version'), 'develop') || str_contains((string) config('firefly.version'), 'branch')) {
$isDevelop = true;
}
- if (str_contains((string)config('firefly.version'), 'beta')) {
+ if (str_contains((string) config('firefly.version'), 'beta')) {
$isBeta = true;
}
@@ -146,11 +147,11 @@ abstract class Controller extends BaseController
View::share('FF_IS_DEVELOP', $isDevelop);
$this->middleware(function ($request, $next): mixed {
- $locale = Steam::getLocale();
+ $locale = Steam::getLocale();
// translations for specific strings:
- $this->monthFormat = (string)trans('config.month_js', [], $locale);
- $this->monthAndDayFormat = (string)trans('config.month_and_day_js', [], $locale);
- $this->dateTimeFormat = (string)trans('config.date_time_js', [], $locale);
+ $this->monthFormat = (string) trans('config.month_js', [], $locale);
+ $this->monthAndDayFormat = (string) trans('config.month_and_day_js', [], $locale);
+ $this->dateTimeFormat = (string) trans('config.date_time_js', [], $locale);
$darkMode = 'browser';
$this->primaryCurrency = null;
// get shown-intro-preference:
@@ -191,12 +192,13 @@ abstract class Controller extends BaseController
if (array_key_exists('path', $current)) {
$from = $current['path'];
}
- if (array_key_exists('query', $current) && strlen($current['query']) > 0) {
- $from .= '?' . $current['query'];
+ if (array_key_exists('query', $current) && '' !== $current['query']) {
+ $from .= '?'.$current['query'];
}
- if (array_key_exists('fragment', $current) && strlen($current['fragment']) > 0) {
- $from .= '#' . $current['fragment'];
+ if (array_key_exists('fragment', $current) && '' !== $current['fragment']) {
+ $from .= '#'.$current['fragment'];
}
+
return $from;
}
}
diff --git a/app/Http/Requests/AccountFormRequest.php b/app/Http/Requests/AccountFormRequest.php
index 8f3dbc583f..0690053481 100644
--- a/app/Http/Requests/AccountFormRequest.php
+++ b/app/Http/Requests/AccountFormRequest.php
@@ -121,7 +121,7 @@ class AccountFormRequest extends FormRequest
'what' => 'in:'.$types,
'interest_period' => 'in:daily,monthly,yearly',
'notes' => ['min:1', 'max:32768', 'nullable'],
- '_from' => ['string','min:0','max:255', new IsValidOriginUrl()],
+ '_from' => ['string', 'min:0', 'max:255', new IsValidOriginUrl()],
];
$rules = Location::requestRules($rules);
diff --git a/app/Jobs/CreateAutoBudgetLimits.php b/app/Jobs/CreateAutoBudgetLimits.php
index d61661dd50..93cf5e9364 100644
--- a/app/Jobs/CreateAutoBudgetLimits.php
+++ b/app/Jobs/CreateAutoBudgetLimits.php
@@ -122,13 +122,7 @@ class CreateAutoBudgetLimits implements ShouldQueue
// if has one, calculate expenses and use that as a base.
$repository = app(OperationsRepositoryInterface::class);
$repository->setUser($autoBudget->budget->user);
- $spent = $repository->sumExpenses(
- $previousStart,
- $previousEnd,
- null,
- new Collection()->push($autoBudget->budget),
- $autoBudget->transactionCurrency
- );
+ $spent = $repository->sumExpenses($previousStart, $previousEnd, null, new Collection()->push($autoBudget->budget), $autoBudget->transactionCurrency);
$currencyId = $autoBudget->transaction_currency_id;
$spentAmount = $spent[$currencyId]['sum'] ?? '0';
Log::debug(sprintf('Spent in previous budget period (%s-%s) is %s', $previousStart->format('Y-m-d'), $previousEnd->format('Y-m-d'), $spentAmount));
@@ -218,13 +212,7 @@ class CreateAutoBudgetLimits implements ShouldQueue
// if has one, calculate expenses and use that as a base.
$repository = app(OperationsRepositoryInterface::class);
$repository->setUser($autoBudget->budget->user);
- $spent = $repository->sumExpenses(
- $previousStart,
- $previousEnd,
- null,
- new Collection()->push($autoBudget->budget),
- $autoBudget->transactionCurrency
- );
+ $spent = $repository->sumExpenses($previousStart, $previousEnd, null, new Collection()->push($autoBudget->budget), $autoBudget->transactionCurrency);
$currencyId = $autoBudget->transaction_currency_id;
$spentAmount = $spent[$currencyId]['sum'] ?? '0';
Log::debug(sprintf('Spent in previous budget period (%s-%s) is %s', $previousStart->format('Y-m-d'), $previousEnd->format('Y-m-d'), $spentAmount));
diff --git a/app/Models/Account.php b/app/Models/Account.php
index f682e9efaa..746592af6c 100644
--- a/app/Models/Account.php
+++ b/app/Models/Account.php
@@ -63,7 +63,7 @@ class Account extends Model
/**
* Route binder. Converts the key in the URL to the specified object (or throw 404).
*
- * @throws NotFoundHttpException|AuthenticationException
+ * @throws AuthenticationException|NotFoundHttpException
*/
public static function routeBinder(self|string $value): self
{
@@ -81,6 +81,7 @@ class Account extends Model
if (null !== $account) {
return $account;
}
+
throw new NotFoundHttpException();
}
diff --git a/app/Models/Attachment.php b/app/Models/Attachment.php
index e91c4c73ba..a47fab6df0 100644
--- a/app/Models/Attachment.php
+++ b/app/Models/Attachment.php
@@ -79,6 +79,7 @@ class Attachment extends Model
if (null !== $attachment) {
return $attachment;
}
+
throw new NotFoundHttpException();
}
diff --git a/app/Models/AvailableBudget.php b/app/Models/AvailableBudget.php
index 185addadd6..dae5b7fa0f 100644
--- a/app/Models/AvailableBudget.php
+++ b/app/Models/AvailableBudget.php
@@ -80,6 +80,7 @@ class AvailableBudget extends Model
if (null !== $availableBudget) {
return $availableBudget;
}
+
throw new NotFoundHttpException();
}
diff --git a/app/Models/Bill.php b/app/Models/Bill.php
index 410735eaf1..b1945fb695 100644
--- a/app/Models/Bill.php
+++ b/app/Models/Bill.php
@@ -99,6 +99,7 @@ class Bill extends Model
if (null !== $bill) {
return $bill;
}
+
throw new NotFoundHttpException();
}
diff --git a/app/Models/Budget.php b/app/Models/Budget.php
index efb53d79da..b212fcb6eb 100644
--- a/app/Models/Budget.php
+++ b/app/Models/Budget.php
@@ -67,6 +67,7 @@ class Budget extends Model
if (null !== $budget) {
return $budget;
}
+
throw new NotFoundHttpException();
}
diff --git a/app/Models/BudgetLimit.php b/app/Models/BudgetLimit.php
index a6db0f9e38..335299d42b 100644
--- a/app/Models/BudgetLimit.php
+++ b/app/Models/BudgetLimit.php
@@ -69,6 +69,7 @@ class BudgetLimit extends Model
if (null !== $budgetLimit) {
return $budgetLimit;
}
+
throw new NotFoundHttpException();
}
diff --git a/app/Models/Category.php b/app/Models/Category.php
index 272f4b5712..6a655e1ffe 100644
--- a/app/Models/Category.php
+++ b/app/Models/Category.php
@@ -69,6 +69,7 @@ class Category extends Model
if (null !== $category) {
return $category;
}
+
throw new NotFoundHttpException();
}
diff --git a/app/Models/InvitedUser.php b/app/Models/InvitedUser.php
index edbb7b4fc1..41edac8054 100644
--- a/app/Models/InvitedUser.php
+++ b/app/Models/InvitedUser.php
@@ -60,6 +60,7 @@ class InvitedUser extends Model
if (null !== $attempt) {
return $attempt;
}
+
throw new NotFoundHttpException();
}
diff --git a/app/Models/LinkType.php b/app/Models/LinkType.php
index fa12b2ef51..2326e1fc3d 100644
--- a/app/Models/LinkType.php
+++ b/app/Models/LinkType.php
@@ -53,6 +53,7 @@ class LinkType extends Model
if (null !== $linkType) {
return $linkType;
}
+
throw new NotFoundHttpException();
}
diff --git a/app/Models/ObjectGroup.php b/app/Models/ObjectGroup.php
index d072a39a9d..2d5c4f824c 100644
--- a/app/Models/ObjectGroup.php
+++ b/app/Models/ObjectGroup.php
@@ -59,6 +59,7 @@ class ObjectGroup extends Model
if (null !== $objectGroup) {
return $objectGroup;
}
+
throw new NotFoundHttpException();
}
diff --git a/app/Models/PiggyBank.php b/app/Models/PiggyBank.php
index 78d40432b0..c91445aae9 100644
--- a/app/Models/PiggyBank.php
+++ b/app/Models/PiggyBank.php
@@ -83,6 +83,7 @@ class PiggyBank extends Model
if (null !== $piggyBank) {
return $piggyBank;
}
+
throw new NotFoundHttpException();
}
diff --git a/app/Models/Preference.php b/app/Models/Preference.php
index 238e4b1c3d..00eb677000 100644
--- a/app/Models/Preference.php
+++ b/app/Models/Preference.php
@@ -95,6 +95,7 @@ class Preference extends Model
return $preference;
}
+
throw new NotFoundHttpException();
}
diff --git a/app/Models/Recurrence.php b/app/Models/Recurrence.php
index 521e6c9cb9..c2cfd32a62 100644
--- a/app/Models/Recurrence.php
+++ b/app/Models/Recurrence.php
@@ -93,6 +93,7 @@ class Recurrence extends Model
if (null !== $recurrence) {
return $recurrence;
}
+
throw new NotFoundHttpException();
}
diff --git a/app/Models/Rule.php b/app/Models/Rule.php
index 8a6f13d128..7485c8eefc 100644
--- a/app/Models/Rule.php
+++ b/app/Models/Rule.php
@@ -71,6 +71,7 @@ class Rule extends Model
if (null !== $rule) {
return $rule;
}
+
throw new NotFoundHttpException();
}
diff --git a/app/Models/RuleGroup.php b/app/Models/RuleGroup.php
index 41ed0aa8d7..2be62b2a79 100644
--- a/app/Models/RuleGroup.php
+++ b/app/Models/RuleGroup.php
@@ -71,6 +71,7 @@ class RuleGroup extends Model
if (null !== $ruleGroup) {
return $ruleGroup;
}
+
throw new NotFoundHttpException();
}
diff --git a/app/Models/Tag.php b/app/Models/Tag.php
index 35d50ab4b6..b14a05815c 100644
--- a/app/Models/Tag.php
+++ b/app/Models/Tag.php
@@ -73,6 +73,7 @@ class Tag extends Model
if (null !== $tag) {
return $tag;
}
+
throw new NotFoundHttpException();
}
diff --git a/app/Models/TransactionCurrency.php b/app/Models/TransactionCurrency.php
index ad37f71f9f..5c0ba14f3e 100644
--- a/app/Models/TransactionCurrency.php
+++ b/app/Models/TransactionCurrency.php
@@ -63,6 +63,7 @@ class TransactionCurrency extends Model
return $currency;
}
+
throw new NotFoundHttpException();
}
diff --git a/app/Models/TransactionJournal.php b/app/Models/TransactionJournal.php
index 9bd50919da..b1ebd93356 100644
--- a/app/Models/TransactionJournal.php
+++ b/app/Models/TransactionJournal.php
@@ -110,6 +110,7 @@ class TransactionJournal extends Model
if (null !== $journal) {
return $journal;
}
+
throw new NotFoundHttpException();
}
diff --git a/app/Models/TransactionJournalLink.php b/app/Models/TransactionJournalLink.php
index 75225ec22d..92c1cdb136 100644
--- a/app/Models/TransactionJournalLink.php
+++ b/app/Models/TransactionJournalLink.php
@@ -60,6 +60,7 @@ class TransactionJournalLink extends Model
if (null !== $link) {
return $link;
}
+
throw new NotFoundHttpException();
}
diff --git a/app/Models/WebhookAttempt.php b/app/Models/WebhookAttempt.php
index 0c15d97b89..5351356496 100644
--- a/app/Models/WebhookAttempt.php
+++ b/app/Models/WebhookAttempt.php
@@ -59,6 +59,7 @@ class WebhookAttempt extends Model
if (null !== $attempt && $attempt->webhookMessage->webhook->user_id === $user->id) {
return $attempt;
}
+
throw new NotFoundHttpException();
}
diff --git a/app/Models/WebhookMessage.php b/app/Models/WebhookMessage.php
index 8d77ac76b5..c64e0bb527 100644
--- a/app/Models/WebhookMessage.php
+++ b/app/Models/WebhookMessage.php
@@ -64,6 +64,7 @@ class WebhookMessage extends Model
if (null !== $message && $message->webhook->user_id === $user->id) {
return $message;
}
+
throw new NotFoundHttpException();
}
diff --git a/app/Rules/System/IsValidOriginUrl.php b/app/Rules/System/IsValidOriginUrl.php
index 9cdb603e4c..c1a73f97f9 100644
--- a/app/Rules/System/IsValidOriginUrl.php
+++ b/app/Rules/System/IsValidOriginUrl.php
@@ -1,4 +1,7 @@
check()) {
- $fail('validation.no_auth_present')->translate();
+ $fail('validation.no_auth_present')->translate();
return;
}
- $value = (string)$value;
- if(str_contains($value, '%2F')) {
+ $value = (string) $value;
+ if (str_contains($value, '%2F')) {
$value = urldecode($value);
}
- if('' === $value) {
+ if ('' === $value) {
// string can be empty.
return;
}
+
try {
$parts = parse_url($value);
} catch (UrlException) {
@@ -52,12 +57,14 @@ class IsValidOriginUrl implements ValidationRule
return;
}
- if(!array_key_exists('path', $parts) || array_key_exists('scheme', $parts) || array_key_exists('host', $parts)) {
+ if (!array_key_exists('path', $parts) || array_key_exists('scheme', $parts) || array_key_exists('host', $parts)) {
$fail('validation.bad_url_parts')->translate();
+
return;
}
- if(!str_starts_with($parts['path'], '/')) {
+ if (!str_starts_with($parts['path'], '/')) {
$fail('validation.bad_url_parts')->translate();
+
// return;
}
}
diff --git a/app/Support/Http/Controllers/AugumentData.php b/app/Support/Http/Controllers/AugumentData.php
index a507156873..a3a940b1ba 100644
--- a/app/Support/Http/Controllers/AugumentData.php
+++ b/app/Support/Http/Controllers/AugumentData.php
@@ -222,14 +222,7 @@ trait AugumentData
$currentEnd->addMonth();
}
// primary currency amount.
- $expenses = $opsRepository->sumExpenses(
- $currentStart,
- $currentEnd,
- null,
- $budgetCollection,
- $entry->transactionCurrency,
- $this->convertToPrimary
- );
+ $expenses = $opsRepository->sumExpenses($currentStart, $currentEnd, null, $budgetCollection, $entry->transactionCurrency, $this->convertToPrimary);
$spent = $expenses[$currency->id]['sum'] ?? '0';
$entry->pc_spent = $spent;
diff --git a/app/Support/JsonApi/Enrichments/RecurringEnrichment.php b/app/Support/JsonApi/Enrichments/RecurringEnrichment.php
index 2428353cb0..d0c09bf027 100644
--- a/app/Support/JsonApi/Enrichments/RecurringEnrichment.php
+++ b/app/Support/JsonApi/Enrichments/RecurringEnrichment.php
@@ -354,11 +354,7 @@ class RecurringEnrichment implements EnrichmentInterface
/** @var RecurrenceRepetition $repetition */
foreach ($set as $repetition) {
- $recurrence = $this->collection->filter(
- static fn (Recurrence $item): bool => (int) $item->id === (int) $repetition->recurrence_id
- )
- ->first()
- ;
+ $recurrence = $this->collection->filter(static fn (Recurrence $item): bool => (int) $item->id === (int) $repetition->recurrence_id)->first();
$fromDate = clone ($recurrence->latest_date ?? $recurrence->first_date);
$recurrenceId = (int) $repetition->recurrence_id;
$repId = (int) $repetition->id;
diff --git a/app/User.php b/app/User.php
index 8b4aa0f9d1..16c8e82c0a 100644
--- a/app/User.php
+++ b/app/User.php
@@ -102,6 +102,7 @@ class User extends Authenticatable implements OAuthenticatable
if (null !== $user) {
return $user;
}
+
throw new NotFoundHttpException();
}
diff --git a/composer.lock b/composer.lock
index 328be2ac19..c8d400a7a8 100644
--- a/composer.lock
+++ b/composer.lock
@@ -2508,16 +2508,16 @@
},
{
"name": "league/commonmark",
- "version": "2.9.0",
+ "version": "2.9.1",
"source": {
"type": "git",
"url": "https://github.com/thephpleague/commonmark.git",
- "reference": "5703d83ba3da3b2e356a5fedc848ed6d8ffb6529"
+ "reference": "73cb188c785abfa7a7bec73487148202968274c6"
},
"dist": {
"type": "zip",
- "url": "https://api.github.com/repos/thephpleague/commonmark/zipball/5703d83ba3da3b2e356a5fedc848ed6d8ffb6529",
- "reference": "5703d83ba3da3b2e356a5fedc848ed6d8ffb6529",
+ "url": "https://api.github.com/repos/thephpleague/commonmark/zipball/73cb188c785abfa7a7bec73487148202968274c6",
+ "reference": "73cb188c785abfa7a7bec73487148202968274c6",
"shasum": ""
},
"require": {
@@ -2611,7 +2611,7 @@
"type": "tidelift"
}
],
- "time": "2026-08-03T13:42:31+00:00"
+ "time": "2026-08-09T14:10:38+00:00"
},
{
"name": "league/config",
diff --git a/config/firefly.php b/config/firefly.php
index c44717febf..e1010b35a9 100644
--- a/config/firefly.php
+++ b/config/firefly.php
@@ -78,8 +78,8 @@ return [
'running_balance_column' => (bool)env_default_when_empty(env('USE_RUNNING_BALANCE'), true), // this is only the default value, is not used.
// see cer.php for exchange rates feature flag.
],
-'version' => 'develop/2026-08-07',
-'build_time' => 1786105226,
+'version' => 'develop/2026-08-09',
+'build_time' => 1786295232,
'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 6cceeef607..0755d875f0 100644
--- a/package-lock.json
+++ b/package-lock.json
@@ -2701,9 +2701,9 @@
"license": "MIT"
},
"node_modules/@types/node": {
- "version": "26.1.2",
- "resolved": "https://registry.npmjs.org/@types/node/-/node-26.1.2.tgz",
- "integrity": "sha512-Vu4a5UFA9rIIFJ7rB/Vaafh9lrCQszopTCx6KjFboXTGQbPNasehVR5TEiithSDGyd1DEiUByggTZsg8jukeIg==",
+ "version": "26.2.0",
+ "resolved": "https://registry.npmjs.org/@types/node/-/node-26.2.0.tgz",
+ "integrity": "sha512-5IviulTZeRNp2vAJ514cc/HUlY5nZ9fCbq9DMyC52BrhFZACo3nI0R7qBxhQmo/d27NFe96ur/b7Wwxklda+kg==",
"dev": true,
"license": "MIT",
"dependencies": {
@@ -3499,9 +3499,9 @@
"license": "MIT"
},
"node_modules/baseline-browser-mapping": {
- "version": "2.11.12",
- "resolved": "https://registry.npmjs.org/baseline-browser-mapping/-/baseline-browser-mapping-2.11.12.tgz",
- "integrity": "sha512-r7WnVImvVCeFpf2DOXfy41aPWzeNg3H/A2X4dKmy1QL0MSyyk/e7z8ihJ3N6Nn2PsdhkVlqnEfnUE4a05P2aTA==",
+ "version": "2.11.13",
+ "resolved": "https://registry.npmjs.org/baseline-browser-mapping/-/baseline-browser-mapping-2.11.13.tgz",
+ "integrity": "sha512-k9HNuUVMlqVjQ9UHzfPjIqiDbWw7WqT1AoT7GL8VwvF3r0ZfArtgiSPAlmupyNquNgOJHTuH4CKYf8ttMTWBTQ==",
"dev": true,
"license": "Apache-2.0",
"bin": {
@@ -3779,9 +3779,9 @@
}
},
"node_modules/browserslist": {
- "version": "4.28.7",
- "resolved": "https://registry.npmjs.org/browserslist/-/browserslist-4.28.7.tgz",
- "integrity": "sha512-JxV13hNrFxqjOc8alRbq9dK1MM79NEXYpma2B2J4wAtpWS5zIEIKqWPGCl7N4o7Uc7B7itylh7SuDujATRyyTw==",
+ "version": "4.28.8",
+ "resolved": "https://registry.npmjs.org/browserslist/-/browserslist-4.28.8.tgz",
+ "integrity": "sha512-V2NpofLblG64mfOtSgDhOJESZEGogzDMBv/q+W6oc4LXWP/q75eOXoOaaOu1EOadB9U4Bwx/e0yzbvwKH8zalA==",
"dev": true,
"funding": [
{
@@ -3799,11 +3799,11 @@
],
"license": "MIT",
"dependencies": {
- "baseline-browser-mapping": "^2.10.44",
- "caniuse-lite": "^1.0.30001806",
- "electron-to-chromium": "^1.5.393",
- "node-releases": "^2.0.51",
- "update-browserslist-db": "^1.2.3"
+ "baseline-browser-mapping": "^2.11.12",
+ "caniuse-lite": "^1.0.30001809",
+ "electron-to-chromium": "^1.5.402",
+ "node-releases": "^2.0.53",
+ "update-browserslist-db": "^1.3.0"
},
"bin": {
"browserslist": "cli.js"
@@ -5186,9 +5186,9 @@
"license": "MIT"
},
"node_modules/electron-to-chromium": {
- "version": "1.5.402",
- "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.5.402.tgz",
- "integrity": "sha512-/oOpMaPT6Yg+6/1XQhyIPlzgj7Ye9zf+nNM2Uh6OcE2G2oNptWazFa+qB2Pdqqbsc9KnIDzgAntoYN0dbwOXwA==",
+ "version": "1.5.403",
+ "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.5.403.tgz",
+ "integrity": "sha512-MQsYmdaLzvaCX5j+ZZBr5Fm6uCCnPQcRtlvmvRlWqrXy+BH2O4ffXIAScF+JQznQWB9brWp4lSD9Z4yNmaf2BA==",
"dev": true,
"license": "ISC"
},
@@ -7954,9 +7954,9 @@
}
},
"node_modules/nanoid": {
- "version": "3.3.17",
- "resolved": "https://registry.npmjs.org/nanoid/-/nanoid-3.3.17.tgz",
- "integrity": "sha512-xQLf0A3HOMlgHq0n247/LRuAOYmB7dXJ/DvAxGvsSBij45XtBSmQycu+F8ODbHwns/XyFZagyL1+J0Offw1E0g==",
+ "version": "3.3.18",
+ "resolved": "https://registry.npmjs.org/nanoid/-/nanoid-3.3.18.tgz",
+ "integrity": "sha512-DTg4MJbGMWkfi6VZFdNt2/caMbQy4Ou+Op/hJQvGEWcnVfoA1QA+xzRKAzw9jD6+GVOOeYr/mIcuDSdug6F6+w==",
"dev": true,
"funding": [
{
@@ -11888,9 +11888,9 @@
"license": "ISC"
},
"node_modules/ws": {
- "version": "8.21.2",
- "resolved": "https://registry.npmjs.org/ws/-/ws-8.21.2.tgz",
- "integrity": "sha512-54dMVAo4WIe6SKy3vBgN+9bJZqqQ8IMRevAkOLQALhi49qkkQDQfWdAZ8KQlXiEabw88ARXXdUrlvtbKQX+aKw==",
+ "version": "8.21.3",
+ "resolved": "https://registry.npmjs.org/ws/-/ws-8.21.3.tgz",
+ "integrity": "sha512-201TZ/kPWxoPr/OKWjquZR1SWKXcvxdH+e1xrx89b3YbmzLMFCLfnaG1HFIgWzJOEWZ7MvpK++odZufgYR50Rw==",
"dev": true,
"license": "MIT",
"engines": {
diff --git a/resources/lang/en_US/errors.php b/resources/lang/en_US/errors.php
index 1590aba79d..8a38b40695 100644
--- a/resources/lang/en_US/errors.php
+++ b/resources/lang/en_US/errors.php
@@ -23,37 +23,37 @@
declare(strict_types=1);
return [
- '404_header' => 'Firefly III cannot find this page.',
- '404_page_does_not_exist' => 'The page you have requested does not exist. Please check that you have not entered the wrong URL. Did you make a typo perhaps?',
- '404_send_error' => 'If you were redirected to this page automatically, please accept my apologies. There is a mention of this error in your log files and I would be grateful if you sent me the error to me.',
- '404_github_link' => 'If you are sure this page should exist, please open a ticket on GitHub.',
- 'whoops' => 'Whoops',
- 'note_not_found_account' => 'Account ":name" has been deleted and can no longer be viewed. Please enjoy this overview of all other accounts of the same type.',
- 'note_not_found_group' => 'Transaction ":description" has been deleted and can no longer be viewed. Please enjoy this overview of all other transactions of the same type.',
+ '404_header' => 'Firefly III cannot find this page.',
+ '404_page_does_not_exist' => 'The page you have requested does not exist. Please check that you have not entered the wrong URL. Did you make a typo perhaps?',
+ '404_send_error' => 'If you were redirected to this page automatically, please accept my apologies. There is a mention of this error in your log files and I would be grateful if you sent me the error to me.',
+ '404_github_link' => 'If you are sure this page should exist, please open a ticket on GitHub.',
+ 'whoops' => 'Whoops',
+ 'note_not_found_account' => 'Account ":name" has been deleted and can no longer be viewed. Please enjoy this overview of all other accounts of the same type.',
+ 'note_not_found_group' => 'Transaction ":description" has been deleted and can no longer be viewed. Please enjoy this overview of all other transactions of the same type.',
'note_not_found_reconciliation' => 'Reconciliation ":description" has been deleted and can no longer be viewed. Here is an overview of the account it belonged to.',
- 'fatal_error' => 'There was a fatal error. Please check the log files in "storage/logs" or use "docker logs -f [container]" to see what\'s going on.',
- 'maintenance_mode' => 'Firefly III is in maintenance mode.',
- 'be_right_back' => 'Be right back!',
- 'check_back' => 'Firefly III is down for some necessary maintenance. Please check back in a second. If you happen to see this message on the demo site, just wait a few minutes. The database is reset every few hours.',
- 'error_occurred' => 'Whoops! An error occurred.',
- 'db_error_occurred' => 'Whoops! A database error occurred.',
- 'error_not_recoverable' => 'Unfortunately, this error was not recoverable :(. Firefly III broke. The error is:',
- 'error' => 'Error',
- 'error_location' => 'This error occurred in file :file on line :line with code :code.',
- 'stacktrace' => 'Stack trace',
- 'more_info' => 'More information',
+ 'fatal_error' => 'There was a fatal error. Please check the log files in "storage/logs" or use "docker logs -f [container]" to see what\'s going on.',
+ 'maintenance_mode' => 'Firefly III is in maintenance mode.',
+ 'be_right_back' => 'Be right back!',
+ 'check_back' => 'Firefly III is down for some necessary maintenance. Please check back in a second. If you happen to see this message on the demo site, just wait a few minutes. The database is reset every few hours.',
+ 'error_occurred' => 'Whoops! An error occurred.',
+ 'db_error_occurred' => 'Whoops! A database error occurred.',
+ 'error_not_recoverable' => 'Unfortunately, this error was not recoverable :(. Firefly III broke. The error is:',
+ 'error' => 'Error',
+ 'error_location' => 'This error occurred in file :file on line :line with code :code.',
+ 'stacktrace' => 'Stack trace',
+ 'more_info' => 'More information',
- 'collect_info' => 'Please collect more information in the storage/logs directory where you will find log files. If you\'re running Docker, use docker logs -f [container].',
- 'collect_info_more' => 'You can read more about collecting error information in the FAQ.',
- 'github_help' => 'Get help on GitHub',
- 'github_instructions' => 'You\'re more than welcome to open a new issue on GitHub.',
- 'use_search' => 'Use the search!',
- 'include_info' => 'Include the information from this debug page.',
- 'tell_more' => 'Tell us more than "it says Whoops!"',
- 'include_logs' => 'Include error logs (see above).',
- 'what_did_you_do' => 'Tell us what you were doing.',
- 'offline_header' => 'You are probably offline',
- 'offline_unreachable' => 'Firefly III is unreachable. Your device is currently offline or the server is not working.',
- 'offline_github' => 'If you are sure both your device and the server are online, please open a ticket on GitHub.',
+ 'collect_info' => 'Please collect more information in the storage/logs directory where you will find log files. If you\'re running Docker, use docker logs -f [container].',
+ 'collect_info_more' => 'You can read more about collecting error information in the FAQ.',
+ 'github_help' => 'Get help on GitHub',
+ 'github_instructions' => 'You\'re more than welcome to open a new issue on GitHub.',
+ 'use_search' => 'Use the search!',
+ 'include_info' => 'Include the information from this debug page.',
+ 'tell_more' => 'Tell us more than "it says Whoops!"',
+ 'include_logs' => 'Include error logs (see above).',
+ 'what_did_you_do' => 'Tell us what you were doing.',
+ 'offline_header' => 'You are probably offline',
+ 'offline_unreachable' => 'Firefly III is unreachable. Your device is currently offline or the server is not working.',
+ 'offline_github' => 'If you are sure both your device and the server are online, please open a ticket on GitHub.',
];
diff --git a/resources/lang/en_US/validation.php b/resources/lang/en_US/validation.php
index 4ffd7f4355..f05a3dc6eb 100644
--- a/resources/lang/en_US/validation.php
+++ b/resources/lang/en_US/validation.php
@@ -23,8 +23,8 @@
declare(strict_types=1);
return [
- 'no_auth_present' => 'Looks like you\'re not authenticated',
- 'bad_url_parts' => 'The redirect URL is invalid.',
+ 'no_auth_present' => 'Looks like you\'re not authenticated',
+ 'bad_url_parts' => 'The redirect URL is invalid.',
'verifying_password' => 'Verifying password...',
'invalid_account_list' => 'Invalid account type list entry ":value"',
'invalid_transaction_type_list' => 'Invalid transaction type list',