2012-05-22 42 views
6

Uno de mis requisitos para mi proyecto actual es permitir que un usuario elija un huso horario para su cuenta y luego usar esta zona horaria para todas las funciones relacionadas con la fecha/hora todo el sitio.Symfony2: Dónde establecer un huso horario definido por el usuario

La forma en que lo veo, tengo dos opciones:

  • pase en un objeto DateTimeZone al constructor de DateTime para cada nuevo DateTime
  • Establecer la zona horaria predeterminada usando PHP date_default_timezone_set()

Parece que utilizar date_default_timezone_set es el camino a seguir, pero no estoy seguro exactamente dónde debo configurarlo. Debido a que el huso horario será diferente de usuario a usuario y DateTime se usa en todo el sitio, debo configurarlo en alguna parte para que afecte a todas las páginas.

Tal vez podría escribir un detector de eventos que lo configura después de un inicio de sesión exitoso? Si tomo este enfoque, ¿permanecerá establecido en todas las páginas o solo se establecerá por página?

Me encantaría escuchar cómo otros se acercarían a esto.

Respuesta

14

Sí, podría usar un detector de eventos, conectando el evento kernel.request.

Aquí es el oyente de uno de mis proyectos:

<?php 
namespace Vendor\Bundle\AppBundle\Listener; 

use Symfony\Component\Security\Core\SecurityContextInterface; 
use Doctrine\DBAL\Connection; 
use JMS\DiExtraBundle\Annotation\Service; 
use JMS\DiExtraBundle\Annotation\Observe; 
use JMS\DiExtraBundle\Annotation\InjectParams; 
use JMS\DiExtraBundle\Annotation\Inject; 

/** 
* @Service 
*/ 
class TimezoneListener 
{ 
    /** 
    * @var \Symfony\Component\Security\Core\SecurityContextInterface 
    */ 
    private $securityContext; 

    /** 
    * @var \Doctrine\DBAL\Connection 
    */ 
    private $connection; 

    /** 
    * @InjectParams({ 
    *  "securityContext" = @Inject("security.context"), 
    *  "connection"  = @Inject("database_connection") 
    * }) 
    * 
    * @param \Symfony\Component\Security\Core\SecurityContextInterface $securityContext 
    * @param \Doctrine\DBAL\Connection $connection 
    */ 
    public function __construct(SecurityContextInterface $securityContext, Connection $connection) 
    { 
     $this->securityContext = $securityContext; 
     $this->connection  = $connection; 
    } 

    /** 
    * @Observe("kernel.request") 
    */ 
    public function onKernelRequest() 
    { 
     if (!$this->securityContext->isGranted('ROLE_USER')) { 
      return; 
     } 

     $user = $this->securityContext->getToken()->getUser(); 
     if (!$user->getTimezone()) { 
      return; 
     } 

     date_default_timezone_set($user->getTimezone()); 
     $this->connection->query("SET timezone TO '{$user->getTimezone()}'"); 
    } 
} 
+3

@elnur, supongamos que mi servidor está ajustado a "UTC" y el usuario "América/Caracas". Con su solución, ¿qué sucede cuando un usuario envía una fecha y hora en algún campo de entidad? ¿Se almacenará la fecha y hora con la zona horaria del usuario (sin cambios en comparación con el valor ingresado por el usuario) o con la zona horaria del servidor (el valor cambió para coincidir con la hora UTC)? –

+0

@David Solo debe almacenar horas/fechas basadas en UTC en su base de datos. De esa manera siempre puede formatearlo correctamente para el usuario. – Luke

Cuestiones relacionadas