Right now, Drupal has the following horrible code that runs inside filter.module when a text format is deleted:
$default = variable_get('filter_default_format', 1);
// Replace existing instances of the deleted format with the default format.
db_query("UPDATE {node_revision} SET format = %d WHERE format = %d", $default, $form_state['values']['format']);
db_query("UPDATE {comment} SET format = %d WHERE format = %d", $default, $form_state['values']['format']);
db_query("UPDATE {box} SET format = %d WHERE format = %d", $default, $form_state['values']['format']);
This is a problem for several reasons:
- As of Drupal 7, there is at least one more set of database tables in Drupal core that can store text formats (those provided by the Field API).
- It doesn't allow for any text formats stored by contrib modules to be updated. This was one of the main reasons why SA-2008-073 was a somewhat serious security issue.
- It's just plain ugly for the filter module to hardcode stuff about other modules' database tables, especially since some of those database tables aren't even guaranteed to exist in Drupal 7 (another aspect of the bug...)
A simple proposal to fix this is that we change this to a module_invoke_all() that informs other modules that a text format was just deleted.
However, a bigger issue is that it's not even clear that switching things over to the default text format is the correct behavior when a format is deleted... There are cases where that will lead to weird results. So do we let people do it and warn them about the possible problems? Do we give them various options? Do we try to detect if the format being deleted is still in use on the site (probably difficult, but maybe it could be done by polling modules via a hook)? Something else?
Comment | File | Size | Author |
---|---|---|---|
#24 | drupal.format-hooks.24.patch | 15.5 KB | sun |
#22 | drupal.format-hooks.22.patch | 11.71 KB | sun |
#21 | drupal.format-hooks.patch | 11.71 KB | sun |
#19 | formats-hooks-428296-19.patch | 10.04 KB | dropcube |
#17 | formats-hooks-428296-17.patch | 9.86 KB | dropcube |
Comments
Comment #1
yched CreditAttribution: yched commentedAdditional issue about Field API 'text fields' is that :
- a mass update can be expensive
- you cannot even assume SQL storage...
Comment #2
Damien Tournoud CreditAttribution: Damien Tournoud commentedRoadmap suggestion:
- add a hook_filter_delete()
- implement hook_filter_delete() in node.module, comment.module, block.module and text.module (is there others?)
- possibly, make customer modules form_alter to the filter deletion confirmation form in the case deleting a filter could lead to potential disasters
Comment #3
sunDeletion is only part of the picture. Any possible content caches need to be flushed whenever a text format is altered in any way. Enabling/reconfiguring/disabling filters and deleting a text format both must trigger this hook.
Additionally:
- Page cache must be flushed
- Block cache must be flushed
- Search index must be reset (contains not only indexed content itself, but also excerpts of filtered [and strip_tags()'ed] content)
So we probably need hook_filter_update($format) and hook_filter_delete($format).
drupal_flush_all_caches() would be an alternative to hook_filter_update(), but that would flush each and everything, while we only want to flush the cache for affected stuff.
Comment #4
sun.
Comment #5
catchThis is also needed for #369011: Performance: do check_markup() in text_field_load().
Attached patch adds the two hooks next to the cache_clear_all() - I didn't add documentation or attempt to clear up any of the existing mess there - which also means that the _update hook gets invoked on insert as well. Not planning to work on this beyond here but wanted to see this in the patch queue instead of active.
Comment #6
bjaspan CreditAttribution: bjaspan commentedsubscribe
Comment #7
dropcube CreditAttribution: dropcube commentedHere, the 'object' being altered is a format (text format) not a filter, why the hooks are called
hook_filter_update($format)
andhook_filter_delete($format)
, instead ofhook_format_update($format)
hook_format_delete($format)
Comment #8
dropcube CreditAttribution: dropcube commentedAttached patch uses hook_format_* instead of hook_filter_*, implements the hooks in block.module, comment.module and text.module, and add hooks documentation to filter.api.php
There still a TODO in text.module. Fields in core experts required ;)
Comment #10
sunHook names need to be in the namespace of the providing module. So if you want to use *format_*, then you have to use hook_filter_format_*().
Comment #11
dropcube CreditAttribution: dropcube commentedOk, here is the patch using hook_filter_format_* and fixing the exceptions reported by the tests.
Comment #12
dropcube CreditAttribution: dropcube commentedTagging.
Comment #13
yched CreditAttribution: yched commented"DX" tag: this is not only DX, it's a condition for text Fields to work properly.
Comment #14
catchIndentation issue.
Exceeds 80 characters.
I think this should be a (critical, bug), followup issue rather than a TODO.
All the changes here look really sane and those nitpicks are very minor. I think we could do with some very basic tests like some of the other hook tests in core (set a variable if it's required, check the value before and after, that sort of thing) - or maybe do that as part of the text.module implementation. Apart from that it's ready to go.
It's not required by the use cases we currently have, but is it possible/worth adding hook_filter_format_insert() separate to _update()?
I'm on crack. Are you, too?
Comment #15
dropcube CreditAttribution: dropcube commentedThanks catch for the review.
Updated patch.
- Fixed minor issues pointed by catch.
- Added
hook_filter_format_insert()
, for consistency, though there is no use case in core.- Added test module filter_test.module to test filter hooks that are not implemented in core.
- Added tests for the hooks introduced.
- Remove incomplete implementation of the hook in text.module, it's better to fix that in a separate issue: #556022: When a text format is deleted, some modules (like text.module) don't update their data, even though we say they do
Comment #17
dropcube CreditAttribution: dropcube commentedUpdated patch, rerolled for #556832: Add text format API to manipulate formats.
Comment #19
dropcube CreditAttribution: dropcube commentedForgot to add hook_filter_format_delete(), and there was a test for it already!
Comment #20
sunI'll try to re-roll this.
Missing trailing comma.
(and elsewhere) Trailing white-space here.
(and elsewhere) Please always add a newline to the end of files to avoid this diff message.
(and elsewhere) Please remove the empty blank line.
Also containing trailing white-space.
@see should come last. Only put @see right below a PHPDoc paragraph, if the paragraph refers to some really special stuff that's not tightly coupled with the function at hand.
Something weird going on here. ;)
We can remove the quotes here.
Beer-o-mania starts in 5 days! Don't drink and patch.
Comment #21
sunFixed those issues and
- Reworked filter_format_delete() to take a format object (instead of the format id) like the other CUD functions.
- Reworked filter_admin_delete() accordingly - another arg() bites the dust - yay! :)
- Reworked hook_filter_format_delete() to pass on the default format (object), to make it easier for modules to perform their updates and decrease the chance that someone retrieves a wrong default format.
RTBC if the bot comes back green.
Comment #22
sunsorry, silly typo in that last patch.
Comment #24
sunFixing the tests and also
- Changed the menu router item path from admin/settings/formats/delete to admin/settings/formats/%text_format/delete to make the whole thing even more trivial.
Comment #25
dropcube CreditAttribution: dropcube commentedRTBC as far as I can see.
This review is powered by Dreditor.
Comment #26
Dries CreditAttribution: Dries commentedLooks great. Committed to CVS HEAD. Thanks for the steady stream of great work, sun and dropcube.