Clean up various phpstan issues.

This commit is contained in:
James Cole
2026-03-06 13:52:11 +01:00
parent 993a2491e9
commit e882530a69
43 changed files with 372 additions and 351 deletions
+8 -20
View File
@@ -34,24 +34,8 @@ parameters:
reportUnmatchedIgnoredErrors: true
ignoreErrors:
# these are actually interesting but not right now:
- identifier: staticMethod.dynamicCall
- identifier: argument.templateType
- identifier: method.childReturnType
- identifier: instanceof.alwaysFalse
- identifier: deadCode.unreachable
- identifier: method.dynamicName
- identifier: larastan.noEnvCallsOutsideOfConfig
- identifier: property.notFound
- identifier: arguments.count
- identifier: staticMethod.dynamicName
- identifier: catch.neverThrown
- identifier: notIdentical.alwaysTrue
- identifier: method.notFound
- identifier: nullsafe.neverNull
- identifier: identical.alwaysFalse
- identifier: if.condNotBoolean
# - identifier: booleanNot.exprNotBoolean
- identifier: method.nonObject
- identifier: function.impossibleType
- identifier: booleanNot.exprNotBoolean
- identifier: ternary.condNotBoolean
@@ -66,9 +50,7 @@ parameters:
- identifier: larastan.noUnnecessaryCollectionCall
- identifier: varTag.differentVariable
- identifier: identical.alwaysTrue
- identifier: clone.nonObject
- identifier: assign.propertyReadOnly
- identifier: property.nonObject
- identifier: varTag.nativeType
- identifier: booleanAnd.leftAlwaysFalse
- identifier: property.onlyWritten
@@ -77,7 +59,6 @@ parameters:
- identifier: property.unusedType
- identifier: staticMethod.deprecated
- identifier: greater.invalid
- identifier: instanceof.alwaysTrue
# ignore everything but things that BREAK
- identifier: property.deprecated
- identifier: method.deprecated
@@ -89,7 +70,14 @@ parameters:
- identifier: assign.propertyType
- identifier: return.unusedType
- identifier: return.phpDocType
# all errors below I will never fix.
# all errors below I will (probably) never fix.
- identifier: catch.neverThrown # plenty of errors that are thrown undocumented
- identifier: staticMethod.dynamicName # dont care
- identifier: arguments.count # one false positive
- identifier: property.notFound # false positives
- identifier: method.dynamicName # i dont care
- identifier: staticMethod.dynamicCall # many false positives.
- identifier: argument.templateType # no clue how to fix single occurrence.
# - '#expects view-string\|null, string given#'
# - '#expects view-string, string given#'
# - "#Parameter \\#[1-2] \\$num[1-2] of function bc[a-z]+ expects numeric-string, [a-z\\-|&]+ given#"
@@ -45,7 +45,7 @@ final class DestroyController extends Controller
parent::__construct();
$this->middleware(function ($request, $next) {
$this->repository = app(BillRepositoryInterface::class);
$this->repository->setUser(auth()->user());
$this->repository->setUser(auth( )->user());
return $next($request);
});
@@ -62,7 +62,7 @@ final class BatchController extends Controller
}
Log::debug(sprintf('Counted %d journals.', count($journals)));
/** @var TransactionJournal $first */
/** @var TransactionJournal|null $first */
$first = $journals->first();
$group = $first?->transactionGroup;
if (null === $group) {
+1 -1
View File
@@ -38,7 +38,7 @@ class DateRangeRequest extends ApiRequest
public function withValidator(Validator $validator): void
{
$validator->after(function (Validator $validator): void {
if ($validator->failed()) {
if (count($validator->failed()) > 0) {
return;
}
$start = $this->getCarbonDate('start')?->startOfDay();
+1 -1
View File
@@ -36,7 +36,7 @@ class DateRequest extends ApiRequest
public function withValidator(Validator $validator): void
{
$validator->after(function (Validator $validator): void {
if ($validator->failed()) {
if (count($validator->failed()) > 0) {
return;
}
$date = $this->getCarbonDate('date')?->endOfDay();
@@ -75,7 +75,7 @@ class ObjectTypeApiRequest extends ApiRequest
public function withValidator(Validator $validator): void
{
$validator->after(function (Validator $validator): void {
if ($validator->failed()) {
if (count($validator->failed()) > 0) {
return;
}
$type = $this->convertString('types', 'all');
+1 -1
View File
@@ -42,7 +42,7 @@ class QueryRequest extends ApiRequest
public function withValidator(Validator $validator): void
{
$validator->after(function (Validator $validator): void {
if ($validator->failed()) {
if (count($validator->failed()) > 0) {
return;
}
$query = $this->convertString('query');
@@ -40,7 +40,7 @@ class AccountTypeApiRequest extends ApiRequest
public function withValidator(Validator $validator): void
{
$validator->after(function (Validator $validator): void {
if ($validator->failed()) {
if (count($validator->failed()) > 0) {
return;
}
@@ -42,7 +42,7 @@ class AccountTypesApiRequest extends ApiRequest
public function withValidator(Validator $validator): void
{
$validator->after(function (Validator $validator): void {
if ($validator->failed()) {
if (count($validator->failed()) > 0) {
return;
}
$types = explode(',', $this->convertString('types', 'all'));
@@ -26,6 +26,7 @@ namespace FireflyIII\Api\V1\Requests\Models\BudgetLimit;
use Carbon\Carbon;
use FireflyIII\Factory\TransactionCurrencyFactory;
use FireflyIII\Models\Budget;
use FireflyIII\Repositories\Currency\CurrencyRepositoryInterface;
use FireflyIII\Rules\IsBoolean;
use FireflyIII\Rules\IsValidPositiveAmount;
@@ -85,6 +86,7 @@ class StoreRequest extends FormRequest
*/
public function withValidator(Validator $validator): void
{
/** @var Budget $budget */
$budget = $this->route()->parameter('budget');
$validator->after(static function (Validator $validator) use ($budget): void {
if (0 !== count($validator->failed())) {
+1 -1
View File
@@ -58,7 +58,7 @@ class PaginationRequest extends ApiRequest
public function withValidator(Validator $validator): void
{
$validator->after(function (Validator $validator): void {
if ($validator->failed()) {
if (count($validator->failed()) > 0) {
return;
}
+1 -1
View File
@@ -45,7 +45,7 @@ class CountRequest extends AggregateFormRequest
public function withValidator(Validator $validator): void
{
$validator->after(function (Validator $validator): void {
if ($validator->failed()) {
if (count($validator->failed()) > 0) {
return;
}
$this->attributes->set('include_deleted', $this->convertBoolean($this->input('include_deleted', 'false')));
@@ -37,7 +37,7 @@ class SearchQueryRequest extends ApiRequest
public function withValidator(Validator $validator): void
{
$validator->after(function (Validator $validator): void {
if ($validator->failed()) {
if (count($validator->failed()) > 0) {
return;
}
$query = $this->convertString('query');
@@ -101,8 +101,11 @@ class UpgradesLiabilitiesEight extends Command
private function hasBadOpening(Account $account): bool
{
/** @var TransactionType $openingBalanceType */
$openingBalanceType = TransactionType::whereType(TransactionTypeEnum::OPENING_BALANCE->value)->first();
/** @var TransactionType $liabilityType */
$liabilityType = TransactionType::whereType(TransactionTypeEnum::LIABILITY_CREDIT->value)->first();
/** @var TransactionJournal|null $openingJournal */
$openingJournal = TransactionJournal::leftJoin('transactions', 'transactions.transaction_journal_id', '=', 'transaction_journals.id')
->where('transactions.account_id', $account->id)
->where('transaction_journals.transaction_type_id', $openingBalanceType->id)
@@ -111,6 +114,7 @@ class UpgradesLiabilitiesEight extends Command
if (null === $openingJournal) {
return false;
}
/** @var TransactionJournal|null $liabilityJournal */
$liabilityJournal = TransactionJournal::leftJoin('transactions', 'transactions.transaction_journal_id', '=', 'transaction_journals.id')
->where('transactions.account_id', $account->id)
->where('transaction_journals.transaction_type_id', $liabilityType->id)
@@ -120,7 +124,7 @@ class UpgradesLiabilitiesEight extends Command
return false;
}
return (bool) $openingJournal->date->isSameDay($liabilityJournal->date);
return $openingJournal->date->isSameDay($liabilityJournal->date);
}
private function isExecuted(): bool
+81 -88
View File
@@ -56,7 +56,6 @@ use FireflyIII\Validation\AccountValidator;
use Illuminate\Support\Collection;
use Illuminate\Support\Facades\Log;
use JsonException;
use function Safe\json_encode;
/**
@@ -68,17 +67,17 @@ class TransactionJournalFactory
{
use JournalServiceTrait;
private AccountRepositoryInterface $accountRepository;
private AccountValidator $accountValidator;
private BillRepositoryInterface $billRepository;
private CurrencyRepositoryInterface $currencyRepository;
private bool $errorOnHash = false;
private array $fields;
private PiggyBankEventFactory $piggyEventFactory;
private PiggyBankRepositoryInterface $piggyRepository;
private AccountRepositoryInterface $accountRepository;
private AccountValidator $accountValidator;
private BillRepositoryInterface $billRepository;
private CurrencyRepositoryInterface $currencyRepository;
private bool $errorOnHash = false;
private array $fields;
private PiggyBankEventFactory $piggyEventFactory;
private PiggyBankRepositoryInterface $piggyRepository;
private TransactionTypeRepositoryInterface $typeRepository;
private User $user;
private UserGroup $userGroup;
private User $user;
private UserGroup $userGroup;
/**
* Constructor.
@@ -109,8 +108,8 @@ class TransactionJournalFactory
public function create(array $data): Collection
{
Log::debug('Now in TransactionJournalFactory::create()');
$collection = new Collection();
$transactions = $data['transactions'] ?? [];
$collection = new Collection();
$transactions = $data['transactions'] ?? [];
if (0 === count($transactions)) {
Log::error('There are no transactions in the array, the TransactionJournalFactory cannot continue.');
@@ -123,7 +122,7 @@ class TransactionJournalFactory
foreach ($transactions as $index => $row) {
$row['batch_submission'] = $batchSubmission;
Log::debug(sprintf('Now creating journal %d/%d', $index + 1, count($transactions)));
$journal = $this->createJournal(new NullArrayObject($row));
$journal = $this->createJournal(new NullArrayObject($row));
if ($journal instanceof TransactionJournal) {
$collection->push($journal);
}
@@ -188,7 +187,7 @@ class TransactionJournalFactory
protected function storeMeta(TransactionJournal $journal, array $data, string $field): void
{
$set = ['journal' => $journal, 'name' => $field, 'data' => (string) ($data[$field] ?? '')];
$set = ['journal' => $journal, 'name' => $field, 'data' => (string)($data[$field] ?? '')];
if (array_key_exists($field, $data) && $data[$field] instanceof Carbon) {
$data[$field]->setTimezone(config('app.timezone'));
Log::debug(sprintf('%s Date: %s (%s)', $field, $data[$field], $data[$field]->timezone->getName()));
@@ -235,18 +234,18 @@ class TransactionJournalFactory
$this->errorIfDuplicate($row['import_hash_v2']);
// Some basic fields
$type = $this->typeRepository->findTransactionType(null, $row['type']);
$carbon = $row['date'] ?? today(config('app.timezone'));
$order = $row['order'] ?? 0;
$type = $this->typeRepository->findTransactionType(null, $row['type']);
$carbon = $row['date'] ?? today(config('app.timezone'));
$order = $row['order'] ?? 0;
Log::debug('Find currency or return default.');
$currency = $this->currencyRepository->findCurrency((int) $row['currency_id'], $row['currency_code']);
$currency = $this->currencyRepository->findCurrency((int)$row['currency_id'], $row['currency_code']);
Log::debug('Find foreign currency or return NULL.');
$foreignCurrency = $this->currencyRepository->findCurrencyNull($row['foreign_currency_id'], $row['foreign_currency_code']);
$bill = $this->billRepository->findBill((int) $row['bill_id'], $row['bill_name']);
$billId = TransactionTypeEnum::WITHDRAWAL->value === $type->type && $bill instanceof Bill ? $bill->id : null;
$description = (string) $row['description'];
$foreignCurrency = $this->currencyRepository->findCurrencyNull($row['foreign_currency_id'], $row['foreign_currency_code']);
$bill = $this->billRepository->findBill((int)$row['bill_id'], $row['bill_name']);
$billId = TransactionTypeEnum::WITHDRAWAL->value === $type->type && $bill instanceof Bill ? $bill->id : null;
$description = (string)$row['description'];
// Manipulate basic fields
$carbon->setTimezone(config('app.timezone'));
@@ -267,7 +266,7 @@ class TransactionJournalFactory
}
/** create or get source and destination accounts */
$sourceInfo = [
$sourceInfo = [
'id' => $row['source_id'],
'name' => $row['source_name'],
'iban' => $row['source_iban'],
@@ -276,7 +275,7 @@ class TransactionJournalFactory
'currency_id' => $currency->id,
];
$destInfo = [
$destInfo = [
'id' => $row['destination_id'],
'name' => $row['destination_name'],
'iban' => $row['destination_iban'],
@@ -286,8 +285,8 @@ class TransactionJournalFactory
];
Log::debug('Source info:', $sourceInfo);
Log::debug('Destination info:', $destInfo);
$destinationAccount = null;
$sourceAccount = null;
$destinationAccount = null;
$sourceAccount = null;
if (TransactionTypeEnum::DEPOSIT->value === $type->type) {
Log::debug('Transaction type is deposit, start with destination first.');
$destinationAccount = $this->getAccount($type->type, 'destination', $destInfo);
@@ -312,38 +311,38 @@ class TransactionJournalFactory
[$sourceAccount, $destinationAccount] = $this->reconciliationSanityCheck($sourceAccount, $destinationAccount);
}
$currency = $this->getCurrencyByAccount($type->type, $currency, $sourceAccount, $destinationAccount);
$foreignCurrency = $this->compareCurrencies($currency, $foreignCurrency);
$foreignCurrency = $this->getForeignByAccount($type->type, $foreignCurrency, $destinationAccount);
$description = $this->getDescription($description);
$currency = $this->getCurrencyByAccount($type->type, $currency, $sourceAccount, $destinationAccount);
$foreignCurrency = $this->compareCurrencies($currency, $foreignCurrency);
$foreignCurrency = $this->getForeignByAccount($type->type, $foreignCurrency, $destinationAccount);
$description = $this->getDescription($description);
Log::debug(sprintf(
'Currency is #%d "%s", foreign currency is #%d "%s"',
$currency->id,
$currency->code,
$foreignCurrency?->id,
$foreignCurrency?->code
));
'Currency is #%d "%s", foreign currency is #%d "%s"',
$currency->id,
$currency->code,
$foreignCurrency?->id,
$foreignCurrency?->code
));
Log::debug(sprintf('Date: %s (%s)', $carbon->toW3cString(), $carbon->getTimezone()->getName()));
/** Create a basic journal. */
$journal = TransactionJournal::create([
'user_id' => $this->user->id,
'user_group_id' => $this->userGroup->id,
'transaction_type_id' => $type->id,
'bill_id' => $billId,
'transaction_currency_id' => $currency->id,
'description' => substr($description, 0, 1000),
'date' => $carbon,
'date_tz' => $carbon->format('e'),
'order' => $order,
'tag_count' => 0,
'completed' => !$row['batch_submission'],
]);
$journal = TransactionJournal::create([
'user_id' => $this->user->id,
'user_group_id' => $this->userGroup->id,
'transaction_type_id' => $type->id,
'bill_id' => $billId,
'transaction_currency_id' => $currency->id,
'description' => substr($description, 0, 1000),
'date' => $carbon,
'date_tz' => $carbon->format('e'),
'order' => $order,
'tag_count' => 0,
'completed' => !$row['batch_submission'],
]);
Log::debug(sprintf('Created new journal #%d: "%s"', $journal->id, $journal->description));
/** Create two transactions. */
$transactionFactory = app(TransactionFactory::class);
$transactionFactory = app(TransactionFactory::class);
$transactionFactory->setJournal($journal);
$transactionFactory->setAccount($sourceAccount);
$transactionFactory->setCurrency($currency);
@@ -352,7 +351,7 @@ class TransactionJournalFactory
$transactionFactory->setReconciled($row['reconciled'] ?? false);
try {
$negative = $transactionFactory->createNegative((string) $row['amount'], (string) $row['foreign_amount']);
$negative = $transactionFactory->createNegative((string)$row['amount'], (string)$row['foreign_amount']);
} catch (FireflyException $e) {
Log::error(sprintf('Exception creating negative transaction: %s', $e->getMessage()));
$this->forceDeleteOnError(new Collection()->push($journal));
@@ -361,7 +360,7 @@ class TransactionJournalFactory
}
/** @var TransactionFactory $transactionFactory */
$transactionFactory = app(TransactionFactory::class);
$transactionFactory = app(TransactionFactory::class);
$transactionFactory->setJournal($journal);
$transactionFactory->setAccount($destinationAccount);
$transactionFactory->setAccountInformation($destInfo);
@@ -373,8 +372,8 @@ class TransactionJournalFactory
// Firefly III will save the foreign currency information in such a way that both
// asset accounts can look at the "amount" and "transaction_currency_id" column and
// see the currency they expect to see.
$amount = (string) $row['amount'];
$foreignAmount = (string) $row['foreign_amount'];
$amount = (string)$row['amount'];
$foreignAmount = (string)$row['foreign_amount'];
if (
$foreignCurrency instanceof TransactionCurrency
&& $foreignCurrency->id !== $currency->id
@@ -382,8 +381,8 @@ class TransactionJournalFactory
) {
$transactionFactory->setCurrency($foreignCurrency);
$transactionFactory->setForeignCurrency($currency);
$amount = (string) $row['foreign_amount'];
$foreignAmount = (string) $row['amount'];
$amount = (string)$row['foreign_amount'];
$foreignAmount = (string)$row['amount'];
Log::debug('Swap primary/foreign amounts in transfer for new save method.');
}
@@ -426,18 +425,17 @@ class TransactionJournalFactory
/** @var null|TransactionJournalMeta $result */
$result = TransactionJournalMeta::withTrashed()
->leftJoin('transaction_journals', 'transaction_journals.id', '=', 'journal_meta.transaction_journal_id')
->whereNotNull('transaction_journals.id')
->where('transaction_journals.user_id', $this->user->id)
->where('data', json_encode($hash, JSON_THROW_ON_ERROR))
->with(['transactionJournal', 'transactionJournal.transactionGroup'])
->first(['journal_meta.*'])
;
->leftJoin('transaction_journals', 'transaction_journals.id', '=', 'journal_meta.transaction_journal_id')
->whereNotNull('transaction_journals.id')
->where('transaction_journals.user_id', $this->user->id)
->where('data', json_encode($hash, JSON_THROW_ON_ERROR))
->with(['transactionJournal', 'transactionJournal.transactionGroup'])
->first(['journal_meta.*']);
if (null !== $result) {
Log::warning(sprintf('Found a duplicate in errorIfDuplicate because hash %s is not unique!', $hash));
$journal = $result->transactionJournal()->withTrashed()->first();
$group = $journal?->transactionGroup()->withTrashed()->first();
$groupId = (int) $group?->id;
$groupId = (int)$group?->id;
throw new DuplicateTransactionException(sprintf('Duplicate of transaction #%d.', $groupId));
}
@@ -474,7 +472,7 @@ class TransactionJournalFactory
// return user's default:
return Amount::getPrimaryCurrencyByUserGroup($this->user->userGroup);
}
$result = $preference ?? $currency;
$result = $preference ?? $currency;
Log::debug(sprintf('Currency is now #%d (%s) because of account #%d (%s)', $result->id, $result->code, $account->id, $account->name));
return $result;
@@ -574,16 +572,11 @@ class TransactionJournalFactory
return [$sourceAccount, $account];
}
if (!$sourceAccount instanceof Account) {
Log::debug('Source account is NULL, destination account is not.');
$account = $this->accountRepository->getReconciliation($destinationAccount);
Log::debug(sprintf('Will return account #%d ("%s") of type "%s"', $account->id, $account->name, $account->accountType->type));
Log::debug('Source account is NULL, destination account is not.');
$account = $this->accountRepository->getReconciliation($destinationAccount);
Log::debug(sprintf('Will return account #%d ("%s") of type "%s"', $account->id, $account->name, $account->accountType->type));
return [$account, $destinationAccount];
}
Log::debug('Unused fallback');
return [$sourceAccount, $destinationAccount];
return [$account, $destinationAccount];
}
private function storeLocation(TransactionJournal $journal, NullArrayObject $data): void
@@ -612,7 +605,7 @@ class TransactionJournalFactory
{
Log::debug('Will now store piggy event.');
$piggyBank = $this->piggyRepository->findPiggyBank((int) $data['piggy_bank_id'], $data['piggy_bank_name']);
$piggyBank = $this->piggyRepository->findPiggyBank((int)$data['piggy_bank_id'], $data['piggy_bank_name']);
if ($piggyBank instanceof PiggyBank) {
$this->piggyEventFactory->create($journal, $piggyBank);
@@ -629,18 +622,18 @@ class TransactionJournalFactory
private function validateAccounts(NullArrayObject $data): void
{
Log::debug(sprintf('Now in %s', __METHOD__));
$transactionType = $data['type'] ?? 'invalid';
$transactionType = $data['type'] ?? 'invalid';
$this->accountValidator->setUser($this->user);
$this->accountValidator->setTransactionType($transactionType);
// validate source account.
$array = [
'id' => null !== $data['source_id'] ? (int) $data['source_id'] : null,
'name' => null !== $data['source_name'] ? (string) $data['source_name'] : null,
'iban' => null !== $data['source_iban'] ? (string) $data['source_iban'] : null,
'number' => null !== $data['source_number'] ? (string) $data['source_number'] : null,
$array = [
'id' => null !== $data['source_id'] ? (int)$data['source_id'] : null,
'name' => null !== $data['source_name'] ? (string)$data['source_name'] : null,
'iban' => null !== $data['source_iban'] ? (string)$data['source_iban'] : null,
'number' => null !== $data['source_number'] ? (string)$data['source_number'] : null,
];
$validSource = $this->accountValidator->validateSource($array);
$validSource = $this->accountValidator->validateSource($array);
// do something with result:
if (false === $validSource) {
@@ -649,11 +642,11 @@ class TransactionJournalFactory
Log::debug('Source seems valid.');
// validate destination account
$array = [
'id' => null !== $data['destination_id'] ? (int) $data['destination_id'] : null,
'name' => null !== $data['destination_name'] ? (string) $data['destination_name'] : null,
'iban' => null !== $data['destination_iban'] ? (string) $data['destination_iban'] : null,
'number' => null !== $data['destination_number'] ? (string) $data['destination_number'] : null,
$array = [
'id' => null !== $data['destination_id'] ? (int)$data['destination_id'] : null,
'name' => null !== $data['destination_name'] ? (string)$data['destination_name'] : null,
'iban' => null !== $data['destination_iban'] ? (string)$data['destination_iban'] : null,
'number' => null !== $data['destination_number'] ? (string)$data['destination_number'] : null,
];
$validDestination = $this->accountValidator->validateDestination($array);
@@ -123,7 +123,6 @@ final class LoginController extends Controller
// send a custom login event because laravel will also fire a login event if a "remember me"-cookie
// restores the event.
event(new UserSuccessfullyLoggedIn($this->guard()->user()));
return $this->sendLoginResponse($request);
}
Log::warning('Login attempt failed.');
@@ -275,7 +274,7 @@ final class LoginController extends Controller
$request->session()->regenerate();
$this->clearLoginAttempts($request);
$response = $this->authenticated($request, $this->guard()->user());
if ($response) {
if (null !== $response) {
return $response;
}
$path = Steam::getSafeUrl(session()->pull('url.intended', route('index')), route('index'));
+30 -38
View File
@@ -52,10 +52,8 @@ use Illuminate\View\View;
use Monolog\Handler\RotatingFileHandler;
use Safe\Exceptions\FilesystemException;
use Symfony\Component\HttpKernel\Exception\NotFoundHttpException;
use function Safe\file_get_contents;
use function Safe\ini_get;
use const PHP_INT_SIZE;
use const PHP_SAPI;
@@ -104,7 +102,7 @@ final class DebugController extends Controller
*
* @throws FireflyException
*/
public function flush(Request $request): Redirector|RedirectResponse
public function flush(Request $request): Redirector | RedirectResponse
{
Preferences::mark();
$request->session()->forget(['start', 'end', '_previous', 'viewRange', 'range', 'is_custom_range', 'temp-mfa-secret', 'temp-mfa-codes']);
@@ -140,14 +138,14 @@ final class DebugController extends Controller
*
* @throws FilesystemException
*/
public function index(): Factory|\Illuminate\Contracts\View\View
public function index(): Factory | \Illuminate\Contracts\View\View
{
$table = $this->generateTable();
$table = str_replace(["\n", "\t", ' '], '', $table);
$now = now(config('app.timezone'))->format('Y-m-d H:i:s');
$table = $this->generateTable();
$table = str_replace(["\n", "\t", ' '], '', $table);
$now = now(config('app.timezone'))->format('Y-m-d H:i:s');
// get latest log file:
$logger = Log::driver();
$logger = Log::driver();
// PHPstan doesn't recognize the method because of its polymorphic nature.
$handlers = $logger->getHandlers();
$logContent = '';
@@ -161,10 +159,10 @@ final class DebugController extends Controller
}
if ('' !== $logContent) {
// last few lines
$logContent = 'Truncated from this point <----|'.substr($logContent, -16384);
$logContent = 'Truncated from this point <----|' . substr($logContent, -16384);
}
return view('debug', ['table' => $table, 'now' => $now, 'logContent' => $logContent]);
return view('debug', ['table' => $table, 'now' => $now, 'logContent' => $logContent]);
}
public function routes(Request $request): never
@@ -241,13 +239,13 @@ final class DebugController extends Controller
continue;
}
$params = [];
$params = [];
foreach ($route->parameterNames() as $name) {
$params[] = $this->getParameter($name);
}
$return[$route->getName()] = route($route->getName(), $params);
}
$count = 0;
$count = 0;
echo '<hr>';
echo '<h1>Routes</h1>';
echo sprintf('<h2>%s</h2>', $count);
@@ -267,7 +265,7 @@ final class DebugController extends Controller
/**
* Flash all types of messages.
*/
public function testFlash(Request $request): Redirector|RedirectResponse
public function testFlash(Request $request): Redirector | RedirectResponse
{
$request->session()->flash('success', 'This is a success message.');
$request->session()->flash('info', 'This is an info message.');
@@ -285,15 +283,15 @@ final class DebugController extends Controller
$app = $this->getAppInfo();
$user = $this->getUserInfo();
return (string) view('partials.debug-table', ['system' => $system, 'docker' => $docker, 'app' => $app, 'user' => $user]);
return (string)view('partials.debug-table', ['system' => $system, 'docker' => $docker, 'app' => $app, 'user' => $user]);
}
private function getAppInfo(): array
{
$userGuard = config('auth.defaults.guard');
$userGuard = config('auth.defaults.guard');
$config = FireflyConfig::get('last_rt_job', 0);
$lastTime = (int) $config->data;
$lastTime = (int)$config->data;
$lastCronjob = 'never';
$lastCronjobAgo = 'never';
if ($lastTime > 0) {
@@ -304,9 +302,9 @@ final class DebugController extends Controller
return [
'debug' => var_export(config('app.debug'), true),
'audit_log_channel' => envNonEmpty('AUDIT_LOG_CHANNEL', '(empty)'),
'default_language' => (string) config('firefly.default_language'),
'default_locale' => (string) config('firefly.default_locale'),
'audit_log_channel' => join(', ', config('logging.channels.audit.channels')),
'default_language' => (string)config('firefly.default_language'),
'default_locale' => (string)config('firefly.default_locale'),
'remote_header' => 'remote_user_guard' === $userGuard ? config('auth.guard_header') : 'N/A',
'remote_mail_header' => 'remote_user_guard' === $userGuard ? config('auth.guard_email') : 'N/A',
'stateful_domains' => implode(', ', config('sanctum.stateful')),
@@ -315,19 +313,19 @@ final class DebugController extends Controller
// any of the cron jobs will do, they always run at the same time.
// but this job is the oldest, so the biggest chance it ran once
'last_cronjob' => $lastCronjob,
'last_cronjob_ago' => $lastCronjobAgo,
'last_cronjob' => $lastCronjob,
'last_cronjob_ago' => $lastCronjobAgo,
];
}
private function getBuildInfo(): array
{
$return = [
'is_docker' => env('IS_DOCKER', false),
'is_docker' => config('firefly.is_docker'),
'build' => '(unknown)',
'build_date' => '(unknown)',
'base_build' => '(unknown)',
'base_build_date' => '(unknown)',
'base_build' => config('firefly.base_image_build'),
'base_build_date' => config('firefly.base_image_date'),
];
try {
@@ -348,12 +346,6 @@ final class DebugController extends Controller
Log::debug('Could not check build date, but thats ok.');
Log::warning($e->getMessage());
}
if ('' !== (string) env('BASE_IMAGE_BUILD')) {
$return['base_build'] = env('BASE_IMAGE_BUILD');
}
if ('' !== (string) env('BASE_IMAGE_DATE')) {
$return['base_build_date'] = env('BASE_IMAGE_DATE');
}
return $return;
}
@@ -471,7 +463,7 @@ final class DebugController extends Controller
'bits' => PHP_INT_SIZE * 8,
'bcscale' => bcscale(),
'display_errors' => ini_get('display_errors'),
'error_reporting' => $this->errorReporting((int) ini_get('error_reporting')),
'error_reporting' => $this->errorReporting((int)ini_get('error_reporting')),
'upload_size' => min($maxFileSize, $maxPostSize),
'all_drivers' => $drivers,
'current_driver' => $currentDriver,
@@ -480,10 +472,10 @@ final class DebugController extends Controller
private function getUserFlags(): string
{
$flags = [];
$flags = [];
/** @var User $user */
$user = auth()->user();
$user = auth()->user();
// has liabilities
if ($user->accounts()->accountTypeIn([AccountTypeEnum::DEBT->value, AccountTypeEnum::LOAN->value, AccountTypeEnum::MORTGAGE->value])->count() > 0) {
@@ -499,7 +491,7 @@ final class DebugController extends Controller
}
// has stored reconciliations
$type = TransactionType::whereType(TransactionTypeEnum::RECONCILIATION->value)->first();
$type = TransactionType::whereType(TransactionTypeEnum::RECONCILIATION->value)->first();
if ($user->transactionJournals()->where('transaction_type_id', $type->id)->count() > 0) {
$flags[] = '<span title="Has reconciled">:ledger:</span>';
}
@@ -531,22 +523,22 @@ final class DebugController extends Controller
private function getUserInfo(): array
{
$userFlags = $this->getUserFlags();
$userFlags = $this->getUserFlags();
// user info
$userAgent = request()->header('user-agent');
$userAgent = request()->header('user-agent');
// set languages, see what happens:
$original = setlocale(LC_ALL, '0');
$localeAttempts = [];
$parts = Steam::getLocaleArray(Steam::getLocale());
foreach ($parts as $code) {
$code = trim($code);
$code = trim($code);
Log::debug(sprintf('Trying to set %s', $code));
$result = setlocale(LC_ALL, $code);
$localeAttempts[$code] = $result === $code;
}
setlocale(LC_ALL, (string) $original);
setlocale(LC_ALL, (string)$original);
return [
'user_id' => auth()->user()->id,
@@ -86,7 +86,7 @@ final class PreferencesController extends Controller
AccountTypeEnum::DEBT->value,
AccountTypeEnum::MORTGAGE->value,
]);
$isDocker = env('IS_DOCKER', false);
$isDocker = config('firefly.is_docker');
$groupedAccounts = [];
/** @var Account $account */
+1 -1
View File
@@ -67,7 +67,7 @@ class SecureHeaders
];
// overrule in development mode
if (true === env('IS_LOCAL_DEV')) {
if (true === config('firefly.is_local_dev')) {
$csp = [
"default-src 'none'",
"object-src 'none'",
+1 -1
View File
@@ -213,7 +213,7 @@ class CreateRecurringTransactions implements ShouldQueue
/** @var RecurrenceTransaction $transaction */
foreach ($transactions as $index => $transaction) {
$single = [
'type' => null === $transaction?->transactionType?->type
'type' => null === $transaction->transactionType?->type
? strtolower((string) $recurrence->transactionType->type)
: strtolower($transaction->transactionType->type),
'date' => $date,
@@ -42,7 +42,7 @@ class ProcessesBudgetLimits implements ShouldQueue
public function handle(CreatedBudgetLimit|DestroyedBudgetLimit|UpdatedBudgetLimit $event): void
{
Log::debug(sprintf('Now in ProcessesBudgetLimits::handle for event %s', get_class($event)));
if ($event instanceof DestroyedBudgetLimit && null !== $event->user) {
if ($event instanceof DestroyedBudgetLimit) {
// need to recalculate all available budgets for this user.
$calculator = new AvailableBudgetCalculator();
$calculator->setUser($event->user);
@@ -58,10 +58,9 @@ class SendsWebhookMessages implements ShouldQueue
$message->save();
Log::debug(sprintf('Send message #%d', $message->id));
SendWebhookMessage::dispatch($message)->afterResponse();
continue;
}
if (false !== $message->sent) {
Log::debug(sprintf('Skip message #%d', $message->id));
}
Log::debug(sprintf('Skip message #%d', $message->id));
}
// clean up sent messages table:
+41 -34
View File
@@ -23,6 +23,7 @@ declare(strict_types=1);
namespace FireflyIII\Models;
use Carbon\Carbon;
use FireflyIII\Casts\SeparateTimezoneCaster;
use FireflyIII\Handlers\Observer\BillObserver;
use FireflyIII\Support\Models\ReturnsIntegerIdTrait;
@@ -38,6 +39,11 @@ use Illuminate\Database\Eloquent\Relations\MorphToMany;
use Illuminate\Database\Eloquent\SoftDeletes;
use Symfony\Component\HttpKernel\Exception\NotFoundHttpException;
/**
* @property Carbon $date
* @property Carbon|null $end_date
* @property Carbon|null $extension_date
*/
#[ObservedBy([BillObserver::class])]
class Bill extends Model
{
@@ -45,48 +51,49 @@ class Bill extends Model
use ReturnsIntegerUserIdTrait;
use SoftDeletes;
protected $fillable = [
'name',
'match',
'amount_min',
'user_id',
'user_group_id',
'amount_max',
'date',
'date_tz',
'repeat_freq',
'skip',
'automatch',
'active',
'transaction_currency_id',
'end_date',
'extension_date',
'end_date_tz',
'extension_date_tz',
'native_amount_min',
'native_amount_max',
];
protected $fillable
= [
'name',
'match',
'amount_min',
'user_id',
'user_group_id',
'amount_max',
'date',
'date_tz',
'repeat_freq',
'skip',
'automatch',
'active',
'transaction_currency_id',
'end_date',
'extension_date',
'end_date_tz',
'extension_date_tz',
'native_amount_min',
'native_amount_max',
];
protected $hidden = ['amount_min_encrypted', 'amount_max_encrypted', 'name_encrypted', 'match_encrypted'];
protected $hidden = ['amount_min_encrypted', 'amount_max_encrypted', 'name_encrypted', 'match_encrypted'];
/**
* Route binder. Converts the key in the URL to the specified object (or throw 404).
*
* @throws NotFoundHttpException
*/
public static function routeBinder(self|string $value): self
public static function routeBinder(self | string $value): self
{
if ($value instanceof self) {
$value = (int) $value->id;
$value = (int)$value->id;
}
if (auth()->check()) {
$billId = (int) $value;
$billId = (int)$value;
/** @var User $user */
$user = auth()->user();
$user = auth()->user();
/** @var null|Bill $bill */
$bill = $user->bills()->find($billId);
$bill = $user->bills()->find($billId);
if (null !== $bill) {
return $bill;
}
@@ -121,7 +128,7 @@ class Bill extends Model
*/
public function setAmountMaxAttribute($value): void
{
$this->attributes['amount_max'] = (string) $value;
$this->attributes['amount_max'] = (string)$value;
}
/**
@@ -129,7 +136,7 @@ class Bill extends Model
*/
public function setAmountMinAttribute($value): void
{
$this->attributes['amount_min'] = (string) $value;
$this->attributes['amount_min'] = (string)$value;
}
public function transactionCurrency(): BelongsTo
@@ -152,7 +159,7 @@ class Bill extends Model
*/
protected function amountMax(): Attribute
{
return Attribute::make(get: static fn ($value): string => (string) $value);
return Attribute::make(get: static fn($value): string => (string)$value);
}
/**
@@ -160,7 +167,7 @@ class Bill extends Model
*/
protected function amountMin(): Attribute
{
return Attribute::make(get: static fn ($value): string => (string) $value);
return Attribute::make(get: static fn($value): string => (string)$value);
}
protected function casts(): array
@@ -186,7 +193,7 @@ class Bill extends Model
protected function order(): Attribute
{
return Attribute::make(get: static fn ($value): int => (int) $value);
return Attribute::make(get: static fn($value): int => (int)$value);
}
/**
@@ -194,11 +201,11 @@ class Bill extends Model
*/
protected function skip(): Attribute
{
return Attribute::make(get: static fn ($value): int => (int) $value);
return Attribute::make(get: static fn($value): int => (int)$value);
}
protected function transactionCurrencyId(): Attribute
{
return Attribute::make(get: static fn ($value): int => (int) $value);
return Attribute::make(get: static fn($value): int => (int)$value);
}
}
+4
View File
@@ -23,6 +23,7 @@ declare(strict_types=1);
namespace FireflyIII\Models;
use Carbon\Carbon;
use FireflyIII\Casts\SeparateTimezoneCaster;
use FireflyIII\Support\Models\ReturnsIntegerIdTrait;
use FireflyIII\Support\Models\ReturnsIntegerUserIdTrait;
@@ -32,6 +33,9 @@ use Illuminate\Database\Eloquent\Model;
use Illuminate\Database\Eloquent\Relations\BelongsTo;
use Illuminate\Database\Eloquent\SoftDeletes;
/**
* @property Carbon $date
*/
class CurrencyExchangeRate extends Model
{
use ReturnsIntegerIdTrait;
+5
View File
@@ -4,6 +4,7 @@ declare(strict_types=1);
namespace FireflyIII\Models;
use Carbon\Carbon;
use FireflyIII\Casts\SeparateTimezoneCaster;
use FireflyIII\Support\Models\ReturnsIntegerUserIdTrait;
use Illuminate\Database\Eloquent\Casts\Attribute;
@@ -11,6 +12,10 @@ use Illuminate\Database\Eloquent\Model;
use Illuminate\Database\Eloquent\Relations\BelongsTo;
use Illuminate\Database\Eloquent\Relations\MorphTo;
/**
* @property Carbon $start
* @property Carbon $end
*/
class PeriodStatistic extends Model
{
use ReturnsIntegerUserIdTrait;
+29 -24
View File
@@ -23,6 +23,7 @@ declare(strict_types=1);
namespace FireflyIII\Models;
use Carbon\Carbon;
use FireflyIII\Handlers\Observer\PiggyBankObserver;
use FireflyIII\Support\Models\ReturnsIntegerIdTrait;
use Illuminate\Database\Eloquent\Attributes\ObservedBy;
@@ -36,43 +37,47 @@ use Illuminate\Database\Eloquent\Relations\MorphToMany;
use Illuminate\Database\Eloquent\SoftDeletes;
use Symfony\Component\HttpKernel\Exception\NotFoundHttpException;
/**
* @property Carbon|null $target_date
* @property Carbon|null $start_date
*/
#[ObservedBy([PiggyBankObserver::class])]
class PiggyBank extends Model
{
use ReturnsIntegerIdTrait;
use SoftDeletes;
protected $fillable = [
'name',
'order',
'target_amount',
'start_date',
'start_date_tz',
'target_date',
'target_date_tz',
'active',
'transaction_currency_id',
'native_target_amount',
];
protected $fillable
= [
'name',
'order',
'target_amount',
'start_date',
'start_date_tz',
'target_date',
'target_date_tz',
'active',
'transaction_currency_id',
'native_target_amount',
];
/**
* Route binder. Converts the key in the URL to the specified object (or throw 404).
*
* @throws NotFoundHttpException
*/
public static function routeBinder(self|string $value): self
public static function routeBinder(self | string $value): self
{
if ($value instanceof self) {
$value = (int) $value->id;
$value = (int)$value->id;
}
if (auth()->check()) {
$piggyBankId = (int) $value;
$piggyBankId = (int)$value;
$piggyBank = self::where('piggy_banks.id', $piggyBankId)
->leftJoin('account_piggy_bank', 'account_piggy_bank.piggy_bank_id', '=', 'piggy_banks.id')
->leftJoin('accounts', 'accounts.id', '=', 'account_piggy_bank.account_id')
->where('accounts.user_id', auth()->user()->id)
->first(['piggy_banks.*'])
;
->leftJoin('account_piggy_bank', 'account_piggy_bank.piggy_bank_id', '=', 'piggy_banks.id')
->leftJoin('accounts', 'accounts.id', '=', 'account_piggy_bank.account_id')
->where('accounts.user_id', auth()->user()->id)
->first(['piggy_banks.*']);
if (null !== $piggyBank) {
return $piggyBank;
}
@@ -127,7 +132,7 @@ class PiggyBank extends Model
*/
public function setTargetAmountAttribute($value): void
{
$this->attributes['target_amount'] = (string) $value;
$this->attributes['target_amount'] = (string)$value;
}
public function transactionCurrency(): BelongsTo
@@ -137,7 +142,7 @@ class PiggyBank extends Model
protected function accountId(): Attribute
{
return Attribute::make(get: static fn ($value): int => (int) $value);
return Attribute::make(get: static fn($value): int => (int)$value);
}
protected function casts(): array
@@ -158,7 +163,7 @@ class PiggyBank extends Model
protected function order(): Attribute
{
return Attribute::make(get: static fn ($value): int => (int) $value);
return Attribute::make(get: static fn($value): int => (int)$value);
}
/**
@@ -166,6 +171,6 @@ class PiggyBank extends Model
*/
protected function targetAmount(): Attribute
{
return Attribute::make(get: static fn ($value): string => (string) $value);
return Attribute::make(get: static fn($value): string => (string)$value);
}
}
+4
View File
@@ -23,6 +23,7 @@ declare(strict_types=1);
namespace FireflyIII\Models;
use Carbon\Carbon;
use FireflyIII\Casts\SeparateTimezoneCaster;
use FireflyIII\Handlers\Observer\PiggyBankEventObserver;
use FireflyIII\Support\Models\ReturnsIntegerIdTrait;
@@ -31,6 +32,9 @@ use Illuminate\Database\Eloquent\Casts\Attribute;
use Illuminate\Database\Eloquent\Model;
use Illuminate\Database\Eloquent\Relations\BelongsTo;
/**
* @property Carbon $date
*/
#[ObservedBy([PiggyBankEventObserver::class])]
class PiggyBankEvent extends Model
{
+26 -24
View File
@@ -40,8 +40,9 @@ use Illuminate\Database\Eloquent\SoftDeletes;
use Symfony\Component\HttpKernel\Exception\NotFoundHttpException;
/**
* @property Carbon $first_date
* @property Carbon|null $first_date
* @property null|Carbon $latest_date
* @property null|Carbon $repeat_until
*/
#[ObservedBy([DeletedRecurrenceObserver::class])]
class Recurrence extends Model
@@ -50,43 +51,44 @@ class Recurrence extends Model
use ReturnsIntegerUserIdTrait;
use SoftDeletes;
protected $fillable = [
'user_id',
'user_group_id',
'transaction_type_id',
'title',
'description',
'first_date',
'first_date_tz',
'repeat_until',
'repeat_until_tz',
'latest_date',
'latest_date_tz',
'repetitions',
'apply_rules',
'active',
];
protected $fillable
= [
'user_id',
'user_group_id',
'transaction_type_id',
'title',
'description',
'first_date',
'first_date_tz',
'repeat_until',
'repeat_until_tz',
'latest_date',
'latest_date_tz',
'repetitions',
'apply_rules',
'active',
];
protected $table = 'recurrences';
protected $table = 'recurrences';
/**
* Route binder. Converts the key in the URL to the specified object (or throw 404).
*
* @throws NotFoundHttpException
*/
public static function routeBinder(self|string $value): self
public static function routeBinder(self | string $value): self
{
if ($value instanceof self) {
$value = (int) $value->id;
$value = (int)$value->id;
}
if (auth()->check()) {
$recurrenceId = (int) $value;
$recurrenceId = (int)$value;
/** @var User $user */
$user = auth()->user();
$user = auth()->user();
/** @var null|Recurrence $recurrence */
$recurrence = $user->recurrences()->find($recurrenceId);
$recurrence = $user->recurrences()->find($recurrenceId);
if (null !== $recurrence) {
return $recurrence;
}
@@ -160,6 +162,6 @@ class Recurrence extends Model
protected function transactionTypeId(): Attribute
{
return Attribute::make(get: static fn ($value): int => (int) $value);
return Attribute::make(get: static fn($value): int => (int)$value);
}
}
+4
View File
@@ -23,6 +23,7 @@ declare(strict_types=1);
namespace FireflyIII\Models;
use Carbon\Carbon;
use FireflyIII\Casts\SeparateTimezoneCaster;
use FireflyIII\Handlers\Observer\DeletedTagObserver;
use FireflyIII\Support\Models\ReturnsIntegerIdTrait;
@@ -36,6 +37,9 @@ use Illuminate\Database\Eloquent\Relations\MorphMany;
use Illuminate\Database\Eloquent\SoftDeletes;
use Symfony\Component\HttpKernel\Exception\NotFoundHttpException;
/**
* @property Carbon|null $date
*/
#[ObservedBy([DeletedTagObserver::class])]
class Tag extends Model
{
+2 -1
View File
@@ -47,7 +47,8 @@ use Symfony\Component\HttpKernel\Exception\NotFoundHttpException;
* @method EloquentBuilder|static after()
* @method static EloquentBuilder|static query()
*
* @property TransactionGroup $transactionGroup
* @property TransactionGroup|null $transactionGroup
* @property Carbon $date
*/
#[ObservedBy([DeletedTransactionJournalObserver::class])]
class TransactionJournal extends Model
@@ -86,6 +86,7 @@ class AccountDestroyService
foreach ($collection as $row) {
if ((int) $row->the_count > 1) {
$journalId = $row->transaction_journal_id;
/** @var TransactionJournal|null $journal */
$journal = $user->transactionJournals()->find($journalId);
if (null !== $journal) {
Log::debug(sprintf('Deleted journal #%d because it has the same source as destination.', $journal->id));
@@ -144,15 +144,16 @@ class RemoteUserGuard implements Guard
return $this->user?->id;
}
public function setUser(Authenticatable|User|null $user): void
public function setUser(Authenticatable|User|null $user): Guard
{
// Log::debug(sprintf('Now at %s', __METHOD__));
if ($user instanceof User) {
$this->user = $user;
return;
return $this;
}
Log::error(sprintf('Did not set user at %s', __METHOD__));
return $this;
}
public function user(): ?User
@@ -128,6 +128,10 @@ class BillDateCalculator
}
}
Log::debug('end of loop');
/** @template T
* @param Carbon $date
* @return null|T
*/
$simple = $set->map(static fn (Carbon $date) => $date->format('Y-m-d'));
Log::debug(sprintf('Found %d pay dates', $set->count()), $simple->toArray());
+13 -13
View File
@@ -201,25 +201,25 @@ class Navigation
Log::debug('endOfPeriod() requests "YTD" + future, set it to "3M" instead.');
$repeatFreq = '3M';
}
$new = Carbon::now();
$functionMap = [
'1D' => 'endOfDay',
'daily' => 'endOfDay',
'1W' => 'addWeek',
'week' => 'addWeek',
'weekly' => 'addWeek',
'1M' => 'addMonth',
'month' => 'addMonth',
'monthly' => 'addMonth',
'3M' => 'addQuarter',
'quarter' => 'addQuarter',
'quarterly' => 'addQuarter',
'1W' => 'addWeeks',
'week' => 'addWeeks',
'weekly' => 'addWeeks',
'1M' => 'addMonths',
'month' => 'addMonths',
'monthly' => 'addMonths',
'3M' => 'addQuarters',
'quarter' => 'addQuarters',
'quarterly' => 'addQuarters',
'6M' => 'addMonths',
'half-year' => 'addMonths',
'half_year' => 'addMonths',
'year' => 'addYear',
'yearly' => 'addYear',
'1Y' => 'addYear',
'year' => 'addYears',
'yearly' => 'addYears',
'1Y' => 'addYears',
];
$modifierMap = ['half-year' => 6, 'half_year' => 6, '6M' => 6];
$subDay = ['week', 'weekly', '1W', 'month', 'monthly', '1M', '3M', 'quarter', 'quarterly', '6M', 'half-year', 'half_year', '1Y', 'year', 'yearly'];
+7 -7
View File
@@ -47,7 +47,6 @@ use Illuminate\Http\Middleware\HandleCors;
use Illuminate\Http\Middleware\ValidatePostSize;
use Illuminate\View\Middleware\ShareErrorsFromSession;
use Laravel\Passport\Http\Middleware\CreateFreshApiToken;
use Laravel\Sanctum\Http\Middleware\EnsureFrontendRequestsAreStateful;
use PragmaRX\Google2FALaravel\Middleware as MFAMiddleware;
/*
@@ -63,19 +62,20 @@ use PragmaRX\Google2FALaravel\Middleware as MFAMiddleware;
bcscale(12);
if (!function_exists('envNonEmpty')) {
if (!function_exists('envDefaultWhenEmpty')) {
/**
*
* @return mixed|null
*/
function envNonEmpty(string $key, string | int | bool | null $default = null)
function envDefaultWhenEmpty(mixed $value, string | int | bool | null $default = null): mixed
{
$result = env($key, $default);
if ('' === $result) {
if(null === $value) {
return $default;
}
return $result;
if('' === $value) {
return $default;
}
return $value;
}
}
+5 -5
View File
@@ -36,12 +36,12 @@ use Illuminate\Support\Facades\URL;
use Spatie\Html\Facades\Html;
return [
'name' => envNonEmpty('APP_NAME', 'Firefly III'),
'env' => envNonEmpty('APP_ENV', 'production'),
'name' => envDefaultWhenEmpty(env('APP_NAME'), 'Firefly III'),
'env' => envDefaultWhenEmpty(env('APP_ENV'), 'production'),
'debug' => env('APP_DEBUG', false),
'url' => envNonEmpty('APP_URL', 'http://localhost'),
'timezone' => envNonEmpty('TZ', 'UTC'),
'locale' => envNonEmpty('DEFAULT_LANGUAGE', 'en_US'),
'url' => envDefaultWhenEmpty(env('APP_URL'), 'http://localhost'),
'timezone' => envDefaultWhenEmpty(env('TZ'), 'UTC'),
'locale' => envDefaultWhenEmpty(env('DEFAULT_LANGUAGE'), 'en_US'),
'fallback_locale' => 'en_US',
'key' => env('APP_KEY'),
'cipher' => 'AES-256-CBC',
+3 -3
View File
@@ -37,11 +37,11 @@ return [
*/
'defaults' => [
'guard' => envNonEmpty('AUTHENTICATION_GUARD', 'web'),
'guard' => envDefaultWhenEmpty(env('AUTHENTICATION_GUARD'), 'web'),
'passwords' => 'users',
],
'guard_header' => envNonEmpty('AUTHENTICATION_GUARD_HEADER', 'REMOTE_USER'),
'guard_email' => envNonEmpty('AUTHENTICATION_GUARD_EMAIL'),
'guard_header' => envDefaultWhenEmpty(env('AUTHENTICATION_GUARD_HEADER'), 'REMOTE_USER'),
'guard_email' => env('AUTHENTICATION_GUARD_EMAIL'),
/*
|--------------------------------------------------------------------------
+1 -1
View File
@@ -36,7 +36,7 @@ return [
|
*/
'default' => envNonEmpty('CACHE_DRIVER', 'file'),
'default' => envDefaultWhenEmpty(env('CACHE_DRIVER'), 'file'),
/*
|--------------------------------------------------------------------------
+40 -40
View File
@@ -24,12 +24,12 @@ declare(strict_types=1);
use function Safe\parse_url;
$databaseUrl = getenv('DATABASE_URL');
$host = '';
$username = '';
$password = '';
$database = '';
$port = '';
$databaseUrl = getenv('DATABASE_URL');
$host = '';
$username = '';
$password = '';
$database = '';
$port = '';
if (false !== $databaseUrl) {
$options = parse_url($databaseUrl);
@@ -41,15 +41,15 @@ if (false !== $databaseUrl) {
}
// Get SSL parameters from .env file.
$mysql_ssl_ca_dir = envNonEmpty('MYSQL_SSL_CAPATH');
$mysql_ssl_ca_file = envNonEmpty('MYSQL_SSL_CA');
$mysql_ssl_cert = envNonEmpty('MYSQL_SSL_CERT');
$mysql_ssl_key = envNonEmpty('MYSQL_SSL_KEY');
$mysql_ssl_ciphers = envNonEmpty('MYSQL_SSL_CIPHER');
$mysql_ssl_verify = envNonEmpty('MYSQL_SSL_VERIFY_SERVER_CERT');
$mysql_ssl_ca_dir = env('MYSQL_SSL_CAPATH');
$mysql_ssl_ca_file = env('MYSQL_SSL_CA');
$mysql_ssl_cert = env('MYSQL_SSL_CERT');
$mysql_ssl_key = env('MYSQL_SSL_KEY');
$mysql_ssl_ciphers = env('MYSQL_SSL_CIPHER');
$mysql_ssl_verify = env('MYSQL_SSL_VERIFY_SERVER_CERT');
$mySqlSSLOptions = [];
$useSSL = envNonEmpty('MYSQL_USE_SSL', false);
$mySqlSSLOptions = [];
$useSSL = envDefaultWhenEmpty(env('MYSQL_USE_SSL'), false);
if (false !== $useSSL && null !== $useSSL && '' !== $useSSL) {
if (null !== $mysql_ssl_ca_dir) {
$mySqlSSLOptions[PDO::MYSQL_ATTR_SSL_CAPATH] = $mysql_ssl_ca_dir;
@@ -72,19 +72,19 @@ if (false !== $useSSL && null !== $useSSL && '' !== $useSSL) {
}
return [
'default' => envNonEmpty('DB_CONNECTION', 'mysql'),
'default' => envDefaultWhenEmpty(env('DB_CONNECTION'), 'mysql'),
'connections' => [
'sqlite' => [
'driver' => 'sqlite',
'database' => envNonEmpty('DB_DATABASE', storage_path('database/database.sqlite')),
'database' => envDefaultWhenEmpty(env('DB_DATABASE'), storage_path('database/database.sqlite')),
'prefix' => '',
],
'mysql' => [
'driver' => 'mysql',
'host' => envNonEmpty('DB_HOST', $host),
'port' => envNonEmpty('DB_PORT', $port),
'database' => envNonEmpty('DB_DATABASE', $database),
'username' => envNonEmpty('DB_USERNAME', $username),
'host' => envDefaultWhenEmpty(env('DB_HOST'), $host),
'port' => envDefaultWhenEmpty(env('DB_PORT'), $port),
'database' => envDefaultWhenEmpty(env('DB_DATABASE'), $database),
'username' => envDefaultWhenEmpty(env('DB_USERNAME'), $username),
'password' => env('DB_PASSWORD', $password),
'unix_socket' => env('DB_SOCKET', ''),
'charset' => 'utf8mb4',
@@ -96,19 +96,19 @@ return [
],
'pgsql' => [
'driver' => 'pgsql',
'host' => envNonEmpty('DB_HOST', $host),
'port' => envNonEmpty('DB_PORT', $port),
'database' => envNonEmpty('DB_DATABASE', $database),
'username' => envNonEmpty('DB_USERNAME', $username),
'host' => envDefaultWhenEmpty(env('DB_HOST'), $host),
'port' => envDefaultWhenEmpty(env('DB_PORT'), $port),
'database' => envDefaultWhenEmpty(env('DB_DATABASE'), $database),
'username' => envDefaultWhenEmpty(env('DB_USERNAME'), $username),
'password' => env('DB_PASSWORD', $password),
'charset' => 'utf8',
'prefix' => '',
'search_path' => envNonEmpty('PGSQL_SCHEMA', 'public'),
'schema' => envNonEmpty('PGSQL_SCHEMA', 'public'),
'sslmode' => envNonEmpty('PGSQL_SSL_MODE', 'prefer'),
'sslcert' => envNonEmpty('PGSQL_SSL_CERT'),
'sslkey' => envNonEmpty('PGSQL_SSL_KEY'),
'sslrootcert' => envNonEmpty('PGSQL_SSL_ROOT_CERT'),
'search_path' => envDefaultWhenEmpty(env('PGSQL_SCHEMA'), 'public'),
'schema' => envDefaultWhenEmpty(env('PGSQL_SCHEMA'), 'public'),
'sslmode' => envDefaultWhenEmpty(env('PGSQL_SSL_MODE'), 'prefer'),
'sslcert' => env('PGSQL_SSL_CERT'),
'sslkey' => env('PGSQL_SSL_KEY'),
'sslrootcert' => env('PGSQL_SSL_ROOT_CERT'),
],
'sqlsrv' => [
'driver' => 'sqlsrv',
@@ -139,21 +139,21 @@ return [
// 'prefix' => env('REDIS_PREFIX', Str::slug(env('APP_NAME', 'laravel'), '_') . '_database_'),
],
'default' => [
'scheme' => envNonEmpty('REDIS_SCHEME', 'tcp'),
'url' => envNonEmpty('REDIS_URL'),
'path' => envNonEmpty('REDIS_PATH'),
'host' => envNonEmpty('REDIS_HOST', '127.0.0.1'),
'port' => envNonEmpty('REDIS_PORT', 6379),
'scheme' => envDefaultWhenEmpty(env('REDIS_SCHEME'), 'tcp'),
'url' => env('REDIS_URL'),
'path' => env('REDIS_PATH'),
'host' => envDefaultWhenEmpty(env('REDIS_HOST'), '127.0.0.1'),
'port' => envDefaultWhenEmpty(env('REDIS_PORT'), 6379),
'username' => env('REDIS_USERNAME'),
'password' => env('REDIS_PASSWORD'),
'database' => env('REDIS_DB', '0'),
],
'cache' => [
'scheme' => envNonEmpty('REDIS_SCHEME', 'tcp'),
'url' => envNonEmpty('REDIS_URL'),
'path' => envNonEmpty('REDIS_PATH'),
'host' => envNonEmpty('REDIS_HOST', '127.0.0.1'),
'port' => envNonEmpty('REDIS_PORT', 6379),
'scheme' => envDefaultWhenEmpty(env('REDIS_SCHEME'), 'tcp'),
'url' => env('REDIS_URL'),
'path' => env('REDIS_PATH'),
'host' => envDefaultWhenEmpty(env('REDIS_HOST'), '127.0.0.1'),
'port' => envDefaultWhenEmpty(env('REDIS_PORT'), 6379),
'username' => env('REDIS_USERNAME'),
'password' => env('REDIS_PASSWORD'),
'database' => env('REDIS_CACHE_DB', '1'),
+13 -7
View File
@@ -75,7 +75,7 @@ return [
'webhooks' => true,
'handle_debts' => true,
'expression_engine' => true,
'running_balance_column' => (bool)envNonEmpty('USE_RUNNING_BALANCE', true), // this is only the default value, is not used.
'running_balance_column' => (bool)envDefaultWhenEmpty(env('USE_RUNNING_BALANCE'), true), // this is only the default value, is not used.
// see cer.php for exchange rates feature flag.
],
'version' => '6.5.4',
@@ -83,6 +83,12 @@ return [
'api_version' => '2.1.0', // field is no longer used.
'db_version' => 28, // field is no longer used.
// Docker build info, if present:
'is_docker' => env('IS_DOCKER', false),
'base_image_build' => envDefaultWhenEmpty(env('BASE_IMAGE_BUILD'),'(unknown)'),
'base_image_date' => envDefaultWhenEmpty(env('BASE_IMAGE_DATE'),'(unknown)'),
'is_local_dev' => env('IS_LOCAL_DEV', false),
// generic settings
'maxUploadSize' => 1073741824, // 1 GB
'send_error_message' => env('SEND_ERROR_MESSAGE', true),
@@ -91,7 +97,7 @@ return [
// tokens and keys
'fixer_api_key' => env('FIXER_API_KEY', ''),
'ipinfo_token' => env('IPINFO_TOKEN', ''),
'static_cron_token' => envNonEmpty('STATIC_CRON_TOKEN'),
'static_cron_token' => env('STATIC_CRON_TOKEN'),
// flags
'enable_external_map' => env('ENABLE_EXTERNAL_MAP', false), // no longer used, only for default.
@@ -106,8 +112,8 @@ return [
'tracker_url' => env('TRACKER_URL', ''),
// authentication settings
'authentication_guard' => envNonEmpty('AUTHENTICATION_GUARD', 'web'),
'custom_logout_url' => envNonEmpty('CUSTOM_LOGOUT_URL', ''),
'authentication_guard' => envDefaultWhenEmpty(env('AUTHENTICATION_GUARD'), 'web'),
'custom_logout_url' => envDefaultWhenEmpty(env('CUSTOM_LOGOUT_URL'), ''),
// static config (cannot be changed by user)
'update_endpoint' => 'https://version.firefly-iii.org/index.json',
@@ -188,8 +194,8 @@ return [
'convertToPrimary' => false,
],
'default_currency' => 'EUR',
'default_language' => envNonEmpty('DEFAULT_LANGUAGE', 'en_US'),
'default_locale' => envNonEmpty('DEFAULT_LOCALE', 'equal'),
'default_language' => envDefaultWhenEmpty(env('DEFAULT_LANGUAGE'), 'en_US'),
'default_locale' => envDefaultWhenEmpty(env('DEFAULT_LOCALE'), 'equal'),
// account types that may have or set a currency
'valid_currency_account_types' => [
@@ -218,7 +224,7 @@ return [
'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'), // no longer used, only for default.
'valid_url_protocols' => envDefaultWhenEmpty(env('VALID_URL_PROTOCOLS'), 'http,https,ftp,ftps,mailto'), // no longer used, only for default.
'allowedMimes' => [
// plain files
'text/plain',
+15 -15
View File
@@ -34,8 +34,8 @@ $validChannels = ['single', 'papertrail', 'stdout', 'daily', 'syslog', 'err
$validAuditChannels = ['audit_papertrail', 'audit_stdout', 'audit_stdout', 'audit_daily', 'audit_syslog', 'audit_errorlog'];
// which settings did the user set, if any?
$defaultLogChannel = (string) envNonEmpty('LOG_CHANNEL', 'stack');
$auditLogChannel = (string) envNonEmpty('AUDIT_LOG_CHANNEL', '');
$defaultLogChannel = (string) envDefaultWhenEmpty(env('LOG_CHANNEL'), 'stack');
$auditLogChannel = (string) env('AUDIT_LOG_CHANNEL');
if ('stack' === $defaultLogChannel) {
$defaultChannels = ['daily', 'stdout'];
@@ -60,8 +60,8 @@ return [
|
*/
'default' => envNonEmpty('LOG_CHANNEL', 'stack'),
'level' => envNonEmpty('APP_LOG_LEVEL', 'info'),
'default' => envDefaultWhenEmpty(env('LOG_CHANNEL'), 'stack'),
'level' => envDefaultWhenEmpty(env('APP_LOG_LEVEL'), 'info'),
/*
|--------------------------------------------------------------------------
| Log Channels
@@ -93,11 +93,11 @@ return [
'single' => [
'driver' => 'single',
'path' => storage_path('logs/laravel.log'),
'level' => envNonEmpty('APP_LOG_LEVEL', 'info'),
'level' => envDefaultWhenEmpty(env('APP_LOG_LEVEL'), 'info'),
],
'papertrail' => [
'driver' => 'monolog',
'level' => envNonEmpty('APP_LOG_LEVEL', 'info'),
'level' => envDefaultWhenEmpty(env('APP_LOG_LEVEL'), 'info'),
'handler' => SyslogUdpHandler::class,
'handler_with' => [
'host' => env('PAPERTRAIL_HOST'),
@@ -107,21 +107,21 @@ return [
'stdout' => [
'driver' => 'single',
'path' => 'php://stdout',
'level' => envNonEmpty('APP_LOG_LEVEL', 'info'),
'level' => envDefaultWhenEmpty(env('APP_LOG_LEVEL'), 'info'),
],
'daily' => [
'driver' => 'daily',
'path' => storage_path('logs/ff3-'.PHP_SAPI.'.log'),
'level' => envNonEmpty('APP_LOG_LEVEL', 'info'),
'level' => envDefaultWhenEmpty(env('APP_LOG_LEVEL'), 'info'),
'days' => 7,
],
'syslog' => [
'driver' => 'syslog',
'level' => envNonEmpty('APP_LOG_LEVEL', 'info'),
'level' => envDefaultWhenEmpty(env('APP_LOG_LEVEL'), 'info'),
],
'errorlog' => [
'driver' => 'errorlog',
'level' => envNonEmpty('APP_LOG_LEVEL', 'info'),
'level' => envDefaultWhenEmpty(env('APP_LOG_LEVEL'), 'info'),
],
/*
@@ -130,7 +130,7 @@ return [
*/
'audit_papertrail' => [
'driver' => 'monolog',
'level' => envNonEmpty('AUDIT_LOG_LEVEL', 'info'),
'level' => envDefaultWhenEmpty(env('AUDIT_LOG_LEVEL'), 'info'),
'handler' => SyslogUdpHandler::class,
'tap' => [AuditLogger::class],
'handler_with' => [
@@ -142,24 +142,24 @@ return [
'driver' => 'single',
'path' => 'php://stdout',
'tap' => [AuditLogger::class],
'level' => envNonEmpty('AUDIT_LOG_LEVEL', 'info'),
'level' => envDefaultWhenEmpty(env('AUDIT_LOG_LEVEL'), 'info'),
],
'audit_daily' => [
'driver' => 'daily',
'path' => storage_path('logs/ff3-audit.log'),
'tap' => [AuditLogger::class],
'level' => envNonEmpty('AUDIT_LOG_LEVEL', 'info'),
'level' => envDefaultWhenEmpty(env('AUDIT_LOG_LEVEL'), 'info'),
'days' => 90,
],
'audit_syslog' => [
'driver' => 'syslog',
'tap' => [AuditLogger::class],
'level' => envNonEmpty('AUDIT_LOG_LEVEL', 'info'),
'level' => envDefaultWhenEmpty(env('AUDIT_LOG_LEVEL'), 'info'),
],
'audit_errorlog' => [
'driver' => 'errorlog',
'tap' => [AuditLogger::class],
'level' => envNonEmpty('AUDIT_LOG_LEVEL', 'info'),
'level' => envDefaultWhenEmpty(env('AUDIT_LOG_LEVEL'), 'info'),
],
],
];
+7 -7
View File
@@ -34,16 +34,16 @@ return [
| and used as needed; however, this mailer will be used by default.
|
*/
'default' => envNonEmpty('MAIL_MAILER', 'log'),
'default' => envDefaultWhenEmpty(env('MAIL_MAILER'), 'log'),
'mailers' => [
'smtp' => [
'transport' => 'smtp',
'host' => envNonEmpty('MAIL_HOST', 'smtp.mailtrap.io'),
'host' => envDefaultWhenEmpty(env('MAIL_HOST'), 'smtp.mailtrap.io'),
'port' => (int) env('MAIL_PORT', 2525),
'encryption' => envNonEmpty('MAIL_ENCRYPTION', 'tls'),
'username' => envNonEmpty('MAIL_USERNAME', 'user@example.com'),
'password' => envNonEmpty('MAIL_PASSWORD', 'password'),
'encryption' => envDefaultWhenEmpty(env('MAIL_ENCRYPTION'), 'tls'),
'username' => envDefaultWhenEmpty(env('MAIL_USERNAME'), 'user@example.com'),
'password' => envDefaultWhenEmpty(env('MAIL_PASSWORD'), 'password'),
'timeout' => null,
'scheme' => env('MAIL_SCHEME'),
'url' => env('MAIL_URL'),
@@ -73,7 +73,7 @@ return [
'sendmail' => [
'transport' => 'sendmail',
'path' => envNonEmpty('MAIL_SENDMAIL_COMMAND', '/usr/sbin/sendmail -bs'),
'path' => envDefaultWhenEmpty(env('MAIL_SENDMAIL_COMMAND'), '/usr/sbin/sendmail -bs'),
],
'log' => [
'transport' => 'log',
@@ -91,7 +91,7 @@ return [
],
],
'from' => ['address' => envNonEmpty('MAIL_FROM', 'changeme@example.com'), 'name' => 'Firefly III Mailer'],
'from' => ['address' => envDefaultWhenEmpty(env('MAIL_FROM'), 'changeme@example.com'), 'name' => 'Firefly III Mailer'],
'markdown' => [
'theme' => 'default',
+1 -1
View File
@@ -34,7 +34,7 @@ return [
|
*/
'guard' => envNonEmpty('AUTHENTICATION_GUARD', 'web'),
'guard' => envDefaultWhenEmpty(env('AUTHENTICATION_GUARD'), 'web'),
/*
|--------------------------------------------------------------------------