13

Apparently, now Magento 2 supports uninstall scripts that allow db schema modification when uninstalling a module (horay!!).
As explained in here this only works for module installed via composer.
(I hope it will work in the future for all modules, but that's a different issue).
Let's say I have a module called Testing_Demo.
This module does 3 things that I would like to be removed when uninstalling it.

  1. adds a table called testing_demo. So I need to drop it.
  2. adds a product attribute called demo. So this needs to be removed
  3. has some settings in system->configuration that might or might not be stored in the table core_config_data. All these settings have the path testing_demo/.... So these need to be removed also.

How should my module uninstall script look like?

  • I guess your uninstallation script should be more like a integration test to see if the removal of your extensions will f up the frontend or the schema relations – Anton S Aug 10 '15 at 13:09
  • I cannot contradict you there. you are probably right, but how do I do that? :) – Marius Aug 10 '15 at 13:13
  • I have no idea jet but in theory you should know if the data you collect can be dropped or not and therefore the uninstallation process should be a step by step guide that instructs a merchant to verify if the following process has effects on merchant liabilities on accounting , on clients etc . so the part that is purely technical is probably easy to traverse layouts and see if your extension is referenced , extended , others are depending etc parts that are uniform to all extensions but the business decisions behind are still up to merchant to decide and you can only point out conflicts – Anton S Aug 10 '15 at 13:25
  • the dependency should be handled before the uninstall so this is not my problem. Let's say I decided to remove the extension completely, and there is nothing depending on it. – Marius Aug 10 '15 at 13:34
  • so you just need to narrow this down to plain dumping tables and data side of things? – Anton S Aug 10 '15 at 15:39
18

Searching the codebase for UninstallInterface gives \Magento\Setup\Model\UninstallCollector.

If you search for UninstallCollector then, you'll find that's used in \Magento\Setup\Console\Command\ModuleUninstallCommand. Particularly relevant:

    $uninstalls = $this->collector->collectUninstall();
    $setupModel = $this->objectManager->get('Magento\Setup\Module\Setup');
    foreach ($modules as $module) {
        if (isset($uninstalls[$module])) {
            $output->writeln("<info>Removing data of $module</info>");
            $uninstalls[$module]->uninstall(
                $setupModel,
                new ModuleContext($this->moduleResource->getDbVersion($module) ?: '')
            );
        } else {
            $output->writeln("<info>No data to clear in $module</info>");
        }
    }

Put together, we can surmise:

  1. Your module should contain an Uninstall class at {module}\Setup\Uninstall.php.
  2. This class should implement Magento\Framework\Setup\UninstallInterface.
  3. This class should have an uninstall method containing any necessary logic.
  4. The same objects and methods are available to you as in any setup or upgrade script.

So, here's your skeleton:

<?php

namespace \Custom\Module\Setup;

class Uninstall implements \Magento\Framework\Setup\UninstallInterface
{
    /**
     * Module uninstall code
     *
     * @param \Magento\Framework\Setup\SchemaSetupInterface $setup
     * @param \Magento\Framework\Setup\ModuleContextInterface $context
     * @return void
     */
    public function uninstall(
        \Magento\Framework\Setup\SchemaSetupInterface $setup,
        \Magento\Framework\Setup\ModuleContextInterface $context
    ) {
        $setup->startSetup();

        // Uninstall logic here

        $setup->endSetup();
    }
}

Remove any tables, columns, or data using the appropriate methods. See \Magento\Framework\DB\Adapter\AdapterInterface, available as $setup->getConnection().

  • Thanks for the answer. I will test and come back with a result. – Marius Aug 10 '15 at 20:30
  • @Marius you didn't mention whether it is working for you or not. Additionally I would like to know will this uninstall script runs directly or it will be triggered when we run module:uninstall – Adnan Apr 17 '17 at 7:50
  • 1
    @Adnan. Yes. It worked. The script is called when running the console command do uninstall the module. – Marius Apr 17 '17 at 9:06
  • @Marius, In case you have a team, what should do other developers? each of them locally should run command? Is any case to run it automatically with next pull? – sergio Oct 6 '17 at 7:53
  • [Exception] Deprecated Functionality: Methods with the same name as their class will no t be constructors in a future version of PHP; Uninstall has a deprecated co nstructor in .../Setup/Uninstall .php on line 5 – Pini Jun 24 '18 at 10:32

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.