/** * Validate the given module name or ask the user to select a module from a list of installed modules. * * <p>This method is available to console tasks only. * * @param string $moduleName A variable reference. If empty, it will be set to the selected module name. * @param callable $filter Display only modules that match a filtering condition. * <p>Callback syntax: <code>function (ModuleInfo $module):bool</code> * @param bool $suppressErrors Do not abort execution with an error message if the module name is not valid. * @return bool false if the specified module name does not match an installed module * @internal param bool $onlyEnabled Display only modules that are enabled. */ function selectModule(&$moduleName, callable $filter = null, $suppressErrors = false) { if ($moduleName) { if (!ModulesRegistry::validateModuleName($moduleName)) { if ($suppressErrors) { return false; } $this->io->error("Invalid module name {$moduleName}. Correct syntax: vendor-name/product-name"); } if (!$this->registry->isInstalled($moduleName)) { if ($suppressErrors) { return false; } $this->io->error("Module {$moduleName} is not installed"); } if ($filter && !$filter($this->registry->getModule($moduleName))) { if ($suppressErrors) { return false; } $this->io->error("Module {$moduleName} can't be renamed"); } } else { $modules = $this->registry->onlyPrivateOrPlugins()->only($filter)->getModuleNames(); if ($modules) { $i = $this->io->menu("Select a module:", $modules); if ($i < 0) { $this->io->cancel(); } $moduleName = $modules[$i]; } else { if ($suppressErrors) { return false; } $this->io->error("No modules are available"); } } return true; }
/** * Scaffolds a new project module * * @param string|null $moduleName The full name (vendor-name/module-name) of the module to be created * @param string $scaffold The scaffold's folder name. */ private function makeModuleFromScaffold($moduleName, $scaffold) { $io = $this->io; $moduleName = $moduleName ?: $io->askDefault("Module name", "company-name/project-name"); if (!ModulesRegistry::validateModuleName($moduleName)) { $io->error("Invalid module name {$moduleName}. Correct syntax: company-name/project-name"); } if ($this->modulesRegistry->isInstalled($moduleName)) { $io->error("You can't use that name because a module named {$moduleName} already exists"); } $___MODULE___ = $moduleName; $___NAMESPACE___ = ModuleInfo::moduleNameToNamespace($___MODULE___); $___CLASS___ = explode('\\', $___NAMESPACE___)[1] . 'Module'; if (!$moduleName) { $___NAMESPACE___ = $io->askDefault("PHP namespace for the module's classes", $___NAMESPACE___); $___CLASS___ = $io->askDefault("Name of the class that represents the module:", $___CLASS___); } $___PSR4_NAMESPACE___ = str_replace('\\', '\\\\', "{$___NAMESPACE___}\\"); $path = "{$this->kernelSettings->modulesPath}/{$___MODULE___}"; if (is_dir($path)) { $io->say("A directory for that module already exists, but the module is not registered.\nIf you proceed, the directory contents will be discarded."); if (!$io->confirm("Proceed")) { $io->cancel(); } (new DeleteDir($path))->run(); } $io->mute(); (new CopyDir(["{$this->settings->scaffoldsPath()}/{$scaffold}" => $path]))->run(); $this->fs->rename("{$path}/src/Config/___CLASS___.php", "{$path}/src/Config/{$___CLASS___}.php")->run(); foreach (["{$path}/src/Config/{$___CLASS___}.php", "{$path}/src/Config/Navigation.php", "{$path}/src/Config/Routes.php", "{$path}/composer.json"] as $file) { (new Replace($file))->from(['___MODULE___', '___CLASS___', '___NAMESPACE___', '___PSR4_NAMESPACE___', '___MODULE_PATH___'])->to([$___MODULE___, $___CLASS___, $___NAMESPACE___, $___PSR4_NAMESPACE___, $path])->run(); } $io->unmute(); // Register the module's namespace $cfg = new ComposerConfigHandler(); $require = $cfg->get('require', []); $require[$moduleName] = 'self.version'; $cfg->set('require', $require); $cfg->save(); $this->composerUpdate(); // It also updates the modules registry $io->done("Module <info>{$___MODULE___}</info> was created"); }