First off, the current callback method of deactivating the extensions is simply not working as far as the dropping of the extension's tables are concerned - wonder when was the last time it worked, if ever.
Lines 213 to 225 of the current admin/inst_module.php file are:
foreach($exts as $i => $ext) {
if ($ext['package'] && ($ext['active'] ^ check_value('Active'.$i))) {
if (!$ext['active'])
$activated = activate_hooks($ext['package'], $comp);
else
$activated = hook_invoke($ext['package'], check_value('Active'.$i) ?
'activate_extension':'deactivate_extension', $comp, false);
if ($activated !== null)
$result &= $activated;
if ($activated || ($activated === null))
$exts[$i]['active'] = check_value('Active'.$i);
}
}
The second line (first if) above has an XOR (^) which means that the code fragment is executed only if either
the extension was already active or
the activate extension checkbox has just been ticked and submitted
but not both.
The second "if" activates the extension using the direct function activate _hooks() if it was inactive which because of the XOR condition above would mean that the activate extension checkbox had just been ticked. This works correctly and the module gets installed. However, this does not happen through the callback portion of the hook_invoke() function through which it is never called. The use of the direct function activate _hooks() was necessary since the value of the $Hooks global array variable is empty when it enters the activate_extension() method by callback if the hook_invoke() was used.
The "else" of the second "if" triggers the callback only for the deactivate_extension() method when the activate extension checkbox has just been unticked whilst the extension was active. Here, the value of the $Hooks global array variable is empty when it enters the said deactivate_extension() method which exits without executing the deactivation sql if any. It is for this reason that the new direct function deactivate_hooks() was used to do the job.
The esoteric callback method in hook_invoke() seems to make the code quite a bit of a challenge for the average user to comprehend and I was initially blinded to conclude that the said deactivate_extension() method was never called. We should try to use simple and easy to understand constructs for ease of debugging / troubleshooting by the average user for mass trusted adoption.
Steps to reproduce:
1. Install and activate for one company any extension (currently, only dashboard extension has a drop sql separately) that creates tables and has a means to drop them as well. Alternatively create an extension that only creates one table and then on deactivation drops that table and then install and activate it for one company.
2. Now choose to deactivate it for the company for which it is currently active.
3. Check and find that the newly created table(s) have not been dropped despite deactivation.
4. Use my new function method and then repeat the steps above and you will find successful deactivation with the newly created table(s) dropped.