Symptoms
I first noticed the following symptom, on a feature with ckeditor profiles.
drush fr -y --force FEATURE
drush fd FEATURE
-> feature is clean.
drush en -y RANDOM_UNRELATED_MODULE
drush fd FEATURE
-> feature is overridden, with a diff like this:
'loadPlugins' => array(
'dnd' => array(
+ 'active' => 1,
'buttons' => array(
Exporting the feature again fixes this (but then I get some other issues, which are not relevant here).
The underlying problem
#1692666: [D7] Unset Ckeditor-Plugin upon uninstalling
#1870270: [D7] Disable plugins which not exists and are stored in ckeditor profiles
These issues deal with plugins that are enabled in profiles, but are no longer available because the providing module is disabled.
The solution implemented there is to mark those plugins with "active = 0", if they are no longer available, and with "active = 1" if they are available. In other words, the "active = 0" signifies that the profile still has this plugin, but it is temporarily inactive.
Unfortunately, this solution is not consistently implemented. The "active = 1" is set in ckeditor_modules_enabled(), but there are places where profiles are stored in the database with the "active = 1" setting missing on the plugin settings. Just grep for db_insert('ckeditor_settings') (and also check the db_update('ckeditor_settings')).
Then on features export / update the "active = 1" is missing. Later, after the "active = 1" has been added in the database, the feature shows up as overridden.
Interesting to observe is also that in all places in the code that check for the "active" setting, "active = 1" is equivalent with this setting not being set at all.
Quick fix
The immediate solution is to consistently set "active = 1" in all places in the module where plugin settings are written to the database.
Maybe even add a hook_update_N() to fix existing instances.
Quick fix II
Maybe easier to just add the "active = 1" on features export..
Proposed alternative I
I think we don't really need the "active = 1". Instead we could simply unset it.
- $profile->settings['loadPlugins'][$plugin_name]['active'] = 1;
+ unset($profile->settings['loadPlugins'][$plugin_name]['active']);
Proposed alternative II
If the only meaningful value for a setting is '0', and '1' behaves as if the setting is not set, then maybe we should rename the setting.
E.g. instead of "active = 0" we say "unavailable = 1" or "orphan = 1". In the normal case the setting would simply be not set.
Proposed alternative III
Maybe even better to normalize this stuff and eliminate this setting entirely.
Instead, we expose the list of available plugin names on client side through Drupal.settings.ckeditor.available_plugins.
Then in Drupal.ckeditorLoadPlugins, instead of checking for 'active', we check if the plugin name is in the list of available plugins.
This will require a features update on all sites that already have the "active" setting in their ckeditor profiles.
But I think it is the right thing to do on the long run.
| Comment | File | Size | Author |
|---|---|---|---|
| #12 | 2550535-ckeditor-disabled-plugins-12-interdiff.txt | 682 bytes | jcisio |
| #12 | 2550535-ckeditor-disabled-plugins-12.patch | 8.1 KB | jcisio |
| #10 | 2550535-from-2-8-interdiff.txt | 4.58 KB | jcisio |
| #8 | 2550535-ckeditor-8.patch | 8.31 KB | jcisio |
| #7 | 2550535-ckeditor-7.patch | 8.1 KB | jcisio |
Comments
Comment #2
donquixote commentedPatch with proposed alternative III.
Comment #3
donquixote commentedI guess this plugin lookup list should be cached if we go with this option..
Comment #4
donquixote commentedThe filtering of plugins could also happen on server side..
E.g. in ckeditor_profile_settings_compile() the unavailable plugins could be removed.
Comment #5
jcisio commentedComment #6
jcisio commentedComment #7
jcisio commentedMade a patch in the last direction. I don't think we need cache, it's about 3 ms to load plugins.
Comment #8
jcisio commentedPatch #7 contains a wrong pasted line. Test this one.
Comment #9
donquixote commentedCan you interdiffs? Or publish a git branch or tag somewhere that shows the history from #2 to #7. Or is it totally new?
Comment #10
jcisio commentedI've just move the server/client part from fully server. The removal in hook_modules_enabled/hook_modules_disabled is kept as-is. Here is an interdiff.
Comment #11
jcisio commentedI've just read the patch again and found a bug. Uploading new patch...
Comment #12
jcisio commentedI think I changed the code to something more fancy without testing it again...
Comment #14
jcisio commentedI've checked the patch again. All coding standard clean up aside, the change is small and quite clear. So I went ahead, committed and pushed.