diff --git a/config/packages/doctrine.yaml b/config/packages/doctrine.yaml index 3ef8d933..a549dbb3 100644 --- a/config/packages/doctrine.yaml +++ b/config/packages/doctrine.yaml @@ -16,6 +16,9 @@ doctrine: collate: utf8mb4_unicode_ci url: '%env(resolve:DATABASE_URL)%' + types: + datetime: App\Helpers\UTCDateTimeType + date: App\Helpers\UTCDateTimeType schema_filter: ~^(?!internal|log)~ diff --git a/config/services.yaml b/config/services.yaml index 6e0451d1..252f8f36 100644 --- a/config/services.yaml +++ b/config/services.yaml @@ -6,6 +6,7 @@ parameters: locale: 'en' # Set the default language to use her + timezone: 'Europe/Berlin' partdb_title: 'Part-DB' # The title shown inside of Part-DB (e.g. in the navbar and on homepage) banner: '' # The info text shown in the homepage use_gravatar: true # Set to false, if no Gravatar images should be used for user profiles. @@ -69,6 +70,10 @@ services: arguments: $base_currency: '%default_currency%' + App\EventSubscriber\TimezoneListener: + arguments: + $timezone: '%timezone%' + App\Services\TranslationExtractor\PermissionExtractor: tags: - { name: 'translation.extractor', alias: 'permissionExtractor'} \ No newline at end of file diff --git a/src/EventSubscriber/TimezoneListener.php b/src/EventSubscriber/TimezoneListener.php new file mode 100644 index 00000000..78d0dec1 --- /dev/null +++ b/src/EventSubscriber/TimezoneListener.php @@ -0,0 +1,104 @@ +default_timezone = $timezone; + $this->security = $security; + } + + public function setTimeZone(ControllerEvent $event) + { + $timezone = null; + + //Check if the user has set a timezone + $user = $this->security->getUser(); + if ($user instanceof User && !empty($user->getTimezone())) { + $timezone = $user->getTimezone(); + } + + //Fill with default value if needed + if ($timezone === null && !empty($this->default_timezone)) { + $timezone = $this->default_timezone; + } + + //If timezone was configured anywhere set it, otherwise just use the one from php.ini + if ($timezone !== null) { + date_default_timezone_set($timezone); + + } + } + + /** + * Returns an array of event names this subscriber wants to listen to. + * + * The array keys are event names and the value can be: + * + * * The method name to call (priority defaults to 0) + * * An array composed of the method name to call and the priority + * * An array of arrays composed of the method names to call and respective + * priorities, or 0 if unset + * + * For instance: + * + * * ['eventName' => 'methodName'] + * * ['eventName' => ['methodName', $priority]] + * * ['eventName' => [['methodName1', $priority], ['methodName2']]] + * + * @return array The event names to listen to + */ + public static function getSubscribedEvents() + { + //Set the timezone shortly before executing the controller + return [ + KernelEvents::CONTROLLER => 'setTimeZone' + ]; + } +} \ No newline at end of file diff --git a/src/Form/UserSettingsType.php b/src/Form/UserSettingsType.php index f6be1899..9424e4bf 100644 --- a/src/Form/UserSettingsType.php +++ b/src/Form/UserSettingsType.php @@ -68,6 +68,7 @@ class UserSettingsType extends AbstractType 'attr' => ['class' => 'selectpicker', 'data-live-search' => true], 'placeholder' => $this->trans->trans('user_settings.timezone.placeholder'), 'label' => $this->trans->trans('user.timezone.label'), + 'preferred_choices' => ['Europe/Berlin'] ]) ->add('theme', ChoiceType::class, [ 'required' => false, diff --git a/src/Helpers/UTCDateTimeType.php b/src/Helpers/UTCDateTimeType.php new file mode 100644 index 00000000..7e8a5f51 --- /dev/null +++ b/src/Helpers/UTCDateTimeType.php @@ -0,0 +1,78 @@ +setTimezone(self::$utc); + } + + return parent::convertToDatabaseValue($value, $platform); + } + + public function convertToPHPValue($value, AbstractPlatform $platform) + { + if (null === $value || $value instanceof \DateTime) { + return $value; + } + + $converted = \DateTime::createFromFormat( + $platform->getDateTimeFormatString(), + $value, + self::$utc ? self::$utc : self::$utc = new \DateTimeZone('UTC') + ); + + if (! $converted) { + throw ConversionException::conversionFailedFormat( + $value, + $this->getName(), + $platform->getDateTimeFormatString() + ); + } + + return $converted; + } +} \ No newline at end of file