Problem/Motivation
The roles property of text formats was thought to be a convenience originally, but it has become more of a nuisance by now.
First of all, there is #2569741: [PP-1] FilterFormat should add the roles as config dependencies. In particular, in #39 there it is made clear that having those roles there introduces a circular dependency between text formats and roles.
Furthermore, the roles are not included when exporting text formats, which leads to unintentional diffs in version control. This has long been a problem for custom sites owners, but has also struck core development: #3086965: Allow embedding media in CKEditor in Umami removed the roles property from the Basic HTML and Full HTML formats in Umami, as those were re-exported for the patch there. The Restricted HTML format in Umami and all three formats in Standard still have the roles in there, however. This inconsistency is unfortunate and should be resolved one way or the other. But instead of manually re-introducing the roles where they were removed, let's go ahead and remove them everywhere.
And if we are not using it in core and both for profiles/distributions as well as for custom sites the trend has strongly gone in favor of automatically exporting configuration over handcrafting it, we might as well deprecate it so we can resolve #2569741: [PP-1] FilterFormat should add the roles as config dependencies in Drupal 10.
Proposed resolution
Remove the roles property from all filters in core. The respective roles in Umami and Standard already have the proper permissions, so this will not be a functional change.
Subsequently add a deprecation notice in FilterFormat::get() and FilterFormat::set() for the roles property.
Remaining tasks
- ✅
Review MR - ✅
Write change notice
User interface changes
None.
API changes
None.
Data model changes
The roles property of text formats will be deprecated.
| Comment | File | Size | Author |
|---|
Issue fork drupal-3167198
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:
Comments
Comment #2
tstoecklerHere's an initial patch. It has the deprecation and moves the existing test coverage into a legacy test. Somehow I can't get the legacy test to work correctly, though, maybe someone else can figure out what is going on.
Comment #4
tstoecklerSo I had the logic a little bit mixed up. We cannot (yet) deprecate getting the property altogether, as we are still doing that in
FilterFormat::postSave(). We can, however, throw a deprecation if we are getting it and the value is non-empty.This fixes a couple of the tests, I did not run all of the ones that failed.
Comment #6
tstoecklerThis should fix more test failures. One more leftover roles property in the test text format and fixed the text format form calling ->set('roles', ...).
Comment #8
tstoecklerThis should fix the remaining tests but for one. In order to fix
ConfigEntityImportTestI removed therolesproperty from the list of export property, so it's possible that other things break due to this, although I couldn't think of anything specific.Also fixed the unneeded use statement.
Still haven't figured out what's wrong with
FilterLegacyTest, so if that's the only failure, I'll leave this for someone else.Comment #10
tstoecklerAhhh, figured it out now. The failure output was confusing due to the expected deprecations, but the fix was trivial in the end.
Also fixed up the method overrides to have a proper @inheritdoc, the previous descriptions were still left over from when I used (non-overriding) __get() and __set().
Comment #11
tstoecklerComment #12
tstoecklerSorry, stray newline I looked over in the new code.
Comment #13
tstoecklerNow that the patch is (presumably) green, some notes for reviewers:
filter_testtext format, some permissions are missing in some of the tests. This may lead to some disruption in contrib. The changes are 100% backwards-compatible (i.e. assuming this lands in 9.1, the changed test will pass with both 9.0 and 9.1), though, so I think this is acceptable (and I also do not know of a different way to fix this). But this may be contentiousComment #14
alexpottThere's an interesting tension here. in HEAD \Drupal\Core\Entity\EntityForm::copyFormValuesToEntity loops around $form_state->getValues() setting all the values on the entity apart from the filters - because thats the plugin collect key.
With this change we're hardcoding the name and format values in copyFormValuesToEntity but we're still looping around in submitForm.
If we want to avoid causing modules any problems we could implement hook_ENTITY_TYPE_insert in the filter test module. That way any contrib relying on this test config doesn't have to change. As the tests changed here should the update is simple and will work on Drupal 9.0 too. However adding the hook might be worth it given some modules do install the filter_test module in their tests - see http://codcontrib.hank.vps-private.net/search?text=%27filter_test%27&fil...
This is what causes the deprecation to be triggered. So the test is testing itself. I think we need to trigger the deprecation in the postSave()... specifically in
Ah that is going to trigger the deprecation. Because of
$this->get('roles'). So I guess this is okay but also I think we should not make calls in the test that trigger the deprecation so that we can test that regular runtime usage does indeed trigger it as expected.I think we should use a filter format without the roles key for this test now - so that we can be sure that setting it what triggers the deprecation.
I think we should assert that the roles key is not present when toArray() is called. After making this save.
This works because the administator role is given every permission. Nice.
Comment #15
tstoecklerThanks for the review!
Answering in order:
::submitForm()is superfluous because::copyFormValuesToEntity()should already have been called at that point. I just wanted to keep the change here as minimal as possible. But looking over it again, I agree that having the foreach there makes the code less clear than it could be, so I think that just setting the values explicitly would be an improvement. But will also investigate if my suspicion is correct and this is dead code anyway (although I'm not sure if we should remove it here, in that case, or in a separate issue).::get()if there is a value, so the$this->assertNull($format->get('roles'))will not trigger it. It has to be that way, otherwise the referenced code in::postSave()would always trigger a deprecation even without any roles. Of course open to any suggestions, but as far as I can tell it's not correct that we are triggering the deprecation explicitly in the test.::set()deprecation is currently muddled together with the runtime deprecation so it's not being tested explicitly. Great catch! In order for your suggestion to work we have to move the installation of the legacy config into::testInstallRoles()but that's actually great as that is what actually triggers the deprecation so it makes the test even more explicit.Comment #16
tstoecklerFixed 1., 3., 5. and 6.
I looked into 2. and it does turn out that we can remove the double setting and saving of the properties so went ahead and implemented it here.
FilterAdminTestwas green so assuming this didn't break anything.Regarding 4: I updated the test to match what your suggestion. I then also checked whether we actually still need to install the user entity schema, which I copied from
FilterDefaultConfigTest, and it turns out we don't, so I removed that. Furthermore, it turns out that this is dead code inFilterDefaultConfigTestas well, so I removed it there, as well. I do think it is related since we are removing a bunch of things there already, but it could theoretically be considered out of scope here so wanted to point it out for full disclosure's sake.So as far as I can tell this resolves as points in #14.
Comment #17
tstoecklerAh, forgot one more thing I wanted to point out: I wasn't sure about the format of the deprecation message, as it seems most places we are using the
drupal:10.0.0versioning style in the message. I took the message here fromDeprecatedServicePropertyTrait(and adapted it) which has a slightly differently format, but since it's used in core I thought it must be fine, as well. 🤷Comment #18
alexpottThis is looking really nice.
Also we need to use the new config schema deprecation stuff to deprecate the the roles schema.
Done some thinking about this added code. I don't think it is necessary. I think we can add the deprecation to \Drupal\filter\Entity\FilterFormat::postSave() as this is the only place where the roles info is used and can possibly exist because the way it is working is HEAD is that the roles property only exists while we're creating the filter config entity. Due to the head implementation of toArray() it is always removed.
\Drupal\filter\Entity\FilterFormat::$rolesneeds to be deprecated to I think.Comment #19
alexpottSee drupal.org/node/3129881 for how to deprecation bits of schema.
Comment #20
tstoecklerRe #18: Sure, just deprecating the (only) code path where it is used is fine by me as well.
Added the schema deprecation notice, added @deprecated to the property itself, updated the deprecation notices to match the documentation at https://www.drupal.org/core/deprecation and added a little expansion to the test to trigger the schema deprecation notice.
Comment #22
tstoecklerCannot reproduce the failure locally, so adding some (temporary) debugging info to the deprecation output.
Also fixed the coding standards issues.
Comment #24
tstoecklerHmm... absolutely cannot figure out why
DefaultConfigTesthas any business installingfilter_test_legacyand it doesn't do that for me locally either.But anyway, here's a workaround for that. It is anything but elegant, but I couldn't think of anything better. Any help - both on understanding why this happens in the first place and finding a better fix - is appreciated, but maybe this is also acceptable for now, albeit not being ideal.
Comment #26
tstoecklerSo this is fun: We have both
\Drupal\KernelTests\Core\Config\DefaultConfigTestand\Drupal\KernelTests\Config\DefaultConfigTest. The former does actually fail reproducably with #24 locally, as well. I was just looking at the latter.So this should be green, hopefully.
Comment #29
catchMarking #1901636: Importing a disabled format that is assigned to a role causes a fatal as duplicate, and bumping this to major in its stead, since this issue might fix several other ones.
Comment #30
joachim commentedLooks good in general, just a few points:
The version needs bumping up.
I don't like how this is having to do all the properties that are NOT 'roles'.
Could we use $form_state->unsetValue() before the parent class gets hold of it?
This looks like an unrelated fix.
Comment #32
wim leersPostponed #2569741: [PP-1] FilterFormat should add the roles as config dependencies on this.
Rerolled. #2852557: Config export key order is not predictable, use config schema to order keys for maps was the main conflict.
Comment #33
wim leers#30:
::submitForm()(which used to update permissions and theFilterFormatconfig entity) tocopyFormValuesToEntity()(to only update theFilterFormatconfig entity), which then means @tstoeckler had no choice but to update the permissions in::save().Comment #38
andypostNW for deprecation message
Comment #40
karishmaamin commentedRe-rolled patch at #33 against 11.x-dev
Comment #44
andypostneeds to change deprecation message and not clear about upgrade path
Comment #45
dimitriskr commentedTests finally pass
NR for what's currently in the MR and NW for the upgrade path
Comment #46
dimitriskr commentedUpdated remaining tasks in IS. CR needs update for updating drupal versions in body
Comment #47
wim leersNice work here, @dimitriskr! But rather than expecting deprecations in tests, we should be updating the tests to not create text formats with the
rolesproperty anymore.The default config of install profiles has been updated already, we just need to do the same for config in tests 😊
This blocks #2569741: [PP-1] FilterFormat should add the roles as config dependencies.
Comment #48
dimitriskr commentedThanks for the review Wim! One question. In some previous issues regarding deprecation, it had to have one test that would test that the deprecation message would pop up.
I'll remove the deprecated config from the test configuration but shouldn't exist one test to test the deprecation message? (by creating a separate test module with the deprecated config for this exact purpose)
Comment #49
wim leersThat's right.
Yes, this is the way 😊👍
Comment #50
wim leersThis blocks #3421946: [PP-2] Make FilterFormat config entities fully validatable.
Comment #51
dimitriskr commentedAlright, I'll continue on this.
And what about the upgrade path? Don't we need to change the configuration of the existing installations?
I was thinking about a hook_post_update (since it's configuration) and load all filters and remove the
rolesproperty. Would this be enough?If there is an example on testing the upgrade path, I could add this too.
Comment #52
dimitriskr commentedI've removed the expectDeprecation calls in the tests, as also remove the roles property in the formats
I've kept it in
\Drupal\Tests\ckeditor5\Kernel\SmartDefaultSettingsTestsince it loads config from a folder calledckeditor4_configand don't want to mess up anything there. If it's ok to remove it, let me know.The deprecation message testing already exists in
\Drupal\Tests\filter\Kernel\FilterLegacyTestComment #53
berdir> And what about the upgrade path? Don't we need to change the configuration of the existing installations?
No, because as stored configuration, the property isn't there anyway, This only affects default config files, and you can't files in an update function.
> I've kept it in \Drupal\Tests\ckeditor5\Kernel\SmartDefaultSettingsTest since it loads config from a folder called ckeditor4_config and don't want to mess up anything there. If it's ok to remove it, let me know.
I think it's fine to change that. the roles/permission are not actually tested by that test I think, they look like they were copy pasted from standard profile (an old, ckeditor4 version of them). You most likely don't even need to add any permissions, unlike some of the other tests I commented on.
Comment #54
dimitriskr commentedThe failures in the Functional Tests mean that the test user has no access in
ckeditor5.upload_imageso it cannot upload the image.We have to set to the user the permission to use the text format, with maybe the following? Otherwise the tests will fail. (tested locally)
Or, if we move the calls of
$this->createBasicFormat();to setUp() (since it's called in every test method + in inherited ImageUploadAccessTest), we can add the permission as parameter indrupalCreateUser()As for the FunctionalJavascript fails, I have no idea what is going on.
Comment #55
wim leers@Berdir++ in #53 😊
#54: I'll debug this. Thanks for pushing it so far already! 🙏
Comment #56
wim leersAs far as I'm concerned, this is now RTBC-worthy. Updated the change record.
Hoping @Berdir will RTBC 😇
Comment #57
wim leersActually, I have two more questions:
Roleentities. So AFAICT there's nothing to be done? → tagged for thisrolesproperty?Comment #58
wim leersFinally, closed #2569741 in favor of this, see explanation at #2569741-57: [PP-1] FilterFormat should add the roles as config dependencies.
Comment #59
dimitriskr commentedThanks Wim for taking care of this, it was getting difficult for me
1. I put the upgrade path to the tasks, since I thought it was necessary. Since #53, it was made clear it's not necessary, so we can remove it
2. Is it possible to point a URL to /admin/people/permissions, in the filter module permissions so they can be set directly from there? Or just tell people that in Drupal 11, in order to set permissions for the text formats, you must go to the URL above, in the release notes. And add a note in the current field that in 11 this will change
Comment #60
wim leers#59:
On second thought … I don't think we need special consideration for this — literally EVERYTHING ELSE in Drupal requires going to the "permission" UI. This is the only inconsistency left AFAIK.
That means this now is truly RTBC-worthy! 😊
Comment #62
wim leersThis part is missing. But … I'd argue it's not necessary, since
FilterFormat::postSave()will still trigger a deprecation notice. It might be a slightly nicer/clearer way for contributed/custom module maintainers to be notified though?Comment #63
berdirI think the UI question is entirely disconnected from this issue. It's only related because it requires special workarounds to not trigger the deprecation because config entity forms by default just throw everything the form defines directly onto the entity. We could in theory revert this change in D11, it would just set an undefined property on the object but won't do anything with it (like many, many other form elements)
I do agree that this is special, but who can access which text format is IMHO such a central question that I definitely see this being useful here. That said, we have a pattern now with a permissions local task on e.g. node types that we could also use for this, it would be a bit overkill as it's always going to be a single permission only though.
Comment #64
wim leersThat's really helpful, @Berdir — and I'd forgotten about the "permissions local task" pattern! 👍
You've convinced me that this issue is indeed 100% independent of any UI impact. Which means it's definitely in an RTBC'able state 🥳
Comment #66
smustgrave commentedApplied the suggestions by @Wim Leers.
Will this need an upgrade path though to remove roles key from existing config?
Comment #67
tstoeckler@Wim Leers summoned me to take another look at this. Really looks great, have no objections. I did review all the changes since my last patch and they are all fine, but since I did author a good chunk of what is still in the current patch, not going to RTBC as people do sometimes get very sensitive with that. Total endorsement of this landing, though, would really love to see this in for all kinds of reasons! Thanks everyone for pushing this along and AFAICT very close to the finish line.
Comment #68
wim leers#66: it's deprecated, not removed. See #53 for why that is not necessary.
#67: We're more pragmatic than that at this point 😄 It's been a long time since you touched this, plus I reviewed YOUR changes, so if you can review mine and @dimitriskr's , then … there's no reason you cannot RTBC this! As @alexpott likes to say (paraphrasing)
: "why would you not be allowed to RTBC it if you happen to have the expertise to thoroughly review this particular area?" 😊
… and in that same vein: I've re-reviewed everything and only made trivial tests-only changes to the CKEditor 5 tests, to ensure that
@group legacyonly appears in the sole legacy test.Let's get this done! 😄
Comment #69
tstoecklerAwesome, thanks!
Yeah, I totally agree, just want to avoid getting into arguments with people...
But then RTBC++, I guess ;-)
Comment #70
catchOne small and one slightly larger question on the MR - would be good to document this in the issue summary and we probably need an explicit follow-up to track removal.
This is one where I think we should deprecate for removal in Drupal 11 since we're maintaining a non-trivial bc layer and at worst this will affect shipped config.
Comment #71
wim leers@catch See my comment on the MR — I'd be fine with removing this UI, I just figured we're trying to minimize change for site builders during the D10 cycle too. Happy to do so though — it'd mean a more consistent UX anyway, so I sort of see the appeal: consistent UX and less code complexity!
Comment #72
wim leers@catch in Drupal Slack:
So: let's do that! (Separate change record for the UI change 🙏)
@dimitriskr: Are you interested in making that part happen? :D
Comment #73
dimitriskr commentedSure, I can give it a go!
Could you also update the remaining tasks in IS?
Comment #74
dimitriskr commented#62 Do we still need this?
Comment #75
dimitriskr commentedComment #76
dimitriskr commentedI've pushed some code changes and asked some clarifications too.
There needs to be a change at
\Drupal\Tests\ckeditor5\FunctionalJavascript\CKEditor5TestBase::createNewTextFormatin order to grant the required permission to the current user to allow using each text format. I guess that will make CKEditor5 tests pass and the whole pipeline go greenComment #77
dimitriskr commentedTests now pass :)
Comment #78
wim leersThanks! Will review 🤓
Comment #79
smustgrave commented@Wim Leers just following up if you had a chance to review this one? Think it would be a good thing for 11.x
Comment #80
berdirPosted a review.
FWIW, I still think that the UI change should be a separate issue even if it adds a bit of technical dept on the form.
I always thought this is pretty convenient, because setting correct permissions is pretty much mandatory for a new filter format. Without this, it will not show up for users and there is no indication or feedback that you need to go to a completely different section of the UI to then grant users the permission to actually use this format.
IMHO we need some sort of replacement for that (a message maybe, or the mentioned permissions local task, but unlike bundles, saving does not bring us to a page where we'd see that local task). I think this change needs a UX review (and that's exactly why it should IMHO be separate from the technical change).
Comment #81
godotislateAdding #3519300: Provide a way to deprecate form API array value keys as related, because I'm not sure whether the
rolesform API array key should to be deprecated before it's removed.Comment #82
dimitriskr commented1. Shall we wait for #3519300: Provide a way to deprecate form API array value keys and then deprecate
$form['roles']field properly? I think that covers comments from berdir and catch in MR and here, if I'm not mistaken.2. There are some open threads on the MR I cannot answer
3.
Drupal\Tests\filter\Functional\FilterSecurityfails because it cannot disable the format, but the code tests it can edit the format.entity.filter_format.disableroute returns access denied.entity.filter_format.edit_formis OKI'm investigating
4.
Drupal\Tests\filter\Functional\FilterHooksfails because it cannot select the filter on the node add form, below the editor