diff --git a/.env b/.env index 2b0260c6..ae2d1e07 100644 --- a/.env +++ b/.env @@ -32,11 +32,11 @@ DATABASE_EMULATE_NATURAL_SORT=0 ################################################################################### # The language to use serverwide as default (en, de, ru, etc.) -DEFAULT_LANG="en" +#DEFAULT_LANG="en" # The default timezone to use serverwide (e.g. Europe/Berlin) -DEFAULT_TIMEZONE="Europe/Berlin" +#DEFAULT_TIMEZONE="Europe/Berlin" # The currency that is used inside the DB (and is assumed when no currency is set). This can not be changed later, so be sure to set it the currency used in your country -BASE_CURRENCY="EUR" +#BASE_CURRENCY="EUR" # The public reachable URL of this Part-DB installation. This is used for generating links in SAML and email templates # This must end with a slash! diff --git a/config/packages/translation.yaml b/config/packages/translation.yaml index 7266a176..cbc1cd7e 100644 --- a/config/packages/translation.yaml +++ b/config/packages/translation.yaml @@ -1,11 +1,10 @@ framework: - default_locale: '%partdb.locale%' + default_locale: 'en' # Just enable the locales we need for performance reasons. enabled_locale: '%partdb.locale_menu%' translator: default_path: '%kernel.project_dir%/translations' fallbacks: - - '%partdb.locale%' - 'en' providers: # crowdin: diff --git a/config/packages/twig.yaml b/config/packages/twig.yaml index d04a93e6..3f1e94fb 100644 --- a/config/packages/twig.yaml +++ b/config/packages/twig.yaml @@ -6,7 +6,6 @@ twig: '%kernel.project_dir%/assets/css': css globals: - default_currency: '%partdb.default_currency%' allow_email_pw_reset: '%partdb.users.email_pw_reset%' locale_menu: '%partdb.locale_menu%' attachment_manager: '@App\Services\Attachments\AttachmentManager' diff --git a/config/parameters.yaml b/config/parameters.yaml index a3d66202..a266e1a4 100644 --- a/config/parameters.yaml +++ b/config/parameters.yaml @@ -5,12 +5,9 @@ parameters: ###################################################################################################################### # Common ###################################################################################################################### - partdb.locale: '%env(string:DEFAULT_LANG)%' # The default language to use serverwide - partdb.timezone: '%env(string:DEFAULT_TIMEZONE)%' # The default timezone # This is used as workaround for places where we can not access the settings directly (like the 2FA application names) partdb.title: '%env(string:settings:customization:instanceName)%' # The title shown inside of Part-DB (e.g. in the navbar and on homepage) - partdb.default_currency: '%env(string:BASE_CURRENCY)%' # The currency that is used inside the DB (and is assumed when no currency is set). This can not be changed later, so be sure to set it the currency used in your country partdb.locale_menu: ['en', 'de', 'it', 'fr', 'ru', 'ja', 'cs', 'da', 'zh'] # The languages that are shown in user drop down menu partdb.default_uri: '%env(string:DEFAULT_URI)%' # The default URI to use for the Part-DB instance (e.g. https://part-db.example.com/). This is used for generating links in emails @@ -103,11 +100,6 @@ parameters: # Env default values ###################################################################################################################### - env(DEFAULT_LANG): 'en' - env(DEFAULT_TIMEZONE): 'Europe/Berlin' - env(INSTANCE_NAME): 'Part-DB' - env(BASE_CURRENCY): 'EUR' - env(REDIRECT_TO_HTTPS): 0 env(ERROR_PAGE_ADMIN_EMAIL): '' diff --git a/config/services.yaml b/config/services.yaml index 2f4f08e9..5deeef34 100644 --- a/config/services.yaml +++ b/config/services.yaml @@ -17,7 +17,6 @@ services: bool $gdpr_compliance: '%partdb.gdpr_compliance%' bool $kernel_debug_enabled: '%kernel.debug%' string $kernel_cache_dir: '%kernel.cache_dir%' - string $base_currency: '%partdb.default_currency%' _instanceof: App\Services\LabelSystem\PlaceholderProviders\PlaceholderProviderInterface: @@ -137,29 +136,6 @@ services: tags: - { name: doctrine.orm.entity_listener } - #################################################################################################################### - # Price system - #################################################################################################################### - App\Command\Currencies\UpdateExchangeRatesCommand: - arguments: - $base_current: '%partdb.default_currency%' - - App\Form\Type\CurrencyEntityType: - arguments: - $base_currency: '%partdb.default_currency%' - - App\Services\Parts\PricedetailHelper: - arguments: - $base_currency: '%partdb.default_currency%' - - App\Services\Formatters\MoneyFormatter: - arguments: - $base_currency: '%partdb.default_currency%' - - App\Services\Tools\ExchangeRateUpdater: - arguments: - $base_currency: '%partdb.default_currency%' - ################################################################################################################### # User system #################################################################################################################### @@ -167,10 +143,6 @@ services: arguments: $demo_mode: '%partdb.demo_mode%' - App\EventSubscriber\UserSystem\SetUserTimezoneSubscriber: - arguments: - $default_timezone: '%partdb.timezone%' - App\Controller\SecurityController: arguments: $allow_email_pw_reset: '%partdb.users.email_pw_reset%' @@ -261,8 +233,6 @@ services: App\State\PartDBInfoProvider: arguments: $default_uri: '%partdb.default_uri%' - $global_locale: '%partdb.locale%' - $global_timezone: '%partdb.timezone%' #################################################################################################################### # EDA system @@ -294,7 +264,6 @@ services: #################################################################################################################### App\Controller\RedirectController: arguments: - $default_locale: '%partdb.locale%' $enforce_index_php: '%env(bool:NO_URL_REWRITE_AVAILABLE)%' App\Doctrine\Purger\ResetAutoIncrementPurgerFactory: diff --git a/src/Command/Currencies/UpdateExchangeRatesCommand.php b/src/Command/Currencies/UpdateExchangeRatesCommand.php index 0f3eb11f..2c1f5f92 100644 --- a/src/Command/Currencies/UpdateExchangeRatesCommand.php +++ b/src/Command/Currencies/UpdateExchangeRatesCommand.php @@ -22,6 +22,7 @@ declare(strict_types=1); namespace App\Command\Currencies; +use App\Settings\SystemSettings\LocalizationSettings; use Symfony\Component\Console\Attribute\AsCommand; use App\Entity\PriceInformations\Currency; use App\Services\Tools\ExchangeRateUpdater; @@ -39,7 +40,7 @@ use function strlen; #[AsCommand('partdb:currencies:update-exchange-rates|partdb:update-exchange-rates|app:update-exchange-rates', 'Updates the currency exchange rates.')] class UpdateExchangeRatesCommand extends Command { - public function __construct(protected string $base_current, protected EntityManagerInterface $em, protected ExchangeRateUpdater $exchangeRateUpdater) + public function __construct(protected EntityManagerInterface $em, protected ExchangeRateUpdater $exchangeRateUpdater, private readonly LocalizationSettings $localizationSettings) { parent::__construct(); } @@ -54,13 +55,13 @@ class UpdateExchangeRatesCommand extends Command $io = new SymfonyStyle($input, $output); //Check for valid base current - if (3 !== strlen($this->base_current)) { + if (3 !== strlen($this->localizationSettings->baseCurrency)) { $io->error('Chosen Base current is not valid. Check your settings!'); return Command::FAILURE; } - $io->note('Update currency exchange rates with base currency: '.$this->base_current); + $io->note('Update currency exchange rates with base currency: '.$this->localizationSettings->baseCurrency); //Check what currencies we need to update: $iso_code = $input->getArgument('iso_code'); diff --git a/src/Controller/RedirectController.php b/src/Controller/RedirectController.php index 65bd78f5..a4cac3aa 100644 --- a/src/Controller/RedirectController.php +++ b/src/Controller/RedirectController.php @@ -23,6 +23,7 @@ declare(strict_types=1); namespace App\Controller; use App\Entity\UserSystem\User; +use App\Settings\SystemSettings\LocalizationSettings; use function function_exists; use function in_array; use Symfony\Bundle\FrameworkBundle\Controller\AbstractController; @@ -35,7 +36,7 @@ use Symfony\Contracts\Translation\TranslatorInterface; */ class RedirectController extends AbstractController { - public function __construct(protected string $default_locale, protected TranslatorInterface $translator, protected bool $enforce_index_php) + public function __construct(private readonly LocalizationSettings $localizationSettings, protected TranslatorInterface $translator, protected bool $enforce_index_php) { } @@ -46,7 +47,7 @@ class RedirectController extends AbstractController public function addLocalePart(Request $request): RedirectResponse { //By default, we use the global default locale - $locale = $this->default_locale; + $locale = $this->localizationSettings->locale; //Check if a user has set a preferred language setting: $user = $this->getUser(); diff --git a/src/Entity/UserSystem/User.php b/src/Entity/UserSystem/User.php index b26a842d..04cd14fb 100644 --- a/src/Entity/UserSystem/User.php +++ b/src/Entity/UserSystem/User.php @@ -197,7 +197,7 @@ class User extends AttachmentContainingDBElement implements UserInterface, HasPe /** * @var string|null The language/locale the user prefers */ - #[Assert\Language] + #[Assert\Locale] #[Groups(['full', 'import', 'user:read'])] #[ORM\Column(name: 'config_language', type: Types::STRING, nullable: true)] protected ?string $language = ''; diff --git a/src/EventSubscriber/UserSystem/SetUserTimezoneSubscriber.php b/src/EventSubscriber/UserSystem/SetUserTimezoneSubscriber.php index 10ecaddf..35e36375 100644 --- a/src/EventSubscriber/UserSystem/SetUserTimezoneSubscriber.php +++ b/src/EventSubscriber/UserSystem/SetUserTimezoneSubscriber.php @@ -23,6 +23,7 @@ declare(strict_types=1); namespace App\EventSubscriber\UserSystem; use App\Entity\UserSystem\User; +use App\Settings\SystemSettings\LocalizationSettings; use Symfony\Bundle\SecurityBundle\Security; use Symfony\Component\EventDispatcher\EventSubscriberInterface; use Symfony\Component\HttpKernel\Event\ControllerEvent; @@ -33,7 +34,7 @@ use Symfony\Component\HttpKernel\KernelEvents; */ final class SetUserTimezoneSubscriber implements EventSubscriberInterface { - public function __construct(private readonly string $default_timezone, private readonly Security $security) + public function __construct(private readonly LocalizationSettings $localizationSettings, private readonly Security $security) { } @@ -48,8 +49,8 @@ final class SetUserTimezoneSubscriber implements EventSubscriberInterface } //Fill with default value if needed - if (null === $timezone && $this->default_timezone !== '') { - $timezone = $this->default_timezone; + if (null === $timezone && $this->localizationSettings !== '') { + $timezone = $this->localizationSettings->timezone; } //If timezone was configured anywhere set it, otherwise just use the one from php.ini diff --git a/src/Form/AdminPages/CurrencyAdminForm.php b/src/Form/AdminPages/CurrencyAdminForm.php index 0fab055d..afcf3c1f 100644 --- a/src/Form/AdminPages/CurrencyAdminForm.php +++ b/src/Form/AdminPages/CurrencyAdminForm.php @@ -22,6 +22,7 @@ declare(strict_types=1); namespace App\Form\AdminPages; +use App\Settings\SystemSettings\LocalizationSettings; use Symfony\Bundle\SecurityBundle\Security; use App\Entity\Base\AbstractNamedDBElement; use App\Form\Type\BigDecimalMoneyType; @@ -32,7 +33,7 @@ use Symfony\Component\Form\FormBuilderInterface; class CurrencyAdminForm extends BaseEntityAdminForm { - public function __construct(Security $security, EventCommentNeededHelper $eventCommentNeededHelper, private readonly string $base_currency) + public function __construct(Security $security, EventCommentNeededHelper $eventCommentNeededHelper, private readonly LocalizationSettings $localizationSettings) { parent::__construct($security, $eventCommentNeededHelper); } @@ -51,7 +52,7 @@ class CurrencyAdminForm extends BaseEntityAdminForm $builder->add('exchange_rate', BigDecimalMoneyType::class, [ 'required' => false, 'label' => 'currency.edit.exchange_rate', - 'currency' => $this->base_currency, + 'currency' => $this->localizationSettings->baseCurrency, 'scale' => 6, 'disabled' => !$this->security->isGranted($is_new ? 'create' : 'edit', $entity), ]); diff --git a/src/Form/AdminPages/SupplierForm.php b/src/Form/AdminPages/SupplierForm.php index 34b3b27a..43ac0616 100644 --- a/src/Form/AdminPages/SupplierForm.php +++ b/src/Form/AdminPages/SupplierForm.php @@ -22,6 +22,7 @@ declare(strict_types=1); namespace App\Form\AdminPages; +use App\Settings\SystemSettings\LocalizationSettings; use Symfony\Bundle\SecurityBundle\Security; use App\Entity\Base\AbstractNamedDBElement; use App\Entity\PriceInformations\Currency; @@ -32,7 +33,7 @@ use Symfony\Component\Form\FormBuilderInterface; class SupplierForm extends CompanyForm { - public function __construct(Security $security, EventCommentNeededHelper $eventCommentNeededHelper, protected string $base_currency) + public function __construct(Security $security, EventCommentNeededHelper $eventCommentNeededHelper, private readonly LocalizationSettings $localizationSettings) { parent::__construct($security, $eventCommentNeededHelper); } @@ -53,7 +54,7 @@ class SupplierForm extends CompanyForm $builder->add('shipping_costs', BigDecimalMoneyType::class, [ 'required' => false, - 'currency' => $this->base_currency, + 'currency' => $this->localizationSettings->baseCurrency, 'scale' => 3, 'label' => 'supplier.shipping_costs.label', 'disabled' => !$this->security->isGranted($is_new ? 'create' : 'edit', $entity), diff --git a/src/Form/Type/CurrencyEntityType.php b/src/Form/Type/CurrencyEntityType.php index 07f0a9f8..875ca35f 100644 --- a/src/Form/Type/CurrencyEntityType.php +++ b/src/Form/Type/CurrencyEntityType.php @@ -25,6 +25,7 @@ namespace App\Form\Type; use App\Entity\PriceInformations\Currency; use App\Form\Type\Helper\StructuralEntityChoiceHelper; use App\Services\Trees\NodesListBuilder; +use App\Settings\SystemSettings\LocalizationSettings; use Doctrine\ORM\EntityManagerInterface; use Symfony\Component\Intl\Currencies; use Symfony\Component\OptionsResolver\Options; @@ -36,7 +37,7 @@ use Symfony\Contracts\Translation\TranslatorInterface; */ class CurrencyEntityType extends StructuralEntityType { - public function __construct(EntityManagerInterface $em, NodesListBuilder $builder, TranslatorInterface $translator, StructuralEntityChoiceHelper $choiceHelper, protected ?string $base_currency) + public function __construct(EntityManagerInterface $em, NodesListBuilder $builder, TranslatorInterface $translator, StructuralEntityChoiceHelper $choiceHelper, private readonly LocalizationSettings $localizationSettings) { parent::__construct($em, $builder, $translator, $choiceHelper); } @@ -57,7 +58,7 @@ class CurrencyEntityType extends StructuralEntityType $resolver->setDefault('empty_message', function (Options $options) { //By default, we use the global base currency: - $iso_code = $this->base_currency; + $iso_code = $this->localizationSettings->baseCurrency; if ($options['base_currency']) { //Allow to override it $iso_code = $options['base_currency']; diff --git a/src/Form/Type/LocaleSelectType.php b/src/Form/Type/LocaleSelectType.php new file mode 100644 index 00000000..aa7af5c2 --- /dev/null +++ b/src/Form/Type/LocaleSelectType.php @@ -0,0 +1,53 @@ +. + */ + +declare(strict_types=1); + + +namespace App\Form\Type; + +use Symfony\Component\DependencyInjection\Attribute\Autowire; +use Symfony\Component\Form\AbstractType; +use Symfony\Component\Form\Extension\Core\Type\LocaleType; +use Symfony\Component\OptionsResolver\OptionsResolver; + +/** + * A locale select field that uses the preferred languages from the configuration. + + */ +class LocaleSelectType extends AbstractType +{ + + public function __construct(#[Autowire(param: 'partdb.locale_menu')] private readonly array $preferred_languages) + { + + } + public function getParent(): string + { + return LocaleType::class; + } + + public function configureOptions(OptionsResolver $resolver) + { + $resolver->setDefaults([ + 'preferred_choices' => $this->preferred_languages, + ]); + } +} \ No newline at end of file diff --git a/src/Form/UserAdminForm.php b/src/Form/UserAdminForm.php index d1e5924e..d4a71ff4 100644 --- a/src/Form/UserAdminForm.php +++ b/src/Form/UserAdminForm.php @@ -22,6 +22,7 @@ declare(strict_types=1); namespace App\Form; +use App\Form\Type\LocaleSelectType; use Symfony\Bundle\SecurityBundle\Security; use App\Entity\Base\AbstractNamedDBElement; use App\Entity\UserSystem\Group; @@ -35,7 +36,6 @@ use App\Form\Type\ThemeChoiceType; use Symfony\Component\Form\AbstractType; use Symfony\Component\Form\Extension\Core\Type\CheckboxType; use Symfony\Component\Form\Extension\Core\Type\CollectionType; -use Symfony\Component\Form\Extension\Core\Type\LanguageType; use Symfony\Component\Form\Extension\Core\Type\PasswordType; use Symfony\Component\Form\Extension\Core\Type\RepeatedType; use Symfony\Component\Form\Extension\Core\Type\ResetType; @@ -138,11 +138,10 @@ class UserAdminForm extends AbstractType ]) //Config section - ->add('language', LanguageType::class, [ + ->add('language', LocaleSelectType::class, [ 'required' => false, 'placeholder' => 'user_settings.language.placeholder', 'label' => 'user.language_select', - 'preferred_choices' => ['en', 'de'], 'disabled' => !$this->security->isGranted('change_user_settings', $entity), ]) ->add('timezone', TimezoneType::class, [ diff --git a/src/Form/UserSettingsType.php b/src/Form/UserSettingsType.php index 05f63df4..0c7cb169 100644 --- a/src/Form/UserSettingsType.php +++ b/src/Form/UserSettingsType.php @@ -22,6 +22,7 @@ declare(strict_types=1); namespace App\Form; +use App\Form\Type\LocaleSelectType; use Symfony\Bundle\SecurityBundle\Security; use App\Entity\UserSystem\User; use App\Form\Type\CurrencyEntityType; @@ -33,7 +34,6 @@ use Symfony\Component\Form\Event\PreSetDataEvent; use Symfony\Component\Form\Extension\Core\Type\CheckboxType; use Symfony\Component\Form\Extension\Core\Type\EmailType; use Symfony\Component\Form\Extension\Core\Type\FileType; -use Symfony\Component\Form\Extension\Core\Type\LanguageType; use Symfony\Component\Form\Extension\Core\Type\ResetType; use Symfony\Component\Form\Extension\Core\Type\SubmitType; use Symfony\Component\Form\Extension\Core\Type\TextType; @@ -47,7 +47,7 @@ class UserSettingsType extends AbstractType { public function __construct(protected Security $security, protected bool $demo_mode, - #[Autowire(param: 'partdb.locale_menu')] private readonly array $preferred_languages) + ) { } @@ -107,12 +107,11 @@ class UserSettingsType extends AbstractType 'mode' => 'markdown-full', 'disabled' => !$this->security->isGranted('edit_infos', $options['data']) || $this->demo_mode, ]) - ->add('language', LanguageType::class, [ + ->add('language', LocaleSelectType::class, [ 'disabled' => $this->demo_mode, 'required' => false, 'placeholder' => 'user_settings.language.placeholder', 'label' => 'user.language_select', - 'preferred_choices' => $this->preferred_languages, ]) ->add('timezone', TimezoneType::class, [ 'disabled' => $this->demo_mode, diff --git a/src/Services/Formatters/MoneyFormatter.php b/src/Services/Formatters/MoneyFormatter.php index d49b77cf..f6647acf 100644 --- a/src/Services/Formatters/MoneyFormatter.php +++ b/src/Services/Formatters/MoneyFormatter.php @@ -23,6 +23,7 @@ declare(strict_types=1); namespace App\Services\Formatters; use App\Entity\PriceInformations\Currency; +use App\Settings\SystemSettings\LocalizationSettings; use Locale; use NumberFormatter; @@ -30,7 +31,7 @@ class MoneyFormatter { protected string $locale; - public function __construct(protected string $base_currency) + public function __construct(private readonly LocalizationSettings $localizationSettings) { $this->locale = Locale::getDefault(); } @@ -45,7 +46,7 @@ class MoneyFormatter */ public function format(string|float $value, ?Currency $currency = null, int $decimals = 5, bool $show_all_digits = false): string { - $iso_code = $this->base_currency; + $iso_code = $this->localizationSettings->baseCurrency; if ($currency instanceof Currency && ($currency->getIsoCode() !== null && $currency->getIsoCode() !== '')) { $iso_code = $currency->getIsoCode(); } diff --git a/src/Services/ImportExportSystem/PartKeeprImporter/PKPartImporter.php b/src/Services/ImportExportSystem/PartKeeprImporter/PKPartImporter.php index 9dd67233..80c2dbf7 100644 --- a/src/Services/ImportExportSystem/PartKeeprImporter/PKPartImporter.php +++ b/src/Services/ImportExportSystem/PartKeeprImporter/PKPartImporter.php @@ -35,6 +35,7 @@ use App\Entity\Parts\Supplier; use App\Entity\PriceInformations\Currency; use App\Entity\PriceInformations\Orderdetail; use App\Entity\PriceInformations\Pricedetail; +use App\Settings\SystemSettings\LocalizationSettings; use Brick\Math\BigDecimal; use Doctrine\ORM\EntityManagerInterface; use Symfony\Component\Intl\Currencies; @@ -47,7 +48,7 @@ class PKPartImporter { use PKImportHelperTrait; - public function __construct(EntityManagerInterface $em, PropertyAccessorInterface $propertyAccessor, private readonly string $base_currency) + public function __construct(EntityManagerInterface $em, PropertyAccessorInterface $propertyAccessor, private readonly LocalizationSettings $localizationSettings) { $this->em = $em; $this->propertyAccessor = $propertyAccessor; @@ -210,7 +211,7 @@ class PKPartImporter $currency_iso_code = strtoupper($currency_iso_code); //We do not have a currency for the base currency to be consistent with prices without currencies - if ($currency_iso_code === $this->base_currency) { + if ($currency_iso_code === $this->localizationSettings->baseCurrency) { return null; } diff --git a/src/Services/InfoProviderSystem/DTOtoEntityConverter.php b/src/Services/InfoProviderSystem/DTOtoEntityConverter.php index 2c2b4076..42a95406 100644 --- a/src/Services/InfoProviderSystem/DTOtoEntityConverter.php +++ b/src/Services/InfoProviderSystem/DTOtoEntityConverter.php @@ -41,6 +41,7 @@ use App\Services\InfoProviderSystem\DTOs\ParameterDTO; use App\Services\InfoProviderSystem\DTOs\PartDetailDTO; use App\Services\InfoProviderSystem\DTOs\PriceDTO; use App\Services\InfoProviderSystem\DTOs\PurchaseInfoDTO; +use App\Settings\SystemSettings\LocalizationSettings; use Doctrine\ORM\EntityManagerInterface; /** @@ -52,8 +53,11 @@ final class DTOtoEntityConverter private const TYPE_DATASHEETS_NAME = 'Datasheet'; private const TYPE_IMAGE_NAME = 'Image'; - public function __construct(private readonly EntityManagerInterface $em, private readonly string $base_currency) + private readonly string $base_currency; + + public function __construct(private readonly EntityManagerInterface $em, LocalizationSettings $localizationSettings) { + $this->base_currency = $localizationSettings->baseCurrency; } /** diff --git a/src/Services/Parts/PricedetailHelper.php b/src/Services/Parts/PricedetailHelper.php index 092cc278..b2e1340f 100644 --- a/src/Services/Parts/PricedetailHelper.php +++ b/src/Services/Parts/PricedetailHelper.php @@ -25,6 +25,7 @@ namespace App\Services\Parts; use App\Entity\Parts\Part; use App\Entity\PriceInformations\Currency; use App\Entity\PriceInformations\Pricedetail; +use App\Settings\SystemSettings\LocalizationSettings; use Brick\Math\BigDecimal; use Brick\Math\RoundingMode; use Doctrine\ORM\PersistentCollection; @@ -39,7 +40,7 @@ class PricedetailHelper { protected string $locale; - public function __construct(protected string $base_currency) + public function __construct() { $this->locale = Locale::getDefault(); } diff --git a/src/Services/Tools/ExchangeRateUpdater.php b/src/Services/Tools/ExchangeRateUpdater.php index eac6de16..7c14b16f 100644 --- a/src/Services/Tools/ExchangeRateUpdater.php +++ b/src/Services/Tools/ExchangeRateUpdater.php @@ -23,13 +23,14 @@ declare(strict_types=1); namespace App\Services\Tools; use App\Entity\PriceInformations\Currency; +use App\Settings\SystemSettings\LocalizationSettings; use Brick\Math\BigDecimal; use Brick\Math\RoundingMode; use Swap\Swap; class ExchangeRateUpdater { - public function __construct(private readonly string $base_currency, private readonly Swap $swap) + public function __construct(private LocalizationSettings $localizationSettings, private readonly Swap $swap) { } @@ -39,7 +40,7 @@ class ExchangeRateUpdater public function update(Currency $currency): Currency { //Currency pairs are always in the format "BASE/QUOTE" - $rate = $this->swap->latest($this->base_currency.'/'.$currency->getIsoCode()); + $rate = $this->swap->latest($this->localizationSettings->baseCurrency.'/'.$currency->getIsoCode()); //The rate says how many quote units are worth one base unit //So we need to invert it to get the exchange rate diff --git a/src/Settings/SystemSettings.php b/src/Settings/SystemSettings.php index 38dce049..83d00afc 100644 --- a/src/Settings/SystemSettings.php +++ b/src/Settings/SystemSettings.php @@ -26,6 +26,7 @@ namespace App\Settings; use App\Settings\SystemSettings\AttachmentsSettings; use App\Settings\SystemSettings\CustomizationSettings; use App\Settings\SystemSettings\HistorySettings; +use App\Settings\SystemSettings\LocalizationSettings; use App\Settings\SystemSettings\PrivacySettings; use Jbtronics\SettingsBundle\Settings\EmbeddedSettings; use Jbtronics\SettingsBundle\Settings\Settings; @@ -33,6 +34,9 @@ use Jbtronics\SettingsBundle\Settings\Settings; #[Settings] class SystemSettings { + #[EmbeddedSettings()] + public ?LocalizationSettings $localization = null; + #[EmbeddedSettings()] public ?CustomizationSettings $customization = null; diff --git a/src/Settings/SystemSettings/HistorySettings.php b/src/Settings/SystemSettings/HistorySettings.php index 4208cb73..5c50df78 100644 --- a/src/Settings/SystemSettings/HistorySettings.php +++ b/src/Settings/SystemSettings/HistorySettings.php @@ -30,11 +30,14 @@ use Jbtronics\SettingsBundle\ParameterTypes\ArrayType; use Jbtronics\SettingsBundle\ParameterTypes\EnumType; use Jbtronics\SettingsBundle\Settings\Settings; use Jbtronics\SettingsBundle\Settings\SettingsParameter; +use Jbtronics\SettingsBundle\Settings\SettingsTrait; use Symfony\Component\Translation\TranslatableMessage as TM; #[Settings(label: new TM("settings.system.history"))] class HistorySettings { + use SettingsTrait; + #[SettingsParameter( label: new TM("settings.system.history.saveChangedFields"), envVar: "bool:HISTORY_SAVE_CHANGED_FIELDS", envVarMode: EnvVarMode::OVERWRITE)] diff --git a/src/Settings/SystemSettings/LocalizationSettings.php b/src/Settings/SystemSettings/LocalizationSettings.php new file mode 100644 index 00000000..d4820a41 --- /dev/null +++ b/src/Settings/SystemSettings/LocalizationSettings.php @@ -0,0 +1,61 @@ +. + */ + +declare(strict_types=1); + + +namespace App\Settings\SystemSettings; + +use App\Form\Type\LocaleSelectType; +use Jbtronics\SettingsBundle\Metadata\EnvVarMode; +use Jbtronics\SettingsBundle\Settings\Settings; +use Jbtronics\SettingsBundle\Settings\SettingsParameter; +use Jbtronics\SettingsBundle\Settings\SettingsTrait; +use Symfony\Component\Form\Extension\Core\Type\CurrencyType; +use Symfony\Component\Form\Extension\Core\Type\TimezoneType; +use Symfony\Component\Translation\TranslatableMessage as TM; +use Symfony\Component\Validator\Constraints as Assert; + +#[Settings(label: new TM("settings.system.localization"))] +class LocalizationSettings +{ + use SettingsTrait; + + #[Assert\Locale()] + #[Assert\NotBlank()] + #[SettingsParameter(label: new TM("settings.system.localization.locale"), formType: LocaleSelectType::class, + envVar: "string:DEFAULT_LANG", envVarMode: EnvVarMode::OVERWRITE)] + public string $locale = 'en'; + + #[Assert\Timezone()] + #[Assert\NotBlank()] + #[SettingsParameter(label: new TM("settings.system.localization.timezone"), formType: TimezoneType::class, + envVar: "string:DEFAULT_TIMEZONE", envVarMode: EnvVarMode::OVERWRITE)] + public string $timezone = 'Europe/Berlin'; + + #[Assert\Currency()] + #[Assert\NotBlank()] + #[SettingsParameter(label: new TM("settings.system.localization.base_currency"), + description: new TM("settings.system.localization.base_currency_description"), + formType: CurrencyType::class, formOptions: ['preferred_choices' => ['EUR', 'USD', 'GBP', "JPY", "CNY"], 'help_html' => true], + envVar: "string:BASE_CURRENCY", envVarMode: EnvVarMode::OVERWRITE + )] + public string $baseCurrency = 'EUR'; +} \ No newline at end of file diff --git a/src/Settings/SystemSettings/PrivacySettings.php b/src/Settings/SystemSettings/PrivacySettings.php index 3bdb7489..1686326e 100644 --- a/src/Settings/SystemSettings/PrivacySettings.php +++ b/src/Settings/SystemSettings/PrivacySettings.php @@ -29,7 +29,7 @@ use Jbtronics\SettingsBundle\Settings\SettingsParameter; use Jbtronics\SettingsBundle\Settings\SettingsTrait; use Symfony\Component\Translation\TranslatableMessage as TM; -#[Settings] +#[Settings(label: new TM("settings.system.privacy"))] class PrivacySettings { use SettingsTrait; diff --git a/src/State/PartDBInfoProvider.php b/src/State/PartDBInfoProvider.php index 029327b7..b3496cad 100644 --- a/src/State/PartDBInfoProvider.php +++ b/src/State/PartDBInfoProvider.php @@ -10,6 +10,7 @@ use App\ApiResource\PartDBInfo; use App\Services\Misc\GitVersionInfo; use App\Services\System\BannerHelper; use App\Settings\SystemSettings\CustomizationSettings; +use App\Settings\SystemSettings\LocalizationSettings; use Shivas\VersioningBundle\Service\VersionManagerInterface; class PartDBInfoProvider implements ProviderInterface @@ -17,11 +18,9 @@ class PartDBInfoProvider implements ProviderInterface public function __construct(private readonly VersionManagerInterface $versionManager, private readonly GitVersionInfo $gitVersionInfo, - private readonly string $base_currency, private readonly BannerHelper $bannerHelper, private readonly string $default_uri, - private readonly string $global_timezone, - private readonly string $global_locale, + private readonly LocalizationSettings $localizationSettings, private readonly CustomizationSettings $customizationSettings, ) { @@ -37,9 +36,9 @@ class PartDBInfoProvider implements ProviderInterface title: $this->customizationSettings->instanceName, banner: $this->bannerHelper->getBanner(), default_uri: $this->default_uri, - global_timezone: $this->global_timezone, - base_currency: $this->base_currency, - global_locale: $this->global_locale, + global_timezone: $this->localizationSettings->timezone, + base_currency: $this->localizationSettings->baseCurrency, + global_locale: $this->localizationSettings->locale, ); } } diff --git a/translations/messages.en.xlf b/translations/messages.en.xlf index 32c2d7e5..4e16b96d 100644 --- a/translations/messages.en.xlf +++ b/translations/messages.en.xlf @@ -12551,5 +12551,42 @@ Please note, that you can not impersonate a disabled user. If you try you will g Part-DB regularly checks if a new version is available on GitHub. Disable this here, if you do not want this or if your server can not connect to the internet. + + + settings.system.localization.locale + Default language / locale + + + + + settings.system.localization + Localization + + + + + settings.system.localization.timezone + Default timezone + + + + + settings.system.localization.base_currency + Base currency + + + + + settings.system.localization.base_currency_description + Please note that the currencies are not converted, when changing this value. So changing the default currency after you already added price information, will result in wrong prices!]]> + + + + + settings.system.privacy + Privacy + + diff --git a/translations/validators.en.xlf b/translations/validators.en.xlf index 15f61196..c7ef9701 100644 --- a/translations/validators.en.xlf +++ b/translations/validators.en.xlf @@ -354,7 +354,7 @@ - + validator.invalid_range The given range is not valid!