Problem/Motivation
According to documentation, User::getLastAccessedTime returns 0 if the user has never accessed the site:
A value of 0 means the user has never accessed the site
But in fact, the returned value in such case is '0' (string). And for users that accessed the site, the returned timestamp is also a string, when the expected returned value type is integer:
Return value
int Timestamp of the last access.
This is not accurate and makes it fail in some scenarios, like strict comparisons.
Steps to reproduce
After logging into a site as user 1, execute this Drush command: drush eval "var_dump(\Drupal\user\Entity\User::load(1)->getLastAccessedTime());". The dumped value is a string, not an int.
Proposed resolution
- Cast the returned type to integer.
- Change the
\Drupal\Core\Session\UserSession::$accesstype toint.
Remaining tasks
Review
User interface changes
Introduced terminology
API changes
Data model changes
Release notes snippet
| Comment | File | Size | Author |
|---|
Issue fork drupal-2954725
Show commands
Start within a Git clone of the project using the version control instructions.
Or, if you do not have SSH keys set up on git.drupalcode.org:
- 2954725-fix-getlastaccessedtime
changes, plain diff MR !13712
Comments
Comment #2
manuel.adanComment #6
ravi.shankar commentedI have done patch on Drupal 8.8.x-dev
Comment #8
dpiChange looks good, but needs work.
I think we should go ahead and fix the documentation for
\Drupal\Core\Session\UserSession::$access, which claims the value is a string, and check for any createdUser/UserSessionobjects initialised with 'access' => stringComment #17
acbramley commentedLooks like this still needs fixing, but most likely needs a reroll, definitely needs tests, and we should see if the other methods have corresponding issues.
Comment #18
akashkumar07 commentedAdding a reroll of #6.
Comment #19
vsujeetkumar commentedFixing the failed test case, Please have a look.
Comment #20
acbramley commentedLooks good, but we should also have tests around this (core is notorious for setting string values when updating int fields via the UI).
Also need to action #8
Comment #21
quietone commentedChanging to the DX special tag defined on Issue tags -- special tags.
Comment #24
dcam commentedI converted #19 to an MR and added a Kernel test.
Comment #25
dcam commentedComment #26
smustgrave commentedBelieve #8 still needs to be addressed.
Comment #27
dcam commentedI changed the
UserSession->accesstype and updated the proposed resolution accordingly.I searched for instantiations of
UserandUserSession. I didn't find anyUserinstantiations. None of theUserSessioninstantiations set theaccessvalue. No action was taken.Comment #28
smustgrave commentedFeedback appears to be addressed.
Comment #30
needs-review-queue-bot commentedThe Needs Review Queue Bot tested this issue. It fails the Drupal core commit checks. Therefore, this issue status is now "Needs work".
This does not mean that the patch necessarily needs to be re-rolled or the MR rebased. Read the Issue Summary, the issue tags and the latest discussion here to determine what needs to be done.
Consult the Drupal Contributor Guide to find step-by-step guides for working with issues.
Comment #31
dcam commentedPost-bot-rebellion rebase
Comment #32
dcam commentedThere was a merge conflict in
core/modules/user/tests/src/Kernel/UserEntityTest.php. I rebased the MR.Comment #33
dcam commentedHad to rebase due to a deprecation test removal in
core/modules/user/tests/src/Kernel/UserEntityTest.php.Comment #34
dcam commentedThis needed a rebase due to the removal of migrate_drupal.
Comment #35
godotislateAccountProxy and UserSession implement
getLastAccessedTime()as well, so presumably they need int casts on the return value?Comment #36
acbramley commentedConfirming at least UserSession needs the cast -
\Drupal\user\Authentication\Provider\Cookie::getUserFromSessioncreates a UserSesssion with values directly from the database. All of the timestamp fields are strings at this point. The UserSession constructor blindly sets these values on its properties.I think AccountProxy is fine since it just does
$this->getAccount()->getLastAccessedTime()so the other casts will be hit there.Comment #37
acbramley commentedComment #38
dcam commentedThe line being changed in the User entity class was changed today by #3574012: Add a getFieldValue() method to bypass typed data overhead for specific use cases. The bug probably needs to be re-verified and the code has to be updated if it still exists.
Comment #39
acbramley commentedComment #40
smustgrave commentedBelieve feedback for this one has been addressed.
Thanks!
Comment #44
godotislateCommitted and pushed c62d379 to main.
There were merge conflicts against 11.x in the test classes, because of deprecation test methods that were removed in main. I manually resolved and committed dd78526 and pushed to 11.x. Thanks!
Comment #46
godotislateThere was this test failure on 11.x
so I reverted (commit 34e8746cc05c1404dcb1939cf7d80f98cbc42e3)
Set to Patch to be ported, will need an 11.x MR.