diff --git a/README.md b/README.md index 6e42f49..bef1b86 100644 --- a/README.md +++ b/README.md @@ -211,6 +211,19 @@ class AddDemoCulumnToOxUserMigration extends oxMigrationQuery *Note: It is better to use generator for migration queries creation* +## Run Module Migration +*Note: Currently this is an experimental feature* + +We have now an experimental feature to run migration files from modules itself. Now we can put module-related migration files inside the 'migration' directory of the module. + +Module + -- migration + -- XXX.PHP + +You can pass '--skip-module-migration' option to skip to run module migration files. +``` + migration:run --skip-module-migration +``` # Related Projects * https://github.com/OXIDprojects/oxid-module-internals * https://github.com/OXIDprojects/oxid_modules_config diff --git a/src/Command/MigrateCommand.php b/src/Command/MigrateCommand.php index f82b3e5..5178f48 100644 --- a/src/Command/MigrateCommand.php +++ b/src/Command/MigrateCommand.php @@ -13,6 +13,7 @@ use Symfony\Component\Console\Input\InputInterface; use Symfony\Component\Console\Output\OutputInterface; use Symfony\Component\Console\Input\InputArgument; +use Symfony\Component\Console\Input\InputOption; use Symfony\Component\Console\Output\NullOutput; use OxidEsales\Eshop\Core\Registry; use OxidProfessionalServices\OxidConsole\Core\Exception\ConsoleException; @@ -37,7 +38,12 @@ public function configure() ->setName('migration:run') ->setAliases(['migrate']) ->setDescription('Run database migration scripts') - ->addArgument('timestamp', InputArgument::OPTIONAL, "Migration to use for execution"); + ->addArgument('timestamp', InputArgument::OPTIONAL, "Migration to use for execution") + ->addOption('skip-module-migration', null, InputOption::VALUE_NONE, "Skip migration files from modules") + ->setHelp(<<<'EOF' +Command %command.name% will skip migration files from modules. +EOF + ); } /** @@ -52,12 +58,19 @@ public function execute(InputInterface $input, OutputInterface $output) exit(1); } + $output->writeln("NOTE: Running module migrations is currently an experimental feature."); + $output->writeln(" You can skip this by using '--skip-module-migration'."); $output->writeln('Running migration scripts'); $debugOutput = $input->getOption('verbose') ? $output : new NullOutput(); + if ($input->getOption('skip-module-migration')) { + $output->writeln('Skipping Module Migration...'); + MigrationHandler::$skipModuleMigration = true; + } + /** @var MigrationHandler $oMigrationHandler */ $oMigrationHandler = Registry::get(MigrationHandler::class); $oMigrationHandler->run($timestamp, $debugOutput); diff --git a/src/Core/Migration/MigrationHandler.php b/src/Core/Migration/MigrationHandler.php index feae701..fd9b3d3 100644 --- a/src/Core/Migration/MigrationHandler.php +++ b/src/Core/Migration/MigrationHandler.php @@ -15,9 +15,12 @@ use RecursiveDirectoryIterator; use RecursiveIteratorIterator; use RegexIterator; +use AppendIterator; use Symfony\Component\Console\Output\OutputInterface; use OxidEsales\Eshop\Core\DatabaseProvider; use OxidProfessionalServices\OxidConsole\Core\Exception\MigrationException; +use OxidEsales\Eshop\Core\Registry; +use OxidEsales\Eshop\Core\Module\ModuleList; /** * Migration handler for migration queries @@ -55,6 +58,11 @@ class MigrationHandler */ protected $queries = array(); + /** + * @var bool skip module migration + */ + public static $skipModuleMigration = false; + /** * Constructor. * @@ -229,9 +237,37 @@ protected function buildMigrationQueries() } $oDirectory = new RecursiveDirectoryIterator($this->migrationQueriesDir); - $oFlattened = new RecursiveIteratorIterator($oDirectory); + $oIterators = new AppendIterator(); + $oIterators->append(new RecursiveIteratorIterator($oDirectory)); + + // Include module migration files + if (!self::$skipModuleMigration) { + $oConfig = Registry::getConfig(); + + if (!class_exists(ModuleList::class)) { + throw new MigrationException('ERROR: Oxid ModuleList class can not be loaded, ' + . 'please try to run vendor/bin/oe-eshop-unified_namespace_generator'); + } else { + // TODO: We need to use shop internal services to get active modules path + $moduleList = oxNew(ModuleList::class); + $modulesDir = $oConfig->getModulesDir(); + $activeModules = $moduleList->getActiveModuleInfo(); + + if (is_array($activeModules) and count($activeModules) > 0) { + foreach ($activeModules as $activeModule) { + $migrationQueryDir = $modulesDir . $activeModule . DIRECTORY_SEPARATOR . + 'migration' . DIRECTORY_SEPARATOR; + if (!is_dir($migrationQueryDir)) { + continue; + } + $oDirectory = new RecursiveDirectoryIterator($migrationQueryDir); + $oIterators->append(new RecursiveIteratorIterator($oDirectory)); + } + } + } + } - $aFiles = new RegexIterator($oFlattened, AbstractQuery::REGEXP_FILE); + $aFiles = new RegexIterator($oIterators, AbstractQuery::REGEXP_FILE); foreach ($aFiles as $sFilePath) { include_once $sFilePath;