diff --git a/config/packages/kimai.yaml b/config/packages/kimai.yaml
index 8e5e9565..6455de82 100644
--- a/config/packages/kimai.yaml
+++ b/config/packages/kimai.yaml
@@ -283,6 +283,10 @@ kimai:
# timezone: Europe/Berlin
# country: DE
# currency: EUR
+# user:
+# timezone: Europe/Berlin
+# language: de
+# theme: blue-light
# --------------------------------------------------------------------------------
@@ -293,12 +297,3 @@ kimai:
data_dir: '%kernel.project_dir%/var/data'
plugin_dir: '%kernel.project_dir%/var/plugins'
# --------------------------------------------------------------------------------
-
-
-# --------------------------------------------------------------------------------
-# LDAP
-# Connect to your companies directory server, see https://www.kimai.org/documentation/ldap.html
-# --------------------------------------------------------------------------------
-# ldap:
-# active: true
-# --------------------------------------------------------------------------------
diff --git a/src/Configuration/FormConfiguration.php b/src/Configuration/FormConfiguration.php
index 80be2470..95d54550 100644
--- a/src/Configuration/FormConfiguration.php
+++ b/src/Configuration/FormConfiguration.php
@@ -18,7 +18,7 @@ class FormConfiguration implements SystemBundleConfiguration
return 'defaults';
}
- public function getCustomerDefaultTimezone(): string
+ public function getCustomerDefaultTimezone(): ?string
{
return $this->find('customer.timezone');
}
@@ -32,4 +32,19 @@ class FormConfiguration implements SystemBundleConfiguration
{
return $this->find('customer.country');
}
+
+ public function getUserDefaultTimezone(): ?string
+ {
+ return $this->find('user.timezone');
+ }
+
+ public function getUserDefaultTheme(): ?string
+ {
+ return $this->find('user.theme');
+ }
+
+ public function getUserDefaultLanguage(): string
+ {
+ return $this->find('user.language');
+ }
}
diff --git a/src/Controller/CustomerController.php b/src/Controller/CustomerController.php
index 4b61fe1b..0ba5fd9a 100644
--- a/src/Controller/CustomerController.php
+++ b/src/Controller/CustomerController.php
@@ -111,10 +111,15 @@ class CustomerController extends AbstractController
*/
public function createAction(Request $request)
{
+ $timezone = date_default_timezone_get();
+ if (null !== $this->configuration->getCustomerDefaultTimezone()) {
+ $timezone = $this->configuration->getCustomerDefaultTimezone();
+ }
+
$customer = new Customer();
$customer->setCountry($this->configuration->getCustomerDefaultCountry());
$customer->setCurrency($this->configuration->getCustomerDefaultCurrency());
- $customer->setTimezone($this->configuration->getCustomerDefaultTimezone());
+ $customer->setTimezone($timezone);
return $this->renderCustomerForm($customer, $request);
}
diff --git a/src/Controller/SystemConfigurationController.php b/src/Controller/SystemConfigurationController.php
index 89c228f2..55f4b629 100644
--- a/src/Controller/SystemConfigurationController.php
+++ b/src/Controller/SystemConfigurationController.php
@@ -15,6 +15,8 @@ use App\Form\Model\Configuration;
use App\Form\Model\SystemConfiguration as SystemConfigurationModel;
use App\Form\SystemConfigurationForm;
use App\Form\Type\EnhancedSelectboxType;
+use App\Form\Type\LanguageType;
+use App\Form\Type\SkinType;
use App\Form\Type\TrackingModeType;
use App\Repository\ConfigurationRepository;
use Sensio\Bundle\FrameworkExtraBundle\Configuration\Security;
@@ -171,7 +173,10 @@ class SystemConfigurationController extends AbstractController
foreach ($event->getConfigurations() as $configs) {
foreach ($configs->getConfiguration() as $config) {
- $config->setValue($this->configurations->find($config->getName()));
+ $configValue = $this->configurations->find($config->getName());
+ if (null !== $configValue) {
+ $config->setValue($configValue);
+ }
}
}
@@ -216,7 +221,8 @@ class SystemConfigurationController extends AbstractController
(new Configuration())
->setName('defaults.customer.timezone')
->setLabel('timezone')
- ->setType(TimezoneType::class),
+ ->setType(TimezoneType::class)
+ ->setValue(date_default_timezone_get()),
(new Configuration())
->setName('defaults.customer.country')
->setLabel('country')
@@ -226,6 +232,23 @@ class SystemConfigurationController extends AbstractController
->setLabel('currency')
->setType(CurrencyType::class),
]),
+ (new SystemConfigurationModel())
+ ->setSection(SystemConfigurationModel::SECTION_FORM_USER)
+ ->setConfiguration([
+ (new Configuration())
+ ->setName('defaults.user.timezone')
+ ->setLabel('timezone')
+ ->setType(TimezoneType::class)
+ ->setValue(date_default_timezone_get()),
+ (new Configuration())
+ ->setName('defaults.user.language')
+ ->setLabel('language')
+ ->setType(LanguageType::class),
+ (new Configuration())
+ ->setName('defaults.user.theme')
+ ->setLabel('skin')
+ ->setType(SkinType::class),
+ ]),
(new SystemConfigurationModel())
->setSection(SystemConfigurationModel::SECTION_THEME)
->setConfiguration([
diff --git a/src/DependencyInjection/Configuration.php b/src/DependencyInjection/Configuration.php
index 72f2b5b2..16c300c9 100644
--- a/src/DependencyInjection/Configuration.php
+++ b/src/DependencyInjection/Configuration.php
@@ -9,6 +9,7 @@
namespace App\DependencyInjection;
+use App\Entity\User;
use App\Timesheet\Rounding\RoundingInterface;
use Symfony\Component\Config\Definition\Builder\ArrayNodeDefinition;
use Symfony\Component\Config\Definition\Builder\TreeBuilder;
@@ -435,11 +436,20 @@ class Configuration implements ConfigurationInterface
->arrayNode('customer')
->addDefaultsIfNotSet()
->children()
- ->scalarNode('timezone')->defaultValue('Europe/Berlin')->end()
+ ->scalarNode('timezone')->defaultNull()->end()
->scalarNode('country')->defaultValue('DE')->end()
->scalarNode('currency')->defaultValue('EUR')->end()
->end()
->end()
+ ->arrayNode('user')
+ ->addDefaultsIfNotSet()
+ ->children()
+ ->scalarNode('timezone')->defaultNull()->end()
+ ->scalarNode('language')->defaultValue(User::DEFAULT_LANGUAGE)->end()
+ ->scalarNode('theme')->defaultNull()->end()
+ ->end()
+ ->end()
+
->end()
;
diff --git a/src/EventSubscriber/UserPreferenceSubscriber.php b/src/EventSubscriber/UserPreferenceSubscriber.php
index 2998591d..986b739b 100644
--- a/src/EventSubscriber/UserPreferenceSubscriber.php
+++ b/src/EventSubscriber/UserPreferenceSubscriber.php
@@ -9,6 +9,7 @@
namespace App\EventSubscriber;
+use App\Configuration\FormConfiguration;
use App\Entity\User;
use App\Entity\UserPreference;
use App\Event\PrepareUserEvent;
@@ -32,32 +33,27 @@ class UserPreferenceSubscriber implements EventSubscriberInterface
* @var EventDispatcherInterface
*/
protected $eventDispatcher;
-
/**
* @var AuthorizationCheckerInterface
*/
protected $voter;
-
/**
* @var TokenStorageInterface
*/
protected $storage;
-
/**
- * @param EventDispatcherInterface $dispatcher
- * @param TokenStorageInterface $storage
- * @param AuthorizationCheckerInterface $voter
+ * @var FormConfiguration
*/
- public function __construct(EventDispatcherInterface $dispatcher, TokenStorageInterface $storage, AuthorizationCheckerInterface $voter)
+ protected $formConfig;
+
+ public function __construct(EventDispatcherInterface $dispatcher, TokenStorageInterface $storage, AuthorizationCheckerInterface $voter, FormConfiguration $formConfig)
{
$this->eventDispatcher = $dispatcher;
$this->storage = $storage;
$this->voter = $voter;
+ $this->formConfig = $formConfig;
}
- /**
- * @return array
- */
public static function getSubscribedEvents(): array
{
return [
@@ -65,6 +61,26 @@ class UserPreferenceSubscriber implements EventSubscriberInterface
];
}
+ private function getDefaultTheme(): ?string
+ {
+ return $this->formConfig->getUserDefaultTheme();
+ }
+
+ private function getDefaultLanguage(): string
+ {
+ return $this->formConfig->getUserDefaultLanguage();
+ }
+
+ private function getDefaultTimezone(): string
+ {
+ $timezone = $this->formConfig->getUserDefaultTimezone();
+ if (null === $timezone) {
+ $timezone = date_default_timezone_get();
+ }
+
+ return $timezone;
+ }
+
/**
* @param User $user
* @return UserPreference[]
@@ -87,16 +103,17 @@ class UserPreferenceSubscriber implements EventSubscriberInterface
(new UserPreference())
->setName(UserPreference::TIMEZONE)
- ->setValue(date_default_timezone_get())
+ ->setValue($this->getDefaultTimezone())
->setType(TimezoneType::class),
(new UserPreference())
->setName(UserPreference::LOCALE)
- ->setValue(User::DEFAULT_LANGUAGE)
+ ->setValue($this->getDefaultLanguage())
->setType(LanguageType::class),
(new UserPreference())
->setName(UserPreference::SKIN)
+ ->setValue($this->getDefaultTheme())
->setType(SkinType::class),
(new UserPreference())
diff --git a/src/Form/Model/SystemConfiguration.php b/src/Form/Model/SystemConfiguration.php
index 07ca3ef0..a7367145 100644
--- a/src/Form/Model/SystemConfiguration.php
+++ b/src/Form/Model/SystemConfiguration.php
@@ -13,6 +13,7 @@ class SystemConfiguration
{
public const SECTION_TIMESHEET = 'timesheet';
public const SECTION_FORM_CUSTOMER = 'form_customer';
+ public const SECTION_FORM_USER = 'form_user';
public const SECTION_THEME = 'theme';
public const SECTION_CALENDAR = 'calendar';
diff --git a/tests/Controller/CustomerControllerTest.php b/tests/Controller/CustomerControllerTest.php
index 206c7f95..d761f876 100644
--- a/tests/Controller/CustomerControllerTest.php
+++ b/tests/Controller/CustomerControllerTest.php
@@ -61,11 +61,12 @@ class CustomerControllerTest extends ControllerBaseTest
$kernel = self::bootKernel();
$container = $kernel->getContainer();
$defaults = $container->getParameter('kimai.defaults')['customer'];
+ $this->assertNull($defaults['timezone']);
$editForm = $client->getCrawler()->filter('form[name=customer_edit_form]')->form();
$this->assertEquals($defaults['country'], $editForm->get('customer_edit_form[country]')->getValue());
$this->assertEquals($defaults['currency'], $editForm->get('customer_edit_form[currency]')->getValue());
- $this->assertEquals($defaults['timezone'], $editForm->get('customer_edit_form[timezone]')->getValue());
+ $this->assertEquals(date_default_timezone_get(), $editForm->get('customer_edit_form[timezone]')->getValue());
$client->submit($form, [
'customer_edit_form' => [
diff --git a/tests/Controller/SystemConfigurationControllerTest.php b/tests/Controller/SystemConfigurationControllerTest.php
index a3d163c2..123938af 100644
--- a/tests/Controller/SystemConfigurationControllerTest.php
+++ b/tests/Controller/SystemConfigurationControllerTest.php
@@ -50,6 +50,7 @@ class SystemConfigurationControllerTest extends ControllerBaseTest
return [
['form[name=system_configuration_form_timesheet]', $this->createUrl('/admin/system-config/update/timesheet')],
['form[name=system_configuration_form_form_customer]', $this->createUrl('/admin/system-config/update/form_customer')],
+ ['form[name=system_configuration_form_form_user]', $this->createUrl('/admin/system-config/update/form_user')],
['form[name=system_configuration_form_theme]', $this->createUrl('/admin/system-config/update/theme')],
['form[name=system_configuration_form_calendar]', $this->createUrl('/admin/system-config/update/calendar')],
];
@@ -121,7 +122,7 @@ class SystemConfigurationControllerTest extends ControllerBaseTest
$this->assertAccessIsGranted($client, '/admin/system-config/');
$configService = $client->getContainer()->get(SystemConfiguration::class);
- $this->assertEquals('Europe/Berlin', $configService->find('defaults.customer.timezone'));
+ $this->assertNull($configService->find('defaults.customer.timezone'));
$this->assertEquals('DE', $configService->find('defaults.customer.country'));
$this->assertEquals('EUR', $configService->find('defaults.customer.currency'));
@@ -147,6 +148,38 @@ class SystemConfigurationControllerTest extends ControllerBaseTest
$this->assertEquals('GBP', $configService->find('defaults.customer.currency'));
}
+ public function testUpdateUserConfig()
+ {
+ $client = $this->getClientForAuthenticatedUser(User::ROLE_SUPER_ADMIN);
+ $this->assertAccessIsGranted($client, '/admin/system-config/');
+
+ $configService = $client->getContainer()->get(SystemConfiguration::class);
+ $this->assertNull($configService->find('defaults.user.timezone'));
+ $this->assertNull($configService->find('defaults.user.theme'));
+ $this->assertEquals('en', $configService->find('defaults.user.language'));
+
+ $form = $client->getCrawler()->filter('form[name=system_configuration_form_form_user]')->form();
+ $client->submit($form, [
+ 'system_configuration_form_form_user' => [
+ 'configuration' => [
+ ['name' => 'defaults.user.timezone', 'value' => 'Pacific/Tahiti'],
+ ['name' => 'defaults.user.language', 'value' => 'ru'],
+ ['name' => 'defaults.user.theme', 'value' => 'purple'],
+ ]
+ ]
+ ]);
+
+ $this->assertIsRedirect($client, $this->createUrl('/admin/system-config/'));
+ $client->followRedirect();
+ $this->assertTrue($client->getResponse()->isSuccessful());
+ $this->assertHasFlashSaveSuccess($client);
+
+ $configService = $client->getContainer()->get(SystemConfiguration::class);
+ $this->assertEquals('Pacific/Tahiti', $configService->find('defaults.user.timezone'));
+ $this->assertEquals('purple', $configService->find('defaults.user.theme'));
+ $this->assertEquals('ru', $configService->find('defaults.user.language'));
+ }
+
public function testUpdateCustomerConfigValidation()
{
$this->assertFormHasValidationError(
diff --git a/tests/DependencyInjection/AppExtensionTest.php b/tests/DependencyInjection/AppExtensionTest.php
index 6be21c7a..99f9b029 100644
--- a/tests/DependencyInjection/AppExtensionTest.php
+++ b/tests/DependencyInjection/AppExtensionTest.php
@@ -86,9 +86,14 @@ class AppExtensionTest extends TestCase
],
'kimai.defaults' => [
'customer' => [
- 'timezone' => 'Europe/Berlin',
+ 'timezone' => null,
'country' => 'DE',
'currency' => 'EUR',
+ ],
+ 'user' => [
+ 'timezone' => null,
+ 'language' => 'en',
+ 'theme' => null,
]
],
diff --git a/translations/system-configuration.de.xliff b/translations/system-configuration.de.xliff
index e52415a6..474b27d8 100644
--- a/translations/system-configuration.de.xliff
+++ b/translations/system-configuration.de.xliff
@@ -18,6 +18,10 @@
form_customer
Kunden anlegen - Standard Werte
+
+ form_user
+ Benutzer - Standard Werte
+
theme
Darstellung
diff --git a/translations/system-configuration.en.xliff b/translations/system-configuration.en.xliff
index 53f048d1..2f623a3f 100644
--- a/translations/system-configuration.en.xliff
+++ b/translations/system-configuration.en.xliff
@@ -18,6 +18,10 @@
form_customer
Create customer - default values
+
+ form_user
+ User - default values
+
theme
Theme