Problem
- The fallback format concept was originally introduced to allow Filter module to cope with unforeseen edge-case configuration scenarios, but was never intended to be exposed as a configurable text format.
Details
-
The
plain_textfallback format was only ever meant as a (literal) fallback format. -
Its introduction was caused by technical edge-case scenarios only. Specifically:
- When all existing formats are accessible to certain user roles only,
- and the currently logged-in user does not belong to any of those roles,
- but a text-format-enabled text field happens to be exposed to that user,
- then Filter module logically has no idea what to do, because it was told to accept user input that needs to be filtered, but there is no format the user is allowed to use.
That's the one and only reason for why the fallback format exists. There are multiple possible ways to reach that situation, so we were not able to say "Stuff that, that edge-case is caused by a bogus configuration, fix your configuration instead." Hence, we introduced the fallback format to resolve that problem.
-
That is also the reason for why the
plain_textfallback format is super-restrictive and escapes all HTML.- It is only used in situations when the current user technically does not have access to any format.
- That's also why the fallback format ID is not configurable from the UI.
It was a pretty big mistake to expose it as a configurable format in the administrative UI and we need to fix that.
-
The fallback format was not meant to be exposed in the visible way it is today.
Proposed solution
-
Remove all traces of the fallback format from the administrative Filter module UI.
This inherently means that the fallback format is no longer configurable.
-
Add an API-level condition to disallow filter configuration changes to the fallback format.
-
Since we do not know whether the fallback format was reconfigured on existing sites:
- Introduce a new fallback format
'none'in D8, as a replacement for the previousplain_textformat. - For sites upgrading from D7, the
plain_textformat becomes a regular, configurable format. - The new none fallback format will not be exposed in the UI and its configuration cannot be changed.
- Introduce a new fallback format
-
Remove the additional configuration setting that was introduced with #788114: Unprivileged users should only get one text format by default
Notes
-
With properly set up text formats, anonymous users are able to access (at least) one actual text format.
- The fallback format is not intended to be used as "default format" for anonymous users.
- Anonymous users should still get an actual text format along the lines of filtered_html. They should be allowed to enter basic HTML.
- In most Drupal site use-cases (but certainly not all), anonymous users only get one format and should not see a format selector.
Comments
Comment #1
quicksketchHm, I don't think you can really classify this a bug report. If it were a bug, it means that this would equally be considered a "major bug" for Drupal 7, but the possibility of a backport is practically non-existant considering its potential for breaking existing sites. I would classify this as an inconvenience more than anything else. Even #788114: Unprivileged users should only get one text format by default, which exposed the fallback to ALL users was only considered a task. This is a minor problem that specifically affects administrators.
The original issue that introduced the fallback was #11218: Allow default text formats per role, and integrate text format permissions. The early versions hide the plain text format entirely (one of mine even made it a hard-coded format directly in filter.module). It was added back as a "normal" format for flexibility.
@David_Rothstein rerolled the patch to turn it into a "real format" but hid all the UI components in the second version:
I'm not quite clear on when the the format became shown in the UI from reading the issue, but initially it was only visible but not editable. Then later the ability to edit the fallback format was added back to the UI.
So initially, we set up to make the fallback truly a fallback but gave up on it for "flexibility purposes". I honestly would prefer it disappeared entirely and became truly a fallback, but it does make the whole behavior slightly more magical if it's not mentioned anywhere in the UI.
So in the end, I'm ambivalent to this proposal because I think it'll be beneficial in some ways and restrictive in others. I'm for completely hiding the fallback; but I don't think this is a significant problem in the grand scheme of things.
Comment #2
sunFrom a Filter API/module perspective, this is a major bug in the architectural design.
I'm not talking about any UX or other implications that may happen to be there. Only Filter module's text format API and its reliability and security.
The originally intended concept - as outlined in the issue summary - was sensible. But the current implementation goes way beyond that and that's just simply wrong. It's a typical artifact of applying too many "patterns" and a false-sense of customizability to everything that exists. I'm fairly sure that I'm guilty for some parts of this myself, since as mentioned in #1, the concept was originally introduced with too much flexibility and complexity already, so the entire core contributor army only continued to advance on it, without validating whether this makes any sense (again, myself included).
The fallback format must not be customizable.
I considered already whether we can hard-code this format, so as to make it always available and never configurable. That was the original idea of using
check_plain(). However, all text content that happens to use this fallback format has to reference it and a hard-coded format cannot be referenced or looked up through standard facilities, so ultimately, we better have a proper record of the fallback format in configuration, but disallow any changes to it.And alas, the fact that the current fallback format lives in configuration is also what allows us to easily swap it out today. As long as it is not customizable from the API/UI, we should be fine. We can't protect against manual config files changes, but in general, it looks like manual changes to config files will be considered as "hacks" in D8, following the "don't hack core" mantra, so we should be fine, too.
Comment #2.0
sunUpdated issue summary.
Comment #3
sunUpdated the issue summary and appended a new task.
FWIW, the solution and effective changes here should be fairly straightforward and a no-brainer to implement. To quickly summarize:
filter.format.plain_text.ymltofilter.format.none.ymlhook_update_N()to filter.install to create the new fallback format. (the existing is upgraded already)FilterFormatStorageController::preSave()and throw an exception whenever someone tries to change the'filters'definition.filter.settings+ and its usage infilter_process_format().Comment #4
tim.plunkettI personally think of this as a feature request. I don't agree that plain_text should be not-configurable, just non-deletable (as it is).
Comment #4.0
tim.plunkettUpdated issue summary.
Comment #5
catchComment #21
wim leersFYI this came up again in #3395562: Add validation constraints to filter.settings.
filter.settings:fallback_formatis impossible to validate.This issue would allow removing that from config!