From 19843760e503368172c7e6aa3d87e8d8073b8001 Mon Sep 17 00:00:00 2001 From: Kevin Papst Date: Fri, 5 Jul 2019 02:42:50 +0200 Subject: [PATCH] allow to configure default values for users (#919) --- config/packages/kimai.yaml | 13 ++---- src/Configuration/FormConfiguration.php | 17 +++++++- src/Controller/CustomerController.php | 7 +++- .../SystemConfigurationController.php | 27 +++++++++++- src/DependencyInjection/Configuration.php | 12 +++++- .../UserPreferenceSubscriber.php | 41 +++++++++++++------ src/Form/Model/SystemConfiguration.php | 1 + tests/Controller/CustomerControllerTest.php | 3 +- .../SystemConfigurationControllerTest.php | 35 +++++++++++++++- .../DependencyInjection/AppExtensionTest.php | 7 +++- translations/system-configuration.de.xliff | 4 ++ translations/system-configuration.en.xliff | 4 ++ 12 files changed, 142 insertions(+), 29 deletions(-) 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