Desinstalar módulos y sus tablas con los scripts de desinstalación en Magento2

Scripts de desinstalación en Magento2

Hace un tiempo escribí sobre cómo crear los scripts de creación y actualización de esquema de base de datos en nuestros módulos.

Una de las novedades de Magento2 es que ofrece la posibilidad de crear scritps de desinstalación.

Siguiendo con el módulo Barbanet_SampleModule voy a agregar entonces el script correspondiente.

Dentro del directorio Setup creamos el archivo Uninstall.php. Acorde a mi ejemplo anterior de creación, simplemente voy a eliminar la tabla creada en la base de datos.

Dicho esto, mi clase quedaría así:

namespace Barbanet\SampleModule\Setup;
 
use Magento\Framework\Setup\UninstallInterface;
use Magento\Framework\Setup\SchemaSetupInterface;
use Magento\Framework\Setup\ModuleContextInterface;
 
/**
 * @codeCoverageIgnore
 */
class Uninstall implements UninstallInterface
{
 
    public function uninstall(SchemaSetupInterface $setup, ModuleContextInterface $context)
    {
        $installer = $setup;
        $installer->startSetup();
 
        /**
         * Drop table 'samplemodule_table'
         */
        $installer->getConnection()->dropTable($installer->getTable('barbanet_samplemodule'));
 
        $installer->endSetup();
    }
}

Hasta aquí todo parece muy bonito. Ahora nos tocaría ejecutar el comando de desinstalación, pero hay una primera salvedad que hay que remarcar: para poder desinstalar un módulo con la consola de Magento2 es necesario que sea un paquete instalado con Composer.

Si ejecutara esto para un módulo que estuviera desarrollando, pasaría que recibiría este error:

Barbanet_SampleModule is not an installed composer package

Bien, por eso he instalado el módulo en una instancia limpia.

Barbanet_SampleModule instalado vía Composer
Barbanet_SampleModule instalado vía Composer

Y al revisar la base de datos, veremos que la tabla se ha creado.

Barbanet_SampleModule instalado vía Composer

Ahora si estaríamos en condiciones de proceder con la desinstalación. Volvemos a la consola y ejecutamos:

bin/magento module:uninstall Barbanet_SampleModule

Y veremos (y debermos responder 2 preguntas):

You are about to remove code and/or database tables. Are you sure?[y/N]y
Enabling maintenance mode
You are about to remove a module(s) that might have database data. Do you want to remove the data from database?[y/N]y
You are removing data without a database backup.
Removing data of Barbanet_SampleModule
Removing Barbanet_SampleModule from module registry in database
Removing Barbanet_SampleModule from module list in deployment configuration
Removing code from Magento codebase:
Cache cleared successfully.
Generated classes cleared successfully. Please run the 'setup:di:compile' command to generate classes.
Info: Some modules might require static view files to be cleared. To do this, run 'module:uninstall' with the --clear-static-content option to clear them.
Disabling maintenance mode

Y ahora si, al mirar en el proyecto veremos que el código ha sido eliminado y que la tabla fue eliminada también (se ha ejecutado lo que hemos programado dentro de nuestro desinstalador).

Hay un detalle que debe tenerse en cuenta con respecto a Magento2 y composer. Quizás les suceda que al intentar desinstalar reciban un mensaje de error como este.

You are about to remove code and/or database tables. Are you sure?[y/N]y
Enabling maintenance mode
You are about to remove a module(s) that might have database data. Do you want to remove the data from database?[y/N]y
You are removing data without a database backup.
Removing data of Barbanet_SampleModule
Removing Barbanet_SampleModule from module registry in database
Removing Barbanet_SampleModule from module list in deployment configuration
Removing code from Magento codebase:

Habrá una demora en donde no sucederá nada y aparece el mensaje:

Command "remove" failed: Loading composer repositories with package information
Authentication required (repo.magento.com):
Username:       Password:

[Composer\Downloader\TransportException]
Invalid credentials for 'https://repo.magento.com/packages.json', aborting.

remove [--dev] [--no-progress] [--no-update] [--update-no-dev] [--update-with-dependencies] [--ignore-platform-reqs] [packages1] ... [packagesN]
Please disable maintenance mode after you resolved above issues

Esto sucede porque Magento busca las credenciales para Composer en un lugar específico y no en el home del usuario.

Dicha ubicación es, dentro del directorio de Magento, en: var/composer_home.

Entonces, para que todo funcione correctamente, deberíamos hacer un link simbólico (en lugar de copiar) de nuestro archivo auth.json dentro de este directorio.

ln -s ~/.composer/auth.json .

Luego de esto ya funcionará todo correctamente.

Hay más información sobre este tema en el issue #2523 en GitHub. (Gracias a Alan Storm que me indicó que el error obtenido era similar al de ese issue y podría servir como punto de partida para buscar una solución).