Compare commits

...

15 Commits

Author SHA1 Message Date
github-actions[bot]
0ece35feca Merge pull request #11393 from firefly-iii/release-1766210807
🤖 Automatically merge the PR into the develop branch.
2025-12-20 07:06:54 +01:00
JC5
3b8caba37c 🤖 Auto commit for release 'develop' on 2025-12-20 2025-12-20 07:06:47 +01:00
James Cole
8e729d6bbf Replace references to hard coded config with variables. 2025-12-20 07:00:53 +01:00
James Cole
0f0cdb8e96 Replace config calls. 2025-12-20 06:42:11 +01:00
James Cole
b0cc5f3a46 Remove entries from .env file. 2025-12-20 06:39:58 +01:00
James Cole
71c5bdb198 Move settings to the settings page, out of the .env file. 2025-12-20 06:39:05 +01:00
James Cole
be9078fe99 Remove unused settings. 2025-12-20 06:10:51 +01:00
github-actions[bot]
d235e32c34 Merge pull request #11391 from firefly-iii/release-1766164682
🤖 Automatically merge the PR into the develop branch.
2025-12-19 18:18:09 +01:00
JC5
e34b89da08 🤖 Auto commit for release 'develop' on 2025-12-19 2025-12-19 18:18:02 +01:00
James Cole
f5428595d5 Merge branch 'develop' of github.com:firefly-iii/firefly-iii into develop
# Conflicts:
#	app/Console/Commands/Correction/CorrectsAmounts.php
2025-12-19 18:13:58 +01:00
James Cole
87cb1e1a2b Fix #11378 2025-12-19 18:13:04 +01:00
github-actions[bot]
22448a825b Merge pull request #11390 from firefly-iii/release-1766158480
🤖 Automatically merge the PR into the develop branch.
2025-12-19 16:34:48 +01:00
JC5
476a9ac6e4 🤖 Auto commit for release 'develop' on 2025-12-19 2025-12-19 16:34:41 +01:00
James Cole
0acd07405b Fix #11388 2025-12-19 16:30:39 +01:00
James Cole
1daacb80b1 Fix #11383 2025-12-17 19:27:59 +01:00
93 changed files with 618 additions and 378 deletions

View File

@@ -402,16 +402,16 @@
},
{
"name": "friendsofphp/php-cs-fixer",
"version": "v3.92.2",
"version": "v3.92.3",
"source": {
"type": "git",
"url": "https://github.com/PHP-CS-Fixer/PHP-CS-Fixer.git",
"reference": "64fab3553dce507ce247f7d1a7d65f74ef658c3f"
"reference": "2ba8f5a60f6f42fb65758cfb3768434fa2d1c7e8"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/PHP-CS-Fixer/PHP-CS-Fixer/zipball/64fab3553dce507ce247f7d1a7d65f74ef658c3f",
"reference": "64fab3553dce507ce247f7d1a7d65f74ef658c3f",
"url": "https://api.github.com/repos/PHP-CS-Fixer/PHP-CS-Fixer/zipball/2ba8f5a60f6f42fb65758cfb3768434fa2d1c7e8",
"reference": "2ba8f5a60f6f42fb65758cfb3768434fa2d1c7e8",
"shasum": ""
},
"require": {
@@ -494,7 +494,7 @@
],
"support": {
"issues": "https://github.com/PHP-CS-Fixer/PHP-CS-Fixer/issues",
"source": "https://github.com/PHP-CS-Fixer/PHP-CS-Fixer/tree/v3.92.2"
"source": "https://github.com/PHP-CS-Fixer/PHP-CS-Fixer/tree/v3.92.3"
},
"funding": [
{
@@ -502,7 +502,7 @@
"type": "github"
}
],
"time": "2025-12-17T00:04:16+00:00"
"time": "2025-12-18T10:45:02+00:00"
},
{
"name": "psr/container",

View File

@@ -188,39 +188,11 @@ MAILERSEND_API_KEY=
# Firefly III can send you the following messages.
SEND_ERROR_MESSAGE=true
# These messages contain (sensitive) transaction information:
SEND_REPORT_JOURNALS=true
# Set this value to true if you want to set the location of certain things, like transactions.
# Since this involves an external service, it's optional and disabled by default.
ENABLE_EXTERNAL_MAP=false
#
# Enable or disable exchange rate conversion.
#
ENABLE_EXCHANGE_RATES=false
# Set this value to true if you want Firefly III to download currency exchange rates
# from the internet. These rates are hosted by the creator of Firefly III inside
# an Azure Storage Container.
# Not all currencies may be available. Rates may be wrong.
ENABLE_EXTERNAL_RATES=false
# The map will default to this location:
MAP_DEFAULT_LAT=51.983333
MAP_DEFAULT_LONG=5.916667
MAP_DEFAULT_ZOOM=6
#
# Some objects have room for an URL, like transactions and webhooks.
# By default, the following protocols are allowed:
# http, https, ftp, ftps, mailto
#
# To change this, set your preferred comma separated set below.
# Be sure to include http, https and other default ones if you need to.
#
VALID_URL_PROTOCOLS=
#
# Firefly III authentication settings
#
@@ -275,11 +247,6 @@ DISABLE_CSP_HEADER=false
TRACKER_SITE_ID=
TRACKER_URL=
#
# Firefly III supports webhooks. These are security sensitive and must be enabled manually first.
#
ALLOW_WEBHOOKS=false
#
# The static cron job token can be useful when you use Docker and wish to manage cron jobs.
# 1. Set this token to any 32-character value (this is important!).
@@ -313,25 +280,12 @@ PUSHER_ID=
DEMO_USERNAME=
DEMO_PASSWORD=
#
# Disable or enable the running balance column data.
# If you enable this, please also run "php artisan firefly-iii:correct-database"
# This will take some time the first run.
#
USE_RUNNING_BALANCE=false
#
# The v2 layout is very experimental. If it breaks you get to keep both parts.
# Be wary of data loss.
#
FIREFLY_III_LAYOUT=v1
#
# Which Query Parser implementation to use for the search engine and rules
# 'new' is experimental, 'legacy' is the classic one
#
QUERY_PARSER_IMPLEMENTATION=new
#
# Please make sure this URL matches the external URL of your Firefly III installation.
# It is used to validate specific requests and to generate URLs in emails.

View File

@@ -29,6 +29,7 @@ use FireflyIII\Api\V1\Requests\System\CronRequest;
use FireflyIII\Support\Http\Controllers\CronRunner;
use Illuminate\Http\JsonResponse;
use Illuminate\Support\Facades\Log;
use FireflyIII\Support\Facades\FireflyConfig;
/**
* Class CronController
@@ -50,7 +51,7 @@ class CronController extends Controller
$return = [];
$return['recurring_transactions'] = $this->runRecurring($config['force'], $config['date']);
$return['auto_budgets'] = $this->runAutoBudget($config['force'], $config['date']);
if (true === config('cer.download_enabled')) {
if (true === FireflyConfig::get('enable_external_rates', config('cer.download_enabled'))->data) {
$return['exchange_rates'] = $this->exchangeRatesCronJob($config['force'], $config['date']);
}
$return['bill_notifications'] = $this->billWarningCronJob($config['force'], $config['date']);

View File

@@ -38,6 +38,7 @@ use League\Fractal\Pagination\IlluminatePaginatorAdapter;
use League\Fractal\Resource\Collection as FractalCollection;
use League\Fractal\Resource\Item;
use Symfony\Component\HttpKernel\Exception\NotFoundHttpException;
use FireflyIII\Support\Facades\FireflyConfig;
/**
* Class AttemptController
@@ -71,7 +72,7 @@ class AttemptController extends Controller
if ($message->webhook_id !== $webhook->id) {
throw new FireflyException('200040: Webhook and webhook message are no match');
}
if (false === config('firefly.allow_webhooks')) {
if (false === FireflyConfig::get('allow_webhooks', config('firefly.allow_webhooks'))->data) {
Log::channel('audit')->warning(sprintf('User lists webhook attempts of webhook #%d and message #%d, but webhooks are DISABLED.', $webhook->id, $message->id));
throw new NotFoundHttpException('Webhooks are not enabled.');
@@ -115,7 +116,7 @@ class AttemptController extends Controller
throw new FireflyException('200041: Webhook message and webhook attempt are no match');
}
if (false === config('firefly.allow_webhooks')) {
if (false === FireflyConfig::get('allow_webhooks', config('firefly.allow_webhooks'))->data) {
Log::channel('audit')->warning(sprintf('User views single webhook attempt #%d of webhook #%d and message #%d, but webhooks are DISABLED', $attempt->id, $webhook->id, $message->id));
throw new NotFoundHttpException('Webhooks are not enabled.');

View File

@@ -34,6 +34,7 @@ use FireflyIII\Support\Facades\Preferences;
use Illuminate\Http\JsonResponse;
use Illuminate\Support\Facades\Log;
use Symfony\Component\HttpKernel\Exception\NotFoundHttpException;
use FireflyIII\Support\Facades\FireflyConfig;
/**
* Class DestroyController
@@ -63,7 +64,7 @@ class DestroyController extends Controller
*/
public function destroy(Webhook $webhook): JsonResponse
{
if (false === config('firefly.allow_webhooks')) {
if (false === FireflyConfig::get('allow_webhooks', config('firefly.allow_webhooks'))->data) {
Log::channel('audit')->warning(sprintf('User tries to destroy webhook #%d. but webhooks are DISABLED.', $webhook->id));
throw new NotFoundHttpException('Webhooks are not enabled.');
@@ -93,7 +94,7 @@ class DestroyController extends Controller
throw new FireflyException('200041: Webhook message and webhook attempt are no match');
}
if (false === config('firefly.allow_webhooks')) {
if (false === FireflyConfig::get('allow_webhooks', config('firefly.allow_webhooks'))->data) {
Log::channel('audit')->warning(sprintf('User tries to destroy webhook #%d, message #%d, attempt #%d, but webhooks are DISABLED.', $webhook->id, $message->id, $attempt->id));
throw new NotFoundHttpException('Webhooks are not enabled.');
@@ -121,7 +122,7 @@ class DestroyController extends Controller
throw new FireflyException('200040: Webhook and webhook message are no match');
}
if (false === config('firefly.allow_webhooks')) {
if (false === FireflyConfig::get('allow_webhooks', config('firefly.allow_webhooks'))->data) {
Log::channel('audit')->warning(sprintf('User tries to destroy webhook #%d, message #%d, but webhooks are DISABLED.', $webhook->id, $message->id));
throw new NotFoundHttpException('Webhooks are not enabled.');

View File

@@ -37,6 +37,7 @@ use League\Fractal\Pagination\IlluminatePaginatorAdapter;
use League\Fractal\Resource\Collection as FractalCollection;
use League\Fractal\Resource\Item;
use Symfony\Component\HttpKernel\Exception\NotFoundHttpException;
use FireflyIII\Support\Facades\FireflyConfig;
/**
* Class MessageController
@@ -65,7 +66,7 @@ class MessageController extends Controller
*/
public function index(Webhook $webhook): JsonResponse
{
if (false === config('firefly.allow_webhooks')) {
if (false === FireflyConfig::get('allow_webhooks', config('firefly.allow_webhooks'))->data) {
Log::channel('audit')->warning(sprintf('User tries to view messages of webhook #%d, but webhooks are DISABLED.', $webhook->id));
throw new NotFoundHttpException('Webhooks are not enabled.');
@@ -105,7 +106,7 @@ class MessageController extends Controller
if ($message->webhook_id !== $webhook->id) {
throw new FireflyException('200040: Webhook and webhook message are no match');
}
if (false === config('firefly.allow_webhooks')) {
if (false === FireflyConfig::get('allow_webhooks', config('firefly.allow_webhooks'))->data) {
Log::channel('audit')->warning(sprintf('User tries to view message #%d of webhook #%d, but webhooks are DISABLED.', $message->id, $webhook->id));
throw new NotFoundHttpException('Webhooks are not enabled.');

View File

@@ -42,6 +42,7 @@ use League\Fractal\Pagination\IlluminatePaginatorAdapter;
use League\Fractal\Resource\Collection as FractalCollection;
use League\Fractal\Resource\Item;
use Symfony\Component\HttpKernel\Exception\NotFoundHttpException;
use FireflyIII\Support\Facades\FireflyConfig;
/**
* Class ShowController
@@ -72,7 +73,7 @@ class ShowController extends Controller
*/
public function index(): JsonResponse
{
if (false === config('firefly.allow_webhooks')) {
if (false === FireflyConfig::get('allow_webhooks', config('firefly.allow_webhooks'))->data) {
Log::channel('audit')->info('User tries to view all webhooks, but webhooks are DISABLED.');
throw new NotFoundHttpException('Webhooks are not enabled.');
@@ -114,7 +115,7 @@ class ShowController extends Controller
*/
public function show(Webhook $webhook): JsonResponse
{
if (false === config('firefly.allow_webhooks')) {
if (false === FireflyConfig::get('allow_webhooks', config('firefly.allow_webhooks'))->data) {
Log::channel('audit')->info(sprintf('User tries to view webhook #%d, but webhooks are DISABLED.', $webhook->id));
throw new NotFoundHttpException('Webhooks are not enabled.');
@@ -146,7 +147,7 @@ class ShowController extends Controller
*/
public function triggerTransaction(Webhook $webhook, TransactionGroup $group): JsonResponse
{
if (false === config('firefly.allow_webhooks')) {
if (false === FireflyConfig::get('allow_webhooks', config('firefly.allow_webhooks'))->data) {
Log::channel('audit')->info(sprintf('User tries to trigger webhook #%d on transaction group #%d, but webhooks are DISABLED.', $webhook->id, $group->id));
throw new NotFoundHttpException('Webhooks are not enabled.');

View File

@@ -34,6 +34,7 @@ use Illuminate\Http\JsonResponse;
use Illuminate\Support\Facades\Log;
use League\Fractal\Resource\Item;
use Symfony\Component\HttpKernel\Exception\NotFoundHttpException;
use FireflyIII\Support\Facades\FireflyConfig;
/**
* Class StoreController
@@ -63,7 +64,7 @@ class StoreController extends Controller
public function store(CreateRequest $request): JsonResponse
{
$data = $request->getData();
if (false === config('firefly.allow_webhooks')) {
if (false === FireflyConfig::get('allow_webhooks', config('firefly.allow_webhooks'))->data) {
Log::channel('audit')->info('User tries to store new webhook, but webhooks are DISABLED.', $data);
throw new NotFoundHttpException('Webhooks are not enabled.');

View File

@@ -31,6 +31,7 @@ use FireflyIII\Repositories\Webhook\WebhookRepositoryInterface;
use Illuminate\Http\JsonResponse;
use Illuminate\Support\Facades\Log;
use Symfony\Component\HttpKernel\Exception\NotFoundHttpException;
use FireflyIII\Support\Facades\FireflyConfig;
/**
* Class SubmitController
@@ -58,7 +59,7 @@ class SubmitController extends Controller
*/
public function submit(Webhook $webhook): JsonResponse
{
if (false === config('firefly.allow_webhooks')) {
if (false === FireflyConfig::get('allow_webhooks', config('firefly.allow_webhooks'))->data) {
Log::channel('audit')->info(sprintf('User tries to submit webhook #%d, but webhooks are DISABLED.', $webhook->id));
throw new NotFoundHttpException('Webhooks are not enabled.');

View File

@@ -35,6 +35,7 @@ use Illuminate\Http\JsonResponse;
use Illuminate\Support\Facades\Log;
use League\Fractal\Resource\Item;
use Symfony\Component\HttpKernel\Exception\NotFoundHttpException;
use FireflyIII\Support\Facades\FireflyConfig;
/**
* Class UpdateController
@@ -63,7 +64,7 @@ class UpdateController extends Controller
public function update(Webhook $webhook, UpdateRequest $request): JsonResponse
{
$data = $request->getData();
if (false === config('firefly.allow_webhooks')) {
if (false === FireflyConfig::get('allow_webhooks', config('firefly.allow_webhooks'))->data) {
Log::channel('audit')->info(sprintf('User tries to update webhook #%d, but webhooks are DISABLED.', $webhook->id), $data);
throw new NotFoundHttpException('Webhooks are not enabled.');

View File

@@ -40,6 +40,7 @@ use FireflyIII\Validation\GroupValidation;
use FireflyIII\Validation\TransactionValidation;
use Illuminate\Foundation\Http\FormRequest;
use Illuminate\Support\Facades\Log;
use FireflyIII\Support\Facades\FireflyConfig;
/**
* Class StoreRequest
@@ -176,7 +177,7 @@ class StoreRequest extends FormRequest
public function rules(): array
{
Log::debug('Collect rules of TransactionStoreRequest');
$validProtocols = config('firefly.valid_url_protocols');
$validProtocols = FireflyConfig::get('valid_url_protocols', config('firefly.valid_url_protocols'))->data;
$locationRules = Location::requestRules([]);
return [

View File

@@ -38,6 +38,7 @@ use FireflyIII\Validation\GroupValidation;
use FireflyIII\Validation\TransactionValidation;
use Illuminate\Foundation\Http\FormRequest;
use Illuminate\Support\Facades\Log;
use FireflyIII\Support\Facades\FireflyConfig;
/**
* Class UpdateRequest
@@ -248,7 +249,7 @@ class UpdateRequest extends FormRequest
public function rules(): array
{
Log::debug(sprintf('Now in %s', __METHOD__));
$validProtocols = config('firefly.valid_url_protocols');
$validProtocols = FireflyConfig::get('valid_url_protocols', config('firefly.valid_url_protocols'))->data;
return [
// basic fields for group:

View File

@@ -31,6 +31,7 @@ use FireflyIII\Support\Request\ChecksLogin;
use FireflyIII\Support\Request\ConvertsDataTypes;
use FireflyIII\Support\Request\ValidatesWebhooks;
use Illuminate\Foundation\Http\FormRequest;
use FireflyIII\Support\Facades\FireflyConfig;
/**
* Class CreateRequest
@@ -73,7 +74,7 @@ class CreateRequest extends FormRequest
$triggers = implode(',', array_values(Webhook::getTriggers()));
$responses = implode(',', array_values(Webhook::getResponses()));
$deliveries = implode(',', array_values(Webhook::getDeliveries()));
$validProtocols = config('firefly.valid_url_protocols');
$validProtocols = FireflyConfig::get('valid_url_protocols', config('firefly.valid_url_protocols'))->data;
return [
'title' => 'required|min:1|max:255|uniqueObjectForUser:webhooks,title',

View File

@@ -31,6 +31,7 @@ use FireflyIII\Support\Request\ChecksLogin;
use FireflyIII\Support\Request\ConvertsDataTypes;
use FireflyIII\Support\Request\ValidatesWebhooks;
use Illuminate\Foundation\Http\FormRequest;
use FireflyIII\Support\Facades\FireflyConfig;
/**
* Class UpdateRequest
@@ -73,7 +74,7 @@ class UpdateRequest extends FormRequest
$triggers = implode(',', array_values(Webhook::getTriggers()));
$responses = implode(',', array_values(Webhook::getResponses()));
$deliveries = implode(',', array_values(Webhook::getDeliveries()));
$validProtocols = config('firefly.valid_url_protocols');
$validProtocols = FireflyConfig::get('valid_url_protocols', config('firefly.valid_url_protocols'))->data;
/** @var Webhook $webhook */
$webhook = $this->route()->parameter('webhook');

View File

@@ -39,11 +39,11 @@ use FireflyIII\Models\TransactionJournal;
use FireflyIII\Models\TransactionType;
use FireflyIII\Repositories\Account\AccountRepositoryInterface;
use FireflyIII\Support\Facades\Amount;
use FireflyIII\Support\Facades\Steam;
use Illuminate\Console\Command;
use Illuminate\Support\Facades\DB;
use Illuminate\Support\Facades\Log;
use ValueError;
use FireflyIII\Support\Facades\Steam;
class CorrectsAmounts extends Command
{
@@ -79,6 +79,8 @@ class CorrectsAmounts extends Command
private function correctTransfers(): void
{
Log::debug('Will now correct transfers.');
/** @var AccountRepositoryInterface $repository */
$repository = app(AccountRepositoryInterface::class);
$type = TransactionType::where('type', TransactionTypeEnum::TRANSFER->value)->first();
@@ -89,24 +91,21 @@ class CorrectsAmounts extends Command
$repository->setUser($journal->user);
$primary = Amount::getPrimaryCurrencyByUserGroup($journal->userGroup);
/** @var null|Transaction $source */
$source = $journal->transactions()->where('amount', '<', 0)->first();
$valid = $this->validateJournal($journal);
if (false === $valid) {
Log::debug(sprintf('Journal #%d does not need to be fixed or is invalid (see previous messages)', $journal->id));
/** @var null|Transaction $destination */
$destination = $journal->transactions()->where('amount', '>', 0)->first();
if (null === $source || null === $destination) {
continue;
}
if (null === $source->foreign_currency_id || null === $destination->foreign_currency_id) {
continue;
}
Log::debug(sprintf('Journal #%d is ready to be corrected (if necessary).', $journal->id));
$source = $journal->transactions()->where('amount', '<', '0')->first();
$destination = $journal->transactions()->where('amount', '>', '0')->first();
$sourceAccount = $source->account;
$destAccount = $destination->account;
if (null === $sourceAccount || null === $destAccount) {
continue;
}
$sourceCurrency = $repository->getAccountCurrency($sourceAccount) ?? $primary;
$destCurrency = $repository->getAccountCurrency($destAccount) ?? $primary;
Log::debug(sprintf('Currency of source account #%d "%s" is %s', $sourceAccount->id, $sourceAccount->name, $sourceCurrency->code));
Log::debug(sprintf('Currency of destination account #%d "%s" is %s', $destAccount->id, $destAccount->name, $destCurrency->code));
if ($sourceCurrency->id === $destCurrency->id) {
Log::debug('Both accounts have the same currency. Removing foreign currency info.');
@@ -120,22 +119,40 @@ class CorrectsAmounts extends Command
continue;
}
// validate source
// validate source transaction
if ($destCurrency->id !== $source->foreign_currency_id) {
Log::debug(sprintf('Journal #%d: Transaction #%d refers to "%s" but should refer to "%s".', $journal->id, $source->id, $source->foreignCurrency->code, $destCurrency->code));
Log::debug(sprintf('[a] Journal #%d: transaction #%d refers to foreign currency "%s" but should refer to "%s".', $journal->id, $source->id, $source->foreignCurrency->code, $destCurrency->code));
$source->foreign_currency_id = $destCurrency->id;
$source->save();
}
if ($sourceCurrency->id !== $source->transaction_currency_id) {
Log::debug(sprintf('[b] Journal #%d: transaction #%d refers to currency "%s" but should refer to "%s".', $journal->id, $source->id, $source->transactionCurrency->code, $sourceCurrency->code));
$source->transaction_currency_id = $sourceCurrency->id;
$source->save();
}
// validate destination:
if ($sourceCurrency->id !== $destination->foreign_currency_id) {
Log::debug(sprintf('Journal #%d: Transaction #%d refers to "%s" but should refer to "%s".', $journal->id, $destination->id, $destination->foreignCurrency->code, $sourceCurrency->code));
Log::debug(sprintf('[c] Journal #%d: transaction #%d refers to foreign currency "%s" but should refer to "%s".', $journal->id, $destination->id, $destination->foreignCurrency->code, $sourceCurrency->code));
$destination->foreign_currency_id = $sourceCurrency->id;
$destination->save();
}
if ($destCurrency->id !== $destination->transaction_currency_id) {
Log::debug(sprintf('[d] Journal #%d: transaction #%d refers to currency "%s" but should refer to "%s".', $journal->id, $destination->id, $destination->transactionCurrency->code, $destCurrency->code));
$destination->transaction_currency_id = $destCurrency->id;
$destination->save();
}
Log::debug(sprintf('Done with journal #%d.', $journal->id));
}
}
private function deleteJournal(TransactionJournal $journal): void
{
$journal->transactionGroup?->delete();
$journal->delete();
}
private function fixAutoBudgets(): void
{
$count = AutoBudget::where('amount', '<', 0)->update(['amount' => DB::raw('amount * -1')]);
@@ -235,7 +252,7 @@ class CorrectsAmounts extends Command
private function fixRuleTrigger(RuleTrigger $item): bool
{
try {
$check = bccomp((string) $item->trigger_value, '0');
$check = bccomp((string)$item->trigger_value, '0');
} catch (ValueError) {
$this->friendlyError(sprintf('Rule #%d contained invalid %s-trigger "%s". The trigger has been removed, and the rule is disabled.', $item->rule_id, $item->trigger_type, $item->trigger_value));
$item->rule->active = false;
@@ -253,4 +270,57 @@ class CorrectsAmounts extends Command
return false;
}
private function validateJournal(TransactionJournal $journal): bool
{
$countSource = $journal->transactions()->where('amount', '<', 0)->count();
$countDest = $journal->transactions()->where('amount', '>', 0)->count();
if (1 !== $countSource || 1 !== $countDest) {
$this->friendlyError(sprintf('Transaction journal #%d has bad transaction information. Will delete.', $journal->id));
$this->deleteJournal($journal);
Log::error(sprintf('Transaction journal #%d has bad transaction information. Will delete.', $journal->id));
return false;
}
/** @var null|Transaction $source */
$source = $journal->transactions()->where('amount', '<', 0)->first();
/** @var null|Transaction $destination */
$destination = $journal->transactions()->where('amount', '>', 0)->first();
if (null === $source || null === $destination) {
$this->friendlyError(sprintf('Could not find source OR destination for journal #%d .', $journal->id));
Log::error(sprintf('Could not find source OR destination for journal #%d .', $journal->id));
$this->deleteJournal($journal);
return false;
}
if (null === $source->foreign_currency_id || null === $destination->foreign_currency_id) {
Log::debug('No foreign currency information is present, can safely continue with other transactions.');
return false;
}
if (null === $source->foreign_amount || null === $destination->foreign_amount) {
$this->friendlyError(sprintf('Transactions of journal #%d have no foreign amount, but have foreign currency info. Will reset this.', $journal->id));
$source->foreign_currency_id = null;
$source->save();
$destination->foreign_currency_id = null;
$source->save();
return false;
}
$sourceAccount = $source->account;
$destAccount = $destination->account;
if (null === $sourceAccount || null === $destAccount) {
$this->friendlyError(sprintf('Could not find accounts for journal #%d,', $journal->id));
$this->deleteJournal($journal);
return false;
}
return true;
}
}

View File

@@ -48,6 +48,7 @@ use Illuminate\Database\Eloquent\Builder as EloquentBuilder;
use Illuminate\Database\Query\Builder as DatabaseBuilder;
use Illuminate\Support\Facades\DB;
use Illuminate\Support\Facades\Log;
use FireflyIII\Support\Facades\FireflyConfig;
class CorrectsPrimaryCurrencyAmounts extends Command
{
@@ -62,7 +63,7 @@ class CorrectsPrimaryCurrencyAmounts extends Command
*/
public function handle(): int
{
if (false === config('cer.enabled')) {
if (false === FireflyConfig::get('enable_exchange_rates', config('cer.enabled'))->data) {
$this->friendlyInfo('This command will not run because currency exchange rates are disabled.');
return 0;

View File

@@ -30,6 +30,7 @@ use FireflyIII\Enums\TransactionTypeEnum;
use FireflyIII\Models\Transaction;
use FireflyIII\Models\TransactionJournal;
use FireflyIII\Repositories\Account\AccountRepositoryInterface;
use FireflyIII\Support\Facades\FireflyConfig;
use FireflyIII\Support\Facades\Steam;
use FireflyIII\Support\Models\AccountBalanceCalculator;
use Illuminate\Console\Command;
@@ -60,7 +61,7 @@ class CorrectsUnevenAmount extends Command
$this->fixUnevenAmounts();
$this->matchCurrencies();
if (true === config('firefly.feature_flags.running_balance_column')) {
if (true === FireflyConfig::get('use_running_balance', config('firefly.feature_flags.running_balance_column'))->data) {
$this->friendlyInfo('Will recalculate transaction running balance columns. This may take a LONG time. Please be patient.');
AccountBalanceCalculator::recalculateAll(false);
$this->friendlyInfo('Done recalculating transaction running balance columns.');
@@ -132,11 +133,7 @@ class CorrectsUnevenAmount extends Command
private function fixUnevenAmounts(): void
{
Log::debug('fixUnevenAmounts()');
$journals = DB::table('transactions')
->groupBy('transaction_journal_id')
->whereNull('deleted_at')
->get(['transaction_journal_id', DB::raw('SUM(amount) AS the_sum')])
;
$journals = DB::table('transactions')->groupBy('transaction_journal_id')->whereNull('deleted_at')->get(['transaction_journal_id', DB::raw('SUM(amount) AS the_sum')]);
/** @var stdClass $entry */
foreach ($journals as $entry) {
@@ -146,11 +143,7 @@ class CorrectsUnevenAmount extends Command
|| '' === $sum // @phpstan-ignore-line
|| str_contains($sum, 'e')
|| str_contains($sum, ',')) {
$message = sprintf(
'Journal #%d has an invalid sum ("%s"). No sure what to do.',
$entry->transaction_journal_id,
$entry->the_sum
);
$message = sprintf('Journal #%d has an invalid sum ("%s"). No sure what to do.', $entry->transaction_journal_id, $entry->the_sum);
$this->friendlyWarning($message);
Log::warning($message);
++$this->count;
@@ -184,13 +177,7 @@ class CorrectsUnevenAmount extends Command
$source = $journal->transactions()->where('amount', '<', 0)->first();
if (null === $source) {
$this->friendlyError(
sprintf(
'Journal #%d ("%s") has no source transaction. It will be deleted to maintain database consistency.',
$journal->id ?? 0,
$journal->description ?? ''
)
);
$this->friendlyError(sprintf('Journal #%d ("%s") has no source transaction. It will be deleted to maintain database consistency.', $journal->id ?? 0, $journal->description ?? ''));
Transaction::where('transaction_journal_id', $journal->id ?? 0)->forceDelete();
TransactionJournal::where('id', $journal->id ?? 0)->forceDelete();
++$this->count;
@@ -205,13 +192,7 @@ class CorrectsUnevenAmount extends Command
$destination = $journal->transactions()->where('amount', '>', 0)->first();
if (null === $destination) {
$this->friendlyError(
sprintf(
'Journal #%d ("%s") has no destination transaction. It will be deleted to maintain database consistency.',
$journal->id ?? 0,
$journal->description ?? ''
)
);
$this->friendlyError(sprintf('Journal #%d ("%s") has no destination transaction. It will be deleted to maintain database consistency.', $journal->id ?? 0, $journal->description ?? ''));
Transaction::where('transaction_journal_id', $journal->id ?? 0)->forceDelete();
TransactionJournal::where('id', $journal->id ?? 0)->forceDelete();

View File

@@ -28,6 +28,7 @@ namespace FireflyIII\Console\Commands\System;
use FireflyIII\Console\Commands\ShowsFriendlyMessages;
use FireflyIII\Support\Models\AccountBalanceCalculator;
use Illuminate\Console\Command;
use FireflyIII\Support\Facades\FireflyConfig;
class RecalculatesRunningBalance extends Command
{
@@ -52,7 +53,7 @@ class RecalculatesRunningBalance extends Command
*/
public function handle(): int
{
if (true === config('firefly.feature_flags.running_balance_column')) {
if (true === FireflyConfig::get('use_running_balance', config('firefly.feature_flags.running_balance_column'))->data) {
$this->friendlyInfo('Will recalculate account balances. This may take a LONG time. Please be patient.');
$this->correctBalanceAmounts($this->option('force'));
$this->friendlyInfo('Done recalculating account balances.');

View File

@@ -31,6 +31,7 @@ use Illuminate\Support\Facades\Log;
use Illuminate\Support\Facades\Storage;
use League\Flysystem\FilesystemException;
use Safe\Exceptions\JsonException;
use FireflyIII\Support\Facades\FireflyConfig;
use function Safe\json_decode;
@@ -107,8 +108,8 @@ class VerifySecurityAlerts extends Command
private function removeOldAdvisory(): void
{
try {
app('fireflyconfig')->delete('upgrade_security_message');
app('fireflyconfig')->delete('upgrade_security_level');
FireflyConfig::delete('upgrade_security_message');
FireflyConfig::delete('upgrade_security_level');
} catch (QueryException $e) {
Log::debug(sprintf('Could not delete old security advisory, but thats OK: %s', $e->getMessage()));
}
@@ -117,8 +118,8 @@ class VerifySecurityAlerts extends Command
private function saveSecurityAdvisory(array $array): void
{
try {
app('fireflyconfig')->set('upgrade_security_message', $array['message']);
app('fireflyconfig')->set('upgrade_security_level', $array['level']);
FireflyConfig::set('upgrade_security_message', $array['message']);
FireflyConfig::set('upgrade_security_level', $array['level']);
} catch (QueryException $e) {
Log::debug(sprintf('Could not save new security advisory, but thats OK: %s', $e->getMessage()));
}

View File

@@ -36,6 +36,7 @@ use FireflyIII\Support\Cronjobs\WebhookCronjob;
use Illuminate\Console\Command;
use Illuminate\Support\Facades\Log;
use InvalidArgumentException;
use FireflyIII\Support\Facades\FireflyConfig;
class Cron extends Command
{
@@ -72,7 +73,7 @@ class Cron extends Command
$force = (bool) $this->option('force'); // @phpstan-ignore-line
// Fire exchange rates cron job.
if (true === config('cer.download_enabled') && ($doAll || $this->option('download-cer'))) {
if (true === FireflyConfig::get('enable_external_rates', config('cer.download_enabled'))->data && ($doAll || $this->option('download-cer'))) {
try {
$this->exchangeRatesCronJob($force, $date);
} catch (FireflyException $e) {

View File

@@ -32,6 +32,7 @@ use Illuminate\Console\Command;
use Illuminate\Database\QueryException;
use Illuminate\Support\Facades\Log;
use Illuminate\Support\Facades\Schema;
use FireflyIII\Support\Facades\FireflyConfig;
class AddsTransactionIdentifiers extends Command
{
@@ -97,7 +98,7 @@ class AddsTransactionIdentifiers extends Command
private function isExecuted(): bool
{
$configVar = app('fireflyconfig')->get(self::CONFIG_NAME, false);
$configVar = FireflyConfig::get(self::CONFIG_NAME, false);
return (bool)$configVar?->data;
@@ -157,6 +158,6 @@ class AddsTransactionIdentifiers extends Command
private function markAsExecuted(): void
{
app('fireflyconfig')->set(self::CONFIG_NAME, true);
FireflyConfig::set(self::CONFIG_NAME, true);
}
}

View File

@@ -34,6 +34,7 @@ use Illuminate\Support\Facades\DB;
use Illuminate\Support\Facades\Log;
use JsonException;
use stdClass;
use FireflyIII\Support\Facades\FireflyConfig;
use function Safe\json_decode;
@@ -86,7 +87,7 @@ class RemovesDatabaseDecryption extends Command
$this->friendlyPositive(sprintf('Decrypted the data in table "%s".', $table));
// mark as decrypted:
$configName = sprintf('is_decrypted_%s', $table);
app('fireflyconfig')->set($configName, true);
FireflyConfig::set($configName, true);
}
private function isDecrypted(string $table): bool
@@ -95,7 +96,7 @@ class RemovesDatabaseDecryption extends Command
$configVar = null;
try {
$configVar = app('fireflyconfig')->get($configName, false);
$configVar = FireflyConfig::get($configName, false);
} catch (FireflyException $e) {
Log::error($e->getMessage());
}
@@ -120,7 +121,7 @@ class RemovesDatabaseDecryption extends Command
if (null === $original) {
return;
}
$id = (int) $row->id;
$id = (int)$row->id;
$value = '';
try {
@@ -133,7 +134,7 @@ class RemovesDatabaseDecryption extends Command
}
// A separate routine for preferences table:
if ('preferences' === $table) {
if ('preferences' === $table && is_string($value)) {
$this->decryptPreferencesRow($id, $value);
return;

View File

@@ -1,7 +1,7 @@
<?php
/*
* CorrectAccountBalance.php
* RepairsAccountBalances.php
* Copyright (c) 2024 james@firefly-iii.org.
*
* This file is part of Firefly III (https://github.com/firefly-iii).
@@ -27,6 +27,7 @@ namespace FireflyIII\Console\Commands\Upgrade;
use FireflyIII\Console\Commands\ShowsFriendlyMessages;
use FireflyIII\Support\Models\AccountBalanceCalculator;
use Illuminate\Console\Command;
use FireflyIII\Support\Facades\FireflyConfig;
class RepairsAccountBalances extends Command
{
@@ -43,7 +44,7 @@ class RepairsAccountBalances extends Command
return 0;
}
if (true === config('firefly.feature_flags.running_balance_column')) {
if (true === FireflyConfig::get('use_running_balance', config('firefly.feature_flags.running_balance_column'))->data) {
$this->friendlyInfo('Will recalculate account balances. This may take a LONG time. Please be patient.');
$this->markAsExecuted();
$this->correctBalanceAmounts();
@@ -58,14 +59,14 @@ class RepairsAccountBalances extends Command
private function isExecuted(): bool
{
$configVar = app('fireflyconfig')->get(self::CONFIG_NAME, false);
$configVar = FireflyConfig::get(self::CONFIG_NAME, false);
return (bool) $configVar?->data;
}
private function markAsExecuted(): void
{
app('fireflyconfig')->set(self::CONFIG_NAME, true);
FireflyConfig::set(self::CONFIG_NAME, true);
}
private function correctBalanceAmounts(): void

View File

@@ -41,7 +41,7 @@ class UpgradeSkeleton extends Command
*/
private function isExecuted(): bool
{
$configVar = app('fireflyconfig')->get(self::CONFIG_NAME, false);
$configVar = \FireflyIII\Support\Facades\FireflyConfig::get(self::CONFIG_NAME, false);
if (null !== $configVar) {
return (bool)$configVar->data;
}
@@ -55,6 +55,6 @@ class UpgradeSkeleton extends Command
*/
private function markAsExecuted(): void
{
app('fireflyconfig')->set(self::CONFIG_NAME, true);
\FireflyIII\Support\Facades\FireflyConfig::set(self::CONFIG_NAME, true);
}
}

View File

@@ -35,6 +35,7 @@ use FireflyIII\Repositories\Account\AccountRepositoryInterface;
use FireflyIII\Repositories\User\UserRepositoryInterface;
use FireflyIII\User;
use Illuminate\Console\Command;
use FireflyIII\Support\Facades\FireflyConfig;
class UpgradesAccountCurrencies extends Command
{
@@ -85,7 +86,7 @@ class UpgradesAccountCurrencies extends Command
private function isExecuted(): bool
{
$configVar = app('fireflyconfig')->get(self::CONFIG_NAME, false);
$configVar = FireflyConfig::get(self::CONFIG_NAME, false);
return (bool) $configVar?->data;
}
@@ -155,6 +156,6 @@ class UpgradesAccountCurrencies extends Command
private function markAsExecuted(): void
{
app('fireflyconfig')->set(self::CONFIG_NAME, true);
FireflyConfig::set(self::CONFIG_NAME, true);
}
}

View File

@@ -28,6 +28,7 @@ use FireflyIII\Console\Commands\ShowsFriendlyMessages;
use FireflyIII\Exceptions\FireflyException;
use FireflyIII\Models\AccountMeta;
use Illuminate\Console\Command;
use FireflyIII\Support\Facades\FireflyConfig;
class UpgradesAccountMetaData extends Command
{
@@ -82,7 +83,7 @@ class UpgradesAccountMetaData extends Command
private function isExecuted(): bool
{
$configVar = app('fireflyconfig')->get(self::CONFIG_NAME, false);
$configVar = FireflyConfig::get(self::CONFIG_NAME, false);
return (bool)$configVar?->data;
@@ -90,6 +91,6 @@ class UpgradesAccountMetaData extends Command
private function markAsExecuted(): void
{
app('fireflyconfig')->set(self::CONFIG_NAME, true);
FireflyConfig::set(self::CONFIG_NAME, true);
}
}

View File

@@ -30,6 +30,7 @@ use FireflyIII\Models\Attachment;
use FireflyIII\Models\Note;
use Illuminate\Console\Command;
use Illuminate\Support\Facades\Log;
use FireflyIII\Support\Facades\FireflyConfig;
class UpgradesAttachments extends Command
{
@@ -92,7 +93,7 @@ class UpgradesAttachments extends Command
private function isExecuted(): bool
{
$configVar = app('fireflyconfig')->get(self::CONFIG_NAME, false);
$configVar = FireflyConfig::get(self::CONFIG_NAME, false);
return (bool)$configVar?->data;
@@ -100,6 +101,6 @@ class UpgradesAttachments extends Command
private function markAsExecuted(): void
{
app('fireflyconfig')->set(self::CONFIG_NAME, true);
FireflyConfig::set(self::CONFIG_NAME, true);
}
}

View File

@@ -36,6 +36,7 @@ use FireflyIII\Repositories\User\UserRepositoryInterface;
use FireflyIII\Support\Facades\Preferences;
use FireflyIII\User;
use Illuminate\Console\Command;
use FireflyIII\Support\Facades\FireflyConfig;
class UpgradesBillsToRules extends Command
{
@@ -99,7 +100,7 @@ class UpgradesBillsToRules extends Command
private function isExecuted(): bool
{
$configVar = app('fireflyconfig')->get(self::CONFIG_NAME, false);
$configVar = FireflyConfig::get(self::CONFIG_NAME, false);
return (bool)$configVar?->data;
@@ -206,6 +207,6 @@ class UpgradesBillsToRules extends Command
private function markAsExecuted(): void
{
app('fireflyconfig')->set(self::CONFIG_NAME, true);
FireflyConfig::set(self::CONFIG_NAME, true);
}
}

View File

@@ -28,6 +28,7 @@ use FireflyIII\Console\Commands\ShowsFriendlyMessages;
use FireflyIII\Models\BudgetLimit;
use Illuminate\Console\Command;
use Illuminate\Support\Facades\Log;
use FireflyIII\Support\Facades\FireflyConfig;
class UpgradesBudgetLimitPeriods extends Command
{
@@ -58,7 +59,7 @@ class UpgradesBudgetLimitPeriods extends Command
private function isExecuted(): bool
{
$configVar = app('fireflyconfig')->get(self::CONFIG_NAME, false);
$configVar = FireflyConfig::get(self::CONFIG_NAME, false);
return (bool) $configVar->data;
}
@@ -152,6 +153,6 @@ class UpgradesBudgetLimitPeriods extends Command
private function markAsExecuted(): void
{
app('fireflyconfig')->set(self::CONFIG_NAME, true);
FireflyConfig::set(self::CONFIG_NAME, true);
}
}

View File

@@ -30,6 +30,7 @@ use FireflyIII\Models\Budget;
use FireflyIII\Models\BudgetLimit;
use FireflyIII\User;
use Illuminate\Console\Command;
use FireflyIII\Support\Facades\FireflyConfig;
class UpgradesBudgetLimits extends Command
{
@@ -84,7 +85,7 @@ class UpgradesBudgetLimits extends Command
private function isExecuted(): bool
{
$configVar = app('fireflyconfig')->get(self::CONFIG_NAME, false);
$configVar = FireflyConfig::get(self::CONFIG_NAME, false);
return (bool)$configVar?->data;
@@ -92,6 +93,6 @@ class UpgradesBudgetLimits extends Command
private function markAsExecuted(): void
{
app('fireflyconfig')->set(self::CONFIG_NAME, true);
FireflyConfig::set(self::CONFIG_NAME, true);
}
}

View File

@@ -31,6 +31,7 @@ use FireflyIII\Models\Account;
use FireflyIII\Models\AccountType;
use Illuminate\Console\Command;
use Illuminate\Support\Collection;
use FireflyIII\Support\Facades\FireflyConfig;
class UpgradesCreditCardLiabilities extends Command
{
@@ -80,13 +81,13 @@ class UpgradesCreditCardLiabilities extends Command
private function isExecuted(): bool
{
$configVar = app('fireflyconfig')->get(self::CONFIG_NAME, false);
$configVar = FireflyConfig::get(self::CONFIG_NAME, false);
return (bool) $configVar?->data;
}
private function markAsExecuted(): void
{
app('fireflyconfig')->set(self::CONFIG_NAME, true);
FireflyConfig::set(self::CONFIG_NAME, true);
}
}

View File

@@ -33,6 +33,7 @@ use FireflyIII\Support\Facades\Amount;
use FireflyIII\User;
use Illuminate\Console\Command;
use Illuminate\Support\Collection;
use FireflyIII\Support\Facades\FireflyConfig;
class UpgradesCurrencyPreferences extends Command
{
@@ -65,7 +66,7 @@ class UpgradesCurrencyPreferences extends Command
private function isExecuted(): bool
{
$configVar = app('fireflyconfig')->get(self::CONFIG_NAME, false);
$configVar = FireflyConfig::get(self::CONFIG_NAME, false);
return (bool)$configVar?->data;
@@ -144,6 +145,6 @@ class UpgradesCurrencyPreferences extends Command
private function markAsExecuted(): void
{
app('fireflyconfig')->set(self::CONFIG_NAME, true);
FireflyConfig::set(self::CONFIG_NAME, true);
}
}

View File

@@ -32,6 +32,7 @@ use FireflyIII\Models\TransactionJournal;
use Illuminate\Console\Command;
use Illuminate\Support\Collection;
use Illuminate\Support\Facades\DB;
use FireflyIII\Support\Facades\FireflyConfig;
class UpgradesJournalMetaData extends Command
{
@@ -69,14 +70,14 @@ class UpgradesJournalMetaData extends Command
private function isMigrated(): bool
{
$configVar = app('fireflyconfig')->get(UpgradesToGroups::CONFIG_NAME, false);
$configVar = FireflyConfig::get(UpgradesToGroups::CONFIG_NAME, false);
return (bool) $configVar->data;
}
private function isExecuted(): bool
{
$configVar = app('fireflyconfig')->get(self::CONFIG_NAME, false);
$configVar = FireflyConfig::get(self::CONFIG_NAME, false);
return (bool) $configVar->data;
}
@@ -218,6 +219,6 @@ class UpgradesJournalMetaData extends Command
private function markAsExecuted(): void
{
app('fireflyconfig')->set(self::CONFIG_NAME, true);
FireflyConfig::set(self::CONFIG_NAME, true);
}
}

View File

@@ -29,6 +29,7 @@ use FireflyIII\Models\Note;
use FireflyIII\Models\TransactionJournalMeta;
use Illuminate\Console\Command;
use Illuminate\Support\Facades\Log;
use FireflyIII\Support\Facades\FireflyConfig;
class UpgradesJournalNotes extends Command
{
@@ -86,7 +87,7 @@ class UpgradesJournalNotes extends Command
private function isExecuted(): bool
{
$configVar = app('fireflyconfig')->get(self::CONFIG_NAME, false);
$configVar = FireflyConfig::get(self::CONFIG_NAME, false);
return (bool)$configVar?->data;
@@ -94,6 +95,6 @@ class UpgradesJournalNotes extends Command
private function markAsExecuted(): void
{
app('fireflyconfig')->set(self::CONFIG_NAME, true);
FireflyConfig::set(self::CONFIG_NAME, true);
}
}

View File

@@ -33,6 +33,7 @@ use FireflyIII\Repositories\Account\AccountRepositoryInterface;
use FireflyIII\Services\Internal\Support\CreditRecalculateService;
use FireflyIII\User;
use Illuminate\Console\Command;
use FireflyIII\Support\Facades\FireflyConfig;
class UpgradesLiabilities extends Command
{
@@ -61,7 +62,7 @@ class UpgradesLiabilities extends Command
private function isExecuted(): bool
{
$configVar = app('fireflyconfig')->get(self::CONFIG_NAME, false);
$configVar = FireflyConfig::get(self::CONFIG_NAME, false);
return (bool)$configVar?->data;
@@ -148,6 +149,6 @@ class UpgradesLiabilities extends Command
private function markAsExecuted(): void
{
app('fireflyconfig')->set(self::CONFIG_NAME, true);
FireflyConfig::set(self::CONFIG_NAME, true);
}
}

View File

@@ -36,6 +36,7 @@ use FireflyIII\Services\Internal\Support\CreditRecalculateService;
use FireflyIII\User;
use Illuminate\Console\Command;
use Illuminate\Support\Facades\Log;
use FireflyIII\Support\Facades\FireflyConfig;
class UpgradesLiabilitiesEight extends Command
{
@@ -63,7 +64,7 @@ class UpgradesLiabilitiesEight extends Command
private function isExecuted(): bool
{
$configVar = app('fireflyconfig')->get(self::CONFIG_NAME, false);
$configVar = FireflyConfig::get(self::CONFIG_NAME, false);
return (bool)$configVar?->data;
@@ -137,7 +138,7 @@ class UpgradesLiabilitiesEight extends Command
return false;
}
return (bool) $openingJournal->date->isSameDay($liabilityJournal->date);
return (bool)$openingJournal->date->isSameDay($liabilityJournal->date);
}
private function deleteCreditTransaction(Account $account): void
@@ -148,7 +149,7 @@ class UpgradesLiabilitiesEight extends Command
->where('transaction_journals.transaction_type_id', $liabilityType->id)
->first(['transaction_journals.*'])
;
if (null !== $liabilityJournal) {
if (null !== $liabilityJournal && null !== $liabilityJournal->transactionGroup) {
$group = $liabilityJournal->transactionGroup;
$service = new TransactionGroupDestroyService();
$service->destroy($group);
@@ -192,11 +193,14 @@ class UpgradesLiabilitiesEight extends Command
->where('transactions.account_id', $account->id)->get(['transaction_journals.*'])
;
$service = app(TransactionGroupDestroyService::class);
/** @var TransactionJournal $journal */
foreach ($journals as $journal) {
$service = app(TransactionGroupDestroyService::class);
$service->destroy($journal->transactionGroup);
++$count;
if (null !== $journal->transactionGroup) {
$service->destroy($journal->transactionGroup);
++$count;
}
}
return $count;
@@ -204,6 +208,6 @@ class UpgradesLiabilitiesEight extends Command
private function markAsExecuted(): void
{
app('fireflyconfig')->set(self::CONFIG_NAME, true);
FireflyConfig::set(self::CONFIG_NAME, true);
}
}

View File

@@ -31,6 +31,7 @@ use FireflyIII\Repositories\Account\AccountRepositoryInterface;
use FireflyIII\Repositories\PiggyBank\PiggyBankRepositoryInterface;
use Illuminate\Console\Command;
use Illuminate\Support\Facades\Log;
use FireflyIII\Support\Facades\FireflyConfig;
class UpgradesMultiPiggyBanks extends Command
{
@@ -64,7 +65,7 @@ class UpgradesMultiPiggyBanks extends Command
private function isExecuted(): bool
{
$configVar = app('fireflyconfig')->get(self::CONFIG_NAME, false);
$configVar = FireflyConfig::get(self::CONFIG_NAME, false);
return (bool)$configVar?->data;
@@ -112,6 +113,6 @@ class UpgradesMultiPiggyBanks extends Command
private function markAsExecuted(): void
{
app('fireflyconfig')->set(self::CONFIG_NAME, true);
FireflyConfig::set(self::CONFIG_NAME, true);
}
}

View File

@@ -28,6 +28,7 @@ namespace FireflyIII\Console\Commands\Upgrade;
use FireflyIII\Console\Commands\ShowsFriendlyMessages;
use Illuminate\Console\Command;
use Illuminate\Support\Facades\Artisan;
use FireflyIII\Support\Facades\FireflyConfig;
class UpgradesPrimaryCurrencyAmounts extends Command
{
@@ -60,7 +61,7 @@ class UpgradesPrimaryCurrencyAmounts extends Command
private function isExecuted(): bool
{
$configVar = app('fireflyconfig')->get(self::CONFIG_NAME, false);
$configVar = FireflyConfig::get(self::CONFIG_NAME, false);
return (bool)$configVar?->data;
@@ -68,6 +69,6 @@ class UpgradesPrimaryCurrencyAmounts extends Command
private function markAsExecuted(): void
{
app('fireflyconfig')->set(self::CONFIG_NAME, true);
FireflyConfig::set(self::CONFIG_NAME, true);
}
}

View File

@@ -29,6 +29,7 @@ use FireflyIII\Models\Recurrence;
use FireflyIII\Models\RecurrenceMeta;
use FireflyIII\Models\RecurrenceTransactionMeta;
use Illuminate\Console\Command;
use FireflyIII\Support\Facades\FireflyConfig;
use function Safe\json_encode;
@@ -65,7 +66,7 @@ class UpgradesRecurrenceMetaData extends Command
private function isExecuted(): bool
{
$configVar = app('fireflyconfig')->get(self::CONFIG_NAME, false);
$configVar = FireflyConfig::get(self::CONFIG_NAME, false);
return (bool)$configVar?->data;
@@ -117,6 +118,6 @@ class UpgradesRecurrenceMetaData extends Command
private function markAsExecuted(): void
{
app('fireflyconfig')->set(self::CONFIG_NAME, true);
FireflyConfig::set(self::CONFIG_NAME, true);
}
}

View File

@@ -28,6 +28,7 @@ namespace FireflyIII\Console\Commands\Upgrade;
use FireflyIII\Console\Commands\ShowsFriendlyMessages;
use FireflyIII\Models\RuleAction;
use Illuminate\Console\Command;
use FireflyIII\Support\Facades\FireflyConfig;
class UpgradesRuleActions extends Command
{
@@ -63,7 +64,7 @@ class UpgradesRuleActions extends Command
private function isExecuted(): bool
{
$configVar = app('fireflyconfig')->get(self::CONFIG_NAME, false);
$configVar = FireflyConfig::get(self::CONFIG_NAME, false);
return (bool)$configVar?->data;
@@ -183,6 +184,6 @@ class UpgradesRuleActions extends Command
private function markAsExecuted(): void
{
app('fireflyconfig')->set(self::CONFIG_NAME, true);
FireflyConfig::set(self::CONFIG_NAME, true);
}
}

View File

@@ -28,6 +28,7 @@ use FireflyIII\Console\Commands\ShowsFriendlyMessages;
use FireflyIII\Models\Location;
use FireflyIII\Models\Tag;
use Illuminate\Console\Command;
use FireflyIII\Support\Facades\FireflyConfig;
class UpgradesTagLocations extends Command
{
@@ -57,7 +58,7 @@ class UpgradesTagLocations extends Command
private function isExecuted(): bool
{
$configVar = app('fireflyconfig')->get(self::CONFIG_NAME, false);
$configVar = FireflyConfig::get(self::CONFIG_NAME, false);
return (bool)$configVar?->data;
@@ -97,6 +98,6 @@ class UpgradesTagLocations extends Command
private function markAsExecuted(): void
{
app('fireflyconfig')->set(self::CONFIG_NAME, true);
FireflyConfig::set(self::CONFIG_NAME, true);
}
}

View File

@@ -39,6 +39,7 @@ use Illuminate\Console\Command;
use Illuminate\Support\Collection;
use Illuminate\Support\Facades\DB;
use Illuminate\Support\Facades\Log;
use FireflyIII\Support\Facades\FireflyConfig;
class UpgradesToGroups extends Command
{
@@ -97,7 +98,7 @@ class UpgradesToGroups extends Command
private function isMigrated(): bool
{
$configVar = app('fireflyconfig')->get(self::CONFIG_NAME, false);
$configVar = FireflyConfig::get(self::CONFIG_NAME, false);
return (bool)$configVar?->data;
@@ -379,6 +380,6 @@ class UpgradesToGroups extends Command
private function markAsMigrated(): void
{
app('fireflyconfig')->set(self::CONFIG_NAME, true);
FireflyConfig::set(self::CONFIG_NAME, true);
}
}

View File

@@ -34,6 +34,7 @@ use FireflyIII\Repositories\Account\AccountRepositoryInterface;
use FireflyIII\Repositories\Journal\JournalCLIRepositoryInterface;
use Illuminate\Console\Command;
use Illuminate\Support\Facades\Log;
use FireflyIII\Support\Facades\FireflyConfig;
class UpgradesTransferCurrencies extends Command
{
@@ -105,7 +106,7 @@ class UpgradesTransferCurrencies extends Command
private function isExecuted(): bool
{
$configVar = app('fireflyconfig')->get(self::CONFIG_NAME, false);
$configVar = FireflyConfig::get(self::CONFIG_NAME, false);
return (bool)$configVar?->data;
@@ -480,6 +481,6 @@ class UpgradesTransferCurrencies extends Command
private function markAsExecuted(): void
{
app('fireflyconfig')->set(self::CONFIG_NAME, true);
FireflyConfig::set(self::CONFIG_NAME, true);
}
}

View File

@@ -35,6 +35,7 @@ use FireflyIII\Repositories\Account\AccountRepositoryInterface;
use FireflyIII\Repositories\Journal\JournalCLIRepositoryInterface;
use FireflyIII\Repositories\Journal\JournalRepositoryInterface;
use Illuminate\Console\Command;
use FireflyIII\Support\Facades\FireflyConfig;
class UpgradesVariousCurrencyInformation extends Command
{
@@ -86,7 +87,7 @@ class UpgradesVariousCurrencyInformation extends Command
private function isExecuted(): bool
{
$configVar = app('fireflyconfig')->get(self::CONFIG_NAME, false);
$configVar = FireflyConfig::get(self::CONFIG_NAME, false);
return (bool)$configVar?->data;
@@ -246,6 +247,6 @@ class UpgradesVariousCurrencyInformation extends Command
private function markAsExecuted(): void
{
app('fireflyconfig')->set(self::CONFIG_NAME, true);
FireflyConfig::set(self::CONFIG_NAME, true);
}
}

View File

@@ -34,6 +34,7 @@ use FireflyIII\Models\WebhookDelivery as WebhookDeliveryModel;
use FireflyIII\Models\WebhookResponse as WebhookResponseModel;
use FireflyIII\Models\WebhookTrigger as WebhookTriggerModel;
use Illuminate\Console\Command;
use FireflyIII\Support\Facades\FireflyConfig;
class UpgradesWebhooks extends Command
{
@@ -63,7 +64,7 @@ class UpgradesWebhooks extends Command
private function isExecuted(): bool
{
$configVar = app('fireflyconfig')->get(self::CONFIG_NAME, false);
$configVar = FireflyConfig::get(self::CONFIG_NAME, false);
return (bool)$configVar?->data;
@@ -109,6 +110,6 @@ class UpgradesWebhooks extends Command
private function markAsExecuted(): void
{
app('fireflyconfig')->set(self::CONFIG_NAME, true);
FireflyConfig::set(self::CONFIG_NAME, true);
}
}

View File

@@ -37,6 +37,7 @@ use FireflyIII\Notifications\Test\OwnerTestNotificationPushover;
use FireflyIII\Notifications\Test\OwnerTestNotificationSlack;
use Illuminate\Support\Facades\Log;
use Illuminate\Support\Facades\Notification;
use FireflyIII\Support\Facades\FireflyConfig;
/**
* Class AdminEventHandler.
@@ -45,7 +46,7 @@ class AdminEventHandler
{
public function sendInvitationNotification(InvitationCreated $event): void
{
$sendMail = app('fireflyconfig')->get('notification_invite_created', true)->data;
$sendMail = FireflyConfig::get('notification_invite_created', true)->data;
if (false === $sendMail) {
return;
}
@@ -96,7 +97,7 @@ class AdminEventHandler
*/
public function sendNewVersion(NewVersionAvailable $event): void
{
$sendMail = app('fireflyconfig')->get('notification_new_version', true)->data;
$sendMail = FireflyConfig::get('notification_new_version', true)->data;
if (false === $sendMail) {
return;
}

View File

@@ -57,6 +57,7 @@ use Illuminate\Auth\Events\Login;
use Illuminate\Support\Facades\Log;
use Illuminate\Support\Facades\Mail;
use Illuminate\Support\Facades\Notification;
use FireflyIII\Support\Facades\FireflyConfig;
/**
* Class UserEventHandler.
@@ -224,7 +225,7 @@ class UserEventHandler
public function sendAdminRegistrationNotification(RegisteredUser $event): void
{
$sendMail = (bool)app('fireflyconfig')->get('notification_admin_new_reg', true)->data;
$sendMail = (bool)FireflyConfig::get('notification_admin_new_reg', true)->data;
if ($sendMail) {
$owner = $event->owner;
@@ -367,7 +368,7 @@ class UserEventHandler
*/
public function sendRegistrationMail(RegisteredUser $event): void
{
$sendMail = (bool)app('fireflyconfig')->get('notification_user_new_reg', true)->data;
$sendMail = (bool)FireflyConfig::get('notification_user_new_reg', true)->data;
if ($sendMail) {
try {
Notification::send($event->user, new UserRegistrationNotification());

View File

@@ -33,6 +33,7 @@ use FireflyIII\Repositories\User\UserRepositoryInterface;
use Illuminate\Support\Facades\Log;
use Psr\Container\ContainerExceptionInterface;
use Psr\Container\NotFoundExceptionInterface;
use FireflyIII\Support\Facades\FireflyConfig;
/**
* Class VersionCheckEventHandler
@@ -54,7 +55,7 @@ class VersionCheckEventHandler
Log::debug('Now in checkForUpdates()');
// should not check for updates:
$permission = app('fireflyconfig')->get('permission_update_check', -1);
$permission = FireflyConfig::get('permission_update_check', -1);
$value = (int) $permission->data;
if (1 !== $value) {
Log::debug('Update check is not enabled.');
@@ -73,7 +74,7 @@ class VersionCheckEventHandler
}
/** @var Configuration $lastCheckTime */
$lastCheckTime = app('fireflyconfig')->get('last_update_check', Carbon::now()->getTimestamp());
$lastCheckTime = FireflyConfig::get('last_update_check', Carbon::now()->getTimestamp());
$now = Carbon::now()->getTimestamp();
$diff = $now - $lastCheckTime->data;
Log::debug(sprintf('Last check time is %d, current time is %d, difference is %d', $lastCheckTime->data, $now, $diff));
@@ -87,7 +88,7 @@ class VersionCheckEventHandler
$release = $this->getLatestRelease();
session()->flash($release['level'], $release['message']);
app('fireflyconfig')->set('last_update_check', Carbon::now()->getTimestamp());
FireflyConfig::set('last_update_check', Carbon::now()->getTimestamp());
}
/**
@@ -107,7 +108,7 @@ class VersionCheckEventHandler
}
/** @var Configuration $lastCheckTime */
$lastCheckTime = app('fireflyconfig')->get('last_update_warning', Carbon::now()->getTimestamp());
$lastCheckTime = FireflyConfig::get('last_update_warning', Carbon::now()->getTimestamp());
$now = Carbon::now()->getTimestamp();
$diff = $now - $lastCheckTime->data;
Log::debug(sprintf('Last warning time is %d, current time is %d, difference is %d', $lastCheckTime->data, $now, $diff));
@@ -120,6 +121,6 @@ class VersionCheckEventHandler
Log::debug('Have warned about a new version in four weeks!');
session()->flash('info', (string) trans('firefly.disabled_but_check'));
app('fireflyconfig')->set('last_update_warning', Carbon::now()->getTimestamp());
FireflyConfig::set('last_update_warning', Carbon::now()->getTimestamp());
}
}

View File

@@ -27,6 +27,7 @@ namespace FireflyIII\Handlers\Events;
use FireflyIII\Jobs\SendWebhookMessage;
use FireflyIII\Models\WebhookMessage;
use Illuminate\Support\Facades\Log;
use FireflyIII\Support\Facades\FireflyConfig;
/**
* Class WebhookEventHandler
@@ -39,7 +40,7 @@ class WebhookEventHandler
public function sendWebhookMessages(): void
{
Log::debug(sprintf('Now in %s', __METHOD__));
if (false === config('firefly.feature_flags.webhooks') || false === config('firefly.allow_webhooks')) {
if (false === config('firefly.feature_flags.webhooks') || false === FireflyConfig::get('allow_webhooks', config('firefly.allow_webhooks'))->data) {
Log::debug('Webhook event handler is disabled, do not run sendWebhookMessages().');
return;

View File

@@ -28,6 +28,7 @@ use FireflyIII\Support\Facades\Amount;
use FireflyIII\Support\Http\Api\ExchangeRateConverter;
use FireflyIII\Support\Models\AccountBalanceCalculator;
use Illuminate\Support\Facades\Log;
use FireflyIII\Support\Facades\FireflyConfig;
/**
* Class TransactionObserver
@@ -39,7 +40,7 @@ class TransactionObserver
public function created(Transaction $transaction): void
{
Log::debug('Observe "created" of a transaction.');
if (true === config('firefly.feature_flags.running_balance_column') && (1 === bccomp($transaction->amount, '0') && self::$recalculate)) {
if (true === FireflyConfig::get('use_running_balance', config('firefly.feature_flags.running_balance_column'))->data && (1 === bccomp($transaction->amount, '0') && self::$recalculate)) {
Log::debug('Trigger recalculateForJournal');
AccountBalanceCalculator::recalculateForJournal($transaction->transactionJournal);
}
@@ -82,7 +83,7 @@ class TransactionObserver
public function updated(Transaction $transaction): void
{
// Log::debug('Observe "updated" of a transaction.');
if (true === config('firefly.feature_flags.running_balance_column') && self::$recalculate && 1 === bccomp($transaction->amount, '0')) {
if (true === FireflyConfig::get('use_running_balance', config('firefly.feature_flags.running_balance_column'))->data && self::$recalculate && 1 === bccomp($transaction->amount, '0')) {
Log::debug('Trigger recalculateForJournal');
AccountBalanceCalculator::recalculateForJournal($transaction->transactionJournal);
}

View File

@@ -26,6 +26,7 @@ namespace FireflyIII\Helpers\Update;
use FireflyIII\Services\FireflyIIIOrg\Update\UpdateRequestInterface;
use Illuminate\Support\Facades\Log;
use FireflyIII\Support\Facades\FireflyConfig;
/**
* Trait UpdateTrait
@@ -43,7 +44,7 @@ trait UpdateTrait
/** @var UpdateRequestInterface $checker */
$checker = app(UpdateRequestInterface::class);
$channelConfig = app('fireflyconfig')->get('update_channel', 'stable');
$channelConfig = FireflyConfig::get('update_channel', 'stable');
$channel = (string) $channelConfig->data;
return $checker->getUpdateInformation($channel);

View File

@@ -23,11 +23,11 @@ declare(strict_types=1);
namespace FireflyIII\Http\Controllers\Admin;
use FireflyIII\Support\Facades\Preferences;
use FireflyIII\Http\Controllers\Controller;
use FireflyIII\Http\Middleware\IsDemoUser;
use FireflyIII\Http\Requests\ConfigurationRequest;
use FireflyIII\Support\Facades\FireflyConfig;
use FireflyIII\Support\Facades\Preferences;
use Illuminate\Contracts\View\Factory;
use Illuminate\Http\RedirectResponse;
use Illuminate\Support\Facades\Log;
@@ -47,7 +47,7 @@ class ConfigurationController extends Controller
$this->middleware(
static function ($request, $next) {
app('view')->share('title', (string) trans('firefly.system_settings'));
app('view')->share('title', (string)trans('firefly.system_settings'));
app('view')->share('mainTitleIcon', 'fa-hand-spock-o');
return $next($request);
@@ -63,20 +63,39 @@ class ConfigurationController extends Controller
*/
public function index(): Factory|\Illuminate\Contracts\View\View
{
$subTitle = (string) trans('firefly.instance_configuration');
$subTitleIcon = 'fa-wrench';
$subTitle = (string)trans('firefly.instance_configuration');
$subTitleIcon = 'fa-wrench';
Log::channel('audit')->info('User visits admin config index.');
// all available configuration and their default value in case
// they don't exist yet.
$singleUserMode = FireflyConfig::get('single_user_mode', config('firefly.configuration.single_user_mode'))->data;
$isDemoSite = FireflyConfig::get('is_demo_site', config('firefly.configuration.is_demo_site'))->data;
$siteOwner = config('firefly.site_owner');
$singleUserMode = FireflyConfig::get('single_user_mode', config('firefly.configuration.single_user_mode'))->data;
$isDemoSite = FireflyConfig::get('is_demo_site', config('firefly.configuration.is_demo_site'))->data;
$siteOwner = config('firefly.site_owner');
$enableExchangeRates = FireflyConfig::get('enable_exchange_rates', config('cer.enabled'))->data;
$useRunningBalance = FireflyConfig::get('use_running_balance', config('firefly.feature_flags.running_balance_column'))->data;
$enableExternalMap = FireflyConfig::get('enable_external_map', config('firefly.enable_external_map'))->data;
$enableExternalRates = FireflyConfig::get('enable_external_rates', config('cer.download_enabled'))->data;
$allowWebhooks = FireflyConfig::get('allow_webhooks', config('firefly.allow_webhooks'))->data;
$validUrlProtocols = FireflyConfig::get('valid_url_protocols', config('firefly.valid_url_protocols'))->data;
return view(
'settings.configuration.index',
['subTitle' => $subTitle, 'subTitleIcon' => $subTitleIcon, 'singleUserMode' => $singleUserMode, 'isDemoSite' => $isDemoSite, 'siteOwner' => $siteOwner]
[
'subTitle' => $subTitle,
'subTitleIcon' => $subTitleIcon,
'singleUserMode' => $singleUserMode,
'isDemoSite' => $isDemoSite,
'siteOwner' => $siteOwner,
'enableExchangeRates' => $enableExchangeRates,
'useRunningBalance' => $useRunningBalance,
'enableExternalMap' => $enableExternalMap,
'enableExternalRates' => $enableExternalRates,
'allowWebhooks' => $allowWebhooks,
'validUrlProtocols' => $validUrlProtocols,
]
);
}
@@ -92,10 +111,19 @@ class ConfigurationController extends Controller
// store config values
FireflyConfig::set('single_user_mode', $data['single_user_mode']);
FireflyConfig::set('enable_exchange_rates', $data['enable_exchange_rates']);
FireflyConfig::set('use_running_balance', $data['use_running_balance']);
FireflyConfig::set('enable_external_map', $data['enable_external_map']);
FireflyConfig::set('enable_external_rates', $data['enable_external_rates']);
FireflyConfig::set('allow_webhooks', $data['allow_webhooks']);
FireflyConfig::set('valid_url_protocols', $data['valid_url_protocols']);
FireflyConfig::set('is_demo_site', $data['is_demo_site']);
// flash message
session()->flash('success', (string) trans('firefly.configuration_updated'));
session()->flash('success', (string)trans('firefly.configuration_updated'));
Preferences::mark();
return redirect()->route('settings.configuration.index');

View File

@@ -42,6 +42,7 @@ use Illuminate\Routing\Redirector;
use Illuminate\View\View;
use Psr\Container\ContainerExceptionInterface;
use Psr\Container\NotFoundExceptionInterface;
use FireflyIII\Support\Facades\FireflyConfig;
/**
* Class UserController.
@@ -164,7 +165,7 @@ class UserController extends Controller
$subTitle = (string) trans('firefly.user_administration');
$subTitleIcon = 'fa-users';
$users = $this->repository->all();
$singleUserMode = (bool) app('fireflyconfig')->get('single_user_mode', config('firefly.configuration.single_user_mode'))->data;
$singleUserMode = (bool) FireflyConfig::get('single_user_mode', config('firefly.configuration.single_user_mode'))->data;
$allowInvites = false;
if (!$this->externalIdentity && $singleUserMode) {
// also registration enabled.

View File

@@ -36,6 +36,7 @@ use Illuminate\View\View;
use Psr\Container\ContainerExceptionInterface;
use Psr\Container\NotFoundExceptionInterface;
use Safe\Exceptions\UrlException;
use FireflyIII\Support\Facades\FireflyConfig;
use function Safe\parse_url;
@@ -142,7 +143,7 @@ class ForgotPasswordController extends Controller
}
// is allowed to?
$singleUserMode = app('fireflyconfig')->get('single_user_mode', config('firefly.configuration.single_user_mode'))->data;
$singleUserMode = FireflyConfig::get('single_user_mode', config('firefly.configuration.single_user_mode'))->data;
$userCount = User::count();
$allowRegistration = true;
$pageTitle = (string) trans('firefly.forgot_pw_page_title');

View File

@@ -31,6 +31,7 @@ use FireflyIII\Exceptions\FireflyException;
use FireflyIII\Http\Controllers\Controller;
use FireflyIII\Providers\RouteServiceProvider;
use FireflyIII\Repositories\User\UserRepositoryInterface;
use FireflyIII\Support\Facades\Steam;
use FireflyIII\User;
use Illuminate\Contracts\Foundation\Application;
use Illuminate\Contracts\View\Factory;
@@ -49,6 +50,7 @@ use Illuminate\Validation\ValidationException;
use Psr\Container\ContainerExceptionInterface;
use Psr\Container\NotFoundExceptionInterface;
use Symfony\Component\HttpFoundation\Response as ResponseAlias;
use FireflyIII\Support\Facades\FireflyConfig;
/**
* Class LoginController
@@ -132,7 +134,7 @@ class LoginController extends Controller
return $this->sendLoginResponse($request);
}
Log::warning('Login attempt failed.');
$username = (string) $request->get($this->username());
$username = (string)$request->get($this->username());
$user = $this->repository->findByEmail($username);
if (!$user instanceof User) {
// send event to owner.
@@ -228,14 +230,14 @@ class LoginController extends Controller
$count = DB::table('users')->count();
$guard = config('auth.defaults.guard');
$title = (string) trans('firefly.login_page_title');
$title = (string)trans('firefly.login_page_title');
if (0 === $count && 'web' === $guard) {
return redirect(route('register'));
}
// is allowed to register, etc.
$singleUserMode = app('fireflyconfig')->get('single_user_mode', config('firefly.configuration.single_user_mode'))->data;
$singleUserMode = FireflyConfig::get('single_user_mode', config('firefly.configuration.single_user_mode'))->data;
$allowRegistration = true;
$allowReset = true;
if (true === $singleUserMode && $count > 0) {
@@ -260,4 +262,23 @@ class LoginController extends Controller
return view('auth.login', ['allowRegistration' => $allowRegistration, 'email' => $email, 'remember' => $remember, 'allowReset' => $allowReset, 'title' => $title, 'usernameField' => $usernameField]);
}
/**
* Send the response after the user was authenticated.
*
* @return JsonResponse|RedirectResponse
*/
protected function sendLoginResponse(Request $request)
{
$request->session()->regenerate();
$this->clearLoginAttempts($request);
if ($response = $this->authenticated($request, $this->guard()->user())) {
return $response;
}
$path = Steam::getSafeUrl(session()->pull('url.intended', route('index')), route('index'));
Log::debug(sprintf('SafeURL is %s', $path));
return $request->wantsJson() ? new JsonResponse([], 204) : redirect()->to($path);
}
}

View File

@@ -41,6 +41,7 @@ use Illuminate\Validation\ValidationException;
use Illuminate\View\View;
use Psr\Container\ContainerExceptionInterface;
use Psr\Container\NotFoundExceptionInterface;
use FireflyIII\Support\Facades\FireflyConfig;
/**
* Class RegisterController
@@ -121,7 +122,7 @@ class RegisterController extends Controller
$allowRegistration = true;
try {
$singleUserMode = app('fireflyconfig')->get('single_user_mode', config('firefly.configuration.single_user_mode'))->data;
$singleUserMode = FireflyConfig::get('single_user_mode', config('firefly.configuration.single_user_mode'))->data;
} catch (ContainerExceptionInterface|NotFoundExceptionInterface) {
$singleUserMode = true;
}
@@ -148,7 +149,7 @@ class RegisterController extends Controller
*/
public function showInviteForm(Request $request, string $code): Factory|\Illuminate\Contracts\View\View
{
$isDemoSite = app('fireflyconfig')->get('is_demo_site', config('firefly.configuration.is_demo_site'))->data;
$isDemoSite = FireflyConfig::get('is_demo_site', config('firefly.configuration.is_demo_site'))->data;
$pageTitle = (string) trans('firefly.register_page_title');
$repository = app(UserRepositoryInterface::class);
$allowRegistration = $this->allowedToRegister();
@@ -182,7 +183,7 @@ class RegisterController extends Controller
*/
public function showRegistrationForm(?Request $request = null): Factory|\Illuminate\Contracts\View\View
{
$isDemoSite = app('fireflyconfig')->get('is_demo_site', config('firefly.configuration.is_demo_site'))->data;
$isDemoSite = FireflyConfig::get('is_demo_site', config('firefly.configuration.is_demo_site'))->data;
$pageTitle = (string) trans('firefly.register_page_title');
$allowRegistration = $this->allowedToRegister();

View File

@@ -36,6 +36,7 @@ use Illuminate\Validation\ValidationException;
use Illuminate\View\View;
use Psr\Container\ContainerExceptionInterface;
use Psr\Container\NotFoundExceptionInterface;
use FireflyIII\Support\Facades\FireflyConfig;
/**
* Class ResetPasswordController
@@ -131,7 +132,7 @@ class ResetPasswordController extends Controller
}
// is allowed to register?
$singleUserMode = app('fireflyconfig')->get('single_user_mode', config('firefly.configuration.single_user_mode'))->data;
$singleUserMode = FireflyConfig::get('single_user_mode', config('firefly.configuration.single_user_mode'))->data;
$userCount = User::count();
$allowRegistration = true;
$pageTitle = (string) trans('firefly.reset_pw_page_title');

View File

@@ -38,6 +38,7 @@ use Illuminate\Support\Facades\Config;
use Illuminate\Support\Facades\Log;
use Illuminate\Support\Facades\Route;
use Illuminate\Support\Facades\View;
use FireflyIII\Support\Facades\FireflyConfig;
use function Safe\ini_get;
use function Safe\realpath;
@@ -71,7 +72,7 @@ abstract class Controller extends BaseController
public function __construct()
{
// is site a demo site?
$isDemoSiteConfig = app('fireflyconfig')->get('is_demo_site', config('firefly.configuration.is_demo_site', false));
$isDemoSiteConfig = FireflyConfig::get('is_demo_site', config('firefly.configuration.is_demo_site', false));
$isDemoSite = (bool) $isDemoSiteConfig->data;
View::share('IS_DEMO_SITE', $isDemoSite);
View::share('DEMO_USERNAME', config('firefly.demo_username'));
@@ -80,7 +81,7 @@ abstract class Controller extends BaseController
View::share('FF_BUILD_TIME', config('firefly.build_time'));
// is webhooks enabled?
View::share('featuringWebhooks', true === config('firefly.feature_flags.webhooks') && true === config('firefly.allow_webhooks'));
View::share('featuringWebhooks', true === config('firefly.feature_flags.webhooks') && true === FireflyConfig::get('allow_webhooks', config('firefly.allow_webhooks'))->data);
// share custom auth guard info.
$authGuard = config('firefly.authentication_guard');

View File

@@ -51,6 +51,7 @@ use Illuminate\View\View;
use Monolog\Handler\RotatingFileHandler;
use Safe\Exceptions\FilesystemException;
use Symfony\Component\HttpKernel\Exception\NotFoundHttpException;
use FireflyIII\Support\Facades\FireflyConfig;
use function Safe\file_get_contents;
use function Safe\ini_get;
@@ -241,7 +242,7 @@ class DebugController extends Controller
{
$userGuard = config('auth.defaults.guard');
$config = app('fireflyconfig')->get('last_rt_job', 0);
$config = FireflyConfig::get('last_rt_job', 0);
$lastTime = (int) $config->data;
$lastCronjob = 'never';
$lastCronjobAgo = 'never';

View File

@@ -28,6 +28,7 @@ use FireflyIII\Http\Controllers\Controller;
use FireflyIII\Models\TransactionCurrency;
use Illuminate\View\View;
use Symfony\Component\HttpKernel\Exception\NotFoundHttpException;
use FireflyIII\Support\Facades\FireflyConfig;
class IndexController extends Controller
{
@@ -47,7 +48,7 @@ class IndexController extends Controller
return $next($request);
}
);
if (false === config('cer.enabled')) {
if (false === FireflyConfig::get('enable_exchange_rates', config('cer.enabled'))->data) {
throw new NotFoundHttpException();
}
}

View File

@@ -38,6 +38,7 @@ use Illuminate\Http\Request;
use Psr\Container\ContainerExceptionInterface;
use Psr\Container\NotFoundExceptionInterface;
use Safe\Exceptions\UrlException;
use FireflyIII\Support\Facades\FireflyConfig;
use function Safe\parse_url;
@@ -140,7 +141,7 @@ class CreateController extends Controller
];
$optionalFields['external_url'] ??= false;
$optionalFields['location'] ??= false;
$optionalFields['location'] = $optionalFields['location'] && true === config('firefly.enable_external_map');
$optionalFields['location'] = $optionalFields['location'] && true === FireflyConfig::get('enable_external_map', config('firefly.enable_external_map'))->data;
// map info:
$longitude = config('firefly.default_location.longitude');

View File

@@ -38,6 +38,7 @@ use Illuminate\View\View;
use Psr\Container\ContainerExceptionInterface;
use Psr\Container\NotFoundExceptionInterface;
use Safe\Exceptions\UrlException;
use FireflyIII\Support\Facades\FireflyConfig;
use function Safe\parse_url;
@@ -114,7 +115,7 @@ class EditController extends Controller
];
$optionalFields['external_url'] ??= false;
$optionalFields['location'] ??= false;
$optionalFields['location'] = $optionalFields['location'] && true === config('firefly.enable_external_map');
$optionalFields['location'] = $optionalFields['location'] && true === FireflyConfig::get('enable_external_map', config('firefly.enable_external_map'))->data;
// map info voor v2:
$longitude = config('firefly.default_location.longitude');

View File

@@ -29,6 +29,7 @@ use Illuminate\Contracts\View\Factory;
use Illuminate\Support\Facades\Log;
use Illuminate\View\View;
use Symfony\Component\HttpKernel\Exception\NotFoundHttpException;
use FireflyIII\Support\Facades\FireflyConfig;
/**
* Class CreateController
@@ -59,7 +60,7 @@ class CreateController extends Controller
*/
public function index(): Factory|\Illuminate\Contracts\View\View
{
if (false === config('firefly.allow_webhooks')) {
if (false === FireflyConfig::get('allow_webhooks', config('firefly.allow_webhooks'))->data) {
Log::channel('audit')->warning('User visits webhook create page, but webhooks are DISABLED.');
throw new NotFoundHttpException('Webhooks are not enabled.');

View File

@@ -31,6 +31,7 @@ use Illuminate\Contracts\View\Factory;
use Illuminate\Contracts\View\View;
use Illuminate\Support\Facades\Log;
use Symfony\Component\HttpKernel\Exception\NotFoundHttpException;
use FireflyIII\Support\Facades\FireflyConfig;
/**
* Class DeleteController
@@ -64,7 +65,7 @@ class DeleteController extends Controller
*/
public function index(Webhook $webhook): Factory|View
{
if (false === config('firefly.allow_webhooks')) {
if (false === FireflyConfig::get('allow_webhooks', config('firefly.allow_webhooks'))->data) {
Log::channel('audit')->warning('User visits webhook delete page, but webhooks are DISABLED.');
throw new NotFoundHttpException('Webhooks are not enabled.');

View File

@@ -31,6 +31,7 @@ use Illuminate\Contracts\View\Factory;
use Illuminate\Contracts\View\View;
use Illuminate\Support\Facades\Log;
use Symfony\Component\HttpKernel\Exception\NotFoundHttpException;
use FireflyIII\Support\Facades\FireflyConfig;
/**
* Class EditController
@@ -63,7 +64,7 @@ class EditController extends Controller
*/
public function index(Webhook $webhook): Factory|View
{
if (false === config('firefly.allow_webhooks')) {
if (false === FireflyConfig::get('allow_webhooks', config('firefly.allow_webhooks'))->data) {
Log::channel('audit')->warning('User visits webhook edit page, but webhooks are DISABLED.');
throw new NotFoundHttpException('Webhooks are not enabled.');

View File

@@ -29,6 +29,7 @@ use Illuminate\Contracts\View\Factory;
use Illuminate\Support\Facades\Log;
use Illuminate\View\View;
use Symfony\Component\HttpKernel\Exception\NotFoundHttpException;
use FireflyIII\Support\Facades\FireflyConfig;
/**
* Class IndexController
@@ -55,7 +56,7 @@ class IndexController extends Controller
*/
public function index(): Factory|\Illuminate\Contracts\View\View
{
if (false === config('firefly.allow_webhooks')) {
if (false === FireflyConfig::get('allow_webhooks', config('firefly.allow_webhooks'))->data) {
Log::channel('audit')->warning('User visits webhook index page, but webhooks are DISABLED.');
throw new NotFoundHttpException('Webhooks are not enabled.');

View File

@@ -31,6 +31,7 @@ use Illuminate\Contracts\View\Factory;
use Illuminate\Contracts\View\View;
use Illuminate\Support\Facades\Log;
use Symfony\Component\HttpKernel\Exception\NotFoundHttpException;
use FireflyIII\Support\Facades\FireflyConfig;
/**
* Class ShowController
@@ -63,7 +64,7 @@ class ShowController extends Controller
*/
public function index(Webhook $webhook): Factory|View
{
if (false === config('firefly.allow_webhooks')) {
if (false === FireflyConfig::get('allow_webhooks', config('firefly.allow_webhooks'))->data) {
Log::channel('audit')->warning(sprintf('User visits webhook #%d page, but webhooks are DISABLED.', $webhook->id));
throw new NotFoundHttpException('Webhooks are not enabled.');

View File

@@ -34,6 +34,7 @@ use FireflyIII\Support\Http\Controllers\RequestInformation;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\App;
use Illuminate\Support\Facades\Log;
use FireflyIII\Support\Facades\FireflyConfig;
/**
* Class SessionFilter.
@@ -144,11 +145,11 @@ class Range
// share security message:
if (
app('fireflyconfig')->has('upgrade_security_message')
&& app('fireflyconfig')->has('upgrade_security_level')
FireflyConfig::has('upgrade_security_message')
&& FireflyConfig::has('upgrade_security_level')
) {
app('view')->share('upgrade_security_message', app('fireflyconfig')->get('upgrade_security_message')->data);
app('view')->share('upgrade_security_level', app('fireflyconfig')->get('upgrade_security_level')->data);
app('view')->share('upgrade_security_message', FireflyConfig::get('upgrade_security_message')->data);
app('view')->share('upgrade_security_level', FireflyConfig::get('upgrade_security_level')->data);
}
}
}

View File

@@ -23,8 +23,8 @@ declare(strict_types=1);
namespace FireflyIII\Http\Requests;
use Illuminate\Contracts\Validation\Validator;
use FireflyIII\Support\Request\ChecksLogin;
use Illuminate\Contracts\Validation\Validator;
use Illuminate\Foundation\Http\FormRequest;
use Illuminate\Support\Facades\Log;
@@ -41,8 +41,17 @@ class ConfigurationRequest extends FormRequest
public function getConfigurationData(): array
{
return [
'single_user_mode' => $this->boolean('single_user_mode'),
'is_demo_site' => $this->boolean('is_demo_site'),
'single_user_mode' => $this->boolean('single_user_mode'),
'enable_exchange_rates' => $this->boolean('enable_exchange_rates'),
'use_running_balance' => $this->boolean('use_running_balance'),
'enable_external_map' => $this->boolean('enable_external_map'),
'enable_external_rates' => $this->boolean('enable_external_rates'),
'allow_webhooks' => $this->boolean('allow_webhooks'),
'valid_url_protocols' => $this->string('valid_url_protocols'),
'is_demo_site' => $this->boolean('is_demo_site'),
];
}
@@ -53,8 +62,19 @@ class ConfigurationRequest extends FormRequest
{
// fixed
return [
'single_user_mode' => 'min:0|max:1|numeric',
'is_demo_site' => 'min:0|max:1|numeric',
'single_user_mode' => 'min:0|max:1|numeric',
'enable_exchange_rates' => 'min:0|max:1|numeric',
'use_running_balance' => 'min:0|max:1|numeric',
'enable_external_map' => 'min:0|max:1|numeric',
'enable_external_rates' => 'min:0|max:1|numeric',
'allow_webhooks' => 'min:0|max:1|numeric',
'valid_url_protocols' => 'min:0|max:255',
'is_demo_site' => 'min:0|max:1|numeric',
];
}

View File

@@ -28,6 +28,7 @@ use Illuminate\Notifications\Notification;
use Illuminate\Support\Facades\Log;
use Illuminate\Support\Str;
use NotificationChannels\Pushover\PushoverReceiver;
use FireflyIII\Support\Facades\FireflyConfig;
class OwnerNotifiable
{
@@ -58,8 +59,8 @@ class OwnerNotifiable
public function routeNotificationForPushover(): PushoverReceiver
{
Log::debug('Return settings for routeNotificationForPushover');
$pushoverAppToken = (string) app('fireflyconfig')->getEncrypted('pushover_app_token', '')->data;
$pushoverUserToken = (string) app('fireflyconfig')->getEncrypted('pushover_user_token', '')->data;
$pushoverAppToken = (string) FireflyConfig::getEncrypted('pushover_app_token', '')->data;
$pushoverUserToken = (string) FireflyConfig::getEncrypted('pushover_user_token', '')->data;
return PushoverReceiver::withUserKey($pushoverUserToken)
->withApplicationToken($pushoverAppToken)
@@ -68,7 +69,7 @@ class OwnerNotifiable
public function routeNotificationForSlack(): string
{
$res = app('fireflyconfig')->getEncrypted('slack_webhook_url', '')->data;
$res = FireflyConfig::getEncrypted('slack_webhook_url', '')->data;
if (is_array($res)) {
$res = '';
}

View File

@@ -29,6 +29,7 @@ use FireflyIII\Support\Notifications\UrlValidator;
use FireflyIII\User;
use Illuminate\Support\Facades\Log;
use NotificationChannels\Pushover\PushoverChannel;
use FireflyIII\Support\Facades\FireflyConfig;
// use Wijourdil\NtfyNotificationChannel\Channels\NtfyChannel;
@@ -54,7 +55,7 @@ class ReturnsAvailableChannels
$channels = ['mail'];
if (true === config('notifications.channels.slack.enabled', false)) {
$slackUrl = app('fireflyconfig')->getEncrypted('slack_webhook_url', '')->data;
$slackUrl = FireflyConfig::getEncrypted('slack_webhook_url', '')->data;
if (UrlValidator::isValidWebhookURL($slackUrl)) {
$channels[] = 'slack';
}
@@ -62,19 +63,19 @@ class ReturnsAvailableChannels
// if (true === config('notifications.channels.ntfy.enabled', false)) {
// // validate presence of of Ntfy settings.
// if ('' !== (string) app('fireflyconfig')->getEncrypted('ntfy_topic', '')->data) {
// if ('' !== (string) \FireflyIII\Support\Facades\FireflyConfig::getEncrypted('ntfy_topic', '')->data) {
// Log::debug('Enabled ntfy.');
// $channels[] = NtfyChannel::class;
// }
// if ('' === (string) app('fireflyconfig')->getEncrypted('ntfy_topic', '')->data) {
// if ('' === (string) \FireflyIII\Support\Facades\FireflyConfig::getEncrypted('ntfy_topic', '')->data) {
// Log::warning('No topic name for Ntfy, channel is disabled.');
// }
// }
// pushover
if (true === config('notifications.channels.pushover.enabled', false)) {
$pushoverAppToken = (string) app('fireflyconfig')->getEncrypted('pushover_app_token', '')->data;
$pushoverUserToken = (string) app('fireflyconfig')->getEncrypted('pushover_user_token', '')->data;
$pushoverAppToken = (string) FireflyConfig::getEncrypted('pushover_app_token', '')->data;
$pushoverUserToken = (string) FireflyConfig::getEncrypted('pushover_user_token', '')->data;
if ('' === $pushoverAppToken || '' === $pushoverUserToken) {
Log::warning('[b] No Pushover token, channel is disabled.');
}

View File

@@ -50,12 +50,14 @@ class SearchServiceProvider extends ServiceProvider
{
$this->app->bind(
static function (): QueryParserInterface {
$implementation = config('search.query_parser');
return match ($implementation) {
'new' => app(QueryParser::class),
default => app(GdbotsQueryParser::class),
};
return app(QueryParser::class);
// 2025-12-20 ignore this setting.
// $implementation = config('search.query_parser');
//
// return match ($implementation) {
// 'new' => app(QueryParser::class),
// default => app(GdbotsQueryParser::class),
// };
}
);

View File

@@ -167,12 +167,6 @@ class AccountRepository implements AccountRepositoryInterface, UserGroupInterfac
return $account;
}
#[Override]
public function getAccountBalances(Account $account): Collection
{
return $account->accountBalances;
}
/**
* Return account type or null if not found.
*/

View File

@@ -71,8 +71,6 @@ interface AccountRepositoryInterface
public function findByName(string $name, array $types): ?Account;
public function getAccountBalances(Account $account): Collection;
public function getAccountCurrency(Account $account): ?TransactionCurrency;
/**

View File

@@ -35,6 +35,7 @@ use FireflyIII\User;
use Illuminate\Support\Collection;
use Illuminate\Support\Facades\Log;
use NumberFormatter;
use FireflyIII\Support\Facades\FireflyConfig;
/**
* Class Amount.
@@ -117,7 +118,7 @@ class Amount
if (!$user instanceof User) {
$pref = $instance->getPreference('convert_to_primary_no_user');
if (null === $pref) {
$res = true === Preferences::get('convert_to_primary', false)->data && true === config('cer.enabled');
$res = true === Preferences::get('convert_to_primary', false)->data && true === FireflyConfig::get('enable_exchange_rates', config('cer.enabled'))->data;
$instance->setPreference('convert_to_primary_no_user', $res);
return $res;
@@ -128,7 +129,7 @@ class Amount
$key = sprintf('convert_to_primary_%d', $user->id);
$pref = $instance->getPreference($key);
if (null === $pref) {
$res = true === Preferences::getForUser($user, 'convert_to_primary', false)->data && true === config('cer.enabled');
$res = true === Preferences::getForUser($user, 'convert_to_primary', false)->data && true === FireflyConfig::get('enable_exchange_rates', config('cer.enabled'))->data;
$instance->setPreference($key, $res);
return $res;

View File

@@ -34,6 +34,8 @@ class Balance
{
/**
* Returns the accounts balances as an array, on the account ID.
*
* @deprecated
*/
public function getAccountBalances(Collection $accounts, Carbon $date): array
{

View File

@@ -34,6 +34,7 @@ use FireflyIII\Support\Facades\Amount;
use FireflyIII\Support\Facades\Steam;
use Illuminate\Support\Facades\Cache;
use Illuminate\Support\Facades\Log;
use FireflyIII\Support\Facades\FireflyConfig;
/**
* Class ExchangeRateConverter
@@ -71,7 +72,7 @@ class ExchangeRateConverter
public function enabled(): bool
{
return false !== config('cer.enabled') || $this->ignoreSettings;
return false !== FireflyConfig::get('enable_exchange_rates', config('cer.enabled'))->data || $this->ignoreSettings;
}
/**

View File

@@ -161,7 +161,7 @@ class AccountBalanceCalculator
// then update all transactions.
// save all collected balances in their respective account objects.
$this->storeAccountBalances($balances);
// $this->storeAccountBalances($balances);
}
private function storeAccountBalances(array $balances): void

View File

@@ -23,9 +23,8 @@ declare(strict_types=1);
namespace FireflyIII\Support;
use FireflyIII\Support\Facades\Preferences;
use Deprecated;
use Carbon\Carbon;
use Deprecated;
use Exception;
use FireflyIII\Exceptions\FireflyException;
use FireflyIII\Models\Account;
@@ -33,6 +32,7 @@ use FireflyIII\Models\AccountMeta;
use FireflyIII\Models\Transaction;
use FireflyIII\Models\TransactionCurrency;
use FireflyIII\Support\Facades\Amount;
use FireflyIII\Support\Facades\Preferences;
use FireflyIII\Support\Http\Api\ExchangeRateConverter;
use FireflyIII\Support\Singleton\PreferencesSingleton;
use Illuminate\Support\Collection;
@@ -131,7 +131,8 @@ class Steam
}
/**
* Calls accountsBalancesOptimized for the given accounts and makes sure that inclusive is set to false, so it properly gets the balance of a range.
* Calls accountsBalancesOptimized for the given accounts and makes sure that inclusive is set to false, so it
* properly gets the balance of a range.
*/
public function accountsBalancesInRange(Collection $accounts, Carbon $start, Carbon $end, ?TransactionCurrency $primary = null, ?bool $convertToPrimary = null): array
{
@@ -291,21 +292,23 @@ class Steam
return str_replace($search, '', $string);
}
#[Deprecated(message: <<<'TXT'
#[Deprecated(
message: <<<'TXT'
By default this method returns "smaller than or equal to", so be careful with END OF DAY.
If you need end of day balance, use "inclusive = false".
By default this method returns "smaller than or equal to", so be careful with END OF DAY.
If you need end of day balance, use "inclusive = false".
Returns the balance of an account at exact moment given. Array with at least one value.
Always returns:
"balance": balance in the account's currency OR user's primary currency if the account has no currency
"EUR": balance in EUR (or whatever currencies the account has balance in)
Returns the balance of an account at exact moment given. Array with at least one value.
Always returns:
"balance": balance in the account's currency OR user's primary currency if the account has no currency
"EUR": balance in EUR (or whatever currencies the account has balance in)
If the user has $convertToPrimary:
"balance": balance in the account's currency OR user's primary currency if the account has no currency
--> "pc_balance": balance in the user's primary currency, with all amounts converted to the primary currency.
"EUR": balance in EUR (or whatever currencies the account has balance in)
TXT)]
If the user has $convertToPrimary:
"balance": balance in the account's currency OR user's primary currency if the account has no currency
--> "pc_balance": balance in the user's primary currency, with all amounts converted to the primary currency.
"EUR": balance in EUR (or whatever currencies the account has balance in)
TXT
)]
public function finalAccountBalance(Account $account, Carbon $date, ?TransactionCurrency $primary = null, ?bool $convertToPrimary = null, bool $inclusive = true): array
{
@@ -663,8 +666,10 @@ class Steam
*/
public function getSafePreviousUrl(): string
{
// Log::debug(sprintf('getSafePreviousUrl: "%s"', session()->previousUrl()));
return session()->previousUrl() ?? route('index');
$res = $this->getSafeUrl(session()->previousUrl() ?? route('index'), route('index'));
Log::debug(sprintf('getSafePreviousUrl: "%s"', $res));
return $res;
}
/**
@@ -675,6 +680,7 @@ class Steam
// Log::debug(sprintf('getSafeUrl(%s, %s)', $unknownUrl, $safeUrl));
$returnUrl = $safeUrl;
// die('in get safe url');
try {
$unknownHost = parse_url($unknownUrl, PHP_URL_HOST);
} catch (UrlException $e) {

View File

@@ -27,6 +27,7 @@ namespace FireflyIII\Support\System;
use Illuminate\Support\Facades\Log;
use FireflyIII\Exceptions\FireflyException;
use Ramsey\Uuid\Uuid;
use FireflyIII\Support\Facades\FireflyConfig;
/**
* Trait GeneratesInstallationId
@@ -36,7 +37,7 @@ trait GeneratesInstallationId
protected function generateInstallationId(): void
{
try {
$config = app('fireflyconfig')->get('installation_id');
$config = FireflyConfig::get('installation_id');
} catch (FireflyException) {
Log::info('Could not create or generate installation ID. Do not continue.');
@@ -52,7 +53,7 @@ trait GeneratesInstallationId
$uuid4 = Uuid::uuid4();
$uniqueId = (string)$uuid4;
Log::info(sprintf('Created Firefly III installation ID %s', $uniqueId));
app('fireflyconfig')->set('installation_id', $uniqueId);
FireflyConfig::set('installation_id', $uniqueId);
}
}
}

View File

@@ -24,6 +24,7 @@ declare(strict_types=1);
namespace FireflyIII;
use FireflyIII\Support\Facades\FireflyConfig;
use FireflyIII\Support\Facades\Preferences;
use Illuminate\Support\Facades\Log;
use Deprecated;
@@ -403,7 +404,7 @@ class User extends Authenticatable
public function routeNotificationForSlack(Notification $notification): ?string
{
// this check does not validate if the user is owner, Should be done by notification itself.
$res = app('fireflyconfig')->getEncrypted('slack_webhook_url', '')->data;
$res = FireflyConfig::getEncrypted('slack_webhook_url', '')->data;
if (is_array($res)) {
$res = '';
}

12
composer.lock generated
View File

@@ -10515,16 +10515,16 @@
},
{
"name": "driftingly/rector-laravel",
"version": "2.1.7",
"version": "2.1.8",
"source": {
"type": "git",
"url": "https://github.com/driftingly/rector-laravel.git",
"reference": "2a64c96fa363bc85e4e6d4162c6a6bb7a78fd122"
"reference": "5c5f97354e562b6742b2b7989959061bde60fa71"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/driftingly/rector-laravel/zipball/2a64c96fa363bc85e4e6d4162c6a6bb7a78fd122",
"reference": "2a64c96fa363bc85e4e6d4162c6a6bb7a78fd122",
"url": "https://api.github.com/repos/driftingly/rector-laravel/zipball/5c5f97354e562b6742b2b7989959061bde60fa71",
"reference": "5c5f97354e562b6742b2b7989959061bde60fa71",
"shasum": ""
},
"require": {
@@ -10545,9 +10545,9 @@
"description": "Rector upgrades rules for Laravel Framework",
"support": {
"issues": "https://github.com/driftingly/rector-laravel/issues",
"source": "https://github.com/driftingly/rector-laravel/tree/2.1.7"
"source": "https://github.com/driftingly/rector-laravel/tree/2.1.8"
},
"time": "2025-12-10T11:30:42+00:00"
"time": "2025-12-17T15:29:24+00:00"
},
{
"name": "fakerphp/faker",

View File

@@ -24,8 +24,8 @@ declare(strict_types=1);
return [
'url' => 'https://ff3exchangerates.z6.web.core.windows.net',
'enabled' => env('ENABLE_EXCHANGE_RATES', false),
'download_enabled' => env('ENABLE_EXTERNAL_RATES', false),
'enabled' => env('ENABLE_EXCHANGE_RATES', false), // no longer used, is the default.
'download_enabled' => env('ENABLE_EXTERNAL_RATES', false), // no longer used, only for default.
// if currencies are added, default rates must be added as well!
// source: https://www.xe.com/currencyconverter/

View File

@@ -75,11 +75,11 @@ return [
'webhooks' => true,
'handle_debts' => true,
'expression_engine' => true,
'running_balance_column' => env('USE_RUNNING_BALANCE', false),
'running_balance_column' => env('USE_RUNNING_BALANCE', true), // this is only the default value, is not used.
// see cer.php for exchange rates feature flag.
],
'version' => 'develop/2025-12-17',
'build_time' => 1765957552,
'version' => 'develop/2025-12-20',
'build_time' => 1766210708,
'api_version' => '2.1.0', // field is no longer used.
'db_version' => 28, // field is no longer used.
@@ -94,13 +94,10 @@ return [
'static_cron_token' => envNonEmpty('STATIC_CRON_TOKEN'),
// flags
'enable_external_map' => env('ENABLE_EXTERNAL_MAP', false),
'enable_external_map' => env('ENABLE_EXTERNAL_MAP', false), // no longer used, only for default.
'disable_frame_header' => env('DISABLE_FRAME_HEADER', false),
'disable_csp_header' => env('DISABLE_CSP_HEADER', false),
'allow_webhooks' => env('ALLOW_WEBHOOKS', false),
// flags
'send_report_journals' => envNonEmpty('SEND_REPORT_JOURNALS', true),
'allow_webhooks' => env('ALLOW_WEBHOOKS', false), // no longer used, only for default.
// info for demo site
'demo_username' => env('DEMO_USERNAME', ''),
@@ -221,7 +218,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'),
'valid_url_protocols' => envNonEmpty('VALID_URL_PROTOCOLS', 'http,https,ftp,ftps,mailto'), // no longer used, only for default.
'allowedMimes' => [
// plain files
'text/plain',

View File

@@ -261,6 +261,4 @@ return [
'destination_balance_lt' => ['alias' => false, 'needs_context' => true],
'destination_balance_is' => ['alias' => false, 'needs_context' => true],
],
// Which query parser to use - 'new' or 'legacy'
'query_parser' => env('QUERY_PARSER_IMPLEMENTATION', 'legacy'),
];

80
package-lock.json generated
View File

@@ -3294,42 +3294,42 @@
}
},
"node_modules/@vue/compiler-core": {
"version": "3.5.25",
"resolved": "https://registry.npmjs.org/@vue/compiler-core/-/compiler-core-3.5.25.tgz",
"integrity": "sha512-vay5/oQJdsNHmliWoZfHPoVZZRmnSWhug0BYT34njkYTPqClh3DNWLkZNJBVSjsNMrg0CCrBfoKkjZQPM/QVUw==",
"version": "3.5.26",
"resolved": "https://registry.npmjs.org/@vue/compiler-core/-/compiler-core-3.5.26.tgz",
"integrity": "sha512-vXyI5GMfuoBCnv5ucIT7jhHKl55Y477yxP6fc4eUswjP8FG3FFVFd41eNDArR+Uk3QKn2Z85NavjaxLxOC19/w==",
"dev": true,
"license": "MIT",
"dependencies": {
"@babel/parser": "^7.28.5",
"@vue/shared": "3.5.25",
"entities": "^4.5.0",
"@vue/shared": "3.5.26",
"entities": "^7.0.0",
"estree-walker": "^2.0.2",
"source-map-js": "^1.2.1"
}
},
"node_modules/@vue/compiler-dom": {
"version": "3.5.25",
"resolved": "https://registry.npmjs.org/@vue/compiler-dom/-/compiler-dom-3.5.25.tgz",
"integrity": "sha512-4We0OAcMZsKgYoGlMjzYvaoErltdFI2/25wqanuTu+S4gismOTRTBPi4IASOjxWdzIwrYSjnqONfKvuqkXzE2Q==",
"version": "3.5.26",
"resolved": "https://registry.npmjs.org/@vue/compiler-dom/-/compiler-dom-3.5.26.tgz",
"integrity": "sha512-y1Tcd3eXs834QjswshSilCBnKGeQjQXB6PqFn/1nxcQw4pmG42G8lwz+FZPAZAby6gZeHSt/8LMPfZ4Rb+Bd/A==",
"dev": true,
"license": "MIT",
"dependencies": {
"@vue/compiler-core": "3.5.25",
"@vue/shared": "3.5.25"
"@vue/compiler-core": "3.5.26",
"@vue/shared": "3.5.26"
}
},
"node_modules/@vue/compiler-sfc": {
"version": "3.5.25",
"resolved": "https://registry.npmjs.org/@vue/compiler-sfc/-/compiler-sfc-3.5.25.tgz",
"integrity": "sha512-PUgKp2rn8fFsI++lF2sO7gwO2d9Yj57Utr5yEsDf3GNaQcowCLKL7sf+LvVFvtJDXUp/03+dC6f2+LCv5aK1ag==",
"version": "3.5.26",
"resolved": "https://registry.npmjs.org/@vue/compiler-sfc/-/compiler-sfc-3.5.26.tgz",
"integrity": "sha512-egp69qDTSEZcf4bGOSsprUr4xI73wfrY5oRs6GSgXFTiHrWj4Y3X5Ydtip9QMqiCMCPVwLglB9GBxXtTadJ3mA==",
"dev": true,
"license": "MIT",
"dependencies": {
"@babel/parser": "^7.28.5",
"@vue/compiler-core": "3.5.25",
"@vue/compiler-dom": "3.5.25",
"@vue/compiler-ssr": "3.5.25",
"@vue/shared": "3.5.25",
"@vue/compiler-core": "3.5.26",
"@vue/compiler-dom": "3.5.26",
"@vue/compiler-ssr": "3.5.26",
"@vue/shared": "3.5.26",
"estree-walker": "^2.0.2",
"magic-string": "^0.30.21",
"postcss": "^8.5.6",
@@ -3337,14 +3337,14 @@
}
},
"node_modules/@vue/compiler-ssr": {
"version": "3.5.25",
"resolved": "https://registry.npmjs.org/@vue/compiler-ssr/-/compiler-ssr-3.5.25.tgz",
"integrity": "sha512-ritPSKLBcParnsKYi+GNtbdbrIE1mtuFEJ4U1sWeuOMlIziK5GtOL85t5RhsNy4uWIXPgk+OUdpnXiTdzn8o3A==",
"version": "3.5.26",
"resolved": "https://registry.npmjs.org/@vue/compiler-ssr/-/compiler-ssr-3.5.26.tgz",
"integrity": "sha512-lZT9/Y0nSIRUPVvapFJEVDbEXruZh2IYHMk2zTtEgJSlP5gVOqeWXH54xDKAaFS4rTnDeDBQUYDtxKyoW9FwDw==",
"dev": true,
"license": "MIT",
"dependencies": {
"@vue/compiler-dom": "3.5.25",
"@vue/shared": "3.5.25"
"@vue/compiler-dom": "3.5.26",
"@vue/shared": "3.5.26"
}
},
"node_modules/@vue/component-compiler-utils": {
@@ -3426,9 +3426,9 @@
"license": "MIT"
},
"node_modules/@vue/shared": {
"version": "3.5.25",
"resolved": "https://registry.npmjs.org/@vue/shared/-/shared-3.5.25.tgz",
"integrity": "sha512-AbOPdQQnAnzs58H2FrrDxYj/TJfmeS2jdfEEhgiKINy+bnOANmVizIEgq1r+C5zsbs6l1CCQxtcj71rwNQ4jWg==",
"version": "3.5.26",
"resolved": "https://registry.npmjs.org/@vue/shared/-/shared-3.5.26.tgz",
"integrity": "sha512-7Z6/y3uFI5PRoKeorTOSXKcDj0MSasfNNltcslbFrPpcw6aXRUALq4IfJlaTRspiWIUOEZbrpM+iQGmCOiWe4A==",
"dev": true,
"license": "MIT"
},
@@ -4075,9 +4075,9 @@
"license": "MIT"
},
"node_modules/baseline-browser-mapping": {
"version": "2.9.8",
"resolved": "https://registry.npmjs.org/baseline-browser-mapping/-/baseline-browser-mapping-2.9.8.tgz",
"integrity": "sha512-Y1fOuNDowLfgKOypdc9SPABfoWXuZHBOyCS4cD52IeZBhr4Md6CLLs6atcxVrzRmQ06E7hSlm5bHHApPKR/byA==",
"version": "2.9.11",
"resolved": "https://registry.npmjs.org/baseline-browser-mapping/-/baseline-browser-mapping-2.9.11.tgz",
"integrity": "sha512-Sg0xJUNDU1sJNGdfGWhVHX0kkZ+HWcvmVymJbj6NSgZZmW/8S9Y2HQ5euytnIgakgxN6papOAWiwDo1ctFDcoQ==",
"dev": true,
"license": "Apache-2.0",
"bin": {
@@ -4508,9 +4508,9 @@
}
},
"node_modules/caniuse-lite": {
"version": "1.0.30001760",
"resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001760.tgz",
"integrity": "sha512-7AAMPcueWELt1p3mi13HR/LHH0TJLT11cnwDJEs3xA4+CK/PLKeO9Kl1oru24htkyUKtkGCvAx4ohB0Ttry8Dw==",
"version": "1.0.30001761",
"resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001761.tgz",
"integrity": "sha512-JF9ptu1vP2coz98+5051jZ4PwQgd2ni8A+gYSN7EA7dPKIMf0pDlSUxhdmVOaV3/fYK5uWBkgSXJaRLr4+3A6g==",
"dev": true,
"funding": [
{
@@ -5787,9 +5787,9 @@
}
},
"node_modules/entities": {
"version": "4.5.0",
"resolved": "https://registry.npmjs.org/entities/-/entities-4.5.0.tgz",
"integrity": "sha512-V0hjH4dGPh9Ao5p0MoRY6BVqtwCjhz6vI5LT8AJ55H+4g9/4vbHx1I54fS0XuclLhDHArPQCiMjDxjaL8fPxhw==",
"version": "7.0.0",
"resolved": "https://registry.npmjs.org/entities/-/entities-7.0.0.tgz",
"integrity": "sha512-FDWG5cmEYf2Z00IkYRhbFrwIwvdFKH07uV8dvNy0omp/Qb1xcyCWp2UDtcwJF4QZZvk0sLudP6/hAu42TaqVhQ==",
"dev": true,
"license": "BSD-2-Clause",
"engines": {
@@ -10129,9 +10129,9 @@
"license": "MIT"
},
"node_modules/sass": {
"version": "1.97.0",
"resolved": "https://registry.npmjs.org/sass/-/sass-1.97.0.tgz",
"integrity": "sha512-KR0igP1z4avUJetEuIeOdDlwaUDvkH8wSx7FdSjyYBS3dpyX3TzHfAMO0G1Q4/3cdjcmi3r7idh+KCmKqS+KeQ==",
"version": "1.97.1",
"resolved": "https://registry.npmjs.org/sass/-/sass-1.97.1.tgz",
"integrity": "sha512-uf6HoO8fy6ClsrShvMgaKUn14f2EHQLQRtpsZZLeU/Mv0Q1K5P0+x2uvH6Cub39TVVbWNSrraUhDAoFph6vh0A==",
"dev": true,
"license": "MIT",
"dependencies": {
@@ -11740,9 +11740,9 @@
"license": "BSD-2-Clause"
},
"node_modules/webpack": {
"version": "5.104.0",
"resolved": "https://registry.npmjs.org/webpack/-/webpack-5.104.0.tgz",
"integrity": "sha512-5DeICTX8BVgNp6afSPYXAFjskIgWGlygQH58bcozPOXgo2r/6xx39Y1+cULZ3gTxUYQP88jmwLj2anu4Xaq84g==",
"version": "5.104.1",
"resolved": "https://registry.npmjs.org/webpack/-/webpack-5.104.1.tgz",
"integrity": "sha512-Qphch25abbMNtekmEGJmeRUhLDbe+QfiWTiqpKYkpCOWY64v9eyl+KRRLmqOFA2AvKPpc9DC6+u2n76tQLBoaA==",
"dev": true,
"license": "MIT",
"dependencies": {

View File

@@ -2567,6 +2567,25 @@ return [
'all_users' => 'All users',
'instance_configuration' => 'Configuration',
'firefly_instance_configuration' => 'Firefly III configuration',
'config_security' => 'Security configuration',
'config_features' => 'Enabled features',
'config_tech' => 'Tech related features',
'config_external_connections' => 'Privacy-sensitive settings (connects to the internet)',
'setting_enable_exchange_rates' => 'Enable exchange rates',
'setting_enable_exchange_rates_explain' => 'Firefly III has the capability of calculating exchange rates for you.',
'setting_use_running_balance' => 'Use "running balance"-column and data',
'setting_use_running_balance_explain' => 'Firefly III can calculate the current running balance for you, and display this in various places. It is still slightly experimental, so disabled by default. You may need to restart your container or fire the initial command manually (see the docs).',
'setting_enable_external_map' => 'Use external map service',
'setting_enable_external_map_explain' => 'Firefly III uses an external service to display locations. Is this OK?',
'setting_enable_external_rates' => 'Download exchange rates from the web',
'setting_enable_external_rates_explain' => 'Firefly III can download exchange rates for the built-in currencies. This needs the cron job to work.',
'setting_allow_webhooks' => 'Allow webhooks',
'setting_allow_webhooks_explain' => 'Allow Firefly III to fire webhooks?',
'setting_valid_url_protocols' => 'Allowed URL protocols',
'setting_valid_url_protocols_explain' => 'Firefly III only allows urls to have standard protocols like https and ftp etc. If you\'re a techie you may want to allow others as well.',
'setting_single_user_mode' => 'Single user mode',
'setting_single_user_mode_explain' => 'By default, Firefly III only accepts one (1) registration: you. This is a security measure, preventing others from using your instance unless you allow them to. Future registrations are blocked. When you uncheck this box, others can use your instance as well, assuming they can reach it (when it is connected to the internet).',
'store_configuration' => 'Store configuration',

View File

@@ -67,9 +67,12 @@ return [
'tag_mode' => 'Tag mode',
'virtual_balance' => 'Virtual balance',
'run_after_form' => 'Run this rule',
'valid_url_protocols' => 'Valid URL protocols',
'allow_webhooks' => 'Allow webhooks',
'enable_external_rates' => 'Enable external exchange rates',
'enable_external_map' => 'Enable external map',
'use_running_balance' => 'Calculate running balances',
'enable_exchange_rates' => 'Enable exchange rates',
'targetamount' => 'Target amount',
'target_amount' => 'Target amount',
'account_role' => 'Account role',

View File

@@ -33,7 +33,7 @@
<th class="hidden-xs">&nbsp;</th>
<th>{{ trans('list.description') }}</th>
<th>{{ trans('list.amount') }}</th>
{% if config('firefly.feature_flags.running_balance_column') %}
{% if FireflyConfig.get('use_running_balance', config('firefly.feature_flags.running_balance_column')) %}
<th>{{ trans('list.running_balance') }}</th>
{% endif %}
<th>{{ trans('list.date') }}</th>
@@ -266,7 +266,7 @@
{% endif %}
{% endif %}
</td>
{% if config('firefly.feature_flags.running_balance_column') %}
{% if FireflyConfig.get('use_running_balance', config('firefly.feature_flags.running_balance_column')) %}
<td>
{% if (null == transaction.balance_dirty or false == transaction.balance_dirty) and null != transaction.destination_balance_after and null != transaction.source_balance_after %}
{% if transaction.transaction_type_type == 'Deposit' %}

View File

@@ -119,11 +119,11 @@
</tr>
<tr>
<td>Exchange rates</td>
<td>{% if config('cer.enabled') %}Enabled{% else %}Disabled{% endif %}, downloads {% if config('cer.download_enabled') %}enabled{% else %}disabled{% endif %}</td>
<td>{% if FireflyConfig.get('enable_exchange_rates', config('cer.enabled')) %}Enabled{% else %}Disabled{% endif %}, downloads {% if FireflyConfig.get('enable_external_rates', config('cer.download_enabled')) %}enabled{% else %}disabled{% endif %}</td>
</tr>
<tr>
<td>RB-column</td>
<td>{% if config('firefly.feature_flags.running_balance_column') %}Enabled{% else %}Disabled{% endif %}</td>
<td>{% if FireflyConfig.get('use_running_balance', config('firefly.feature_flags.running_balance_column')) %}Enabled{% else %}Disabled{% endif %}</td>
</tr>
</tbody>
</table>

View File

@@ -226,7 +226,7 @@
<span>{{ 'currencies'|_ }}</span>
</a>
</li>
{% if config('cer.enabled') %}
{% if FireflyConfig.get('enable_exchange_rates', config('cer.enabled')) %}
<li class="{{ activeRoutePartial('exchange-rates') }}">
<a class="{{ activeRoutePartial('exchange-rates') }}" href="{{ route('exchange-rates.index') }}">
<span class="fa fa-angle-right fa-fw"></span>

View File

@@ -101,7 +101,7 @@
</div>
{# conversion back to primary currency #}
{% if config('cer.enabled') %}
{% if FireflyConfig.get('enable_exchange_rates', config('cer.enabled')) %}
<div class="preferences-box">
<h3>{{ 'pref_convert_to_primary'|_ }}</h3>
<p class="text-info">

View File

@@ -4,66 +4,143 @@
{{ Breadcrumbs.render }}
{% endblock %}
{% block content %}
<!--
Security
- single user mode
Features
- enable exchange rates
- use running balance
External connections
- enable external map
- enable external exchange rates
- allow webhooks
Technical stuff
- valid url protocols
- is demo site
-->
<form action="{{ route('settings.configuration.index.post') }}" method="post" id="store" class="form-horizontal">
<input type="hidden" name="_token" value="{{ csrf_token() }}"/>
{# security #}
<div class="row">
<input type="hidden" name="_token" value="{{ csrf_token() }}"/>
{# single user mode #}
<div class="col-lg-4 col-md-6 col-sm-12 col-xs-12">
<div class="col-lg-8 col-lg-offset-2 col-xl-8 col-xl-offset-2 col-md-12 col-sm-12 col-xs-12">
<div class="box box-default">
<div class="box-header with-border">
<h3 class="box-title">{{ 'setting_single_user_mode'|_ }}</h3>
<h3 class="box-title">{{ 'config_security'|_ }}</h3>
</div>
<div class="box-body">
<p class="text-info">
<h4>
{{ 'setting_single_user_mode'|_ }}
</h4>
<p>
{{ 'setting_single_user_mode_explain'|_ }}
</p>
{{ ExpandedForm.checkbox('single_user_mode','1', singleUserMode) }}
</div>
</div>
</div>
</div>
{# installation is demo site #}
<div class="col-lg-4 col-md-6 col-sm-12 col-xs-12">
<div class="row">
<div class="col-lg-8 col-lg-offset-2 col-xl-8 col-xl-offset-2 col-md-12 col-sm-12 col-xs-12">
<div class="box box-default">
<div class="box-header with-border">
<h3 class="box-title">{{ 'setting_is_demo_site'|_ }}</h3>
<h3 class="box-title">{{ 'config_features'|_ }}</h3>
</div>
<div class="box-body">
<p class="text-info">
<h4>
{{ 'setting_enable_exchange_rates'|_ }}
</h4>
<p>
{{ 'setting_enable_exchange_rates_explain'|_ }}
</p>
{{ ExpandedForm.checkbox('enable_exchange_rates','1', enableExchangeRates) }}
<h4>
{{ 'setting_use_running_balance'|_ }}
</h4>
<p>
{{ 'setting_use_running_balance_explain'|_ }}
</p>
{{ ExpandedForm.checkbox('use_running_balance','1', useRunningBalance) }}
</div>
</div>
</div>
</div>
<div class="row">
<div class="col-lg-8 col-lg-offset-2 col-xl-8 col-xl-offset-2 col-md-12 col-sm-12 col-xs-12">
<div class="box box-default">
<div class="box-header with-border">
<h3 class="box-title">{{ 'config_external_connections'|_ }}</h3>
</div>
<div class="box-body">
<h4>
{{ 'setting_enable_external_map'|_ }}
</h4>
<p>
{{ 'setting_enable_external_map_explain'|_ }}
</p>
{{ ExpandedForm.checkbox('enable_external_map','1', enableExternalMap) }}
<h4>
{{ 'setting_enable_external_rates'|_ }}
</h4>
<p>
{{ 'setting_enable_external_rates_explain'|_ }}
</p>
{{ ExpandedForm.checkbox('enable_external_rates','1', enableExternalRates) }}
<h4>
{{ 'setting_allow_webhooks'|_ }}
</h4>
<p>
{{ 'setting_allow_webhooks_explain'|_ }}
</p>
{{ ExpandedForm.checkbox('allow_webhooks','1', allowWebhooks) }}
</div>
</div>
</div>
</div>
<div class="row">
<div class="col-lg-8 col-lg-offset-2 col-xl-8 col-xl-offset-2 col-md-12 col-sm-12 col-xs-12">
<div class="box box-default">
<div class="box-header with-border">
<h3 class="box-title">{{ 'config_tech'|_ }}</h3>
</div>
<div class="box-body">
<h4>
{{ 'setting_valid_url_protocols'|_ }}
</h4>
<p>
{{ 'setting_valid_url_protocols_explain'|_ }}
</p>
{{ ExpandedForm.text('valid_url_protocols', validUrlProtocols) }}
<h4>
{{ 'setting_is_demo_site'|_ }}
</h4>
<p>
{{ 'setting_is_demo_site_explain'|_ }}
</p>
{{ ExpandedForm.checkbox('is_demo_site','1', isDemoSite) }}
</div>
</div>
</div>
{# block for config setting #}
{#
<div class="col-lg-4 col-md-6 col-sm-12 col-xs-12">
<div class="box box-default">
<div class="box-header with-border">
<h3 class="box-title">{{ 'setting_x'|_ }}</h3>
</div>
<div class="box-body">
<p class="text-info">
{{ 'setting_x_explain'|_ }}
<p>
<button type="submit" class="btn btn-success">
{{ ('store_configuration')|_ }}
</button>
</p>
</div>
</div>
</div>
#}
</div>
<div class="row">
<div class="col-lg-4 col-md-6 col-sm-12 col-xs-12">
<button type="submit" class="btn btn-success">
{{ ('store_configuration')|_ }}
</button>
</div>
</div>
</form>
{% endblock %}