One of the last things that was added to 5.0 before the code freeze was a hook_uninstall. However, there is currently no UI for uninstalling a module.

How I picture this happening:

1. admin/build/modules gets two tabs: "administer" which is the default primary tab and contains the current page. then "uninstall" which is a new page.

2. The "uninstall" page loads a list of any disabled modules. Each one gets a button called "Uninstall"

3. When clicking on the button, you are given a confirm form that the data and variables associated with this module will be deleted. (If possible, you even show an excerpt of this data.)

4. Upon clicking "Uninstall", the module's hook_uninstall will fire which should drop tables, delete nodes, delete variables, delete taxonomy terms created, and all the other things that this module does. It is very destructive and this should be reflected in the message in #3.

This needs to be fixed before 5.0 can be released, hence I marked this "critical."

Support from Acquia helps fund testing for Drupal Acquia logo

Comments

merlinofchaos’s picture

I like this approach.

If uninstall is its own page, we can probably use checkboxes to be consistent with the normal module administration page.

hunmonk’s picture

i propose that we use merlin's suggestion, and build this now as a separate module. worst case scenario is that it will be available in contrib for those who want it.

we need to get this done soon, b/c it sure would be nice to have it available for testing w/ the betas...

profix898’s picture

Status: Active » Needs work
FileSize
3.33 KB

I put together a very first version of an uninstall ui patch. It lacks a confirm page atm, but all the rest works nicely.

hunmonk’s picture

Assigned: Unassigned » hunmonk
Status: Needs work » Needs review
FileSize
1.92 KB

i've got one better--here's a complete tested and working uninstall module, with confirm screens.

webchick’s picture

Er. Why a new module? Doesn't this belong in system.module?

Will try and test this tomorrow.

profix898’s picture

FileSize
6.32 KB

I agree with webchick. Uninstall is core functionality and must not be an optional module IMO.
The patch is the completed version from patch for system.module above (incl. messages/confirm page/...). I'm not a native speaker, thus help text and messages need work.

hunmonk’s picture

FileSize
7.2 KB

alrighty then, in core it is!

both our versions had some good ideas, so this patch combines them and puts the functionality in system.module as requested. Patch has been tested on a clean HEAD and appears to work perfectly. Code notation and doxygen included... :)

webchick’s picture

Status: Needs review » Needs work

Here's a quick review.

I enabled both Aggregator and Blog modules, made some bunk content, and then disabled them. Then went to "uninstall modules" and only Aggregator was available (this is because blog doesn't have an uninstall hook; nothing to do with this patch).

I ran Aggregator's uninstall routine and got the following:

* The selected modules have been uninstalled.
* The selected modules have been uninstalled.

* user warning: Unknown table 'aggregator_category' query: DROP TABLE aggregator_category in /Applications/MAMP/htdocs/head/includes/database.mysql.inc on line 157.
* user warning: Unknown table 'aggregator_category_feed' query: DROP TABLE aggregator_category_feed in /Applications/MAMP/htdocs/head/includes/database.mysql.inc on line 157.
* user warning: Unknown table 'aggregator_category_item' query: DROP TABLE aggregator_category_item in /Applications/MAMP/htdocs/head/includes/database.mysql.inc on line 157.
* user warning: Unknown table 'aggregator_feed' query: DROP TABLE aggregator_feed in /Applications/MAMP/htdocs/head/includes/database.mysql.inc on line 157.
* user warning: Unknown table 'aggregator_item' query: DROP TABLE aggregator_item in /Applications/MAMP/htdocs/head/includes/database.mysql.inc on line 157.

Looks like the uninstall hook is being called twice?

When I hit "Cancel" i'm taken back to admin/settings/uninstall which is not a path so I just get the generic admin/settings page. Should be admin/build/uninstall, I think.

I'll try to do a more thorough review later with all of the rest of the core modules and document oddities.

webchick’s picture

Weird. The second time I enabled, disabled, and ran the uninstall routine for Aggregator I didn't have the duplicate problem. Hmmm...

profix898’s picture

Status: Needs work » Needs review
FileSize
7.6 KB

Really nice, hunmonk :) There are just some minor issues:
- wrong path for canceled uninstall => should be 'admin/build/modules/uninstall'
- confirm page title is much too long ('WARNING: The following modules ...'')
- existence of .info file is not essential for being able to uninstall a module (although without it the module wouldnt get listed under modules)
- 'No modules are available to uninstall.' should be a 'empty table' message. Thats more consistent with e.g. taxonomy term tables.

hunmonk’s picture

"// If hook exist, the module can be uninstalled." should be "// If the hook exists, the module can be uninstalled."

also, "t('confirm modules uninstall')," is a bit clunky. i think just "confirm uninstall" would be better english. also, shouldn't the first word be capitalized? not sure on that...

nice catches on the other stuff!

profix898’s picture

FileSize
7.6 KB

Comments/messages corrected. Thanks.

hunmonk’s picture

FileSize
8 KB

so i got to thinking that this stuff belongs in install.inc--no need to load it for every page! system module now only contains the menu calls, help, and a small wrapper function that includes install.inc and invokes the uninstall stuff.

also fixed those two small grammer errors i noted above.

once again patch tested and working on latest HEAD.

drumm’s picture

On code organization- install.inc looks to just have a bunch of API functions. The added code isn't API, but code for user interfaces. I think user interface code (which is specific to the system module) belongs somewhere in the system module's directory, either in system module or a conditionally-included file.

profix898’s picture

The uninstall UI stuff is not that much code, so I think it should be in system.module directly OR we should move all modules-related stuff (admin modules (enable/disable) + uninstall modules) into an include file, e.g. system_modules.inc. I guess we should prefer the include file, because the modules-related code is a large piece in system.module now and it is used only on the two pages.

@hunmonk: Please inform me in case you agree but you cant do the .inc stuff now.

merlinofchaos’s picture

I concur on the conditional include, and think that's probably true for the bulk of the administrative pages as well, and starting on such a path here would be a good thing.

You probably want to do just the uninstall stuff in a conditional include; if that's accepted, a followup patch could move other system.module administrative pages into that same include.

hunmonk’s picture

the code from my last patch is portable to any other include file--just move it there and change the include statement in the wrapper--then we'll need just a couple more include statements in the uninstall functions to grab the install.inc file when it's needed. i like the idea of another include file in the system module--if somebody will throw a name my way for the name of that include, then i'll take two minutes and change it over for the uninstall stuff as our starter. admin.inc?

lemme know...

hunmonk’s picture

FileSize
8.14 KB

after some discussion in IRC, i gathered that system.inc in the system folder was the way to go, so here is the adjusted patch-- tested and working on current HEAD.

i only moved the uninstall stuff over there for now. after this lands, then we can start moving over other admin functions.

RobRoy’s picture

Status: Needs review » Needs work

Took a quick spin of this for aggregator. Works nicely.

One bug I found. If you don't select any modules to uninstall, you get the "No modules selected." error and then if you click a module from THAT page and submit, the form does nothing. Clicking the module again from the form without the error msg, works.

Also, I think the warning messages need be more blatant and in your face as this is a serious operation. I guess only giving 'uninstall' perms to the super admin will alleviate that, but really driving home the fact that THIS WILL DELETE YOUR DATA.

Good work hunmonk! Way to keep the DB clean.

hunmonk’s picture

FileSize
8.2 KB

attached patch fixes the bug RobRoy reported. apparently the button count advances on this validation error, although i'm not sure why, and the form won't properly submit in that state. i don't see any reasonable way to manipulate the button count, so i went with a drupal_set_message, drupal_goto combo in the validation function. since we're only validating that the form is not empty, this should work fine.

as far as the error messages--i'll let someone with more theming knowledge take care of that. :)

hunmonk’s picture

Status: Needs work » Needs review
RobRoy’s picture

Works great hunmonk. Yeah, the warning message is good enough as is. A good ole +1 from me.

profix898’s picture

FileSize
8.15 KB

"the code from my last patch is portable to any other include file" No, I guess its not that simple ;)

- drupal_uninstall_... should be system_... were are back in 'system' namespace
- also system_... should be an internal function (_system_...), it is not to be called from outside system.module.
- added #theme parameter to avoid auto-generated theme__system_... (double underscore)
- use drupal_get_path() to find the path to system.inc (in system.module)

hunmonk’s picture

i'm not sure i agree with some of these changes.

while i do understand the system_ name in the system space argument, i'm not so sure these should be private system functions. i'm pretty sure that other modules could invoke these functions for their own custom package uninstallations. looking at the code, if we were to simply add an optional second argument to what used to be drupal_modules_uninstall: drupal_modules_uninstall($form_values = NULL, $disabled_modules = NULL)

then:

if (!isset($disabled_modules)) {
  $disabled_modules = db_query("SELECT name, filename FROM {system} WHERE type = 'module' AND status = 0 AND schema_version > %d ORDER BY name", SCHEMA_UNINSTALLED);
}

this would allow other modules to invoke the uninstall stuff as generic functions, building their own custom list of modules to disable--possibly good for bigger contribs that have a lot of sub-modules, and want a custom uninstall interface.

i suppose this approach would rightly move the code back out of system.inc, and maybe into uninstall.inc in /includes

thoughts?

profix898’s picture

I dont think uninstall should be a generic function! Some big module packages (ecommerce?) may provide a page to enable/disable dependent modules, but they shouldnt provide uninstall feature IMO. This functionality should be available only in one central place, the modules administration page. Reasons: 1. uninstall is not needed for configuring a module (being able to disable it is really enough) and 2. it is a much too destructive operation to be integrated into the module settings.

We could think to add your proposed feature for enabling/disabling a set of modules. But thats another issue.

hunmonk’s picture

FileSize
8.27 KB

your theme call is wrong--theme_ is automatically prepended... :)

also, if we're sticking w/ internal functions, then we can remove the = NULL form the function declaration for _system_modules_uninstall -- as it will always be passed from the wrapper.

attached patch corrects these, and has been tested as working.

profix898’s picture

"your theme call is wrong" - oh yeah, thats what happens with copy/paste ;) Thanks.

All in all I think we can live with the latest patch. Hope others will agree.

hunmonk’s picture

FileSize
8.27 KB

updated patch to reflect the new capitalization scheme in core. no functionality change whatsoever.

chx’s picture

code / forms are OK.

webchick’s picture

Status: Needs review » Reviewed & tested by the community

Enabled every single core module, and disabled every single core module, then went to the uninstall page, checked all, and went from there. No errors, tables/variables were deleted as expected. RTBC.

hunmonk’s picture

FileSize
7.62 KB

per Steven's suggestions:

  • got rid of the all caps WARNING -- excessive
  • add emphasis tags around the 'all data will be lost' text
  • some minor spacing corrections
  • changed the tab names to 'List' and 'Uninstall'
  • moved the functions back to system.module -- we're not ready to move the admin stuff to a .inc file yet. this also allowed some slight simplification in the fapi calls.

once again, tested as working on a clean HEAD.

webchick’s picture

Confirmed. Ran through some more testing and seems good to go.

profix898’s picture

FileSize
7.7 KB

"moved the functions back to system.module"

you forgot to remove #validate and #submit, these are no longer needed

Dries’s picture

Status: Reviewed & tested by the community » Fixed

Committed to CVS HEAD. Thanks.

profix898’s picture

Status: Fixed » Needs review
FileSize
1.99 KB

Is there any reason, why the help text didnt get committed?
(Also #33 redundant #validate / #submit was included)

hunmonk’s picture

Status: Needs review » Reviewed & tested by the community

ah, the #validate/#submit was needed when the code was living in system.inc--good catch! i removed them and tested, and things still function as advertised, so they should in fact be removed.

dunno why the help text wasn't put in. it was in my original patch.

this needs to go in. RTBC

hunmonk’s picture

FileSize
2.89 KB

attached patch implements the help text in a much cleaner way, and removes the extraneous #validate/#submit handlers. tested as working.

Tobias Maier’s picture

'<p>'. t('The uninstall process removes all
is better than
t('<p>The uninstall process removes all

profix898’s picture

Status: Reviewed & tested by the community » Needs work

Sorry, doesnt work. I will post a fixed version shortly.

profix898’s picture

Status: Needs work » Needs review
FileSize
5.38 KB

- #validate/#submit handlers removed (#33/#35)
- new help text implementation without $POST (#37) also for 'modules/list'
- fixed broken #action path (wrapped in url())

@Tobias: Not sure about the <p>, all the messages in system_help() are implemented this way.

webchick’s picture

Status: Needs review » Needs work

Tobias is right about <p>. The less HTML in t() you can get away with, the better. Fix that and this should be good to go.

webchick’s picture

Also, I should point out that the system_help function includes lots of HTML in order to provide additional context to translators. In this case, it's just a simple string, so the HTML should be left out.

profix898’s picture

Status: Needs work » Reviewed & tested by the community
FileSize
5.39 KB

'<p>'. stuff fixed

Dries’s picture

Status: Reviewed & tested by the community » Fixed

Committed to CVS HEAD. Thanks.

Anonymous’s picture

Status: Fixed » Closed (fixed)