2017-02-22 7 views
0

私はSymfony2で行った作業のアプリケーションを改善する必要があります。私たちは国際レベルへと拡大しているので、タイムゾーン各ユーザは、通知およびその他のアラートを受信する日付を変更することができる。私たちのタイムゾーンはUTC + 1(ヨーロッパ/マドリード)ですので、このタイムゾーンでデータベースに日付を保存する必要があります。しかし、それはアプリになると、それは設定では、ユーザーが設定した時間を表示することができる必要があります。Symfony2のユーザログイン時にプログラムでDateTimeタイムゾーンを設定するには

symfony 2でどのように実装すれば、コントローラとtwigテンプレートをすべて変更する必要はありませんか?

イベントリスナーで実行できますか?

+0

「date_default_timezone_set( "Asia/Bangkok"); 'app.php'と' app_dev.php'ですが、アプリケーションに合わせて呼び出すことができます。 – LBA

+0

ありがとうございました:)。その関数を呼び出すと、DDBBのdateTimeの挿入に影響しますか? – 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. 私は新しいクラスUTCDateTimeTypeに教義の日時を拡張しました:日時のデータを取得したり、persitとき

    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; 
        } 
    } 
    

    だから、それはオールウェイズです私のUTCタイムゾーンで。私はタイムゾーンのフィールドを持つように私のUserエンティティを編集し

    Type::overrideType('datetime', UTCDateTimeType::class); 
    Type::overrideType('datetimetz', UTCDateTimeType::class); 
    
  2. (PHPのタイムゾーン識別子)

  3. その後、ORMをブートストラップする前に、私は、日時の種類をオーバーライドしましたLoginListener - > onSecurityInteractiveLoginでは、セッションを挿入しました。ユーザーがログインすると、ユーザーのタイムゾーンフィールドでSessionに「timezone」変数を設定します。

    public function onSecurityInteractiveLogin(InteractiveLoginEvent $event){ 
        $user = $event->getAuthenticationToken()->getUser(); 
        $this->session->set("timezone",new \DateTimeZone($user->getTimeZone())); 
        // ... 
    } 
    
  4. Iはポストロード教義イベント(エンティティが完全DDBBからロードされたときにトリガ)Iは、各プロパティを検索ポストロード方法において

    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")); 
    
           } 
    
          } 
         } 
        } 
    } 
    
  5. を聞くTimeZoneListenerを作っdatetimeと入力し、ログインしたユーザーのtimeZoneに設定します(以前はセッションにログイン時に設定されていました)

  6. エンティティがロードされるたびに、datetimeフィールドに達すると、レンダリングステージで、datetimeオフセットが正常に適用され、各ユーザーに対して、表示されます。

+0

[公式のDoctrineのドキュメント](http://docs.doctrine-project.org/projects/doctrine-orm/en/latest/cookbook/working-with-datetime.html)を参照するIMOは理にかなっています;-) – Lashae

関連する問題