/** * Checks if module has uninstall class * * @return JsonModel */ public function hasUninstallAction() { $params = Json::decode($this->getRequest()->getContent(), Json::TYPE_ARRAY); if (isset($params['moduleName'])) { $uninstallClasses = $this->uninstallCollector->collectUninstall([$params['moduleName']]); } return new JsonModel(['hasUninstall' => isset($uninstallClasses) && sizeof($uninstallClasses) > 0]); }
public function testUninstallRemoveData() { $this->moduleRegistryUninstaller->expects($this->never())->method($this->anything()); $uninstall = $this->getMockForAbstractClass('Magento\\Framework\\Setup\\UninstallInterface', [], '', false); $uninstall->expects($this->atLeastOnce())->method('uninstall')->with($this->setup, $this->isInstanceOf('Magento\\Setup\\Model\\ModuleContext')); $this->collector->expects($this->once())->method('collectUninstall')->willReturn(['moduleA' => $uninstall, 'moduleB' => $uninstall]); $resource = $this->getMock('Magento\\Framework\\Module\\ModuleResource', [], [], '', false); $resource->expects($this->atLeastOnce())->method('getDbVersion')->willReturn('1.0'); $this->output->expects($this->atLeastOnce())->method('writeln'); $this->objectManager->expects($this->once())->method('get')->with('Magento\\Framework\\Module\\ModuleResource')->willReturn($resource); $this->uninstaller->uninstallData($this->output, ['moduleA', 'moduleB']); }
/** * Invoke remove data routine in each specified module * * @param OutputInterface $output * @param array $modules * @return void */ public function uninstallData(OutputInterface $output, array $modules) { $uninstalls = $this->collector->collectUninstall($modules); $setupModel = $this->setupFactory->create(); $resource = $this->objectManager->get('Magento\\Framework\\Module\\ModuleResource'); foreach ($modules as $module) { if (isset($uninstalls[$module])) { $output->writeln("<info>Removing data of {$module}</info>"); $uninstalls[$module]->uninstall($setupModel, new ModuleContext($resource->getDbVersion($module) ?: '')); } else { $output->writeln("<info>No data to clear in {$module}</info>"); } } }
/** * {@inheritdoc} * @SuppressWarnings(PHPMD.CyclomaticComplexity) */ protected function execute(InputInterface $input, OutputInterface $output) { if (!$this->deploymentConfig->isAvailable()) { $output->writeln('<error>You cannot run this command because the Magento application is not installed.</error>'); // we must have an exit code higher than zero to indicate something was wrong return \Magento\Framework\Console\Cli::RETURN_FAILURE; } $modules = $input->getArgument(self::INPUT_KEY_MODULES); // validate modules input $messages = $this->validate($modules); if (!empty($messages)) { $output->writeln($messages); // we must have an exit code higher than zero to indicate something was wrong return \Magento\Framework\Console\Cli::RETURN_FAILURE; } // check dependencies $dependencyMessages = $this->checkDependencies($modules); if (!empty($dependencyMessages)) { $output->writeln($dependencyMessages); // we must have an exit code higher than zero to indicate something was wrong return \Magento\Framework\Console\Cli::RETURN_FAILURE; } $helper = $this->getHelper('question'); $question = new ConfirmationQuestion('You are about to remove code and/or database tables. Are you sure?[y/N]', false); if (!$helper->ask($input, $output, $question) && $input->isInteractive()) { return \Magento\Framework\Console\Cli::RETURN_FAILURE; } try { $output->writeln('<info>Enabling maintenance mode</info>'); $this->maintenanceMode->set(true); $this->takeBackup($input, $output); $dbBackupOption = $input->getOption(self::INPUT_KEY_BACKUP_DB); if ($input->getOption(self::INPUT_KEY_REMOVE_DATA)) { $this->removeData($modules, $output, $dbBackupOption); } else { if (!empty($this->collector->collectUninstall())) { $question = new ConfirmationQuestion('You are about to remove a module(s) that might have database data. ' . 'Do you want to remove the data from database?[y/N]', false); if ($helper->ask($input, $output, $question) || !$input->isInteractive()) { $this->removeData($modules, $output, $dbBackupOption); } } else { $output->writeln('<info>You are about to remove a module(s) that might have database data. ' . 'Remove the database data manually after uninstalling, if desired.</info>'); } } $this->moduleRegistryUninstaller->removeModulesFromDb($output, $modules); $this->moduleRegistryUninstaller->removeModulesFromDeploymentConfig($output, $modules); $this->moduleUninstaller->uninstallCode($output, $modules); $this->cleanup($input, $output); $output->writeln('<info>Disabling maintenance mode</info>'); $this->maintenanceMode->set(false); } catch (\Exception $e) { $output->writeln('<error>' . $e->getMessage() . '</error>'); $output->writeln('<error>Please disable maintenance mode after you resolved above issues</error>'); return \Magento\Framework\Console\Cli::RETURN_FAILURE; } }
public function testCollectUninstall() { $objectManagerProvider = $this->getMock('Magento\Setup\Model\ObjectManagerProvider', [], [], '', false); $objectManager = $this->getMockForAbstractClass('Magento\Framework\ObjectManagerInterface', [], '', false); $objectManagerProvider->expects($this->once())->method('get')->willReturn($objectManager); $setup = $this->getMock('Magento\Setup\Module\DataSetup', [], [], '', false); $adapterInterface = $this->getMockForAbstractClass( 'Magento\Framework\DB\Adapter\AdapterInterface', [], '', false ); $select = $this->getMock('Magento\Framework\DB\Select', ['from'], [], '', false); $adapterInterface->expects($this->once())->method('select')->willReturn($select); $setup->expects($this->exactly(2))->method('getConnection')->willReturn($adapterInterface); $result = $this->getMock('Magento\Framework\DB\Select', [], [], '', false); $select->expects($this->once())->method('from')->willReturn($result); $adapterInterface->expects($this->once()) ->method('fetchAll') ->with($result) ->willReturn([['module' => 'Magento_A'], ['module' => 'Magento_B'], ['module' => 'Magento_C']]); $uninstallA = 'Uninstall Class A'; $uninstallB = 'Uninstall Class B'; $objectManager->expects($this->any()) ->method('create') ->will( $this->returnValueMap([ ['Magento\A\Setup\Uninstall', [], $uninstallA], ['Magento\B\Setup\Uninstall', [], $uninstallB], ]) ); $objectManager->expects($this->any())->method('get') ->with('Magento\Setup\Module\DataSetup') ->willReturn($setup); $collector = new UninstallCollector($objectManagerProvider); $this->assertEquals(['Magento_A' => 'Uninstall Class A'], $collector->collectUninstall()); }
public function testExecuteAll() { $input = ['module' => ['Magento_A', 'Magento_B'], '-c' => true, '-r' => true]; $this->setUpExecute($input); $this->cleanupFiles->expects($this->once())->method('clearMaterializedViewFiles'); $uninstallMock = $this->getMockForAbstractClass('Magento\Framework\Setup\UninstallInterface', [], '', false); $uninstallMock->expects($this->once()) ->method('uninstall') ->with($this->setup, $this->isInstanceOf('Magento\Setup\Model\ModuleContext')); $this->uninstallCollector->expects($this->once()) ->method('collectUninstall') ->willReturn(['Magento_A' => $uninstallMock]); $this->tester->execute($input); }
/** * Invoke remove data routine in each specified module * * @param string[] $modules * @param OutputInterface $output * @param bool $dbBackupOption * @return void */ private function removeData(array $modules, OutputInterface $output, $dbBackupOption) { if (!$dbBackupOption) { $output->writeln('<error>You are removing data without a database backup.</error>'); } else { $output->writeln('<info>Removing data</info>'); } $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>"); } } }
public function testUninstallCollectorWithInput() { $this->result->expects($this->once())->method('where')->willReturn($this->result); $this->adapterInterface->expects($this->once())->method('fetchAll')->with($this->result)->willReturn([['module' => 'Magento_A']]); $this->assertEquals(['Magento_A' => 'Uninstall Class A'], $this->collector->collectUninstall(['Magento_A'])); }