Support for Drupal 7 is ending on 5 January 2025—it’s time to migrate to Drupal 10! Learn about the many benefits of Drupal 10 and find migration tools in our resource center.
Part of meta issue #1802750: [Meta] Convert configurable data to ConfigEntity system
Problem/Motivation
Text formats should be configuration so we can import them using the new configuration system.
Proposed resolution
Convert Text Formats into Configurables.
Remaining tasks
- Create a FilterFormat class. [done]
- Update all the functions that works with StdClass to work with instances of FilterFormat. [done]
- Update the creation of default Filter formats in filter.install and Standard profile. [done]
- Provide an upgrade path. [done]
- Convert variable filter_fallback_format to the new Configuration system. [done in other issue]
- Write upgrade tests.
Followups
- #1868772: Convert filters to plugins
- #1871586: Clean up architecture once formats are ConfigEntities and filters are plugins
User interface changes
None.
API changes
filter_format_save() is replaced by Drupal\filter\Plugin\Core\Entity\FilterFormat::save();
Filter functions that before expect an object now expects a FilterFormat instance.
{filter} and {filter_format} tables are removed, the settings of a filter are now part of FilterFormat::$filter.
Comment | File | Size | Author |
---|---|---|---|
#178 | drupal8.filter-format.178.patch | 683 bytes | sun |
#171 | filter.config.171.patch | 81.61 KB | sun |
#171 | interdiff.txt | 962 bytes | sun |
#169 | format-1779026-169.patch | 81.55 KB | tim.plunkett |
#169 | interdiff.txt | 1.66 KB | tim.plunkett |
Comments
Comment #1
dagmarI'm working on this. I'm posting a work in progress patch just to get some early feedback to see if I'm implemeting this in the right way.
Comment #3
sunAwesome! :)
Thanks for asking for early feedback - I totally have some essential :)
1) The internal entity type ID/name should be 'filter_format' instead of 'text_format'.
2) I don't know have a strong opinion on TextFormat vs. FilterFormat, but most likely FilterFormat makes more sense.
3) The config prefix should be 'filter.format'.
4) The filters in a text format are like effects in image styles. They are not separate config entities, but instead they define the text format's actual behavior and configuration. Therefore, they should be defined as sub-keys of a 'filters' key in the text format config object.
Comment #4
dagmarThanks!. I'm working on this patch only on Friday, so the updates will usually on Friday.
Ok, so for Filtered HTML we should have something like this?
filter.filtered_html.yml
If this is correct, then I should only implement one Class FilterFormat that extends ConfigEntity.
This change presents several API changes. Because at this moment Formats can be loaded without need to load the filters and its configurations.
Is this approach correct? I mean, load all the info of all the filters only to display the available formats in a select box below the body?
Comment #5
sunGreat! :)
1) The config object name should be "filter.format.[id]", i.e.:
- filter.filtered_html.yml
+ filter.format.filtered_html.yml
2) Yes, FilterFormat extends ConfigEntity! :)
3) Loading formats without their filters... hrm. ;) Good + interesting point there. However, I can't see a way around that right now that wouldn't completely diverge from the direction of how we've converted image styles and effects. So for now I'd say, let's do it in the identical way and keep the methodology consistent. If we need or want to change it later, then we can still do so. :)
Comment #6
dagmarOk this is what I have at this moment. Still needs a lot of work. I will try to do something else before next Friday :)
Comment #8
dagmarThe main functionality is working. Let see how many tests fail.
Comment #9
tim.plunkettWhy not keep this as an array and just pass it to entity_create()?
Comment #12
dagmarTest are failing basically because Form Controller add a 'Save' button instead of 'Save configuration'.
Added changes suggested by @tim.plunkett. Thanks!
Comment #14
dagmarFixed two more tests that work directly with the table {filter}.
Reverted change in 'filter_fallback_format' format.
Comment #14.0
dagmarUpdated issue summary using the Issue Summary Template
Comment #16
dagmarConverted filer variables into the new configuration system.
Test will fail due other test are not using the filter API and make they queries directly from {filter} table.
This is my last patch this day. I would like to get some feedback in the following days, I will be working on this issue next Friday.
Comment #18
yched CreditAttribution: yched commentedIdeally, wed shouldn't have a 'module' entry for each filter, it's not config per se but derived data.
I guess a "turn filters into Plugins" followup issue would make it easier to get rid of those, though, so probably not a blocker for that patch.
Comment #19
dagmarMoved Conversion of variables into a new issue #1799440: Convert Filter variables to Configuration System.
New patch to fix more tests.
Comment #21
dagmarMore fixes.
Comment #23
dagmarComment #25
dagmar#23: 1779026.text_formats_configurables.23.patch queued for re-testing.
Comment #27
tim.plunkettIt doesn't appear that any of this is necessary. I've seen this in several conversions, but we didn't need it at all for Views, and I didn't need for porting view modes. If you just implemented it because it looked important, maybe we need better docs?
From config_import_invoke_owner() (which invokes those):
Allow modules to take over configuration change operations for higher-level configuration data.
Comment #28
dagmarComment #30
dagmarComment #32
tim.plunkettIgnore #27, that will be fixed in #1806178: Remove code duplication for hook_config_import_*() implementations of config entities
Comment #33
xjmMeta issue for these: #1802750: [Meta] Convert configurable data to ConfigEntity system
Comment #33.0
xjmFixed {filter} table name. Added a new remaining task
Comment #34
dagmarI think this should fix the remaining tests.
I have included the upgrade path, but the tests for this upgrade path are missing. I'll try to write this tests in the following days.
Comment #35
dagmarFrom #1588422-142: Convert contact categories to configuration system:
I'll try to revert the EntityFormController part during this week, some feedback would be appreciated until that.
Comment #36
dagmarRemoved the EntityFormController, let see if test still pass.
Comment #38
dagmarComment #39
mohit_aghera CreditAttribution: mohit_aghera commented#1: 1779026.text_formats_configurables.1.patch queued for re-testing.
Comment #40
dagmar#38: 1779026.text_formats_configurables.38.patch queued for re-testing.
Comment #42
dagmarRe-rolled
Comment #44
dagmarUpdated tests for:
#1344078: Local image input filter in core
#1782838: WYSIWYG in core: round one — filter types
Comment #45
dagmarI would like to have some reviews to continue with this issue. Thanks.
Comment #46
yched CreditAttribution: yched commentedI'm not fully familiar with the "convert to ConfigEntity" tasks yet, so this cannot be considered a sufficient review.
looks like $result is not used at all ?
Do we really want to keep a wrapper filter_format_save() on top of $format->save() ? What logic do we have in there that wouldn't rather belong in the FilterFormat::save() method ?
It's actually called within filter_list_format().
Wouldn't filter_list_format($format_id) be now just: load $format entity, return $format->filters ?
Shouldn't those be default .yml files ?
Maybe install profiles don't get their default .yml files copied over at install time like modules do ? Is there an issue for this ?
Comment #47
dagmarThanks @yched!
Remoed.
Fixed
Hm, filtes are objects, but the configuration save they as arrays. The conversion is required. I tried to avoid as much as possible api changes.
Done.
Thanks @DamZ, @Berdir and @timpunket also for the help in the irc. Now text formats are yml files that are provided by the standard profile and the filter module.
Comment #48
yched CreditAttribution: yched commentedThe yml files includes no filter settings ? I would expect at least filter_html to have the list of filtered tags ?
I guess that would be something for a "filters as plugins" patch to address. Can we then at least leave a @todo in filter_list_format() ?
Comment #50
dagmarI'm almost sure the fails from #48 are related to a caching issue.
Comment #52
dagmarComment #54
dagmarComment #55
gddI didn't have time to do an extensive review, however at a glance I agree with yched's comment in #46 that we should look into refactoring or even removing filter_format_save(). It looks like much of this can be removed or moved.
This will also now need a reroll because of #1763974: Convert entity type info into plugins (see conversion instructions at http://drupal.org/node/1827470.
Comment #56
xjm#54: 1779026.text_formats_configurables.54.patch queued for re-testing.
Comment #58
tim.plunkettRerolled!
Comment #59
quicksketchThanks for this great work so far guys. I'd love to see this in before I continue pushing further with WYSIWYG configuration (which will be bound to the format configuration) in #1833716: WYSIWYG: Introduce "Text editors" as part of filter format configuration. Right now that patch just extends the existing Filter module tables, but obviously this patch removes those tables. If we get this patch and the other patch completed, then not only will format configuration be exportable through CMI, but WYSIWYG configuration also (since they become the same thing).
Comment #60
dagmar@quicksketch I just readed your issue, lets try to speed up this issue.
This patch removes filter_format_save() and move the logic into Drupal\filter\Plugin\Core\Entity\FilterFormat::save().
Let see if tests still pass.
Comment #62
dagmarComment #64
dagmarComment #66
yched CreditAttribution: yched commentedYay for the end of filter_format_save() !
Cannot do a full-fledged review, but :
I think the Entity system takes care of invoking the proper hook_entity_[entity_type]_[op]() ops during save(), so invoking dedicated hooks shouldn't be needed - which de-facto means the existing hooks are renamed, thus filter.api.php needs to be updated accordingly.
21 days to next Drupal core point release.
Comment #67
dagmarComment #68
alexpottAwesome work!
All Yaml values should all be strings so for example... this is what
filter.format.plain_text.yml
looks like after I press save in the admin interface after a minimal install.If they're not then it's possible that the config system will detect a change when there is none. OTOH: there is a patch to enable variable type persistence in YAML files.
Comment #69
yched CreditAttribution: yched commented- #68 shows that filters not enabled in the format (status:0) are saved back in the yml file.
The form submit should filter items with status = 0 and not save those.
Meaning, the status flag doesn't need to be part of the yml file, since it will always be 1.
[edit: Ignore this. As per discussion in #70/#75 below, we want to keep config for disabled filters in a format]
- Also, the filters should probably be ordered by weight before writing the file (this should happen within FilterFormat::save(), before calling parent::save())
- Last remark, the input formats shipped in default config should include full settings for the filter_url and filter_html filters, and 'empty array' settings entries for the others, not rely on default values that will get saved back. (i.e : default config should not be written by hand, but be taken from real-life config files saved by the system)
Those three things would make the yml files more diff-friendly. CMI files should be idempotent, i.e. save the config in the UI without changing anything, the file should see no changes.
Comment #70
alexpottNot sure about not saving the one's with status 0 - if we don't save them when the user re-enables any custom settings they have made will be lost. Is that what we want and this is not what happens in Drupal 7 (as far as I can discern after a very quick skim)
Comment #71
yched CreditAttribution: yched commentedRight, I guess that's debatable. The current input formats UI behaves the way you describe :
- Configure a filter in an input format, save
- Remove the filter, save
- enable it again, the previous settings for the filter are back in place as default values.
I'd tend to consider that an input format remembering the settings a disabled filter had last time it was enabled, so that they are back again in case it gets re-enabled some day, is not a feature we should really expect from the config system. IMO config files should contain the strict definition that corresponds to the desired run-time behavior, and are not meant to keep track of history - CSVs are here for that.
That's not a behavior we'd expect from an image style, for example - and input formats and image styles are conceptually not really different : an ordered list of configured plugins with a machine name...
Also, this behavior means that the config file for a given input format contains entries for all filters available in the system at the moment it was saved. Enable a module that defines a new filter, then save(load(filter_foo)) (UI or programmatic) adds a new entry in the config file, idempotency is lost. I'm not sure idempotency is a critical behavior of config files, but it would sure help managing deployments and making sense of diffs.
So I guess in the end it should be filter.module's maintainers to make that call.
The last two points in #69 still stand, though.
Comment #72
sunFilter module maintainer here. :) I didn't look through the patch yet (I know, I know, ... I have to), but I spent some time thinking through the last comments on storing disabled filter settings:
So, I personally didn't like to see the disabled filters + settings in the config file either, so I can perfectly get behind the concerns here. However, given Filter module's intentions and also the security aspects involved, the above aspects lead me to the conclusion that we should retain the current behavior. We can investigate whether and how we could optimize that in a separate follow-up issue.
I will try hard to have a look at the latest patch ASAP. Thanks for all the hard work so far!
Comment #73
sunDang, forgot to mention: One possible way to address this would be to compare the filter settings against its default settings defined in code upon save, and if the filter is disabled AND the settings are identical to the defaults, only store the filter's position/order/weight within the text format but no settings.
However, that would require new tests to verify that this works as expected, so I still think we should do that in a follow-up issue.
The default configuration in
/core/modules/filter/config/*.yml
can happily diverge from a full definition and does not have to specify all filters though, since the format will be automatically enhanced when it is saved through the API upon import.Comment #74
andypostThere's a similar discussion about disabled state #1826602: Allow all configuration entities to be enabled/disabled
Comment #75
yched CreditAttribution: yched commented@sun : Yeah, I really don't like keeping disabled filters in here, but agreed that the current UI behavior makes sense given the security aspects of the input_format UI.
I edited my #69 to remove that request.
Comment #76
dagmarThanks for the feedback, I'm working to address the suggestions by @yched and @alexpott.
I'm providing a re-roll due #1799440: Convert Filter variables to Configuration System. So I can provide an interdiff later.
Comment #78
dagmarIn this patch:
In my next patch I'll try to write the upgrade path tests.
Also, would be nice if somebody could explain me why filter_format_load is not working in the FilterAdminTest. Seems to be a caching issue, the only way it worked was replacing by entity_load.
Comment #78.0
dagmarUpdated issue summary.
Comment #80
dagmar#78: filter-1779026-78.patch queued for re-testing.
Comment #82
dagmarFilter remaining test. Started upgrade test (work in progress).
Comment #84
dagmar(Updated from #78) In this patch:
Also, would be nice if somebody could explain me why filter_format_load is not working in the FilterAdminTest. Seems to be a caching issue, the only way it worked was replacing by entity_load.
Comment #85
dagmarRerolled
Comment #87
dagmarFixed some tests Sadly I can't find the cause of the entity_test fails.
This
Is not related to my patch, but fails. If somebody could point me in the right direction, I can fix this and continue working on the upgrade path.
Related to the removed asserst in the interdiff, the filter table is no available anymore, should I change this table by another one? What module/table should I use to replace those tests?
Comment #88
tim.plunkettThe assertion mentioned in #87 is bogus, it tests a behavior that shouldn't exist. It's cleaned up in #1848964: EntityManager should process its definitions before altering them.
Comment #90
dagmarRerolled after #1774332: Better handling of invalid/expired cache entries
This patch attemps to finish the upgrade path, I moved the logic to update permissions from the ui into TextFormats::save().
Also I included the upgrade path for roles.
Sadly I cannot run test locally anymore, seems related to #347988: Move $user->data into own table so I cannot ensure this will pass.
Entity access fails are related to #1848964: EntityManager should process its definitions before altering them
Comment #92
dagmarFixed the problems with the previous patch.
Ok, now the upgrade path tests are working, but the upgrade path itself is not assigning the right permissions. At least test detect this.
I'll try to fix the remaining issues during this week.
Comment #94
tim.plunkettThe tests and the upgrade path had different names for the formats.
Also, a disabled format will not show up on the permissions page.
I'd like to think this is RTBC, but it should have one more review.
Comment #95
tstoecklerI think the new standard is to not actually drop these tables in D8 in case any contribs reference it in any way. We should just leave it as is for now and add it to #1860986: Drop left-over tables from 8.x
Comment #97
tim.plunkettAh! Two more test fixes.
Also I removed the db_drop_table(), I'll add it to that issue now.
Comment #98
gddPatch didn't apply anymore, here's a reroll to HEAD.
Comment #99
gddMostly nitpicks
#84.1 - Per #1782244-25: Convert image styles $style array into ImageStyle (extends ConfigEntity), all hook_ENTITY_NAME_CRUD() hooks should not be documented anywhere outside of entity.api.php. So they should be removed from filter.api.php.
In situations where we are retrieving all formats, we should probably standardize on using entity_load_multiple(), unless there's a specific reason filter_formats() is used in the first example, in which case we should probably document it.
I can understand wanting to save the central comment in filter_install(), but having a function exist with nothing but comments in it seems hacky and weird. Maybe we can move it into the @file block?
This is realllly close. Thanks dagmar for your dedication to pushing this through!
Comment #100
tim.plunkettOpened #1870642: Consider removing filter_formats() for entity_load_multiple('filter_format') as a follow-up, and this should address the other two. Thanks @heyrocker!
Unassigning so that it doesn't scare away would-be reviewers.
Comment #100!
Comment #100.0
BerdirUpdated issue summary.
Comment #101
BerdirThis looks quite nice already, bunch of smaller things that we can now do in a better way I think.
Doesn't need to be resolved here, also didn't check if there was any discussion about this yet, but does this still make sense?
format is what must be unique, what do we care if name (the label) is or is not? You can create as many content types, fields, views, .. with the same label as you want, why not filters?
MigrateS?
Similar one, but this certainly can just be a entity_load('filter_format', $format_id) now?
Is there an issue for this already? I'd also suggest to make all of this a @todo comment, because the complete comment is related to the @todo.
Missing the context here, shouldn't this be enforced globally, not just here, when the entity is loaded?
Uh, doesn't this belong in a storageController::pre/postSave() implementation? Why is it in the class?
This looks quite complicated? Can't we start with $minimum_weight = 0 or something to simplify the loop?
This one should also be like 10x easier if the code relies on the format instead of the name :)
Isn't there a filter_default() function or something like that that could help here? Or just rely on plain_text, which we know exists?
There are more of these below.
Not sure if the "id" is necessary at all or should be "identifier"? Also, filter format should probably be lower case?
Comment #102
tim.plunkettThanks for the thorough review!
I think a third of that feedback is fixable now, which I'll do now.
A good part of the filter-specific, not format-specific stuff, should just be left for #1868772: Convert filters to plugins
The last segment is "now that we have this new system, maybe we can refactor!"
I'd like to hold off until after this AND the filter get in. I can open a follow-up.
This is supposed to just be a conversion to ConfigEntity, then filters can become plugins, THEN we can revisit and refactor the system as a whole.
Comment #103
tim.plunkettI'm going to pretend each dreditor hunk in #101 is numbered.
1) Fix in followup
2) From http://drupal.org/node/1354: "Note that the first line should start with an imperative verb, so it will make sense to people running update.php."
3) Fixed in newest patch
4, 5) Fixed in #1868772: Convert filters to plugins
6) Fixed in newest patch
7, 8) Fix in followup
9) Fixed in newest patch
Comment #103.0
tim.plunkettFix typo.
Comment #105
tim.plunkettOkay, @Berdir and I talked more, and I agree now that it's worth cleaning up the php_enable() code
Here are two approaches. If both pass, I think A is cleaner than B.
Comment #110
tim.plunkettThis is #104-a plus the fix from #1871774: ModuleTestBase::assertModuleConfig() assumes all of module's default config is owned by that module
Comment #111
BerdirOk, I think I'm fine with this, the php.install change looks great :)
RTBC, but it will probably need a re-roll once #1871774 is commited (which is already RTBC).
Comment #112
sunThanks for pushing this forward! The patch already looks really good so far.
I did not apply it yet and also did not perform an in-depth comparison of old vs. new code. So what follows is a pure code/patch review. I'll try to perform a deeper review ASAP - Filter module involves various security aspects, so we want to make sure that we do not introduce any kind of problems or regressions here.
Hm. This default format lacks a uuid.
OTOH, default config is installed through the config import process, which in turn passes the raw config through a true entity save operation.
Thus, it's probably fine to omit the uuid. But at the same time, we can also remove all declarations for filters that are not enabled from the default config file.
1) Why is this using the values instead of the keys returned by user_roles()? AFAICS, the array keys are the role IDs, the array values are the human-readable role labels. We want to store the role IDs.
2) The default config object has each role ID both as key and value. The update should migrate the formats to use the same values as a manually created format.
Btw, it looks like this module update could be simplified by not fetching the rows into objects, but fetching them into arrays via PDO::FETCHASSOC instead. That, combined with querying only needed columns instead of *, could likely trim down this update to a few lines only.
Can we remove the error suppression here?
The current situation with default values for entities is not really clear to me. Is there any particular reason for why we're not setting these default values as the default values of the entity properties? I.e., in the same way the Entity::$langcode property has a default value of 'und'?
Hm. Our past attempts for (prematurely) optimizing for this went all wrong. I wonder whether we should rather remove this ksort() for now.
It looks like we're doing this sorting both on save and load now. The sorting in filter_list_format() is critical, so I think we can/should drop the additional sorting on save, and perhaps replace it with ksort() instead, so filter settings can be found more easily in a config file.
Why are permissions only updated on save when the format is enabled?
We should add a @todo for these to rename them to $id and $label, and create a follow-up issue for doing so.
Let's remove the default value here.
Hm. The documentation here could use some polishing. Let's clarify that the array keys are IDs of filters as registered in
hook_filter_info()
, and that there is an additional 'module' key denoting the module name that provides a filter for each filter in an existing format, but the module key can be omitted when creating a new format.It looks like we're missing a corresponding label() method override.
Most of these test changes look unnecessarily complex to me... Why didn't we simply replace them as follows?
In other words: Let's remove the intermediate $foo_format_config variable and directly invoke entity_create() with the existing array instead, followed by a simple ->
save()
.Hm. The proper replacement for these test assertions would probably have been to load the raw config() object; i.e., replacing the storage assertions with new storage assertions. However, it is probably OK to drop them entirely. I can't remember why I added those originally.
Sorry, these changes are wrong, since they remove essential test coverage. We need to replace 'filter' with some other simple module that has permissions and a database schema.
We added the $module prefix in this line only recently, so I do not understand why it's removed here.
The
array_pop()
here will probably return the plain_text format in almost all cases - I'm not sure whether that is good or bad. Let's see how it goes.1) Oh, erm... Did we test whether supplying default config in an installation profile's ./config directory actually works already? I.e., did someone install with Standard profile and see the default formats? This functionality is not covered by tests yet...
2) The 'roles' definition in a format does not look very clean to me. Is there any reason for why we're recording unallowed/disabled roles in the first place? I didn't expect them to be contained.
3) Now that I see diverging 'roles' values, I'm actually fairly sure that the upgrade path is wrong, since it only pollutes values but no keys.
Unless I'm missing something,
FilterFormat::save()
will already grant the necessary user permissions, according to the roles defined in the format — as a result, we shouldn't have to grant those permissions manually anymore...?Comment #113
tim.plunkettI'll respond to things not addressed in the patch.
I didn't touch the error suppresion on the uasorts, because those are specific to filters, not formats, and it's best handled in #1868772: Convert filters to plugins
Same with the ksort()
The user permission saving came is triggered from the format configuration form, which can only be performed on active formats.
I didn't touch the FilterFormat::$filters docs either, that's also handled by the filter conversion.
Entity::id() doesn't check entity keys for performance, but Entity::label() does, so no need for an override.
Comment #115
tim.plunkettWhoops, didn't restore testEnableModulesInstall() all the way.
Comment #116
tim.plunkettI think this covers enough of your feedback to forge ahead. I'll now go update the filter issue to list the things I've asked to follow-up on there.
Comment #117
aspilicious CreditAttribution: aspilicious commentedWhy do we de '+=' here? Shouldn't just do "$filter_format = array(..." in each loop?
the @todo says the opposite of the docs before it.
Comment #118
tim.plunkettIt's adding in extra values into each result from the db_query()
The @todo is implying that we shouldn't have to cast to an object on the following line. Either way, that's all handled in the filters-as-plugins patch.
Comment #125
tim.plunkett#115: formats-1779026-115.patch queued for re-testing.
Comment #127
alexpottNone of the other conversions have used entity_create as it depends on entity_get_info which uses module hooks and therefore is not safe to use during an update.
contact_update_8001()
is a good template.Comment #128
tim.plunkettThanks @alexpott!
Comment #130
tim.plunkettWhoops, that install change was broken. Yay for working tests! :)
Comment #132
tim.plunkett#130: format-1779026-130.patch queued for re-testing.
Comment #133
alexpottNow
filter_update_8000()
is missing creating the manifest files :)There is a helper function to do this... http://api.drupal.org/api/drupal/core%21includes%21update.inc/function/u...
Comment #134
yched CreditAttribution: yched commented[edit: crosspost...]
@tim: you need to create manifest entries too, with update_config_manifest_add().
That one's so easily forgotten, I wish we had a more integrated solution here. Something like ConfigEntityUpdateHelper extends Config, where $config->save() takes care of adding the UUID and creating the manifest entry (i.e what $config_entity->save() does, but in an update-kosher way).
Not for that issue, though...
Comment #135
tim.plunkettOr some tests to fail when I don't do it...
Comment #136
yched CreditAttribution: yched commentedYeah, but not sure how that could be done - at the end of update, check that all existing config files for all existing entity types that are also config entities have a manifest entry ? Tricky...
Comment #137
tim.plunkettOkay, added. That wasn't too bad :)
Comment #139
tim.plunkettWhoops! I confused the entity with the config object. Just using the id directly.
This should be good to go!
Comment #140
tim.plunkettAttempted reroll after the blocks patch.
Comment #141
aspilicious CreditAttribution: aspilicious commentedI know womse stuff is changed regarding these functions. Are they still needed here?
Can we have more reviews? :p
Comment #142
sunI plan to work on this and tweak it a little in the next few hours this evening. Unassign me if I don't deliver today.
Comment #143
sunHere we go. Upfront, please note that I'm participating in this issue as Filter module maintainer, not as Configuration system maintainer, which is a slight, but noteworthy difference, and partially, conflict of interest. I mostly ignored the config system perspective and solely focused on Filter module's interests. This means I care less about the config conversion, but much more about the API/UI/sanity/security/documentation/whatnot aspects of Filter module, in order to ensure that existing logic is still contained and the module continues to function as intended.
Created a (rather major) API clean-up follow-up task for this issue:
#1881664: Clean up and complete text format config entity conversion
Reverted the change to ModuleTestBase, which means that this issue is now blocked by:
#1850158: Bugged assumption in ModuleTestBase::assertModuleConfig()
Once that issue is fixed, this patch should pass. Assuming attached patch comes back green, I'd consider this patch to be RTBC from a Filter module/API perspective.
Though let's be clear about the overall, resulting state: As mentioned and linked to above, this change will cause a large amount of follow-up clean-up and polishing work to be done. That's good, appreciated, and also expected. :) However, it should be clear for everyone that this commit will leave the Filter module/API/code in a half-baked state, so the clean-up absolutely has to happen before D8 gets out.
Summary of changes: (apparently, my disciplined commit log is much larger than the interdiff :P)
Comment #145
sunThe EnableDisableTest failures are expected and will go away with #1850158: Bugged assumption in ModuleTestBase::assertModuleConfig()
I need to study the format permission failures though. The more I think about it, the less I'm sure whether it is legit to store and factually duplicate the allowed user roles within a format's configuration, whereas the actual access is stored + updated elsewhere. (This wasn't the case before - the user roles were dynamically fetched for the format admin form and
filter_format_save()
performed the remaining wiring between Filter API and User Access API - the actual values, however, weren't stored in the {filter_format} table.)Comment #146
gdd#143: filter.config.143.patch queued for re-testing.
Comment #148
sunFound the culprit.
I consider this patch RTBC, if it comes back green.
Comment #150
tim.plunkettAw, I was rather attached to that method! :)
---
I'm not sure what could have broken sorting, was it really the error suppression?
Comment #151
sunI was just looking into that and tried to debug it in the past minutes...
I don't know why the FilterDefaultFormatTest passed before, but based on the debugging steps so far, we're definitely facing the problem space of #145 — i.e., user role access is stored additionally within formats, next to actual user permissions, which means duplicate data/housekeeping. The reverse housekeeping doesn't happen right now - when granting a user role the permission to use a text format, then the text format is not updated accordingly.
And that's essentially what happens in that test. Now I'm not sure what to do. I'd think the most safe + sensible compromise might be this:
1) Keep the $roles property for formats. [EDIT: Because it really really simplifies default format configurations for installation profiles + tests, and that's almost the most beautiful part of this patch. :)]
2) Populate it on load, based on the actual user role permissions.
3) Update user role permissions according to $roles on save.
4) Potentially even export/save the value into the config object, but essentially, it's just a historical track record and we ignore it.
Comment #152
sunAlright, attached patch implements #151 and should come back green.
Fixed FilterFormat::$roles are not updated when user role permissions are changed.
Comment #154
sunThe test failures are caused by this form submit handler:
When replacing
filter_formats()
withentity_load_multiple('filter_format')
, then tests are passing.For some unknown reason, the formats contained in
filter_formats()
do not contain the $roles they ought to contain.......gotcha.
The test performs these actions:
1) Create a format via UI.
2) Grant permissions to test users/roles via User Role API.
3) Change the format weights via UI.
filter_formats_reset()
is not invoked between 1) and 3).The filter admin overview UI loads the formats via
filter_formats()
, which has its independent cache. That cache is not updated when the user role permissions are changed. Therefore, the previously contained formats are still cached and still not assigned to any roles, since the cache is outdated.For some reason,
entity_load_multiple()
doesn't hit that cache problem, but technically it should, too, since off-hand I can't see why the configuration system cache would be invalidated by changing user permissions. (Config entities are not cached, since they'd duplicate the Config cache.)Hm.
Comment #155
sunD'oh. It's exactly the fact that
entity_load_multiple()
is NOT cached, which makes the difference.Essentially, each config entity is reloaded from (cached) storage whenever it is loaded. The entity itself, however, is not cached, since the entity cache is explicitly disabled in ConfigStorageController. (Duh, that might be another, quite heavy performance optimization...)
And that's why
entity_load_multiple()
reloads all the formats and re-attaches the actual and currently granted user roles onto $roles.Whereas
filter_formats()
is not reloaded and still based on the preexisting cache, which doesn't get flushed, just because user role permissions are changed.Proper usage of cache tags for
filter_formats()
+ proper invalidation in user_role_*() might be the answer here.Otherwise, we'd have to drop the $roles property, which I wouldn't like to do. :-/
Comment #156
sunFYI: #1885830: Enable static caching for config entities
Comment #157
sunI still need to sleep over it, but I'm relatively sure this boils down to two options only:
1) Proper usage of cache tags — which means to patch the User Role API, as well as the Cache Tags API itself, since the tags are currently bound to a specific cache bin, but the User Role API wouldn't know about Filter module and which cache bins it uses. (Apparently, that cache tags problem came up before, so it would be a very good idea to resolve that in either case.)
2) Remove $roles from filter format config entities. All we *could* still support for convenience would be a super-temporary $roles property that has an impact during the creation of a format only, and which would really only exist for DX/convenience of creating new formats, but would otherwise not be part of text format entities, nor their storage.
Comment #158
tim.plunkett#2 sounds like a more reasonable first step, and #1 could be a follow-up.
Comment #159
sunLimit FilterFormat::$roles to newly inserted entities; restore form submit handling for user roles.
i.e., #157.2.
If this comes back green, we should be ready to go here.
Comment #161
sunFixed bogus variable name.
Comment #163
sunoh, wow, stupid me. Finally figured out what's going on ;)
Comment #165
sunFixed newborn MetadataGeneratorTest of Edit module.
This one should finally come back green. :)
Comment #167
tim.plunkettGood catch in #163! Editor has some weird stuff in it.
Comment #169
tim.plunkettWhoops.
Comment #171
sunFixed EditorManagerTest.
Unfortunately, there's no memory backend implementation for path.alias yet, so every DUTB test that installs Filter module needs to install the {url_alias} database schema. We can clean this up later.
Comment #172
Wim Leers#163: Woah, how did those indentation errors still exist? :O I probably introduced those. I really need to work on setting up git commit hooks that do coding standards check some time… :) In any case, my apologies for that weirdness. And YAY, green patch!
Comment #173
gddI just reviewed this again and it looks really great to me. Given that sun and timplunkett are both good lets get this in!
Comment #174
tim.plunkett#171: filter.config.171.patch queued for re-testing.
Comment #175
webchickThis is really nice clean-up, thanks! Spent about 20 minutes on this patch but it was very boring because there was nothing to complain about. :D Even came with an upgrade path + tests.
Committed and pushed to 8.x. Thanks!
This will need a change notice.
Comment #176
Eric_A CreditAttribution: Eric_A commentedDid we lose the format property on filter objects?
When the filter object is passed into my filter process callback function the format property is now gone. I'm guessing it is related to this change.
Comment #177
tim.plunkettI'll be posting a patch for #1868772: Convert filters to plugins soon, and that will completely revamp filters anyway.
Comment #178
sunWe can quickly fix that for now though, independently of that conversion issue.
I've unpostponed #1881664: Clean up and complete text format config entity conversion.
Lastly, I've also filed #1893730: Provide an in-memory mock implementation of Path\AliasManager for tests and update.php
Comment #179
Eric_A CreditAttribution: Eric_A commentedIn the other issue it was suggested to discuss a removal in a follow-up to that issue. A big +1 for quickly reverting the removal, even if the removal may make a lot of sense. Why make these conversions harder on contrib?
The D7 practice of selecting all table values and then not unsetting foreign keys may lead to more cases of properties getting lost without discussion when there are no use cases within core.
Comment #180
gddhttp://drupal.org/node/1910176 is start of a change notice for review. I largely copied it from the change notice for [#1907430]. There may be more to add but this covers everything in the issue summary at least.
Comment #181
tim.plunkettThis was (thankfully) a pretty straight conversion, so heyrocker's change notice was spot on. #1868772: Convert filters to plugins is where more of the API functions will be removed/changed.
Comment #182.0
(not verified) CreditAttribution: commentedAdded followups