This issue grew out of #306027: user_modules_uninistalled() is missing. Looking at drupal_uninstall_module(), it seems to me that the function is very non-Drupal. It calls a module-specific hook and then does some menu cleanup.
However, we also need to do permission, block, and other types of automated cleanup. Now we could force the developer to do these in hook_uninstall(), but it seems a better solution is a hook that lets modules act on their 'child' hooks.
That is, the current logic for menu cleanup should go into a menu.inc function.
Proposed hook would be hook_uninstall_module(), whith $module a string as parameter.
Some uses:
-- user.module user_uninstall_module($module) to remove permissions set by the module.
-- menu.inc menu_uninstall_module($module) to remove menu items set by the module.
-- block.module block_uninstall_module($module) to remove blocks set by the module.
-- node.module node_uninstall_module($module) to remove node types items created by the module.
This could also apply to trigger, filter, and other core modules. Making it a hook would also let contibuted modules (like Views) perform cleanups.
We could also use a similar function that fires a hook on module enable/disable, so that modules can react to changes in the module list.
| Comment | File | Size | Author |
|---|---|---|---|
| #36 | 306151-schema-based-install_5.patch | 26.72 KB | David_Rothstein |
| #31 | 306151-schema-based-install.patch | 25.92 KB | agentrickard |
| #28 | 306151-schema-based-install.patch | 25.92 KB | agentrickard |
| #26 | 306151-schema-based-install.patch | 25.2 KB | agentrickard |
| #23 | 306151-schema-based-install.patch | 23.77 KB | agentrickard |
Comments
Comment #1
dave reidActually this would be a perfect use for #253569: DX: Add hook_modules to act on other module status changes! Yay! Working on patch...
Comment #2
dave reidHere's just some functions that would show what would be changed. Not a patch.
Comment #3
agentrickardI support hook_module(). Then we can use this issue for implementing the above list of implementations.
Comment #4
Anonymous (not verified) commented+1 - subscribe
Comment #5
moshe weitzman commentedThat pseudo patch is quite nice. Anyone available to refine and re-submit?
Comment #6
dave reidTrying to keep all these module uninstall issues in one post...
#306027: user_modules_uninistalled() is missing
#320303: Remove module menus on uninstall
#335237: DX: Remove module filters on uninstall
#335240: DX: Remove module blocks on uninstall
Comment #7
dave reidComment #8
babbage commentedSubscribing.
Comment #9
dave reidAdding #420124: DX: Remove module actions on uninstall.
Comment #10
agentrickardHere is a test patch to get this rolling.
It appears that we can simply call the schema hooks directly, which removes an unneeded module_load_install(), since the schema function calls that.
Tested by removing hook_install() from comment module and removing drupal_uninstall_schema() from comment_uninstall().
I think this is the right approach -- it lets us remove cruft and streamline DX.
Comment #12
babbage commentedSubscribing.
Comment #13
catchRe-titling, interesting patch.
Comment #14
agentrickard@catch
This was a DX movement that Dave Reid and I were workin on and we got sidetracked. The idea is simple:
Module authors should not need to declare their own schema (un)installs, since Drupal is smart enough to do that for them. In fact, there are a number of related tasks that can be automated.
Comment #15
agentrickardPatch applies cleanly in dev. The problem is that it will break almost all tests, since we have to remove the duplicate install/uninstall calls.
Comment #16
damien tournoud commented(1) why removing the module_load_install() call?
(2) I would rather see the schema installation happen *after* we called the uninstall hook.
Comment #17
agentrickard1) Because drupal_uninstall_schema() calls module_load_install() already, so we don't need both. (It happens in http://api.drupal.org/api/function/drupal_get_schema_unprocessed/7)
2) This comment makes no sense. Installation after uninstallation? You mean reverse the order. Call the module's hook_uninstall() in case the module needs to act on its data?
In that case, we would need the module_load_install(). But are there use-cases for modules that act to cleanup after their own data?
Comment #18
moshe weitzman commentedSure he meant "would rather see the schema uninstallation happen *after* we called the uninstall hook". I agree that this sounds safer. Some uninstall logic may depend on the state of the tables.
Comment #19
catchThe uninstall hook absolutely has to run while the tables are still there - if I need to call an API function for the uninstalled module to do clean up something in my module, the tables have to be there for that to work (say cleaning out vocabulary related tables when taxonomy module is uninstalled).
Comment #20
webchickI would love to see this fixed before code freeze. It's always embarrassing explaining to people that they need to explicitly install/uninstall their tables.
Comment #21
agentrickard@webchick
Does that mean you want to see a patch against all of core using the pattern defined in #17?
Comment #22
agentrickardFor the record, there is an instance in book.install that validates Damien's correction.
Comment #23
agentrickardAnd here we go. For some reason, this patch breaks SimpleTest entirely, but I can't figure out why.
Comment #24
agentrickardBumping to get some eyes on the testing problem.
Comment #26
agentrickardBah. This fails because drupal_install_schema() -- used in system_install() -- doesn't update the schema version of a module, which makes no sense to me.
I account for that by wrapping db_create_table() in db_table_exists() check, which fixes the problem.
But the schema install functions are spread out all over the place. Some are in common.inc and some are in install.inc. I think they should all be centralized in database.inc, and the db_install_schema should update the {system} table.
But that is a different patch.
Comment #28
agentrickardThis seems to work fine now. Let's see what testbot says!
Comment #30
agentrickardThis works, but testbot hates it. I have no idea how to make the bot happy.
Comment #31
agentrickardFound out why the tests fail, I think. Trying again.
Comment #32
Crell commentedAbout time we used the schema properly...
Comment #33
David_Rothstein commentedThis patch would make it impossible to uninstall a whole bunch of modules via the Drupal user interface - since only modules which implement hook_uninstall() show up on the list.
I've leaving this RTBC because that can probably be fixed in a very simple followup, but it's critical that it be fixed if this patch goes in.
Comment #34
Crell commentedShould be easy to add. Just show any module with an uninstall hook OR a schema hook. Problem solved.
Comment #35
agentrickard@David_Rothstein
Then why do all tests pass? Can you prove this? Happy to fix if you can provide an error.
Comment #36
David_Rothstein commentedHm, it's a good question why there is no test that catches this. I checked, and we do have a test that uninstalls modules via the UI, but it uses the aggregator module when doing so, and that module still has a hook_uninstall() even after this patch, so that's why it doesn't catch it. I suppose we could change it to use a different module that would catch this case, but it would be somewhat fragile to rely on that anyway, so maybe not worth doing.
Anyway, as was said above, this is easy to fix. The attached patch is identical to the previous one, except for the addition of this:
Pretty trivial, so still RTBC.
To see the difference between this patch and the previous one, try disabling the database logging module and then going to the uninstall page. The previous patch would not give you an option to uninstall the module via the UI (and therefore you'd be stuck with the watchdog table around forever), but this one does.
Comment #37
agentrickardExcellent catch!
Comment #38
dries commentedGreat little improvement. Committed this to CVS HEAD. This needs to be documented in the upgrade instructions so marking this as 'code needs work'. Set to 'fixed' after it has been properly documented. Thanks!
Comment #39
dropcube commentedNeeds Documentation
Comment #40
agentrickardhttp://drupal.org/node/224333#install-schema
Comment #41
robloachAwesome to the max!
Comment #43
decipheredI know this was marked as done quite some time ago, but I notice that with the latest dev release of Drupal 7 that if a module doesn't have hook_uninstall defined it will not show up in the uninstall list or uninstall the schema, which I distinctly see discussed in this issue.
Was it rolled back? Do I need to have hook_uninstall defined even when it has no contents?
Cheers,
Deciphered.
Comment #44
dave reidNo, it should list any modules that have hook_uninstall *or* hook_schema.
Comment #45
decipheredDave,
A module I was using definitely wasn't showing up in the uninstall list when it did have hook_schema defined but not hook_uninstall.
It does appear to be working now. I did update to todays dev release (from yesterdays) between the time of creating my previous post, so that could have been the cause.
Either way, it definitely wasn't showing up and is now, so I will re-close this unless I manage to uncover anymore information.
Cheers,
Deciphered.
Comment #46
geerlingguy commentedHmm... #1031120: Uninstallation doesn't remove tables.
Comment #47
WhiplashInfo commentedDubble Hhhhmmmm:
This isn't fixed:
http://drupal.org/node/1031120#comment-4863198
Just now I tryed to activate User Revisions as the core tell my that it exist. But that didn't worked. I was given a PDOException:
---------------------------
PDOException: SQLSTATE[42S02]: Base table or view not found: 1146 Table 'web25518_drup1.user_revision' doesn't exist: update user_revision set vid=0 where uid=0;; Array ( ) in user_revision_install() (line 165 of /home/web25518/domains/fmedk.se/public_html/d/sites/all/modules/user_revision/user_revision.install).
---------------------------
I use Core version 7.7
Thanks / Tomas