Problem/Motivation
#2807785: Move global constants from *.module files into interfaces deprecated a bunch of constants but it did not actually replace their usage. We should do this. This issue handles DRUPAL_USER_TIMEZONE_DEFAULT
, DRUPAL_USER_TIMEZONE_EMPTY
, and DRUPAL_USER_TIMEZONE_SELECT
. This is a bug because we've deprecated something but we've not completed the task and, more importantly, the old constants are in the System module and used by it but the new constants are in the User module. That does not work. The user module is dependent on the System module not the other way around.
Proposed resolution
TBD
Remaining tasks
Work out the solution
User interface changes
None
API changes
TBD
Data model changes
None
Comment | File | Size | Author |
---|---|---|---|
#33 | 3015811-8.9.x-32.patch | 11.17 KB | alexpott |
#33 | 30-32-interdiff.txt | 1.66 KB | alexpott |
#30 | 3015811-9.0.x-30.patch | 12.01 KB | alexpott |
#30 | 3015811-8.9.x-30.patch | 12.02 KB | alexpott |
#24 | 3015811-24.patch | 12.02 KB | alexpott |
Comments
Comment #2
alexpottComment #5
longwaveThis moves all the user timezone related code out of system.module and into user.module where it belongs.
The config is still owned by
system.date
but instead of simply migrating it to the user module I wonder if we should go further and deprecatetimezone.user.configurable
andUserInterface::TIMEZONE_SELECT
entirely and rely on the form display configuration to allow users to hide or show the timezone field in the relevant contexts. As I discovered in testing even if you allow the timezone to be configured in this custom config, it is still not shown if you remove it from the form display.Comment #6
BerdirI think a lot of this was already done in #2331763: Remove user hooks and form alters from system module but never found anyway that wanted to review this :)
Comment #7
longwaveWhoops, didn't see that. The default value approach is different here, I should probably take your method, but the rest of it is so out of date it needed a complete reroll anyway by the looks of it :)
Comment #9
longwaveGood that we got the same single test failure, but not sure I understand why...
Comment #10
alexpottSo the test is failing because these changes have an interesting side effect. It's because an empty string is being filtered by \Drupal\Core\Field\FieldItemList::preSave(). In HEAD the system_user_post_save() is fired after this and is therefore unaffected and can set an empty string value. But moving it to User::preSave() means it comes before.
Comment #11
alexpottSo we could move the preSave functionality to \Drupal\user\UserStorage::doSaveFieldItems() to preserve the order and functionality but OTOH does it really matter? I think a NULL and an empty string will be treated the same.
Comment #12
longwaveBorrowed @Berdir's approach from #2331763: Remove user hooks and form alters from system module for the default value, and modified the D6 migration test to use assertEquals, which works around the "" vs null issue.
Comment #13
borisson_I don't think this is the right call here. The interface
\Drupal\Core\Session\AccountInterface::getTimeZone
has an@return string
as docblok, so it should always return a string. Other code that uses strict checking could start misbehaving when it gets a NULL-value instead of''
.I discussed this with @Wim Leers at the sprint weekend, because I wasn't sure about this, he mentioned #3095922. That issue adds a default value to the comment language field.
I think we could also add a default value of '' to the user's timezone, so that it doesn't use NULL but it uses that instead.
Because this issue otherwise would not be just a deprecation but it would also introduce a behavior change.
We could also update the interface to say
@return string|NULL
- but I think that is an even bigger change.I haven't validated if that this actually works though
Comment #14
longwaveSetting the default value of the timezone field in the User entity doesn't work, as it is still filtered by FieldItemList::preSave() as noted in #10, and I think this would also be considered a behaviour change?
One alternative that doesn't mean altering the test is overriding TimeZoneItem::isEmpty() to allow an empty string timezone which then doesn't get filtered, this passes the test but I am also not sure if this is considered a behaviour change.
Comment #16
longwaveSo #14 is also a behaviour change in different ways, as it causes other tests to fail. Not sure what to do now, but it does feel like allowing both NULL and empty string for the timezone shouldn't be allowed, we should pick just one that means "unknown/not set" and stick to it.
Comment #17
andypostit looks weird name for function in user's module
Comment #18
Gábor HojtsyIn #3111942: Remove all remaining @deprecated code from system module this issue was raised as one that would take care of DRUPAL_USER_TIMEZONE_* constants. It indeed seems to do as there does not seem to be any further actual use of them.
It is not possible to remove them here, but a 9.0.x-only issue is possible after this to remove them cleanly.
Comment #19
alexpottHow about we just punt on system_user_presave() and leave it alone - and maybe open a follow up. It's not necessary to complete the deprecation.
Comment #20
alexpottThinking about this some more - we can move the hook implementation to the user module - a little odd but at least all the oddness is in the user module. Also fixing #17
Comment #22
Gábor HojtsyMarking as 9 beta requirement given we need to remove usages before we an remove the constant.
Comment #23
longwave#19/20 look OK to me, we could add a @todo to user_user_presave() as we know we should clean it up in the future?
Comment #24
alexpottAdds a @todo
Comment #25
alexpottSo you could argue that is API but it is only used as a helper to alter forms (and form alters are not API) - also it is completely unused by contrib - http://grep.xnddx.ru/search?text=system_user_timezone&filename=
Comment #26
BerdirIMHO \Drupal\Tests\user\Kernel\Migrate\d6\MigrateUserTest::testUser() is just broken, having the timezone behavior set to setting a default but then expecting it to be '' just because it is a kernel test that didn't actually set a default timezone makes no sense :)
Also, content entity fields never have been type-safe and you can't expect that from them $node->id() could be an integer or a string, that's just how it is atm. Same for '' vs NULL IMHO.
But we can discuss that in the follow-up to unblock this.
Glad that we finally moved that piece to user.module, even though I don't think it would have been necessary to resolve this issue. system and user are both required modules, both depend on each other, before and after this change. And it's only half-done now with this, as the setting is still in system.date and its expected values are constants defined in user.module, so nothing really changed :) But maybe it's the first step to further cleanups ;)
Haven't seen this @todo format before (URL first), but we do seem to have 50 instances of that in core. I'm used to @todo Do xy in URL.
Comment #27
BerdirFunny enough, in 2014 I wrote this in the issue summary of #2331763: Remove user hooks and form alters from system module (which I just closed as duplicate)
> Because one required module altering the other makes so much sense.
And what we end up doing here is just inverting it by altering a system.module form in user.module for the settings UI ;)
Comment #28
alexpottWell at least in user.info.yml we have
So dependencies are the right way around. And also the user module is installed after system in the installer.
Comment #29
catchThis doesn't apply to 9.0.x.
Comment #30
alexpottHere's a patch for 9.0.x and 8.9.x - the 8.9.x patch is the same as #24
Comment #31
alexpottFixing tags
Comment #32
catchSo I don't think the 8.9.x patch should remove this. We could maybe mark it @internal explicitly?
Comment #33
alexpottOkay marking it @internal and created a change record for this.
I asked @catch if we should follow the deprecation process and he said:
Comment #34
longwaveThis looks good and gets us one step closer to D9 beta1.
Comment #37
Gábor HojtsySuperb, thanks all. The Drupal 8.9 patch did not apply but it was an easy fix on commit (the removed use statement's context changed).
Comment #38
Gábor HojtsyComment #39
kim.pepperDid we mean to publish the draft change record?
Comment #40
andypostPublished CR