Problem/Motivation

This is text format schema (removed some parts for readability):

filter.format.*:
  type: config_entity
  mapping:
    name:
      type: required_label
    (...)
    filters:
      type: sequence
      orderby: key
      sequence:
        type: filter

Each filter is of type filter:

filter:
  type: mapping
  mapping:
    id:
      type: string
    (...)
    settings:
      type: filter_settings.[%parent.id]

Each filter's settings is of type filter_settings.<filter_plugin_id>, defaulting to filter_settings.*

But here comes the weirdness: Each filter_settings.<filter_plugin_id> is again of type filter (except filter_settings.* which correctly goes to a sequence)

For instance:

filter_settings.filter_html:
  type: filter
  mapping:
    ...

I think each filter_settings.<filter_plugin_id> should be of type mapping

Proposed resolution

Fix all core schemas to filter_settings.<filter_plugin_id>, including filter_settings.*

Remaining tasks

None.

User interface changes

None.

API changes

None.

Data model changes

None.

Release notes snippet

Core filter_settings.<filter_plugin_id> schemas have now correct mapping type

Issue fork drupal-3404431

Command icon 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

claudiu.cristea created an issue. See original summary.

claudiu.cristea’s picture

Title: Filter schema types are incorrect » Filter settings schema types are incorrect

Fix title

claudiu.cristea’s picture

Component: configuration entity system » filter.module
wim leers’s picture

Status: Active » Needs work
Related issues: +#3401837: Add basic validation to config schema definitions

+1!

This is technically a duplicate of #3401837: Add basic validation to config schema definitions, but there I'm trying to add automatic detection of this very problem to ensure it can happen never again (reviews + help appreciated 🤓).

But that issue is likely to take a long time to land. I think it makes sense to fix core's schema regardless of deeper configuration schema system DX/architecture improvements 👍

claudiu.cristea’s picture

Status: Needs work » Needs review

I came here from #3404070: Slick filter schema is incomplete (weird issue there)

We don't need a new type: filter_settings_base.

I was thinking that it's good to have a base schema for a particular *kind* of configs

wim leers’s picture

StatusFileSize
new1.48 MB

The change of filter.settings.* from type: sequence to type: mapping implies all keys must now be defined.

Which means every @Filter plugin with settings now MUST define filter.settings.<PLUGIN ID> if they want to

Consequence is this validation error now appearing for (all?) CKEditor 5 functional JS tests:

'filter_url_length' is not a supported key.

But why?

  1. In Drupal core, the only config entity validation that occurs anywhere in Drupal core
  2. The Text Format & Editor UI itself generates configuration that does not conform the config schema: \Drupal\Tests\ckeditor5\FunctionalJavascript\CKEditor5TestBase::createNewTextFormat() uses the UI to generate a new text format, resulting in filters.filter_url being set to:
    [
      'status' => 0,
      'weight' => '0',
      'settings' => [
        'filter_url_length' => 72,
      ],
    ]
    
  3. ✅ The settings value complies with type: filter_settings.filter_url 👍
  4. ❌ But that entire value (the entire array) should comply with type: filter, which it does NOT: id and provider are missing. That's why config schema was unable to resolve type: filter_settings.[%parent.id] to filter_settings.filter_url and instead fell back to filter_settings.* 😱
  5. Or annotated in the debugger:
wim leers’s picture

Status: Needs review » Needs work
StatusFileSize
new1.27 KB

AFAICT we have two choices:

  1. tighten scope: drop the change to filter_settings.*, to allow it to continue to accept arbitrary garbage values
  2. broaden scope: fix \Drupal\filter\FilterFormatFormBase

Better to fix all the broken things that are connected IMO, so attached a suggested interdiff that AFAICT should fix it 🤞

claudiu.cristea’s picture

Status: Needs work » Needs review

I went with #8.2 as it avoids adding any arbitrary sequence but used fields of type value. Let's see the bot

claudiu.cristea’s picture

Issue summary: View changes

Fixing IS

wim leers’s picture

Status: Needs review » Reviewed & tested by the community
Issue tags: +validation

Wow, that worked! 😃

wim leers’s picture

Issue tags: +blocker
wim leers’s picture

Status: Reviewed & tested by the community » Needs work
Issue tags: +Needs update path, +Needs update path tests

Actually … I think this needs an update path + test.

My suggestion in #8 only works because it affects new text formats, and that happens to be the only thing being tested.

We need to ensure everything is in a consistent state, which means making sure all FilterFormat config entities contain the missing data. Fortunately, it's simple enough to populate those 2 property paths for each filter in each format.

Thanks to filter_post_update_sort_filters() and \Drupal\filter\Entity\FilterFormat::preSave() in #3017054: Consistently sort filter formats to simplify config exports there is a very recent example in the same area 👍 Back to you, @claudiu.cristea 😊

borisson_’s picture

There are a couple of remaining failures in the javascript test coverage, they seem to be related (as they fail in ckeditor / filter things).
But I agree with @Wim Leers, this issue is great!

Removing tags that have been implemented already.

wim leers’s picture

Assigned: Unassigned » wim leers

Debugging the failing Functional JS CKEditor 5 tests…

wim leers’s picture

Assigned: wim leers » Unassigned
Status: Needs work » Needs review

e2ac97aff5ebcf0b7a226d1749036b8fd06f2c98 caused this regression. We still need the changes in FilterFormatFormBase that I proposed in #8.

The reason: FilterFormat::preSave() does not get called until after validation happens.

wim leers’s picture

Status: Needs review » Reviewed & tested by the community

@claudiu.cristea independently discovered and diagnosed this issue after I opened the broader scoped #3401837: Add basic validation to config schema definitions to forever detect and prevent this bug pattern from getting reintroduced.

I only helped with debugging the failing CKEditor 5 JS tests (see #8 for details) and provided a trivial suggestion … that happened to work on the first try :D

@claudiu.cristea also provided an update path + tests, to automatically fix all of filter.format.* config objects on all sites, to add the missing information (id + provider).

This looks excellent, so RTBC'ing 😊

quietone’s picture

Status: Reviewed & tested by the community » Needs work

I'm triaging RTBC issues. I read the IS, the comments and the MR. I didn't find any unanswered questions.

I left a comment on the MR. I would have made the change myself but maybe someone here has a better one line summary.

And, correct me if I am wrong but I also think it prudent to have a change record.

Sorry, but back to NW for two items.

claudiu.cristea’s picture

Status: Needs work » Reviewed & tested by the community

@quietone, thank you. I’ve applied the suggestion but I don’t see the need for a CR, we’re fixing here a bug. No idea what I could write in a CR

longwave’s picture

Status: Reviewed & tested by the community » Needs review

Are we sure we don't need a change record?

--- a/core/modules/media/config/schema/media.schema.yml
+++ b/core/modules/media/config/schema/media.schema.yml
@@ -119,7 +119,7 @@ media.source.field_aware:
       label: 'Source field'
 
 filter_settings.media_embed:
-  type: filter
+  type: mapping
   label: 'Media Embed'
   mapping:
     default_view_mode:

If contrib or custom code that adds a filter setting schema has made the same mistake, we need them to update from filter to mapping, no?

And if existing code has made that mistake, will there be any side effects anywhere if we commit this?

wim leers’s picture

Status: Needs review » Reviewed & tested by the community

If contrib or custom code that adds a filter setting schema has made the same mistake, we need them to update from filter to mapping, no?

Yes, they should all change. You're right that they likely all copied the wrong pattern from Drupal core. CR to announce this: https://www.drupal.org/node/3419181.

And if existing code has made that mistake, will there be any side effects anywhere if we commit this?

No, zero side effects in production. This only:

  1. blocks making filter settings validatable in #3395562: Add validation constraints to filter.settings
  2. impacted https://www.drupal.org/project/config_inspector.

To prevent such circular config schema types from being introduced accidentally in the future in core/contrib, I created #3401837: Add basic validation to config schema definitions.

longwave’s picture

Status: Reviewed & tested by the community » Fixed

Thanks for the explanation.

Committed d8c4e4c and pushed to 11.x. Thanks!

Also published the change record.

  • longwave committed d8c4e4cf on 11.x
    Issue #3404431 by claudiu.cristea, Wim Leers, borisson_, quietone:...

wim leers’s picture

Status: Fixed » Closed (fixed)

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

quietone credited alexpott.

quietone credited berdir.

quietone credited jgeryk.

quietone’s picture