Support for Drupal 7 is ending on 5 January 2025—it’s time to migrate to Drupal 10! Learn about the many benefits of Drupal 10 and find migration tools in our resource center.
Problem/Motivation
Trying to resolve [user:last-login] token leads to fatal error
PHP Fatal error: Call to undefined method Drupal\Core\Session\AccountProxy::getLastLoginTime() in /[...]/core/modules/user/user.tokens.inc on line 111
Comments
Comment #1
BerdirTrying to resolve based on what? The current user?
A lot of methods in there assume that account is a user entity, but it looks like you actually get the current user object injected. That's not really supported.
See user_tokens(), where it resolves the current-user token, it explicitly loads the user entity, so that should be fine.
I assume you (or some code that you are using) have your own token replace and are passing in the account proxy/current user in there directly. That code needs to do the same as user_tokens() does for the current-user use case.
The only thing that core can do is add an explicit interface check for UserInterface somewhere in there and ignore the tokens if it doesn't match. Not sure if that's a major problem. Only if the token replace code is actually in core I think.
Setting to needs more info, can you post a full stacktrace or at least steps to reproduce this?
Comment #2
mondrakeThanks a lot @Berdir for the explanation. In fact you are right, culprit is here, exactly current user instead of user.
Maybe, still, we could throw an exception in user_tokens if $data['user'] is not the expected object, instead of letting it fail fatally?
Comment #5
dpiRe-iterating on #2493293-2: Validate user variable before continuing token replacement, changing direction of issue:
The cause of this error is that the contrib mistakenly passed an instance of
AccountInterface
, instead ofUserInterface
. This is sometimes not an issue, sometimes there wont be any errors until the user uses a token that is not common betweenAccountInterface
andUserInterface
.We should either:
instanceof UserInterface
, orThe following code leads me to believe checking solution 1 above is the proper solution:
user.tokens.inc
But it will likely break a lot of code...
Comment #6
dpiComment #17
larowlanGiven its been a while, marking this as minor