Hi,
First, thanks for writing this module. It was a real help understanding the drupal 7 'nodeapi' hooks.
I noticed that the variables in the variable table aren't cleaned up on uninstall. This is a minor issue and a case could be made that the code responsible for cleaning up could distract developers from the real thing, which is, the 'nodeapi' hooks.
But I do think this is the right place to let developers know they are responsible for cleaning up their own variables form the variable table on uninstall. Hence I attach a patch to fix this. I also added some comments in hook_uninstall explaining why to clean up.
A little note: this is the first time I created (and submitted) a patch so I hope it's ok.
| Comment | File | Size | Author |
|---|---|---|---|
| #22 | examples.nodeapi_example_uninstall_1115944_22.patch | 8.79 KB | jn2 |
| #18 | examples.nodeapi_example_uninstall_1115944_18.patch | 8.42 KB | rfay |
| #13 | 1115944-again-again.patch | 10.09 KB | mile23 |
| #11 | 1115944_again.patch | 0 bytes | mile23 |
| #6 | nodeapi_example_1115944.patch | 1.77 KB | mile23 |
Comments
Comment #1
ilo commentedThanks for submitting this, braahm. I'd also include a note about 'why not use direct database delete of variables starting with nodeapi_example', but I guess this module may not be the best example for that.
I agree with you about the developer being responsible of deleting the variables, +1 to include it. Patch seems fine, minor cosmetic changes would do.
Now that I see the purpose in the phpdoc header of the uninstall hook, I can't recall any examples for hook_enable or hook_disable methods, and I'm unsure if it is enough to understand that hook_uninstall only runs when the module is completely uninstalled, not only disabled.
Comment #2
rfayWhile you're at it, please mention in the comment *not* to do "delete from variable where name like 'module_%'"" because it deletes unintentional things.
Comment #3
dave reidComment #4
Anonymous (not verified) commentedThanks for the replies. I updated the patch with the following:
1. explanation that hook_uninstall wont be called when disabling the module
2. a note about why calling variable_del instead of doing a mysql delete operation
I don't know what cosmetic changes need to be done. Could you specify what should be done and I'm more than willing to make the changes.
Comment #5
sun1) Missing () after function name.
2) Wraps too early (before 80 chars).
Wraps too early. But also, isn't this documented in hook_uninstall() already? If it's going to be kept, it can be merged with the first paragraph (actually should be prepended to it).
No leading blank lines, please.
1) The actual module name seems to be "nodeapi_example", not "nodeapi".
2) Never ever use shortcuts such as "don't" in code comments. Not everyone is a native speaker, and even more importantly, not using them enforces a plain and strict language on you.
1) Missing quotes around the variable name.
2) Dynamic parts in function and variables are usually denoted with all-uppercase letters, or alternatively
[variable].Content type are two words.
Repetition?
1) Missing ().
2) "Call foo() to do bar." would sound more natural to me.
1) Trailing white-space.
2) The reasoning needs a bit more explanation to be valid. Doing a wildcard delete on "nodeapi_example_*" surely won't delete unintentional things...
1) This code can be cleaned and shortened into:
...whereas $name is the type name and $type is a node type object.
2) Missing space after foreach.
3) This uninstallation code only takes current node types into account. Does this nodeapi_example module implement the Node Content Type API hook to delete a potentially existing variable when a content type is deleted? (which can happen anytime)
So that being said, the wildcard variable delete approach is valid, at the very least, if your module stores data on behalf of other modules/factors that do not provide a clean CRUD/API to interact with, so your module might never ever have a chance to clean up the stuff it stored. Shit happens.
Powered by Dreditor.
Comment #6
mile23I think we need a wildcard deletion here, because the admin could delete a node type that we have a variable for, and it would remain in the variable table unto eternity, even after we uninstall.
I'd wager this is also a problem in other examples, as well. Who volunteers to look? :-)
See also: #93528: Improve variable_del() by adding another function: variable_del_prefix()
Comment #7
mile23Comment #8
rfayActually, the approach here is not a good example. In this case it's unlikely to fail, but there are many modules that can accidentally delete other module's variables.
The deletion should be based on an explicit list.
Comment #9
mile23Well that would mean reworking the module so it stores a list of which node types to rate, rather than relying on a variable naming convention. Also a demonstration of how to cache that variable for the session. You volunteering? :-)
Comment #10
rfayHmm.
As you know, the problem is that one module's uninstall can delete another module's variables. I saw this actually happen once. An example would be amazon module cleaning up its variables... and accidentally deleting amazon_store's variables.
Can you think of an authoritative way we can query the variables in this case without making that mistake?
Comment #11
mile23One way to do it might be to have a hash of the module name instead of the module name. So b8402bd1149e4f204fb7fd0ad733c59c_NODETYPE if it's md5. Utterly unreadable.... so perhaps the first five chars, plus module name as self-documentation: b8402_example_nodeapi_NODETYPE.
For the Amazon examples it would be: 2d0d4_amazon_stuff and 9681d_amazon_store_stuff. That's unique enough to prevent the problem.
So if the spec is 'create an over-designed best-practice for naming your variables,' then here's a patch with a solution. Drupal really should give us a way to do this.
Comment #12
rfaySorry. I think I'm being annoying.
I do not want to change the variable naming convention. I just want to adhere to best practice of not accidentally deleting somebody else's variables. I'll take a look at this in a little bit and see if I can come up with a reasonable solution.
Comment #13
mile23Wow that applied REEEEEELY cleanly. :-)
Let's try again (again).
Comment #14
mile23There's no way around it other than to change the naming convention, or to change the way the variables are stored. Alternately there could be another table, but variables are so handy and already in the cache.
Comment #15
mile23Also I think my solution is pretty reasonable. :-)
Comment #16
rfayReally sorry, because I'm not trying to make you jump through hoops. It's important to keep this as simple as possible, and introducing hashes won't do that.
Could we compromise on your #6 with a variable naming scheme of nodeapi_example_node_type_$nodetype ? That way a module would have to exist with the name nodeapi_example_node_type (probably) to have a collision, and it's unlikely.
Then just a little note in the uninstall explaining that querying the table is unusual, but we have to do it here because we have no record of what variables have been created, and that a normal module would just do a variable_del on variables it knows it's created. (block_example_uninstall() render_example_uninstall() and image_example_uninstall() are examples of the more normal case)
Comment #17
mile23So in this code, it means changing a form element name to nodeapi_example_node_type, which is not descriptive of the form element. Swap it out for something like nodeapi_example_nodetype_settings and it works both ways, but it's still awkward.
I'll let you do the honors. :-)
Comment #18
rfayOK, ever so sorry. This is built on #6 with just a little bit of fudging here are there.
And I really didn't understand the problem here (dynamically created variables) when I made my first comment, or perhaps my responses would have been more intelligent.
Comment #19
jn2 commentedThis section has already been added by the commit for issue #767204: API.drupal.org: Rework Doxygen comments so people can navigate the comments, so the patch doesn't apply.
So I couldn't test it. Otherwise this patch looks good to me. Just a couple of minor issues with the comments.
I wonder if the namespace is not actually 'nodeapi_example_node_type_', not just 'nodeapi_example_' as it appears here.
Typo. 'This allows our data to STAY in the database...'
Comment #20
jn2 commentedIf someone can confirm my namespace issue in #19, I'll re-roll the patch.
Comment #21
mile23Yes, you're correct, the namespace should be 'nodeapi_example_node_type_'. Thanks for the re-roll. :-)
Comment #22
jn2 commentedHere's the patch.
Comment #23
jn2 commentedComment #24
jn2 commentedI checked this out and it seems to work fine. The testbot likes it. I'll commit tomorrow unless someone says there's a reason not to.
Comment #25
rfayThanks so much for your work on this.
Comment #26
jn2 commentedPushed to both 7.x-1.x and 8.x-1.x.