Problem/Motivation

In #2328645: Remove remaining global $user, I moved that call to setAccount(). Which is nice, because it means that changing the current user also automatically sets the currect timezone. However, it means it's never called for anonymous users, because then the account is created on-demand in getAccount().

This should also be the proper fix for #2446859: Installer warning: date_default_timezone_get(): It is not safe to rely on the system's timezone settings and might allow us to remove the @ there again.

Proposed resolution

Add that line in getAccount() too, after initializing the AnonymousUserSession object.

Remaining tasks

User interface changes

API changes

Data model changes

Support from Acquia helps fund testing for Drupal Acquia logo

Comments

Berdir’s picture

Status: Active » Needs review
Issue tags: +Needs tests

Here's a patch, needs tests.

Berdir’s picture

Status: Needs review » Needs work

The last submitted patch, 2: user-date-timezone-2510150-1.patch, failed testing.

Berdir’s picture

Drupal\Core\Database\DatabaseExceptionWrapper: SQLSTATE[HY000]: General error: failed to instantiate user-supplied statement class: CREATE TABLE {cache_config} error in Drupal\dblog\Tests\ConnectionFailureTest.

Could actually be a real error since that test sounds like it might be doing something funky.

Status: Needs work » Needs review

Status: Needs review » Needs work

The last submitted patch, 2: user-date-timezone-2510150-1.patch, failed testing.

Berdir’s picture

Status: Needs work » Needs review
FileSize
1.86 KB
947 bytes

Yeah, fun test. This fixes it, not very pretty, though.

Berdir’s picture

And here are tests.

The last submitted patch, 8: user-date-timezone-2510150-8-tests-only.patch, failed testing.

Berdir’s picture

That's possible, should we consider reverting that as well then?

dysrama’s picture

Patch works for me, encountered the issue when trying to access the site as anon after turning on page cache.
Don't know enough about d8 to review the code though.

znerol’s picture

I failed to reproduce the message mentioned in #2471405: When not logged Drupal\Core\EventSubscriber\FinishResponseSubscriber->setExpiresNoCache() causes a PHP warning because of an invalid timezone even when evaluating the offending line directly:

$ php -r "DateTime::createFromFormat('j-M-Y H:i:s T', '19-Nov-1978 05:00:00 GMT');"

My environment:

$ php -v
PHP 5.6.9-0+deb8u1 (cli) (built: Jun  5 2015 11:03:27) 
Copyright (c) 1997-2015 The PHP Group
Zend Engine v2.6.0, Copyright (c) 1998-2015 Zend Technologies
    with Zend OPcache v7.0.4-dev, Copyright (c) 1999-2015, by Zend Technologies
    with Xdebug v2.2.5, Copyright (c) 2002-2014, by Derick Rethans
$ php -i | grep timezone
Default timezone => Europe/Berlin
date.timezone => no value => no value
$ php -i | grep error_reporting
error_reporting => 32767 => 32767
$ php -r 'echo(E_ALL);'
32767
Berdir’s picture

Status: Needs review » Needs work

This is also not correct :(

As I just experienced, in a custom controller, it is possible to create a date() without accessing the current user at all. Then this code isn't executed and the timezone is wrong.

Berdir’s picture

Priority: Normal » Major
dawehner’s picture

mhhh, its tricky, given that we should not authenticate too early,
so what about running it after authenciation?

Status: Needs work » Needs review
mpdonadio’s picture

Is this Needs Review or Needs Work? It looks like the retest got stuck.

Berdir’s picture

Just re-uploading the patch.

Berdir’s picture

Status: Needs review » Needs work
Issue tags: +Needs tests

I think we need a test that replicates #14.

Somewhere in a test module, add a route and a controller that does nothing but return the current date in a Response() object. _access: 'true', so that there are no access restrictions.

Then access that in the test, similar to the existing test assertions there.

The last submitted patch, 19: user-date-timezone-2510150-8.patch, failed testing.

tduong’s picture

Status: Needs work » Needs review
FileSize
4.65 KB
6.97 KB

Uploaded patch:

  • added route and controller in the system test module
  • made sure to initialise the timezone when no account has been set explicitly in AuthenticationSubscriber instead of AccountProxy (from patch in #19)
  • added an assertion in the test to ensure that this test date uses the default timezone
  • fixed the NodeAttributesTest failing test

Status: Needs review » Needs work

The last submitted patch, 22: user-date-timezone-2510150-22.patch, failed testing.

almaudoh’s picture

+      }
+      catch (\Exception $e) {
+        // Ignore exceptions that happen when the current user can't be
+        // accessed.
       }
     }

This means an exception may be thrown in subsequent lines if $context['user'] or $context['uid'] is referenced since they may not be defined.

Berdir’s picture

Those two keys are by design optional. It's already wrapped in an if ($this->currentUser) and might sometimes not exist. This just means it might not exist in more cases.

tduong’s picture

Status: Needs work » Needs review
Issue tags: -Needs tests
Related issues: +#2611082: Inconsistent time zones in web tests

To fix these tests we need to explicitly call date_default_timezone_set('Australia/Sydney'); in setUp(), so that the timezone is consistent while the installer runs. The proper fix is already discussed in #2611082: Inconsistent time zones in web tests issue, so the change in the patch #2 is the solution for both issues. Both changes are needed at the same time.

I'll close the other issue as we will now solve the bug here.

tduong’s picture

mpdonadio’s picture

Assigned: Unassigned » mpdonadio

There were other bits in the patch in #2611082: Inconsistent time zones in web tests that also need to be added. I'll add them over my lunch break and upload.

Berdir’s picture

I'm not sure. Maybe the test but we already are adding test coverage for this here and have failing tests without that, so...

We have a passing patch here now, we already had the rdf test fix here too and the other tests are passing with both changes combined.

mpdonadio’s picture

Assigned: mpdonadio » Unassigned

OK, just talked with @berdir on IRC, @tduong is going to add a few bit from the other issue in, and I'll do final review.

tduong’s picture

The last submitted patch, 31: user-date-timezone-2510150-31-test_only.patch, failed testing.

mpdonadio’s picture

+++ b/core/lib/Drupal/Core/Logger/LoggerChannel.php
@@ -93,9 +93,15 @@ public function log($level, $message, array $context = array()) {
+      try {
+        if ($this->currentUser) {
+          $context['user'] = $this->currentUser;
+          $context['uid'] = $this->currentUser->id();
+        }
+      }
+      catch (\Exception $e) {
+        // Ignore exceptions that happen when the current user can't be
+        // accessed.
       }
     }

I think the code here can warrant a better comment as to who the try/catch is needed and expand a bit why the exception can be ignored.

Otherwise, I think the change is reasonable and the test coverage is adequate.

Some of the code is cherry-picked from one of my patches on #2611082: Inconsistent time zones in web tests (mainly the new TimeZoneTest), if anyone objects to me doing the final review.

Going to do some manual testing to double check this before I RTBC it.

mpdonadio’s picture

Status: Needs review » Reviewed & tested by the community

Just ran some manual tests w/ a bad TZ in php.ini, and this does appear to fix the original issue reported in #2638678: date.timezone not being set in php.ini results in exceptions (which is mostly an untestable situation).

I'm not hung up on the comment for the try/catch I mentioned above, so I am setting RTBC, and a committer can the have final call on that.

alexpott’s picture

Status: Reviewed & tested by the community » Needs work
  1. +++ b/core/lib/Drupal/Core/Logger/LoggerChannel.php
    @@ -93,9 +93,15 @@ public function log($level, $message, array $context = array()) {
    +      try {
    +        if ($this->currentUser) {
    +          $context['user'] = $this->currentUser;
    +          $context['uid'] = $this->currentUser->id();
    +        }
    +      }
    +      catch (\Exception $e) {
    +        // Ignore exceptions that happen when the current user can't be
    +        // accessed.
           }
    

    This needs a comment - why is the if($this->currentUser) not working? Or to ask the other way around how do we get into the situation where $this->currentUser == TRUE but ->id() throws an exception?

  2. +++ b/core/modules/simpletest/src/WebTestBase.php
    @@ -674,6 +674,15 @@ protected function drupalLogout() {
    +
    

    Unnecessary blank line

Berdir’s picture

$this->currentUser is just the account proxy. loading the user and especially calling drupal_get_user_timezone() could fail. See the test fail in the first issue https://qa.drupal.org/pifr/test/1077288

We could add something like that not sure. But while we're adding it here, for that specific thing, I think this try/catch is more generic. Whatever happens, we should do everything we can to not throw exceptions or die while trying to log something. and since we're already in the logger, I think we also shouldn't try to log that.

tduong’s picture

Status: Needs work » Needs review
FileSize
1.14 KB
9.51 KB

Updated exception comment and deleted unnecessary blank line.

swentel’s picture

Status: Needs review » Reviewed & tested by the community

Back to RTBC then.

alexpott’s picture

Status: Reviewed & tested by the community » Fixed

Thanks for addressing my feedback. Committed 9970cf7 and pushed to 8.0.x and 8.1.x. Thanks!

  • alexpott committed af54540 on 8.1.x
    Issue #2510150 by tduong, Berdir: AccountProxy is not calling...

  • alexpott committed 9970cf7 on
    Issue #2510150 by tduong, Berdir: AccountProxy is not calling...

Status: Fixed » Closed (fixed)

Automatically closed - issue fixed for 2 weeks with no activity.