2017-02-22 46 views
0

Мне нужно улучшить приложение моей работы, которое я сделал в Symfony2, теперь, когда мы расширяемся на международный уровень, и мы должны внедрить систему часовых поясов так что каждый пользователь может изменить дату, когда они получат уведомления и другие предупреждения. Наш часовой пояс - это UTC + 1 (Европа/Мадрид), поэтому мы должны сохранить даты в базе данных с этим часовым поясом. Но когда дело доходит до приложения, оно должно быть в состоянии показать в настройках время, которое пользователь настроил.Как установить часовой пояс TimeTime программно при входе пользователя в Symfony2

Как я могу реализовать его в Symfony 2, чтобы мне не пришлось изменять все контроллеры и шаблоны ветви?

Это можно сделать в прослушивании событий?

+0

как насчет вызова 'date_default_timezone_set (« Азия/Бангкок »);' как часть вашего, например, 'app.php' и' app_dev.php', но вы можете называть его везде, где это подходит вашему приложению. – LBA

+0

Спасибо за ответ :). Таким образом, вызов этой функции повлияет на вставку dateTime в DDBB? – didix16

ответ

-1

1) Установите часовой пояс по умолчанию, то есть в прослушиватель событий, который прослушивает событие kernel.request.

2) Создайте прослушиватель событий, который прослушивает событие security.interactive_login и извлекает пользователя из события, а затем получает его собственные настройки часового пояса и применяет их. (An example)

+0

Хорошо, спасибо! Я сейчас попробую. – didix16

1

Наконец-то я нашел решение, получив информацию и выполнив поиск похожих вещей, особенно это ->how to get the type of a doctrine entity property помогло мне разработать окончательный код.

Вот что я сделал:

  1. Я продлил DateTime доктрины в новый класс UTCDateTimeType:

    use Doctrine\DBAL\Platforms\AbstractPlatform; 
    use Doctrine\DBAL\Types\ConversionException; 
    use Doctrine\DBAL\Types\DateTimeType; 
    
    class UTCDateTimeType extends DateTimeType { 
    
        static private $utc; 
    
        static function getUtc(){ 
    
         return self::$utc; 
        } 
    
        public function convertToDatabaseValue($value, AbstractPlatform $platform) 
        { 
         if ($value instanceof \DateTime) { 
          $value->setTimezone(self::getUtc()); 
         } 
    
         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('Europe/Madrid') 
         ); 
    
         if (! $converted) { 
          throw ConversionException::conversionFailedFormat(
           $value, 
           $this->getName(), 
           $platform->getDateTimeFormatString() 
          ); 
         } 
    
         return $converted; 
        } 
    } 
    

    Так что, когда прибудете или persit данные даты-времени, это ВСЕГДА в моем часовом поясе UTC.

  2. Затем перед самонастройкой ОРМА, я перекрытая типы даты-времени:

    Type::overrideType('datetime', UTCDateTimeType::class); 
    Type::overrideType('datetimetz', UTCDateTimeType::class); 
    
  3. Я отредактировал мой объект пользователя, чтобы иметь поле часового пояса (временная идентификатор зоны PHP)

  4. В LoginListener -> onSecurityInteractiveLogin я ввел сеанс, и когда пользователь вошел в систему, я установил переменную «часовой пояс» для сеанса с полем пользовательского часового пояса.

    public function onSecurityInteractiveLogin(InteractiveLoginEvent $event){ 
        $user = $event->getAuthenticationToken()->getUser(); 
        $this->session->set("timezone",new \DateTimeZone($user->getTimeZone())); 
        // ... 
    } 
    
  5. Я сделал TimeZoneListener, которые слушают постнагрузки доктрины события (срабатывают, когда предприятие полностью загружено из DDBB)

    use Symfony\Component\Routing\RouterInterface; 
    use Symfony\Component\HttpFoundation\Session\Session; 
    use Symfony\Component\Translation\TranslatorInterface; 
    use Doctrine\ORM\Event\LifecycleEventArgs; 
    use Doctrine\Common\Annotations\AnnotationReader; 
    
    class TimeZoneListener { 
    
        protected $session; 
    
        protected $container; 
    
        protected $router; 
    
        protected $securityContext; 
    
        protected $translator; 
    
        protected $docReader; 
    
        public function __construct(RouterInterface $router, Session $session, TranslatorInterface $translator, $container){ 
    
         $this->session = $session; 
         $this->router = $router; 
         $this->translator = $translator; 
         $this->container = $container; 
         $this->docReader = new AnnotationReader(); 
        } 
    
        public function postLoad(LifecycleEventArgs $args){ 
    
         $reader = $this->docReader; 
         $entity = $args->getEntity(); 
         $reflect = new \ReflectionClass($entity); 
    
         $props = $reflect->getProperties(); 
    
         foreach($props as $prop){ 
    
          $docInfos = $reader->getPropertyAnnotations($prop); 
          foreach($docInfos as $info){ 
    
           if(!$info instanceof \Doctrine\ORM\Mapping\Column) continue; 
           if($info->type !== "datetime") continue; 
    
           $getDateMethod = 'get'.ucfirst($prop->getName()); 
    
           $val = $entity->{$getDateMethod}(); 
           if($val){ 
            $val->setTimeZone($this->session->get("timezone") ? $this->session->get("timezone") : new \DateTimeZone("Europe/Madrid")); 
    
           } 
    
          } 
         } 
        } 
    } 
    
  6. В постнагрузке метода я поиск каждого свойство тип datetime, а затем я установил зарегистрированное пользовательское времяZone (ранее установленное при входе в сессию)

  7. Теперь, каждый раз, когда объект загружается, когда поле даты и времени достигнуто, на этапе рендеринга применяется смещение даты и времени, и для каждого пользователя он отображается, как показано на рисунке.

+0

ИМО, ссылаясь на [официальную документацию доктрины] (http://docs.doctrine-project.org/projects/doctrine-orm/en/latest/cookbook/working-with-datetime.html), будет иметь смысл ;-) – Lashae

 Смежные вопросы

  • Нет связанных вопросов^_^