Issue #3009377 by kim.pepper, andypost, Berdir, alexpott, Wim Leers, mpdonadio, acbramley, larowlan, catch, xjm: Replace drupal_get_user_timezone with a date_default_timezone_get() and an event listener
							parent
							
								
									ae23684beb
								
							
						
					
					
						commit
						e47700f70a
					
				| 
						 | 
				
			
			@ -1530,6 +1530,7 @@ services:
 | 
			
		|||
    arguments: ['@private_key', '@cache.bootstrap', '@cache.static']
 | 
			
		||||
  current_user:
 | 
			
		||||
    class: Drupal\Core\Session\AccountProxy
 | 
			
		||||
    arguments: ['@event_dispatcher']
 | 
			
		||||
  session_configuration:
 | 
			
		||||
    class: Drupal\Core\Session\SessionConfiguration
 | 
			
		||||
    arguments: ['%session.storage.options%']
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -564,20 +564,15 @@ function drupal_get_messages($type = NULL, $clear_queue = TRUE) {
 | 
			
		|||
 *
 | 
			
		||||
 * @return string
 | 
			
		||||
 *   The name of the current user's timezone or the name of the default timezone.
 | 
			
		||||
 *
 | 
			
		||||
 * @deprecated in drupal:8.8.0 and will be removed from drupal:9.0.0. Use
 | 
			
		||||
 *   date_default_timezone_get() instead.
 | 
			
		||||
 *
 | 
			
		||||
 * @see https://www.drupal.org/node/3009387
 | 
			
		||||
 */
 | 
			
		||||
function drupal_get_user_timezone() {
 | 
			
		||||
  $user = \Drupal::currentUser();
 | 
			
		||||
  $config = \Drupal::config('system.date');
 | 
			
		||||
 | 
			
		||||
  if ($user && $config->get('timezone.user.configurable') && $user->isAuthenticated() && $user->getTimezone()) {
 | 
			
		||||
    return $user->getTimezone();
 | 
			
		||||
  }
 | 
			
		||||
  else {
 | 
			
		||||
    // Ignore PHP strict notice if time zone has not yet been set in the php.ini
 | 
			
		||||
    // configuration.
 | 
			
		||||
    $config_data_default_timezone = $config->get('timezone.default');
 | 
			
		||||
    return !empty($config_data_default_timezone) ? $config_data_default_timezone : @date_default_timezone_get();
 | 
			
		||||
  }
 | 
			
		||||
  @trigger_error('drupal_get_user_timezone() is deprecated in drupal:8.8.0. It will be removed from drupal:9.0.0. Use date_default_timezone_get() instead. See https://www.drupal.org/node/3009387', E_USER_DEPRECATED);
 | 
			
		||||
  return date_default_timezone_get();
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -73,7 +73,7 @@ class DrupalDateTime extends DateTimePlus {
 | 
			
		|||
  protected function prepareTimezone($timezone) {
 | 
			
		||||
    if (empty($timezone)) {
 | 
			
		||||
      // Fallback to user or system default timezone.
 | 
			
		||||
      $timezone = drupal_get_user_timezone();
 | 
			
		||||
      $timezone = date_default_timezone_get();
 | 
			
		||||
    }
 | 
			
		||||
    return parent::prepareTimezone($timezone);
 | 
			
		||||
  }
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -33,7 +33,7 @@ class Datelist extends DateElementBase {
 | 
			
		|||
      '#date_year_range' => '1900:2050',
 | 
			
		||||
      '#date_increment' => 1,
 | 
			
		||||
      '#date_date_callbacks' => [],
 | 
			
		||||
      '#date_timezone' => drupal_get_user_timezone(),
 | 
			
		||||
      '#date_timezone' => date_default_timezone_get(),
 | 
			
		||||
    ];
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -149,7 +149,7 @@ class Datelist extends DateElementBase {
 | 
			
		|||
   *     minute.
 | 
			
		||||
   *   - #date_timezone: The Time Zone Identifier (TZID) to use when displaying
 | 
			
		||||
   *     or interpreting dates, i.e: 'Asia/Kolkata'. Defaults to the value
 | 
			
		||||
   *     returned by drupal_get_user_timezone().
 | 
			
		||||
   *     returned by date_default_timezone_get().
 | 
			
		||||
   *
 | 
			
		||||
   * Example usage:
 | 
			
		||||
   * @code
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -61,7 +61,7 @@ class Datetime extends DateElementBase {
 | 
			
		|||
      '#date_time_callbacks' => [],
 | 
			
		||||
      '#date_year_range' => '1900:2050',
 | 
			
		||||
      '#date_increment' => 1,
 | 
			
		||||
      '#date_timezone' => drupal_get_user_timezone(),
 | 
			
		||||
      '#date_timezone' => date_default_timezone_get(),
 | 
			
		||||
    ];
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -190,7 +190,7 @@ class Datetime extends DateElementBase {
 | 
			
		|||
   *     second.
 | 
			
		||||
   *   - #date_timezone: The Time Zone Identifier (TZID) to use when displaying
 | 
			
		||||
   *     or interpreting dates, i.e: 'Asia/Kolkata'. Defaults to the value
 | 
			
		||||
   *     returned by drupal_get_user_timezone().
 | 
			
		||||
   *     returned by date_default_timezone_get().
 | 
			
		||||
   *
 | 
			
		||||
   * Example usage:
 | 
			
		||||
   * @code
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -2,8 +2,8 @@
 | 
			
		|||
 | 
			
		||||
namespace Drupal\Core\EventSubscriber;
 | 
			
		||||
 | 
			
		||||
use Drupal\Core\Authentication\AuthenticationProviderFilterInterface;
 | 
			
		||||
use Drupal\Core\Authentication\AuthenticationProviderChallengeInterface;
 | 
			
		||||
use Drupal\Core\Authentication\AuthenticationProviderFilterInterface;
 | 
			
		||||
use Drupal\Core\Authentication\AuthenticationProviderInterface;
 | 
			
		||||
use Drupal\Core\Session\AccountProxyInterface;
 | 
			
		||||
use Symfony\Component\EventDispatcher\EventSubscriberInterface;
 | 
			
		||||
| 
						 | 
				
			
			@ -80,8 +80,6 @@ class AuthenticationSubscriber implements EventSubscriberInterface {
 | 
			
		|||
          return;
 | 
			
		||||
        }
 | 
			
		||||
      }
 | 
			
		||||
      // No account has been set explicitly, initialize the timezone here.
 | 
			
		||||
      date_default_timezone_set(drupal_get_user_timezone());
 | 
			
		||||
    }
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -0,0 +1,28 @@
 | 
			
		|||
<?php
 | 
			
		||||
 | 
			
		||||
namespace Drupal\Core\Session;
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * Defines events for the account system.
 | 
			
		||||
 *
 | 
			
		||||
 * @see \Drupal\Core\Session\AccountSetEvent
 | 
			
		||||
 */
 | 
			
		||||
final class AccountEvents {
 | 
			
		||||
 | 
			
		||||
  /**
 | 
			
		||||
   * Name of the event fired when the current user is set.
 | 
			
		||||
   *
 | 
			
		||||
   * This event allows modules to perform an action whenever the current user is
 | 
			
		||||
   * set. The event listener receives an \Drupal\Core\Session\AccountSetEvent
 | 
			
		||||
   * instance.
 | 
			
		||||
   *
 | 
			
		||||
   * @Event
 | 
			
		||||
   *
 | 
			
		||||
   * @see \Drupal\Core\Session\AccountSetEvent
 | 
			
		||||
   * @see \Drupal\Core\Session\AccountProxyInterface::setAccount()
 | 
			
		||||
   *
 | 
			
		||||
   * @var string
 | 
			
		||||
   */
 | 
			
		||||
  const SET_USER = 'account.set';
 | 
			
		||||
 | 
			
		||||
}
 | 
			
		||||
| 
						 | 
				
			
			@ -2,6 +2,9 @@
 | 
			
		|||
 | 
			
		||||
namespace Drupal\Core\Session;
 | 
			
		||||
 | 
			
		||||
use Drupal\Core\DependencyInjection\DependencySerializationTrait;
 | 
			
		||||
use Symfony\Component\EventDispatcher\EventDispatcherInterface;
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * A proxied implementation of AccountInterface.
 | 
			
		||||
 *
 | 
			
		||||
| 
						 | 
				
			
			@ -15,6 +18,8 @@ namespace Drupal\Core\Session;
 | 
			
		|||
 */
 | 
			
		||||
class AccountProxy implements AccountProxyInterface {
 | 
			
		||||
 | 
			
		||||
  use DependencySerializationTrait;
 | 
			
		||||
 | 
			
		||||
  /**
 | 
			
		||||
   * The instantiated account.
 | 
			
		||||
   *
 | 
			
		||||
| 
						 | 
				
			
			@ -39,6 +44,27 @@ class AccountProxy implements AccountProxyInterface {
 | 
			
		|||
   */
 | 
			
		||||
  protected $initialAccountId;
 | 
			
		||||
 | 
			
		||||
  /**
 | 
			
		||||
   * Event dispatcher.
 | 
			
		||||
   *
 | 
			
		||||
   * @var \Symfony\Component\EventDispatcher\EventDispatcherInterface
 | 
			
		||||
   */
 | 
			
		||||
  protected $eventDispatcher;
 | 
			
		||||
 | 
			
		||||
  /**
 | 
			
		||||
   * AccountProxy constructor.
 | 
			
		||||
   *
 | 
			
		||||
   * @param \Symfony\Component\EventDispatcher\EventDispatcherInterface $eventDispatcher
 | 
			
		||||
   *   Event dispatcher.
 | 
			
		||||
   */
 | 
			
		||||
  public function __construct(EventDispatcherInterface $eventDispatcher = NULL) {
 | 
			
		||||
    if (!$eventDispatcher) {
 | 
			
		||||
      @trigger_error('Calling AccountProxy::__construct() without the $eventDispatcher argument is deprecated in drupal:8.8.0. The $eventDispatcher argument will be required in drupal:9.0.0. See https://www.drupal.org/node/3009387', E_USER_DEPRECATED);
 | 
			
		||||
      $eventDispatcher = \Drupal::service('event_dispatcher');
 | 
			
		||||
    }
 | 
			
		||||
    $this->eventDispatcher = $eventDispatcher;
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  /**
 | 
			
		||||
   * {@inheritdoc}
 | 
			
		||||
   */
 | 
			
		||||
| 
						 | 
				
			
			@ -50,7 +76,7 @@ class AccountProxy implements AccountProxyInterface {
 | 
			
		|||
    }
 | 
			
		||||
    $this->account = $account;
 | 
			
		||||
    $this->id = $account->id();
 | 
			
		||||
    date_default_timezone_set(drupal_get_user_timezone());
 | 
			
		||||
    $this->eventDispatcher->dispatch(AccountEvents::SET_USER, new AccountSetEvent($account));
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  /**
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -0,0 +1,39 @@
 | 
			
		|||
<?php
 | 
			
		||||
 | 
			
		||||
namespace Drupal\Core\Session;
 | 
			
		||||
 | 
			
		||||
use Symfony\Component\EventDispatcher\Event;
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * Event fired when an account is set for the current session.
 | 
			
		||||
 */
 | 
			
		||||
final class AccountSetEvent extends Event {
 | 
			
		||||
 | 
			
		||||
  /**
 | 
			
		||||
   * The set account.
 | 
			
		||||
   *
 | 
			
		||||
   * @var \Drupal\Core\Session\AccountInterface
 | 
			
		||||
   */
 | 
			
		||||
  protected $account;
 | 
			
		||||
 | 
			
		||||
  /**
 | 
			
		||||
   * AccountSetEvent constructor.
 | 
			
		||||
   *
 | 
			
		||||
   * @param \Drupal\Core\Session\AccountInterface $account
 | 
			
		||||
   *   The set account.
 | 
			
		||||
   */
 | 
			
		||||
  public function __construct(AccountInterface $account) {
 | 
			
		||||
    $this->account = $account;
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  /**
 | 
			
		||||
   * Gets the account.
 | 
			
		||||
   *
 | 
			
		||||
   * @return \Drupal\Core\Session\AccountInterface
 | 
			
		||||
   *   The account.
 | 
			
		||||
   */
 | 
			
		||||
  public function getAccount() {
 | 
			
		||||
    return $this->account;
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
}
 | 
			
		||||
| 
						 | 
				
			
			@ -55,7 +55,7 @@ class DateTimeCustomFormatter extends DateTimeFormatterBase {
 | 
			
		|||
   */
 | 
			
		||||
  protected function formatDate($date) {
 | 
			
		||||
    $format = $this->getSetting('date_format');
 | 
			
		||||
    $timezone = $this->getSetting('timezone_override');
 | 
			
		||||
    $timezone = $this->getSetting('timezone_override') ?: $date->getTimezone()->getName();
 | 
			
		||||
    return $this->dateFormatter->format($date->getTimestamp(), 'custom', $format, $timezone != '' ? $timezone : NULL);
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -160,8 +160,6 @@ abstract class DateTimeFormatterBase extends FormatterBase implements ContainerF
 | 
			
		|||
   * zone applied to it.  This method will apply the time zone for the current
 | 
			
		||||
   * user, based on system and user settings.
 | 
			
		||||
   *
 | 
			
		||||
   * @see drupal_get_user_timezone()
 | 
			
		||||
   *
 | 
			
		||||
   * @param \Drupal\Core\Datetime\DrupalDateTime $date
 | 
			
		||||
   *   A DrupalDateTime object.
 | 
			
		||||
   */
 | 
			
		||||
| 
						 | 
				
			
			@ -171,7 +169,7 @@ abstract class DateTimeFormatterBase extends FormatterBase implements ContainerF
 | 
			
		|||
      $timezone = DateTimeItemInterface::STORAGE_TIMEZONE;
 | 
			
		||||
    }
 | 
			
		||||
    else {
 | 
			
		||||
      $timezone = drupal_get_user_timezone();
 | 
			
		||||
      $timezone = date_default_timezone_get();
 | 
			
		||||
    }
 | 
			
		||||
    $date->setTimeZone(timezone_open($timezone));
 | 
			
		||||
  }
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -42,7 +42,7 @@ class DateTimePlainFormatter extends DateTimeFormatterBase {
 | 
			
		|||
   */
 | 
			
		||||
  protected function formatDate($date) {
 | 
			
		||||
    $format = $this->getFieldSetting('datetime_type') == DateTimeItem::DATETIME_TYPE_DATE ? DateTimeItemInterface::DATE_STORAGE_FORMAT : DateTimeItemInterface::DATETIME_STORAGE_FORMAT;
 | 
			
		||||
    $timezone = $this->getSetting('timezone_override');
 | 
			
		||||
    $timezone = $this->getSetting('timezone_override') ?: $date->getTimezone()->getName();
 | 
			
		||||
    return $this->dateFormatter->format($date->getTimestamp(), 'custom', $format, $timezone != '' ? $timezone : NULL);
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -95,7 +95,7 @@ class DateTimeFieldItemList extends FieldItemList {
 | 
			
		|||
      if ($definition->getSetting('datetime_type') === DateTimeItem::DATETIME_TYPE_DATE) {
 | 
			
		||||
        // A default date only value should be in the format used for date
 | 
			
		||||
        // storage but in the user's local timezone.
 | 
			
		||||
        $date = new DrupalDateTime($default_value[0]['default_date'], drupal_get_user_timezone());
 | 
			
		||||
        $date = new DrupalDateTime($default_value[0]['default_date'], date_default_timezone_get());
 | 
			
		||||
        $format = DateTimeItemInterface::DATE_STORAGE_FORMAT;
 | 
			
		||||
      }
 | 
			
		||||
      else {
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -22,7 +22,7 @@ class DateTimeWidgetBase extends WidgetBase {
 | 
			
		|||
      '#type' => 'datetime',
 | 
			
		||||
      '#default_value' => NULL,
 | 
			
		||||
      '#date_increment' => 1,
 | 
			
		||||
      '#date_timezone' => drupal_get_user_timezone(),
 | 
			
		||||
      '#date_timezone' => date_default_timezone_get(),
 | 
			
		||||
      '#required' => $element['#required'],
 | 
			
		||||
    ];
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -151,7 +151,7 @@ class Date extends NumericDate implements ContainerFactoryPluginInterface {
 | 
			
		|||
  protected function getTimezone() {
 | 
			
		||||
    return $this->dateFormat === DateTimeItemInterface::DATE_STORAGE_FORMAT
 | 
			
		||||
      ? DateTimeItemInterface::STORAGE_TIMEZONE
 | 
			
		||||
      : drupal_get_user_timezone();
 | 
			
		||||
      : date_default_timezone_get();
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  /**
 | 
			
		||||
| 
						 | 
				
			
			@ -173,7 +173,7 @@ class Date extends NumericDate implements ContainerFactoryPluginInterface {
 | 
			
		|||
    // the user's offset from UTC for use in the query.
 | 
			
		||||
    $origin_offset = 0;
 | 
			
		||||
    if ($this->dateFormat === DateTimeItemInterface::DATE_STORAGE_FORMAT && $this->value['type'] === 'offset') {
 | 
			
		||||
      $origin_offset = $origin_offset + timezone_offset_get(new \DateTimeZone(drupal_get_user_timezone()), new \DateTime($time, new \DateTimeZone($timezone)));
 | 
			
		||||
      $origin_offset = $origin_offset + timezone_offset_get(new \DateTimeZone(date_default_timezone_get()), new \DateTime($time, new \DateTimeZone($timezone)));
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    return $origin_offset;
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -253,7 +253,7 @@ class DateTimeFieldTest extends DateTestBase {
 | 
			
		|||
    $date = new DrupalDateTime($value, 'UTC');
 | 
			
		||||
 | 
			
		||||
    // Update the timezone to the system default.
 | 
			
		||||
    $date->setTimezone(timezone_open(drupal_get_user_timezone()));
 | 
			
		||||
    $date->setTimezone(timezone_open(date_default_timezone_get()));
 | 
			
		||||
 | 
			
		||||
    // Submit a valid date and ensure it is accepted.
 | 
			
		||||
    $date_format = DateFormat::load('html_date')->getPattern();
 | 
			
		||||
| 
						 | 
				
			
			@ -708,7 +708,7 @@ class DateTimeFieldTest extends DateTestBase {
 | 
			
		|||
 | 
			
		||||
      // Create a new node to check that datetime field default value is today.
 | 
			
		||||
      $new_node = Node::create(['type' => 'date_content']);
 | 
			
		||||
      $expected_date = new DrupalDateTime('now', drupal_get_user_timezone());
 | 
			
		||||
      $expected_date = new DrupalDateTime('now', date_default_timezone_get());
 | 
			
		||||
      $this->assertEqual($new_node->get($field_name)
 | 
			
		||||
        ->offsetGet(0)->value, $expected_date->format(DateTimeItemInterface::DATE_STORAGE_FORMAT));
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -747,7 +747,7 @@ class DateTimeFieldTest extends DateTestBase {
 | 
			
		|||
      // Create a new node to check that datetime field default value is +90
 | 
			
		||||
      // days.
 | 
			
		||||
      $new_node = Node::create(['type' => 'date_content']);
 | 
			
		||||
      $expected_date = new DrupalDateTime('+90 days', drupal_get_user_timezone());
 | 
			
		||||
      $expected_date = new DrupalDateTime('+90 days', date_default_timezone_get());
 | 
			
		||||
      $this->assertEqual($new_node->get($field_name)
 | 
			
		||||
        ->offsetGet(0)->value, $expected_date->format(DateTimeItemInterface::DATE_STORAGE_FORMAT));
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -111,7 +111,7 @@ abstract class DateTimeHandlerTestBase extends ViewsKernelTestBase {
 | 
			
		|||
   *   Unix timestamp.
 | 
			
		||||
   */
 | 
			
		||||
  protected function getUTCEquivalentOfUserNowAsTimestamp() {
 | 
			
		||||
    $user_now = new DateTimePlus('now', new \DateTimeZone(drupal_get_user_timezone()));
 | 
			
		||||
    $user_now = new DateTimePlus('now', new \DateTimeZone(date_default_timezone_get()));
 | 
			
		||||
    $utc_equivalent = new DateTimePlus($user_now->format('Y-m-d H:i:s'), new \DateTimeZone(DateTimeItemInterface::STORAGE_TIMEZONE));
 | 
			
		||||
 | 
			
		||||
    return $utc_equivalent->getTimestamp();
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -62,7 +62,7 @@ class DateRangeWidgetBase extends DateTimeWidgetBase {
 | 
			
		|||
    }
 | 
			
		||||
 | 
			
		||||
    $storage_timezone = new \DateTimeZone(DateTimeItemInterface::STORAGE_TIMEZONE);
 | 
			
		||||
    $user_timezone = new \DateTimeZone(drupal_get_user_timezone());
 | 
			
		||||
    $user_timezone = new \DateTimeZone(date_default_timezone_get());
 | 
			
		||||
 | 
			
		||||
    foreach ($values as &$item) {
 | 
			
		||||
      if (!empty($item['value']) && $item['value'] instanceof DrupalDateTime) {
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -304,8 +304,8 @@ class DateRangeFieldTest extends DateTestBase {
 | 
			
		|||
    $end_date = new DrupalDateTime($end_value, 'UTC');
 | 
			
		||||
 | 
			
		||||
    // Update the timezone to the system default.
 | 
			
		||||
    $start_date->setTimezone(timezone_open(drupal_get_user_timezone()));
 | 
			
		||||
    $end_date->setTimezone(timezone_open(drupal_get_user_timezone()));
 | 
			
		||||
    $start_date->setTimezone(timezone_open(date_default_timezone_get()));
 | 
			
		||||
    $end_date->setTimezone(timezone_open(date_default_timezone_get()));
 | 
			
		||||
 | 
			
		||||
    // Submit a valid date and ensure it is accepted.
 | 
			
		||||
    $date_format = DateFormat::load('html_date')->getPattern();
 | 
			
		||||
| 
						 | 
				
			
			@ -390,7 +390,7 @@ class DateRangeFieldTest extends DateTestBase {
 | 
			
		|||
    $this->drupalGet('entity_test/add');
 | 
			
		||||
    $value = '2012-12-31 00:00:00';
 | 
			
		||||
    $start_date = new DrupalDateTime($value, 'UTC');
 | 
			
		||||
    $start_date->setTimezone(timezone_open(drupal_get_user_timezone()));
 | 
			
		||||
    $start_date->setTimezone(timezone_open(date_default_timezone_get()));
 | 
			
		||||
 | 
			
		||||
    $date_format = DateFormat::load('html_date')->getPattern();
 | 
			
		||||
    $time_format = DateFormat::load('html_time')->getPattern();
 | 
			
		||||
| 
						 | 
				
			
			@ -478,9 +478,9 @@ class DateRangeFieldTest extends DateTestBase {
 | 
			
		|||
 | 
			
		||||
    // Build up dates in the proper timezone.
 | 
			
		||||
    $value = '2012-12-31 00:00:00';
 | 
			
		||||
    $start_date = new DrupalDateTime($value, timezone_open(drupal_get_user_timezone()));
 | 
			
		||||
    $start_date = new DrupalDateTime($value, timezone_open(date_default_timezone_get()));
 | 
			
		||||
    $end_value = '2013-06-06 23:59:59';
 | 
			
		||||
    $end_date = new DrupalDateTime($end_value, timezone_open(drupal_get_user_timezone()));
 | 
			
		||||
    $end_date = new DrupalDateTime($end_value, timezone_open(date_default_timezone_get()));
 | 
			
		||||
 | 
			
		||||
    // Submit a valid date and ensure it is accepted.
 | 
			
		||||
    $date_format = DateFormat::load('html_date')->getPattern();
 | 
			
		||||
| 
						 | 
				
			
			@ -563,9 +563,9 @@ class DateRangeFieldTest extends DateTestBase {
 | 
			
		|||
    $this->drupalGet('entity_test/add');
 | 
			
		||||
 | 
			
		||||
    $value = '2012-12-31 00:00:00';
 | 
			
		||||
    $start_date = new DrupalDateTime($value, timezone_open(drupal_get_user_timezone()));
 | 
			
		||||
    $start_date = new DrupalDateTime($value, timezone_open(date_default_timezone_get()));
 | 
			
		||||
    $end_value = '2012-12-31 23:59:59';
 | 
			
		||||
    $end_date = new DrupalDateTime($end_value, timezone_open(drupal_get_user_timezone()));
 | 
			
		||||
    $end_date = new DrupalDateTime($end_value, timezone_open(date_default_timezone_get()));
 | 
			
		||||
 | 
			
		||||
    $date_format = DateFormat::load('html_date')->getPattern();
 | 
			
		||||
    $time_format = DateFormat::load('html_time')->getPattern();
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -0,0 +1,100 @@
 | 
			
		|||
<?php
 | 
			
		||||
 | 
			
		||||
namespace Drupal\system;
 | 
			
		||||
 | 
			
		||||
use Drupal\Core\Config\ConfigCrudEvent;
 | 
			
		||||
use Drupal\Core\Config\ConfigEvents;
 | 
			
		||||
use Drupal\Core\Config\ConfigFactoryInterface;
 | 
			
		||||
use Drupal\Core\Session\AccountEvents;
 | 
			
		||||
use Drupal\Core\Session\AccountInterface;
 | 
			
		||||
use Symfony\Component\EventDispatcher\EventSubscriberInterface;
 | 
			
		||||
use Symfony\Component\HttpKernel\KernelEvents;
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * Event handler that resolves time zone based on site and user configuration.
 | 
			
		||||
 *
 | 
			
		||||
 * Sets the time zone using date_default_timezone_set().
 | 
			
		||||
 *
 | 
			
		||||
 * @see date_default_timezone_set()
 | 
			
		||||
 */
 | 
			
		||||
class TimeZoneResolver implements EventSubscriberInterface {
 | 
			
		||||
 | 
			
		||||
  /**
 | 
			
		||||
   * The config.
 | 
			
		||||
   *
 | 
			
		||||
   * @var \Drupal\Core\Config\ConfigFactoryInterface
 | 
			
		||||
   */
 | 
			
		||||
  protected $configFactory;
 | 
			
		||||
 | 
			
		||||
  /**
 | 
			
		||||
   * The current user.
 | 
			
		||||
   *
 | 
			
		||||
   * @var \Drupal\Core\Session\AccountInterface
 | 
			
		||||
   */
 | 
			
		||||
  private $currentUser;
 | 
			
		||||
 | 
			
		||||
  /**
 | 
			
		||||
   * TimeZoneResolver constructor.
 | 
			
		||||
   *
 | 
			
		||||
   * @param \Drupal\Core\Session\AccountInterface $current_user
 | 
			
		||||
   *   The current user.
 | 
			
		||||
   * @param \Drupal\Core\Config\ConfigFactoryInterface $config_factory
 | 
			
		||||
   *   The config factory.
 | 
			
		||||
   */
 | 
			
		||||
  public function __construct(AccountInterface $current_user, ConfigFactoryInterface $config_factory) {
 | 
			
		||||
    $this->configFactory = $config_factory;
 | 
			
		||||
    $this->currentUser = $current_user;
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  /**
 | 
			
		||||
   * Sets the default time zone.
 | 
			
		||||
   */
 | 
			
		||||
  public function setDefaultTimeZone() {
 | 
			
		||||
    if ($time_zone = $this->getTimeZone()) {
 | 
			
		||||
      date_default_timezone_set($time_zone);
 | 
			
		||||
    }
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  /**
 | 
			
		||||
   * Updates the default time zone when time zone config changes.
 | 
			
		||||
   *
 | 
			
		||||
   * @param \Drupal\Core\Config\ConfigCrudEvent $event
 | 
			
		||||
   *   The config crud event.
 | 
			
		||||
   */
 | 
			
		||||
  public function onConfigSave(ConfigCrudEvent $event) {
 | 
			
		||||
    $saved_config = $event->getConfig();
 | 
			
		||||
    if ($saved_config->getName() === 'system.date' && ($event->isChanged('timezone.default') || $event->isChanged('timezone.user.configurable'))) {
 | 
			
		||||
      $this->setDefaultTimeZone();
 | 
			
		||||
    }
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  /**
 | 
			
		||||
   * {@inheritdoc}
 | 
			
		||||
   */
 | 
			
		||||
  public static function getSubscribedEvents() {
 | 
			
		||||
    $events[ConfigEvents::SAVE][] = ['onConfigSave', 0];
 | 
			
		||||
    // The priority for this must run directly after the authentication
 | 
			
		||||
    // subscriber.
 | 
			
		||||
    $events[KernelEvents::REQUEST][] = ['setDefaultTimeZone', 299];
 | 
			
		||||
    $events[AccountEvents::SET_USER][] = ['setDefaultTimeZone'];
 | 
			
		||||
    return $events;
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  /**
 | 
			
		||||
   * Gets the time zone based on site and user configuration.
 | 
			
		||||
   *
 | 
			
		||||
   * @return string|null
 | 
			
		||||
   *   The time zone, or NULL if nothing is set.
 | 
			
		||||
   */
 | 
			
		||||
  protected function getTimeZone() {
 | 
			
		||||
    $config = $this->configFactory->get('system.date');
 | 
			
		||||
    if ($config->get('timezone.user.configurable') && $this->currentUser->isAuthenticated() && $this->currentUser->getTimezone()) {
 | 
			
		||||
      return $this->currentUser->getTimeZone();
 | 
			
		||||
    }
 | 
			
		||||
    elseif ($default_timezone = $config->get('timezone.default')) {
 | 
			
		||||
      return $default_timezone;
 | 
			
		||||
    }
 | 
			
		||||
    return NULL;
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
}
 | 
			
		||||
| 
						 | 
				
			
			@ -43,3 +43,8 @@ services:
 | 
			
		|||
    arguments: ['@theme_handler', '@cache_tags.invalidator']
 | 
			
		||||
    tags:
 | 
			
		||||
      - { name: event_subscriber }
 | 
			
		||||
  system.timezone_resolver:
 | 
			
		||||
    class: Drupal\system\TimeZoneResolver
 | 
			
		||||
    arguments: ['@current_user', '@config.factory']
 | 
			
		||||
    tags:
 | 
			
		||||
      - { name: event_subscriber }
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -0,0 +1,30 @@
 | 
			
		|||
<?php
 | 
			
		||||
 | 
			
		||||
namespace Drupal\Tests\system\Kernel;
 | 
			
		||||
 | 
			
		||||
use Drupal\KernelTests\KernelTestBase;
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * Tests deprecated methods in bootstrap throw deprecation warnings.
 | 
			
		||||
 *
 | 
			
		||||
 * @group legacy
 | 
			
		||||
 * @group system
 | 
			
		||||
 */
 | 
			
		||||
class TimeZoneDeprecationTest extends KernelTestBase {
 | 
			
		||||
 | 
			
		||||
  /**
 | 
			
		||||
   * {@inheritdoc}
 | 
			
		||||
   */
 | 
			
		||||
  public static $modules = [
 | 
			
		||||
    'system',
 | 
			
		||||
    'user',
 | 
			
		||||
  ];
 | 
			
		||||
 | 
			
		||||
  /**
 | 
			
		||||
   * @expectedDeprecation drupal_get_user_timezone() is deprecated in drupal:8.8.0. It will be removed from drupal:9.0.0. Use date_default_timezone_get() instead. See https://www.drupal.org/node/3009387
 | 
			
		||||
   */
 | 
			
		||||
  public function testDeprecation() {
 | 
			
		||||
    $this->assertEquals('Australia/Sydney', drupal_get_user_timezone());
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
}
 | 
			
		||||
| 
						 | 
				
			
			@ -0,0 +1,62 @@
 | 
			
		|||
<?php
 | 
			
		||||
 | 
			
		||||
namespace Drupal\Tests\system\Kernel;
 | 
			
		||||
 | 
			
		||||
use Drupal\KernelTests\KernelTestBase;
 | 
			
		||||
use Drupal\Tests\user\Traits\UserCreationTrait;
 | 
			
		||||
use Symfony\Component\HttpFoundation\Request;
 | 
			
		||||
use Symfony\Component\HttpKernel\Event\GetResponseEvent;
 | 
			
		||||
use Symfony\Component\HttpKernel\HttpKernelInterface;
 | 
			
		||||
use Symfony\Component\HttpKernel\KernelEvents;
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * @coversDefaultClass \Drupal\system\TimeZoneResolver
 | 
			
		||||
 * @group system
 | 
			
		||||
 */
 | 
			
		||||
class TimezoneResolverTest extends KernelTestBase {
 | 
			
		||||
 | 
			
		||||
  use UserCreationTrait;
 | 
			
		||||
 | 
			
		||||
  /**
 | 
			
		||||
   * {@inheritdoc}
 | 
			
		||||
   */
 | 
			
		||||
  public static $modules = [
 | 
			
		||||
    'system',
 | 
			
		||||
    'user',
 | 
			
		||||
  ];
 | 
			
		||||
 | 
			
		||||
  /**
 | 
			
		||||
   * Tests time zone resolution.
 | 
			
		||||
   */
 | 
			
		||||
  public function testGetTimeZone() {
 | 
			
		||||
    $this->installEntitySchema('user');
 | 
			
		||||
    $this->installSchema('system', ['sequences']);
 | 
			
		||||
    $this->installConfig(['system']);
 | 
			
		||||
 | 
			
		||||
    // Check the default test timezone.
 | 
			
		||||
    $this->assertEquals('Australia/Sydney', date_default_timezone_get());
 | 
			
		||||
 | 
			
		||||
    // Test the configured system timezone.
 | 
			
		||||
    $configFactory = $this->container->get('config.factory');
 | 
			
		||||
    $timeZoneConfig = $configFactory->getEditable('system.date');
 | 
			
		||||
    $timeZoneConfig->set('timezone.default', 'Australia/Adelaide');
 | 
			
		||||
    $timeZoneConfig->save();
 | 
			
		||||
 | 
			
		||||
    $eventDispatcher = $this->container->get('event_dispatcher');
 | 
			
		||||
    $kernel = $this->container->get('kernel');
 | 
			
		||||
 | 
			
		||||
    $eventDispatcher->dispatch(KernelEvents::REQUEST, new GetResponseEvent($kernel, Request::create('http://www.example.com'), HttpKernelInterface::MASTER_REQUEST));
 | 
			
		||||
 | 
			
		||||
    $this->assertEquals('Australia/Adelaide', date_default_timezone_get());
 | 
			
		||||
 | 
			
		||||
    $user = $this->createUser([]);
 | 
			
		||||
    $user->set('timezone', 'Australia/Lord_Howe');
 | 
			
		||||
    $user->save();
 | 
			
		||||
 | 
			
		||||
    $this->setCurrentUser($user);
 | 
			
		||||
 | 
			
		||||
    $this->assertEquals('Australia/Lord_Howe', date_default_timezone_get());
 | 
			
		||||
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
}
 | 
			
		||||
| 
						 | 
				
			
			@ -221,13 +221,13 @@ abstract class QueryPluginBase extends PluginBase implements CacheableDependency
 | 
			
		|||
  }
 | 
			
		||||
 | 
			
		||||
  /**
 | 
			
		||||
   * Set the database to the current user timezone,
 | 
			
		||||
   * Set the database to the current user timezone.
 | 
			
		||||
   *
 | 
			
		||||
   * @return string
 | 
			
		||||
   *   The current timezone as returned by drupal_get_user_timezone().
 | 
			
		||||
   *   The current timezone as returned by date_default_timezone_get().
 | 
			
		||||
   */
 | 
			
		||||
  public function setupTimezone() {
 | 
			
		||||
    return drupal_get_user_timezone();
 | 
			
		||||
    return date_default_timezone_get();
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  /**
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -104,7 +104,7 @@ class TimestampTest extends BrowserTestBase {
 | 
			
		|||
    $date = new DrupalDateTime($value, 'UTC');
 | 
			
		||||
 | 
			
		||||
    // Update the timezone to the system default.
 | 
			
		||||
    $date->setTimezone(timezone_open(drupal_get_user_timezone()));
 | 
			
		||||
    $date->setTimezone(timezone_open(date_default_timezone_get()));
 | 
			
		||||
 | 
			
		||||
    // Display creation form.
 | 
			
		||||
    $this->drupalGet('entity_test/add');
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -191,9 +191,8 @@ class TimezoneTest extends EntityKernelTestBase implements FormInterface {
 | 
			
		|||
    }
 | 
			
		||||
 | 
			
		||||
    // Validate the timezone setup.
 | 
			
		||||
    $this->assertEquals($this->timezones['user'], drupal_get_user_timezone(), 'Subsequent tests assume specific value for drupal_get_user_timezone().');
 | 
			
		||||
    $this->assertEquals(drupal_get_user_timezone(), date_default_timezone_get(), "Subsequent tests may assume PHP's time is set to Drupal user's time zone.");
 | 
			
		||||
    $this->assertEquals(drupal_get_user_timezone(), $this->date->getTimezone()->getName(), 'Subsequent tests assume DrupalDateTime objects default to Drupal user time zone if none specified');
 | 
			
		||||
    $this->assertEquals($this->timezones['user'], date_default_timezone_get(), 'Subsequent tests assume specific value for date_default_timezone_get().');
 | 
			
		||||
    $this->assertEquals(date_default_timezone_get(), $this->date->getTimezone()->getName(), 'Subsequent tests assume DrupalDateTime objects default to Drupal user time zone if none specified');
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  /**
 | 
			
		||||
| 
						 | 
				
			
			@ -295,7 +294,7 @@ class TimezoneTest extends EntityKernelTestBase implements FormInterface {
 | 
			
		|||
 | 
			
		||||
        // Check that $this->date has not anywhere been accidentally changed
 | 
			
		||||
        // from its default timezone, invalidating the test logic.
 | 
			
		||||
        $this->assertEquals(drupal_get_user_timezone(), $this->date->getTimezone()->getName(), "Test date still set to user timezone.");
 | 
			
		||||
        $this->assertEquals(date_default_timezone_get(), $this->date->getTimezone()->getName(), "Test date still set to user timezone.");
 | 
			
		||||
 | 
			
		||||
        // Build a list of cases where the result is not as expected.
 | 
			
		||||
        // Check the time has been understood correctly.
 | 
			
		||||
| 
						 | 
				
			
			@ -348,7 +347,7 @@ class TimezoneTest extends EntityKernelTestBase implements FormInterface {
 | 
			
		|||
          ];
 | 
			
		||||
        }
 | 
			
		||||
      }
 | 
			
		||||
      $this->assertEquals($this->timezones['user'], drupal_get_user_timezone(), 'Subsequent tests assume specific value for drupal_get_user_timezone().');
 | 
			
		||||
      $this->assertEquals($this->timezones['user'], date_default_timezone_get(), 'Subsequent tests assume specific value for date_default_timezone_get().');
 | 
			
		||||
      $message = "The correct timezone should be set on the processed {$this->elementType}  elements: (expected, actual) \n" . print_r($wrongTimezones, TRUE);
 | 
			
		||||
      $this->assertCount(0, $wrongTimezones, $message);
 | 
			
		||||
    }
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -3,8 +3,9 @@
 | 
			
		|||
namespace Drupal\Tests\Core\Session;
 | 
			
		||||
 | 
			
		||||
use Drupal\Core\Session\AccountInterface;
 | 
			
		||||
use Drupal\Tests\UnitTestCase;
 | 
			
		||||
use Drupal\Core\Session\AccountProxy;
 | 
			
		||||
use Drupal\Tests\UnitTestCase;
 | 
			
		||||
use Symfony\Component\EventDispatcher\EventDispatcherInterface;
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * @coversDefaultClass \Drupal\Core\Session\AccountProxy
 | 
			
		||||
| 
						 | 
				
			
			@ -17,7 +18,8 @@ class AccountProxyTest extends UnitTestCase {
 | 
			
		|||
   * @covers ::setInitialAccountId
 | 
			
		||||
   */
 | 
			
		||||
  public function testId() {
 | 
			
		||||
    $account_proxy = new AccountProxy();
 | 
			
		||||
    $dispatcher = $this->prophesize(EventDispatcherInterface::class);
 | 
			
		||||
    $account_proxy = new AccountProxy($dispatcher->reveal());
 | 
			
		||||
    $this->assertSame(0, $account_proxy->id());
 | 
			
		||||
    $account_proxy->setInitialAccountId(1);
 | 
			
		||||
    $this->assertFalse(\Drupal::hasContainer());
 | 
			
		||||
| 
						 | 
				
			
			@ -36,20 +38,11 @@ class AccountProxyTest extends UnitTestCase {
 | 
			
		|||
   */
 | 
			
		||||
  public function testSetInitialAccountIdException() {
 | 
			
		||||
    $this->expectException(\LogicException::class);
 | 
			
		||||
    $account_proxy = new AccountProxy();
 | 
			
		||||
    $dispatcher = $this->prophesize(EventDispatcherInterface::class);
 | 
			
		||||
    $account_proxy = new AccountProxy($dispatcher->reveal());
 | 
			
		||||
    $current_user = $this->prophesize(AccountInterface::class);
 | 
			
		||||
    $account_proxy->setAccount($current_user->reveal());
 | 
			
		||||
    $account_proxy->setInitialAccountId(1);
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
namespace Drupal\Core\Session;
 | 
			
		||||
 | 
			
		||||
if (!function_exists('drupal_get_user_timezone')) {
 | 
			
		||||
 | 
			
		||||
  function drupal_get_user_timezone() {
 | 
			
		||||
    return date_default_timezone_get();
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
}
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
		Loading…
	
		Reference in New Issue