From dc3c3bb0925355982bea5b3a537adf85589ea538 Mon Sep 17 00:00:00 2001 From: James Cole Date: Tue, 30 Dec 2025 07:24:14 +0100 Subject: [PATCH] Add setting for anonymous amounts in preferences. --- app/Http/Controllers/HomeController.php | 1 + .../Controllers/PreferencesController.php | 121 +++++++++--------- resources/lang/en_US/firefly.php | 3 + resources/views/preferences/index.twig | 8 ++ 4 files changed, 75 insertions(+), 58 deletions(-) diff --git a/app/Http/Controllers/HomeController.php b/app/Http/Controllers/HomeController.php index 67118821c6..f96f0e501d 100644 --- a/app/Http/Controllers/HomeController.php +++ b/app/Http/Controllers/HomeController.php @@ -23,6 +23,7 @@ declare(strict_types=1); namespace FireflyIII\Http\Controllers; +use FireflyIII\Support\Facades\Navigation; use FireflyIII\Support\Facades\Preferences; use Carbon\Carbon; use Carbon\Exceptions\InvalidFormatException; diff --git a/app/Http/Controllers/PreferencesController.php b/app/Http/Controllers/PreferencesController.php index 4c526e553d..aca67a7c5e 100644 --- a/app/Http/Controllers/PreferencesController.php +++ b/app/Http/Controllers/PreferencesController.php @@ -23,7 +23,6 @@ declare(strict_types=1); namespace FireflyIII\Http\Controllers; -use FireflyIII\Support\Facades\Navigation; use Carbon\Carbon; use FireflyIII\Enums\AccountTypeEnum; use FireflyIII\Events\Preferences\UserGroupChangedPrimaryCurrency; @@ -33,7 +32,9 @@ use FireflyIII\Http\Requests\PreferencesRequest; use FireflyIII\Models\Account; use FireflyIII\Models\Preference; use FireflyIII\Repositories\Account\AccountRepositoryInterface; +use FireflyIII\Support\Facades\Navigation; use FireflyIII\Support\Facades\Preferences; +use FireflyIII\Support\Facades\Steam; use FireflyIII\Support\Singleton\PreferencesSingleton; use FireflyIII\User; use Illuminate\Contracts\View\Factory; @@ -44,8 +45,6 @@ use Illuminate\Support\Facades\Log; use Illuminate\View\View; use JsonException; use Safe\Exceptions\FilesystemException; -use FireflyIII\Support\Facades\Steam; - use function Safe\file_get_contents; use function Safe\json_decode; @@ -63,7 +62,7 @@ class PreferencesController extends Controller $this->middleware( static function ($request, $next) { - app('view')->share('title', (string) trans('firefly.preferences')); + app('view')->share('title', (string)trans('firefly.preferences')); app('view')->share('mainTitleIcon', 'fa-gear'); return $next($request); @@ -79,16 +78,16 @@ class PreferencesController extends Controller * @throws FireflyException * @throws FilesystemException */ - public function index(AccountRepositoryInterface $repository): Factory|\Illuminate\Contracts\View\View + public function index(AccountRepositoryInterface $repository): Factory | \Illuminate\Contracts\View\View { - $accounts = $repository->getAccountsByType([AccountTypeEnum::DEFAULT->value, AccountTypeEnum::ASSET->value, AccountTypeEnum::LOAN->value, AccountTypeEnum::DEBT->value, AccountTypeEnum::MORTGAGE->value]); - $isDocker = env('IS_DOCKER', false); // @phpstan-ignore-line - $groupedAccounts = []; + $accounts = $repository->getAccountsByType([AccountTypeEnum::DEFAULT->value, AccountTypeEnum::ASSET->value, AccountTypeEnum::LOAN->value, AccountTypeEnum::DEBT->value, AccountTypeEnum::MORTGAGE->value]); + $isDocker = env('IS_DOCKER', false); // @phpstan-ignore-line + $groupedAccounts = []; /** @var Account $account */ foreach ($accounts as $account) { - $type = $account->accountType->type; - $role = sprintf('opt_group_%s', $repository->getMetaValue($account, 'account_role')); + $type = $account->accountType->type; + $role = sprintf('opt_group_%s', $repository->getMetaValue($account, 'account_role')); if (in_array($type, [AccountTypeEnum::MORTGAGE->value, AccountTypeEnum::DEBT->value, AccountTypeEnum::LOAN->value], true)) { $role = sprintf('opt_group_l_%s', $type); @@ -97,54 +96,55 @@ class PreferencesController extends Controller if ('opt_group_' === $role) { $role = 'opt_group_defaultAsset'; } - $groupedAccounts[(string) trans(sprintf('firefly.%s', $role))][$account->id] = $account->name; + $groupedAccounts[(string)trans(sprintf('firefly.%s', $role))][$account->id] = $account->name; } ksort($groupedAccounts); /** @var array $accountIds */ - $accountIds = $accounts->pluck('id')->toArray(); - $viewRange = Navigation::getViewRange(false); - $frontpageAccountsPref = Preferences::get('frontpageAccounts', $accountIds); - $frontpageAccounts = $frontpageAccountsPref->data; + $accountIds = $accounts->pluck('id')->toArray(); + $viewRange = Navigation::getViewRange(false); + $frontpageAccountsPref = Preferences::get('frontpageAccounts', $accountIds); + $frontpageAccounts = $frontpageAccountsPref->data; if (!is_array($frontpageAccounts)) { $frontpageAccounts = $accountIds; } - $language = Steam::getLanguage(); - $languages = config('firefly.languages'); - $locale = Preferences::get('locale', config('firefly.default_locale', 'equal'))->data; - $listPageSize = Preferences::get('listPageSize', 50)->data; - $darkMode = Preferences::get('darkMode', 'browser')->data; - $customFiscalYear = Preferences::get('customFiscalYear', 0)->data; - $fiscalYearStartStr = Preferences::get('fiscalYearStart', '01-01')->data; - $convertToPrimary = $this->convertToPrimary; + $language = Steam::getLanguage(); + $languages = config('firefly.languages'); + $locale = Preferences::get('locale', config('firefly.default_locale', 'equal'))->data; + $listPageSize = Preferences::get('listPageSize', 50)->data; + $darkMode = Preferences::get('darkMode', 'browser')->data; + $customFiscalYear = Preferences::get('customFiscalYear', 0)->data; + $fiscalYearStartStr = Preferences::get('fiscalYearStart', '01-01')->data; + $convertToPrimary = $this->convertToPrimary; if (is_array($fiscalYearStartStr)) { $fiscalYearStartStr = '01-01'; } - $fiscalYearStart = sprintf('%s-%s', Carbon::now()->format('Y'), (string) $fiscalYearStartStr); - $tjOptionalFields = Preferences::get('transaction_journal_optional_fields', [])->data; - $availableDarkModes = config('firefly.available_dark_modes'); + $fiscalYearStart = sprintf('%s-%s', Carbon::now()->format('Y'), (string)$fiscalYearStartStr); + $tjOptionalFields = Preferences::get('transaction_journal_optional_fields', [])->data; + $availableDarkModes = config('firefly.available_dark_modes'); // notifications settings - $slackUrl = Preferences::getEncrypted('slack_webhook_url', '')->data; - $pushoverAppToken = (string) Preferences::getEncrypted('pushover_app_token', '')->data; - $pushoverUserToken = (string) Preferences::getEncrypted('pushover_user_token', '')->data; - $ntfyServer = Preferences::getEncrypted('ntfy_server', 'https://ntfy.sh')->data; - $ntfyTopic = (string) Preferences::getEncrypted('ntfy_topic', '')->data; - $ntfyAuth = '1' === Preferences::get('ntfy_auth', false)->data; - $ntfyUser = Preferences::getEncrypted('ntfy_user', '')->data; - $ntfyPass = (string) Preferences::getEncrypted('ntfy_pass', '')->data; - $channels = config('notifications.channels'); - $forcedAvailability = []; + $slackUrl = Preferences::getEncrypted('slack_webhook_url', '')->data; + $pushoverAppToken = (string)Preferences::getEncrypted('pushover_app_token', '')->data; + $pushoverUserToken = (string)Preferences::getEncrypted('pushover_user_token', '')->data; + $ntfyServer = Preferences::getEncrypted('ntfy_server', 'https://ntfy.sh')->data; + $ntfyTopic = (string)Preferences::getEncrypted('ntfy_topic', '')->data; + $ntfyAuth = '1' === Preferences::get('ntfy_auth', false)->data; + $ntfyUser = Preferences::getEncrypted('ntfy_user', '')->data; + $ntfyPass = (string)Preferences::getEncrypted('ntfy_pass', '')->data; + $channels = config('notifications.channels'); + $forcedAvailability = []; + $anonymous = Steam::anonymous(); // notification preferences - $notifications = []; + $notifications = []; foreach (config('notifications.notifications.user') as $key => $info) { if (true === $info['enabled']) { $notifications[$key] = [ - 'enabled' => true === Preferences::get(sprintf('notification_%s', $key), true)->data, - 'configurable' => $info['configurable'], - ]; + 'enabled' => true === Preferences::get(sprintf('notification_%s', $key), true)->data, + 'configurable' => $info['configurable'], + ]; } } // loop all channels to see if they are available. @@ -164,7 +164,7 @@ class PreferencesController extends Controller Log::error($e->getMessage()); $locales = []; } - $locales = ['equal' => (string) trans('firefly.equal_to_language')] + $locales; + $locales = ['equal' => (string)trans('firefly.equal_to_language')] + $locales; // an important fallback is that the frontPageAccount array gets refilled automatically // when it turns up empty. if (0 === count($frontpageAccounts)) { @@ -184,7 +184,7 @@ class PreferencesController extends Controller $ntfyPass = ''; } - return view('preferences.index', ['language' => $language, 'pushoverAppToken' => $pushoverAppToken, 'pushoverUserToken' => $pushoverUserToken, 'ntfyServer' => $ntfyServer, 'ntfyTopic' => $ntfyTopic, 'ntfyAuth' => $ntfyAuth, 'channels' => $channels, 'ntfyUser' => $ntfyUser, 'forcedAvailability' => $forcedAvailability, 'ntfyPass' => $ntfyPass, 'groupedAccounts' => $groupedAccounts, 'isDocker' => $isDocker, 'frontpageAccounts' => $frontpageAccounts, 'languages' => $languages, 'darkMode' => $darkMode, 'availableDarkModes' => $availableDarkModes, 'notifications' => $notifications, 'convertToPrimary' => $convertToPrimary, 'slackUrl' => $slackUrl, 'locales' => $locales, 'locale' => $locale, 'tjOptionalFields' => $tjOptionalFields, 'viewRange' => $viewRange, 'customFiscalYear' => $customFiscalYear, 'listPageSize' => $listPageSize, 'fiscalYearStart' => $fiscalYearStart]); + return view('preferences.index', ['anonymous' => $anonymous, 'language' => $language, 'pushoverAppToken' => $pushoverAppToken, 'pushoverUserToken' => $pushoverUserToken, 'ntfyServer' => $ntfyServer, 'ntfyTopic' => $ntfyTopic, 'ntfyAuth' => $ntfyAuth, 'channels' => $channels, 'ntfyUser' => $ntfyUser, 'forcedAvailability' => $forcedAvailability, 'ntfyPass' => $ntfyPass, 'groupedAccounts' => $groupedAccounts, 'isDocker' => $isDocker, 'frontpageAccounts' => $frontpageAccounts, 'languages' => $languages, 'darkMode' => $darkMode, 'availableDarkModes' => $availableDarkModes, 'notifications' => $notifications, 'convertToPrimary' => $convertToPrimary, 'slackUrl' => $slackUrl, 'locales' => $locales, 'locale' => $locale, 'tjOptionalFields' => $tjOptionalFields, 'viewRange' => $viewRange, 'customFiscalYear' => $customFiscalYear, 'listPageSize' => $listPageSize, 'fiscalYearStart' => $fiscalYearStart]); } /** @@ -195,19 +195,19 @@ class PreferencesController extends Controller * @SuppressWarnings("PHPMD.ExcessiveMethodLength") * @SuppressWarnings("PHPMD.NPathComplexity") */ - public function postIndex(PreferencesRequest $request): Redirector|RedirectResponse + public function postIndex(PreferencesRequest $request): Redirector | RedirectResponse { // front page accounts $frontpageAccounts = []; if (is_array($request->get('frontpageAccounts')) && count($request->get('frontpageAccounts')) > 0) { foreach ($request->get('frontpageAccounts') as $id) { - $frontpageAccounts[] = (int) $id; + $frontpageAccounts[] = (int)$id; } Preferences::set('frontpageAccounts', $frontpageAccounts); } // extract notifications: - $all = $request->all(); + $all = $request->all(); foreach (config('notifications.notifications.user') as $key => $info) { $key = sprintf('notification_%s', $key); if (array_key_exists($key, $all)) { @@ -241,7 +241,7 @@ class PreferencesController extends Controller } // convert primary - $convertToPrimary = 1 === (int) $request->get('convertToPrimary'); + $convertToPrimary = 1 === (int)$request->get('convertToPrimary'); if ($convertToPrimary && !$this->convertToPrimary) { // set to true! Log::debug('User sets convertToPrimary to true.'); @@ -253,9 +253,9 @@ class PreferencesController extends Controller Preferences::set('convert_to_primary', $convertToPrimary); // custom fiscal year - $customFiscalYear = 1 === (int) $request->get('customFiscalYear'); + $customFiscalYear = 1 === (int)$request->get('customFiscalYear'); Preferences::set('customFiscalYear', $customFiscalYear); - $fiscalYearString = (string) $request->get('fiscalYearStart'); + $fiscalYearString = (string)$request->get('fiscalYearStart'); if ('' !== $fiscalYearString) { $fiscalYearStart = Carbon::parse($fiscalYearString, config('app.timezone'))->format('m-d'); Preferences::set('fiscalYearStart', $fiscalYearStart); @@ -263,15 +263,15 @@ class PreferencesController extends Controller // save page size: Preferences::set('listPageSize', 50); - $listPageSize = (int) $request->get('listPageSize'); + $listPageSize = (int)$request->get('listPageSize'); if ($listPageSize > 0 && $listPageSize < 1337) { Preferences::set('listPageSize', $listPageSize); } // language: /** @var Preference $currentLang */ - $currentLang = Preferences::get('language', 'en_US'); - $lang = $request->get('language'); + $currentLang = Preferences::get('language', 'en_US'); + $lang = $request->get('language'); if (array_key_exists($lang, config('firefly.languages'))) { Preferences::set('language', $lang); } @@ -282,14 +282,14 @@ class PreferencesController extends Controller // same for locale: if (!auth()->user()->hasRole('demo')) { - $locale = (string) $request->get('locale'); + $locale = (string)$request->get('locale'); $locale = '' === $locale ? null : $locale; Preferences::set('locale', $locale); } // optional fields for transactions: - $setOptions = $request->get('tj') ?? []; - $optionalTj = [ + $setOptions = $request->get('tj') ?? []; + $optionalTj = [ 'interest_date' => array_key_exists('interest_date', $setOptions), 'book_date' => array_key_exists('book_date', $setOptions), 'process_date' => array_key_exists('process_date', $setOptions), @@ -306,12 +306,17 @@ class PreferencesController extends Controller Preferences::set('transaction_journal_optional_fields', $optionalTj); // dark mode - $darkMode = $request->get('darkMode') ?? 'browser'; + $darkMode = $request->get('darkMode') ?? 'browser'; if (in_array($darkMode, config('firefly.available_dark_modes'), true)) { Preferences::set('darkMode', $darkMode); } - session()->flash('success', (string) trans('firefly.saved_preferences')); + // anonymous amounts? + $anonymous = '1' === $request->get('anonymous'); + Preferences::set('anonymous', $anonymous); + + // save and continue + session()->flash('success', (string)trans('firefly.saved_preferences')); Preferences::mark(); return redirect(route('preferences.index')); @@ -325,7 +330,7 @@ class PreferencesController extends Controller switch ($channel) { default: - session()->flash('error', (string) trans('firefly.notification_test_failed', ['channel' => $channel])); + session()->flash('error', (string)trans('firefly.notification_test_failed', ['channel' => $channel])); break; @@ -337,7 +342,7 @@ class PreferencesController extends Controller $user = auth()->user(); Log::debug(sprintf('Now in testNotification("%s") controller.', $channel)); event(new UserTestNotificationChannel($channel, $user)); - session()->flash('success', (string) trans('firefly.notification_test_executed', ['channel' => $channel])); + session()->flash('success', (string)trans('firefly.notification_test_executed', ['channel' => $channel])); } return ''; diff --git a/resources/lang/en_US/firefly.php b/resources/lang/en_US/firefly.php index a26b76a875..fd9fd32d9a 100644 --- a/resources/lang/en_US/firefly.php +++ b/resources/lang/en_US/firefly.php @@ -149,6 +149,9 @@ return [ 'left_in_budget_limit' => 'Left to spend according to budgeting', 'current_period' => 'Current period', 'show_the_current_period_and_overview' => 'Show the current period and overview', + 'pref_anonymous' => 'Hidden amounts', + 'pref_anonymous_help' => 'For privacy and anonymity, you can make Firefly III hide all amounts. This will not hide amounts in edit boxes, but the rest are hidden. You can also toggle this with the little "eye"-icon in the top bar.', + 'pref_anonymous_label' => 'Hide amounts', 'pref_languages_locale' => 'For a language other than English to work properly, your operating system must be equipped with the correct locale-information. If these are not present, currency data, dates and amounts may be formatted wrong.', 'budget_in_period' => 'All transactions for budget ":name" between :start and :end in :currency', 'chart_budget_in_period' => 'Chart for all transactions for budget ":name" between :start and :end in :currency', diff --git a/resources/views/preferences/index.twig b/resources/views/preferences/index.twig index 4316a7c390..f35aad6987 100644 --- a/resources/views/preferences/index.twig +++ b/resources/views/preferences/index.twig @@ -110,6 +110,14 @@ {{ ExpandedForm.checkbox('convertToPrimary','1',convertToPrimary,{ 'label' : 'pref_convert_primary_help'|_ }) }} {% endif %} + {# conversion back to primary currency #} +
+

{{ 'pref_anonymous'|_ }}

+

+ {{ 'pref_anonymous_help'|_ }} +

+ {{ ExpandedForm.checkbox('anonymous','1',anonymous,{ 'label' : 'pref_anonymous_label'|_ }) }} +
{# general settings column B #}